ARM: rockchip: add iomap and soc id support
author黄涛 <huangtao@rock-chips.com>
Wed, 11 Dec 2013 11:55:37 +0000 (19:55 +0800)
committer黄涛 <huangtao@rock-chips.com>
Wed, 11 Dec 2013 11:56:05 +0000 (19:56 +0800)
arch/arm/mach-rockchip/Makefile
arch/arm/mach-rockchip/cpu.c [new file with mode: 0644]
arch/arm/mach-rockchip/cpu.h [new file with mode: 0644]
arch/arm/mach-rockchip/iomap.h [new file with mode: 0644]
arch/arm/mach-rockchip/rk3188.c

index 1a6b65bd130532afee5f4b1cf17868d98db485f2..83ae96d69a37e6bfb651b73029534f78cf33a432 100644 (file)
@@ -1,4 +1,5 @@
 obj-y += common.o
+obj-y += cpu.o
 obj-y += rk3188.o
 obj-$(CONFIG_SMP) += platsmp.o
 obj-$(CONFIG_FIQ_DEBUGGER) += rk_fiq_debugger.o
diff --git a/arch/arm/mach-rockchip/cpu.c b/arch/arm/mach-rockchip/cpu.c
new file mode 100644 (file)
index 0000000..114d5b2
--- /dev/null
@@ -0,0 +1,81 @@
+#include <linux/kernel.h>
+#include <linux/cpu.h>
+#include "cpu.h"
+
+unsigned long rockchip_soc_id;
+EXPORT_SYMBOL(rockchip_soc_id);
+
+static ssize_t type_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       const char *type;
+
+       if (cpu_is_rk319x())
+               type = "rk319x";
+       else if (cpu_is_rk3188())
+               type = "rk3188";
+       else if (cpu_is_rk3066b())
+               type = "rk3066b";
+       else if (cpu_is_rk3026())
+               type = "rk3026";
+       else if (cpu_is_rk30xx())
+               type = "rk30xx";
+       else if (cpu_is_rk2928())
+               type = "rk2928";
+       else
+               type = "";
+
+       return sprintf(buf, "%s\n", type);
+}
+
+static struct device_attribute type_attr = __ATTR_RO(type);
+
+static ssize_t soc_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       const char *soc;
+
+       if (soc_is_rk3190())
+               soc = "rk3190";
+       else if (soc_is_rk3188plus())
+               soc = "rk3188+";
+       else if (soc_is_rk3188())
+               soc = "rk3188";
+       else if (soc_is_rk3168())
+               soc = "rk3168";
+       else if (soc_is_rk3028())
+               soc = "rk3028";
+       else if (soc_is_rk3066b())
+               soc = "rk3066b";
+       else if (soc_is_rk3028a())
+               soc = "rk3028a";
+       else if (soc_is_rk3026())
+               soc = "rk3026";
+       else if (soc_is_rk2928g())
+               soc = "rk2928g";
+       else if (soc_is_rk2928l())
+               soc = "rk2928l";
+       else if (soc_is_rk2926())
+               soc = "rk2926";
+       else if (soc_is_rk3066())
+               soc = "rk3066";
+       else if (soc_is_rk3068())
+               soc = "rk3068";
+       else if (soc_is_rk3000())
+               soc = "rk3000";
+       else
+               soc = "";
+
+       return sprintf(buf, "%s\n", soc);
+}
+
+static struct device_attribute soc_attr = __ATTR_RO(soc);
+
+static int __init rockchip_cpu_lateinit(void)
+{
+       int err;
+
+       err = device_create_file(cpu_subsys.dev_root, &type_attr);
+       err = device_create_file(cpu_subsys.dev_root, &soc_attr);
+
+       return err;
+}
+late_initcall(rockchip_cpu_lateinit);
diff --git a/arch/arm/mach-rockchip/cpu.h b/arch/arm/mach-rockchip/cpu.h
new file mode 100644 (file)
index 0000000..06cef95
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __MACH_ROCKCHIP_CPU_H
+#define __MACH_ROCKCHIP_CPU_H
+
+extern unsigned long rockchip_soc_id;
+
+#define ROCKCHIP_CPU_MASK       0xffff0000
+#define ROCKCHIP_CPU_RK2928     0x29280000
+#define ROCKCHIP_CPU_RK3026     0x30260000
+#define ROCKCHIP_CPU_RK30XX     0x30660000
+#define ROCKCHIP_CPU_RK3066B    0x31680000
+#define ROCKCHIP_CPU_RK3188     0x31880000
+#define ROCKCHIP_CPU_RK319X     0x31900000
+
+static inline bool cpu_is_rk2928(void)  { return (rockchip_soc_id & ROCKCHIP_CPU_MASK) == ROCKCHIP_CPU_RK2928; }
+static inline bool cpu_is_rk3026(void)  { return (rockchip_soc_id & ROCKCHIP_CPU_MASK) == ROCKCHIP_CPU_RK3026; }
+static inline bool cpu_is_rk30xx(void)  { return (rockchip_soc_id & ROCKCHIP_CPU_MASK) == ROCKCHIP_CPU_RK30XX; }
+static inline bool cpu_is_rk3066b(void) { return (rockchip_soc_id & ROCKCHIP_CPU_MASK) == ROCKCHIP_CPU_RK3066B; }
+static inline bool cpu_is_rk3188(void)  { return (rockchip_soc_id & ROCKCHIP_CPU_MASK) == ROCKCHIP_CPU_RK3188; }
+static inline bool cpu_is_rk319x(void)  { return (rockchip_soc_id & ROCKCHIP_CPU_MASK) == ROCKCHIP_CPU_RK319X; }
+
+#define ROCKCHIP_SOC_RK2926     (ROCKCHIP_CPU_RK2928 | 0x00)
+#define ROCKCHIP_SOC_RK2928G    (ROCKCHIP_CPU_RK2928 | 0x01)
+#define ROCKCHIP_SOC_RK2928L    (ROCKCHIP_CPU_RK2928 | 0x02)
+#define ROCKCHIP_SOC_RK3028A    (ROCKCHIP_CPU_RK3026 | 0x03)
+#define ROCKCHIP_SOC_RK3026     (ROCKCHIP_CPU_RK3026 | 0x04)
+#define ROCKCHIP_SOC_RK3000     (ROCKCHIP_CPU_RK30XX | 0x00)
+#define ROCKCHIP_SOC_RK3066     (ROCKCHIP_CPU_RK30XX | 0x01)
+#define ROCKCHIP_SOC_RK3068     (ROCKCHIP_CPU_RK30XX | 0x02)
+#define ROCKCHIP_SOC_RK3066B    (ROCKCHIP_CPU_RK3066B| 0x00)
+#define ROCKCHIP_SOC_RK3168     (ROCKCHIP_CPU_RK3066B| 0x01)
+#define ROCKCHIP_SOC_RK3028     (ROCKCHIP_CPU_RK3066B| 0x03)
+#define ROCKCHIP_SOC_RK3188     (ROCKCHIP_CPU_RK3188 | 0x00)
+#define ROCKCHIP_SOC_RK3188PLUS (ROCKCHIP_CPU_RK3188 | 0x10)
+#define ROCKCHIP_SOC_RK3190     (ROCKCHIP_CPU_RK319X | 0x00)
+
+static inline bool soc_is_rk2926(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK2926; }
+static inline bool soc_is_rk2928g(void) { return rockchip_soc_id == ROCKCHIP_SOC_RK2928G; }
+static inline bool soc_is_rk2928l(void) { return rockchip_soc_id == ROCKCHIP_SOC_RK2928L; }
+static inline bool soc_is_rk3028a(void) { return rockchip_soc_id == ROCKCHIP_SOC_RK3028A; }
+static inline bool soc_is_rk3026(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3026; }
+static inline bool soc_is_rk3000(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3000; }
+static inline bool soc_is_rk3066(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3066; }
+static inline bool soc_is_rk3068(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3068; }
+static inline bool soc_is_rk3066b(void) { return rockchip_soc_id == ROCKCHIP_SOC_RK3066B; }
+static inline bool soc_is_rk3168(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3168; }
+static inline bool soc_is_rk3028(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3028; }
+static inline bool soc_is_rk3188(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3188; }
+static inline bool soc_is_rk3188plus(void) { return rockchip_soc_id == ROCKCHIP_SOC_RK3188PLUS; }
+static inline bool soc_is_rk3190(void)  { return rockchip_soc_id == ROCKCHIP_SOC_RK3190; }
+
+#endif
diff --git a/arch/arm/mach-rockchip/iomap.h b/arch/arm/mach-rockchip/iomap.h
new file mode 100644 (file)
index 0000000..d153568
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __MACH_ROCKCHIP_IOMAP_H
+#define __MACH_ROCKCHIP_IOMAP_H
+
+#define RK_IO_ADDRESS(x)        IOMEM(0xFED00000 + x)
+
+#define RK_CRU_VIRT             RK_IO_ADDRESS(0x00000000)
+#define RK_GRF_VIRT             RK_IO_ADDRESS(0x00010000)
+#define RK_PMU_VIRT             RK_IO_ADDRESS(0x00020000)
+#define RK_ROM_VIRT             RK_IO_ADDRESS(0x00030000)
+#define RK_EFUSE_VIRT           RK_IO_ADDRESS(0x00040000)
+#define RK_GPIO_VIRT(n)         RK_IO_ADDRESS(0x00050000 + (n) * 0x1000)
+#define RK_DEBUG_UART_VIRT      RK_IO_ADDRESS(0x00060000)
+#define RK_CPU_AXI_BUS_VIRT     RK_IO_ADDRESS(0x00070000)
+#define RK_TIMER_VIRT           RK_IO_ADDRESS(0x00080000)
+#define RK_DDR_VIRT             RK_IO_ADDRESS(0x000d0000)
+
+#define RK3188_CRU_PHYS         0x20000000
+#define RK3188_CRU_SIZE         SZ_4K
+#define RK3188_GRF_PHYS         0x20008000
+#define RK3188_GRF_SIZE         SZ_4K
+#define RK3188_PMU_PHYS         0x20004000
+#define RK3188_PMU_SIZE         SZ_4K
+#define RK3188_ROM_PHYS         0x10120000
+#define RK3188_ROM_SIZE         SZ_16K
+#define RK3188_EFUSE_PHYS       0x20010000
+#define RK3188_EFUSE_SIZE       SZ_4K
+#define RK3188_GPIO0_PHYS       0x2000a000
+#define RK3188_GPIO1_PHYS       0x2003c000
+#define RK3188_GPIO2_PHYS       0x2003e000
+#define RK3188_GPIO3_PHYS       0x20080000
+#define RK3188_GPIO_SIZE        SZ_4K
+#define RK3188_CPU_AXI_BUS_PHYS 0x10128000
+#define RK3188_CPU_AXI_BUS_SIZE SZ_32K
+#define RK3188_TIMER0_PHYS      0x20038000
+#define RK3188_TIMER3_PHYS      0x2000e000
+#define RK3188_TIMER_SIZE       SZ_4K
+#define RK3188_DDR_PCTL_PHYS    0x20020000
+#define RK3188_DDR_PCTL_SIZE    SZ_16K
+#define RK3188_DDR_PUBL_PHYS    0x20040000
+#define RK3188_DDR_PUBL_SIZE    SZ_16K
+
+#endif
index 7bbfa61c669ea76f46cf4f877d385116d1b309ce..6c3156ee7df6c5b1156fe0074c0641d659054252 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include "core.h"
+#include "cpu.h"
 #include "cpu_axi.h"
