diff options
| -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 */ |
