diff options
Diffstat (limited to 'arch/arm/mach-ux500')
-rw-r--r-- | arch/arm/mach-ux500/cpu-db8500.c | 82 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/db8500-regs.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/hardware.h | 23 | ||||
-rw-r--r-- | arch/arm/mach-ux500/include/mach/setup.h | 7 |
4 files changed, 110 insertions, 4 deletions
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index f21c444edd99..4acab7544b3c 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -38,10 +38,12 @@ static struct platform_device *platform_devs[] __initdata = { | |||
38 | /* minimum static i/o mapping required to boot U8500 platforms */ | 38 | /* minimum static i/o mapping required to boot U8500 platforms */ |
39 | static struct map_desc u8500_io_desc[] __initdata = { | 39 | static struct map_desc u8500_io_desc[] __initdata = { |
40 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), | 40 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), |
41 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), | ||
41 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), | 42 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), |
42 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), | 43 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), |
43 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), | 44 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), |
44 | __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), | 45 | __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), |
46 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | static struct map_desc u8500ed_io_desc[] __initdata = { | 49 | static struct map_desc u8500ed_io_desc[] __initdata = { |
@@ -53,6 +55,69 @@ static struct map_desc u8500v1_io_desc[] __initdata = { | |||
53 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), | 55 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), |
54 | }; | 56 | }; |
55 | 57 | ||
58 | /* | ||
59 | * Functions to differentiate between later ASICs | ||
60 | * We look into the end of the ROM to locate the hardcoded ASIC ID. | ||
61 | * This is only needed to differentiate between minor revisions and | ||
62 | * process variants of an ASIC, the major revisions are encoded in | ||
63 | * the cpuid. | ||
64 | */ | ||
65 | #define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOT_ROM_BASE + 0x1FFF4) | ||
66 | #define U8500_ASIC_ID_LOC_V2 (U8500_BOOT_ROM_BASE + 0x1DBF4) | ||
67 | #define U8500_ASIC_REV_ED 0x01 | ||
68 | #define U8500_ASIC_REV_V10 0xA0 | ||
69 | #define U8500_ASIC_REV_V11 0xA1 | ||
70 | #define U8500_ASIC_REV_V20 0xB0 | ||
71 | |||
72 | /** | ||
73 | * struct db8500_asic_id - fields of the ASIC ID | ||
74 | * @process: the manufacturing process, 0x40 is 40 nm | ||
75 | * 0x00 is "standard" | ||
76 | * @partnumber: hithereto 0x8500 for DB8500 | ||
77 | * @revision: version code in the series | ||
78 | * This field definion is not formally defined but makes | ||
79 | * sense. | ||
80 | */ | ||
81 | struct db8500_asic_id { | ||
82 | u8 process; | ||
83 | u16 partnumber; | ||
84 | u8 revision; | ||
85 | }; | ||
86 | |||
87 | /* This isn't going to change at runtime */ | ||
88 | static struct db8500_asic_id db8500_id; | ||
89 | |||
90 | static void __init get_db8500_asic_id(void) | ||
91 | { | ||
92 | u32 asicid; | ||
93 | |||
94 | if (cpu_is_u8500v1() || cpu_is_u8500ed()) | ||
95 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1)); | ||
96 | else if (cpu_is_u8500v2()) | ||
97 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2)); | ||
98 | else | ||
99 | BUG(); | ||
100 | |||
101 | db8500_id.process = (asicid >> 24); | ||
102 | db8500_id.partnumber = (asicid >> 16) & 0xFFFFU; | ||
103 | db8500_id.revision = asicid & 0xFFU; | ||
104 | } | ||
105 | |||
106 | bool cpu_is_u8500v10(void) | ||
107 | { | ||
108 | return (db8500_id.revision == U8500_ASIC_REV_V10); | ||
109 | } | ||
110 | |||
111 | bool cpu_is_u8500v11(void) | ||
112 | { | ||
113 | return (db8500_id.revision == U8500_ASIC_REV_V11); | ||
114 | } | ||
115 | |||
116 | bool cpu_is_u8500v20(void) | ||
117 | { | ||
118 | return (db8500_id.revision == U8500_ASIC_REV_V20); | ||
119 | } | ||
120 | |||
56 | void __init u8500_map_io(void) | 121 | void __init u8500_map_io(void) |
57 | { | 122 | { |
58 | ux500_map_io(); | 123 | ux500_map_io(); |
@@ -63,6 +128,9 @@ void __init u8500_map_io(void) | |||
63 | iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); | 128 | iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); |
64 | else | 129 | else |
65 | iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); | 130 | iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); |
131 | |||
132 | /* Read out the ASIC ID as early as we can */ | ||
133 | get_db8500_asic_id(); | ||
66 | } | 134 | } |
67 | 135 | ||
68 | /* | 136 | /* |
@@ -70,6 +138,20 @@ void __init u8500_map_io(void) | |||
70 | */ | 138 | */ |
71 | void __init u8500_init_devices(void) | 139 | void __init u8500_init_devices(void) |
72 | { | 140 | { |
141 | /* Display some ASIC boilerplate */ | ||
142 | pr_info("DB8500: process: %02x, revision ID: 0x%02x\n", | ||
143 | db8500_id.process, db8500_id.revision); | ||
144 | if (cpu_is_u8500ed()) | ||
145 | pr_info("DB8500: Early Drop (ED)\n"); | ||
146 | else if (cpu_is_u8500v10()) | ||
147 | pr_info("DB8500: version 1.0\n"); | ||
148 | else if (cpu_is_u8500v11()) | ||
149 | pr_info("DB8500: version 1.1\n"); | ||
150 | else if (cpu_is_u8500v20()) | ||
151 | pr_info("DB8500: version 2.0\n"); | ||
152 | else | ||
153 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); | ||
154 | |||
73 | ux500_init_devices(); | 155 | ux500_init_devices(); |
74 | 156 | ||
75 | if (cpu_is_u8500ed()) | 157 | if (cpu_is_u8500ed()) |
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index f000218210c9..f07d0986409d 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h | |||
@@ -30,8 +30,6 @@ | |||
30 | #define U8500_ICN_BASE 0x81000000 | 30 | #define U8500_ICN_BASE 0x81000000 |
31 | 31 | ||
32 | #define U8500_BOOT_ROM_BASE 0x90000000 | 32 | #define U8500_BOOT_ROM_BASE 0x90000000 |
33 | /* ASIC ID is at 0xff4 offset within this region */ | ||
34 | #define U8500_ASIC_ID_BASE 0x9001F000 | ||
35 | 33 | ||
36 | #define U8500_PER6_BASE 0xa03c0000 | 34 | #define U8500_PER6_BASE 0xa03c0000 |
37 | #define U8500_PER5_BASE 0xa03e0000 | 35 | #define U8500_PER5_BASE 0xa03e0000 |
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 8656379a8309..32e883a8f2a2 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h | |||
@@ -104,16 +104,35 @@ static inline bool cpu_is_u8500(void) | |||
104 | #endif | 104 | #endif |
105 | } | 105 | } |
106 | 106 | ||
107 | #define CPUID_DB8500ED 0x410fc090 | ||
108 | #define CPUID_DB8500V1 0x411fc091 | ||
109 | #define CPUID_DB8500V2 0x412fc091 | ||
110 | |||
107 | static inline bool cpu_is_u8500ed(void) | 111 | static inline bool cpu_is_u8500ed(void) |
108 | { | 112 | { |
109 | return cpu_is_u8500() && (read_cpuid_id() & 15) == 0; | 113 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED); |
110 | } | 114 | } |
111 | 115 | ||
112 | static inline bool cpu_is_u8500v1(void) | 116 | static inline bool cpu_is_u8500v1(void) |
113 | { | 117 | { |
114 | return cpu_is_u8500() && (read_cpuid_id() & 15) == 1; | 118 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1); |
119 | } | ||
120 | |||
121 | static inline bool cpu_is_u8500v2(void) | ||
122 | { | ||
123 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V2); | ||
115 | } | 124 | } |
116 | 125 | ||
126 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
127 | bool cpu_is_u8500v10(void); | ||
128 | bool cpu_is_u8500v11(void); | ||
129 | bool cpu_is_u8500v20(void); | ||
130 | #else | ||
131 | static inline bool cpu_is_u8500v10(void) { return false; } | ||
132 | static inline bool cpu_is_u8500v11(void) { return false; } | ||
133 | static inline bool cpu_is_u8500v20(void) { return false; } | ||
134 | #endif | ||
135 | |||
117 | static inline bool cpu_is_u5500(void) | 136 | static inline bool cpu_is_u5500(void) |
118 | { | 137 | { |
119 | #ifdef CONFIG_UX500_SOC_DB5500 | 138 | #ifdef CONFIG_UX500_SOC_DB5500 |
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index e978dbd9e210..54bbe648bf58 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
@@ -38,4 +38,11 @@ extern struct sys_timer ux500_timer; | |||
38 | .type = MT_DEVICE, \ | 38 | .type = MT_DEVICE, \ |
39 | } | 39 | } |
40 | 40 | ||
41 | #define __MEM_DEV_DESC(x, sz) { \ | ||
42 | .virtual = IO_ADDRESS(x), \ | ||
43 | .pfn = __phys_to_pfn(x), \ | ||
44 | .length = sz, \ | ||
45 | .type = MT_MEMORY, \ | ||
46 | } | ||
47 | |||
41 | #endif /* __ASM_ARCH_SETUP_H */ | 48 | #endif /* __ASM_ARCH_SETUP_H */ |