+#include "iomap.h"
+
+#define RK3188_DEVICE(name) \
+       { \
+               .virtual        = (unsigned long) RK_##name##_VIRT, \
+               .pfn            = __phys_to_pfn(RK3188_##name##_PHYS), \
+               .length         = RK3188_##name##_SIZE, \
+               .type           = MT_DEVICE, \
+       }
+
+static struct map_desc rk3188_io_desc[] __initdata = {
+       RK3188_DEVICE(CRU),
+       RK3188_DEVICE(GRF),
+       RK3188_DEVICE(PMU),
+       RK3188_DEVICE(ROM),
+       RK3188_DEVICE(EFUSE),
+       RK3188_DEVICE(CPU_AXI_BUS),
+       {
+               .virtual        = (unsigned long) RK_DDR_VIRT,
+               .pfn            = __phys_to_pfn(RK3188_DDR_PCTL_PHYS),
+               .length         = RK3188_DDR_PCTL_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = (unsigned long) RK_DDR_VIRT + RK3188_DDR_PCTL_SIZE,
+               .pfn            = __phys_to_pfn(RK3188_DDR_PUBL_PHYS),
+               .length         = RK3188_DDR_PUBL_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = (unsigned long) RK_GPIO_VIRT(0),
+               .pfn            = __phys_to_pfn(RK3188_GPIO0_PHYS),
+               .length         = RK3188_GPIO_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = (unsigned long) RK_GPIO_VIRT(1),
+               .pfn            = __phys_to_pfn(RK3188_GPIO1_PHYS),
+               .length         = RK3188_GPIO_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = (unsigned long) RK_GPIO_VIRT(2),
+               .pfn            = __phys_to_pfn(RK3188_GPIO2_PHYS),
+               .length         = RK3188_GPIO_SIZE,
+               .type           = MT_DEVICE,
+       },
+       {
+               .virtual        = (unsigned long) RK_GPIO_VIRT(3),
+               .pfn            = __phys_to_pfn(RK3188_GPIO3_PHYS),
+               .length         = RK3188_GPIO_SIZE,
+               .type           = MT_DEVICE,
+       },
+};
 
 static void __init rk3188_dt_map_io(void)
 {
        preset_lpj = 11996091ULL / 2;
+       iotable_init(rk3188_io_desc, ARRAY_SIZE(rk3188_io_desc));
        debug_ll_io_init();
+
+       rockchip_soc_id = ROCKCHIP_SOC_RK3188;
+       if (readl_relaxed(RK_ROM_VIRT + 0x27f0) == 0x33313042
+        && readl_relaxed(RK_ROM_VIRT + 0x27f4) == 0x32303133
+        && readl_relaxed(RK_ROM_VIRT + 0x27f8) == 0x30313331
+        && readl_relaxed(RK_ROM_VIRT + 0x27fc) == 0x56313031)
+               rockchip_soc_id = ROCKCHIP_SOC_RK3188PLUS;
 }
 
-static void __init rk3188_dt_timer_init(void)
+static void __init rk3188_dt_init_timer(void)
 {
        of_clk_init(NULL);
        clocksource_of_init();
 }
 
-static void __init rk3188_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
 static const char * const rk3188_dt_compat[] = {
        "rockchip,rk3188",
        NULL,
 };
 
 DT_MACHINE_START(RK3188_DT, "Rockchip RK3188 (Flattened Device Tree)")
-       //.nr_irqs        = 32*10,
        .smp            = smp_ops(rockchip_smp_ops),
        .map_io         = rk3188_dt_map_io,
-       .init_machine   = rk3188_dt_init,
-       .init_time      = rk3188_dt_timer_init,
+       .init_time      = rk3188_dt_init_timer,
        .dt_compat      = rk3188_dt_compat,
 MACHINE_END