Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: OMAP: Add OMAP chip type structure; clean up mach-omap2/id.c

Add a new OMAP chip identification interface, omap_chip_id.
omap_chip_id is a structure which contains one bit for each OMAP2/3
CPU type, and on 3430, ES level. For example, the CHIP_IS_OMAP2420
bit is set in omap_chip at boot on an OMAP2420. On OMAP3430ES2, both
CHIP_IS_OMAP3430 and CHIP_IS_OMAP3430ES2 bits are set.

omap_chip is set in mach-omap2/id.c by _set_omap_chip(). Other
code should use the omap_chip_is() function to test against omap_chip.

Also, clean up id.c by splitting some code out of
omap_check_revision() into its own function, _set_system_rev(); and
converting some debug printk()s into pr_debug().

Second revision.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>


authored by

Paul Walmsley and committed by
Tony Lindgren
097c584c ff00fcc9

+205 -29
+168 -27
arch/arm/mach-omap2/id.c
··· 17 17 18 18 #include <asm/io.h> 19 19 20 - #if defined(CONFIG_ARCH_OMAP2420) 21 - #define OMAP24XX_TAP_BASE io_p2v(0x48014000) 22 - #endif 20 + #include <asm/arch/control.h> 21 + #include <asm/arch/cpu.h> 23 22 24 - #if defined(CONFIG_ARCH_OMAP2430) 25 - #define OMAP24XX_TAP_BASE io_p2v(0x4900A000) 23 + #if defined(CONFIG_ARCH_OMAP2420) 24 + #define TAP_BASE io_p2v(0x48014000) 25 + #elif defined(CONFIG_ARCH_OMAP2430) 26 + #define TAP_BASE io_p2v(0x4900A000) 27 + #elif defined(CONFIG_ARCH_OMAP34XX) 28 + #define TAP_BASE io_p2v(0x4830A000) 26 29 #endif 27 30 28 31 #define OMAP_TAP_IDCODE 0x0204 32 + #if defined(CONFIG_ARCH_OMAP34XX) 33 + #define OMAP_TAP_PROD_ID 0x0210 34 + #else 29 35 #define OMAP_TAP_PROD_ID 0x0208 36 + #endif 30 37 31 38 #define OMAP_TAP_DIE_ID_0 0x0218 32 39 #define OMAP_TAP_DIE_ID_1 0x021C ··· 63 56 { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, 64 57 }; 65 58 59 + static struct omap_chip_id omap_chip; 60 + 61 + /** 62 + * omap_chip_is - test whether currently running OMAP matches a chip type 63 + * @oc: omap_chip_t to test against 64 + * 65 + * Test whether the currently-running OMAP chip matches the supplied 66 + * chip type 'oc'. Returns 1 upon a match; 0 upon failure. 67 + */ 68 + int omap_chip_is(struct omap_chip_id oci) 69 + { 70 + return (oci.oc & omap_chip.oc) ? 1 : 0; 71 + } 72 + EXPORT_SYMBOL(omap_chip_is); 73 + 66 74 static u32 __init read_tap_reg(int reg) 67 75 { 68 - return __raw_readl(OMAP24XX_TAP_BASE + reg); 76 + unsigned int regval = 0; 77 + u32 cpuid; 78 + 79 + /* Reading the IDCODE register on 3430 ES1 results in a 80 + * data abort as the register is not exposed on the OCP 81 + * Hence reading the Cortex Rev 82 + */ 83 + cpuid = read_cpuid(CPUID_ID); 84 + 85 + /* If the processor type is Cortex-A8 and the revision is 0x0 86 + * it means its Cortex r0p0 which is 3430 ES1 87 + */ 88 + if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) { 89 + switch (reg) { 90 + case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break; 91 + /* Making DevType as 0xF in ES1 to differ from ES2 */ 92 + case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break; 93 + case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break; 94 + case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break; 95 + case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break; 96 + case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break; 97 + } 98 + } else 99 + regval = __raw_readl(TAP_BASE + reg); 100 + 101 + return regval; 102 + 103 + } 104 + 105 + /* 106 + * _set_system_rev - set the system_rev global based on current OMAP chip type 107 + * 108 + * Set the system_rev global. This is primarily used by the cpu_is_omapxxxx() 109 + * macros. 110 + */ 111 + static void __init _set_system_rev(u32 type, u8 rev) 112 + { 113 + u32 i, ctrl_status; 114 + 115 + /* 116 + * system_rev encoding is as follows 117 + * system_rev & 0xff000000 -> Omap Class (24xx/34xx) 118 + * system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) 119 + * system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) 120 + * system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) 121 + * system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) 122 + * system_rev & 0x000000c0 -> IDCODE revision[6:7] 123 + * system_rev & 0x0000003f -> sys_boot[0:5] 124 + */ 125 + /* Embedding the ES revision info in type field */ 126 + system_rev = type; 127 + /* Also add IDCODE revision info only two lower bits */ 128 + system_rev |= ((rev & 0x3) << 6); 129 + 130 + /* Add in the device type and sys_boot fields (see above) */ 131 + if (cpu_is_omap24xx()) { 132 + i = OMAP24XX_CONTROL_STATUS; 133 + } else if (cpu_is_omap343x()) { 134 + i = OMAP343X_CONTROL_STATUS; 135 + } else { 136 + printk(KERN_ERR "id: unknown CPU type\n"); 137 + BUG(); 138 + } 139 + ctrl_status = omap_ctrl_readl(i); 140 + system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | 141 + OMAP2_SYSBOOT_4_MASK | 142 + OMAP2_SYSBOOT_3_MASK | 143 + OMAP2_SYSBOOT_2_MASK | 144 + OMAP2_SYSBOOT_1_MASK | 145 + OMAP2_SYSBOOT_0_MASK)); 146 + system_rev |= (ctrl_status & OMAP2_DEVICETYPE_MASK); 147 + } 148 + 149 + 150 + /* 151 + * _set_omap_chip - set the omap_chip global based on OMAP chip type 152 + * 153 + * Build the omap_chip bits. This variable is used by powerdomain and 154 + * clockdomain code to indicate whether structures are applicable for 155 + * the current OMAP chip type by ANDing it against a 'platform' bitfield 156 + * in the structure. 157 + */ 158 + static void __init _set_omap_chip(void) 159 + { 160 + if (cpu_is_omap343x()) { 161 + 162 + omap_chip.oc = CHIP_IS_OMAP3430; 163 + if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) 164 + omap_chip.oc |= CHIP_IS_OMAP3430ES1; 165 + else if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) 166 + omap_chip.oc |= CHIP_IS_OMAP3430ES2; 167 + 168 + } else if (cpu_is_omap243x()) { 169 + 170 + /* Currently only supports 2430ES2.1 and 2430-all */ 171 + omap_chip.oc |= CHIP_IS_OMAP2430; 172 + 173 + } else if (cpu_is_omap242x()) { 174 + 175 + /* Currently only supports 2420ES2.1.1 and 2420-all */ 176 + omap_chip.oc |= CHIP_IS_OMAP2420; 177 + 178 + } else { 179 + 180 + /* Current CPU not supported by this code. */ 181 + printk(KERN_WARNING "OMAP chip type code does not yet support " 182 + "this CPU type.\n"); 183 + WARN_ON(1); 184 + 185 + } 186 + 69 187 } 70 188 71 189 void __init omap2_check_revision(void) ··· 208 76 rev = (idcode >> 28) & 0x0f; 209 77 dev_type = (prod_id >> 16) & 0x0f; 210 78 211 - #ifdef DEBUG 212 - printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", 213 - idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); 214 - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n", 215 - read_tap_reg(OMAP_TAP_DIE_ID_0)); 216 - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", 217 - read_tap_reg(OMAP_TAP_DIE_ID_1), 218 - (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); 219 - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n", 220 - read_tap_reg(OMAP_TAP_DIE_ID_2)); 221 - printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n", 222 - read_tap_reg(OMAP_TAP_DIE_ID_3)); 223 - printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", 224 - prod_id, dev_type); 225 - #endif 79 + pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", 80 + idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); 81 + pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", 82 + read_tap_reg(OMAP_TAP_DIE_ID_0)); 83 + pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", 84 + read_tap_reg(OMAP_TAP_DIE_ID_1), 85 + (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); 86 + pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", 87 + read_tap_reg(OMAP_TAP_DIE_ID_2)); 88 + pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", 89 + read_tap_reg(OMAP_TAP_DIE_ID_3)); 90 + pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", 91 + prod_id, dev_type); 92 + 93 + /* 94 + * Detection for 34xx ES2.0 and above can be done with just 95 + * hawkeye and rev. See TRM 1.5.2 Device Identification. 96 + * Note that rev cannot be used directly as ES1.0 uses value 0. 97 + */ 98 + if (hawkeye == 0xb7ae) { 99 + system_rev = 0x34300000 | ((1 + rev) << 12); 100 + pr_info("OMAP%04x ES2.%i\n", system_rev >> 16, rev); 101 + _set_omap_chip(); 102 + return; 103 + } 226 104 227 105 /* Check hawkeye ids */ 228 106 for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { ··· 256 114 omap_ids[i].type >> 16); 257 115 j = i; 258 116 } 259 - system_rev = omap_ids[j].type; 260 117 261 - system_rev |= rev << 8; 118 + _set_system_rev(omap_ids[j].type, rev); 262 119 263 - /* Add the cpu class info (24xx) */ 264 - system_rev |= 0x24; 120 + _set_omap_chip(); 265 121 266 122 pr_info("OMAP%04x", system_rev >> 16); 267 123 if ((system_rev >> 8) & 0x0f) 268 - printk("%x", (system_rev >> 8) & 0x0f); 269 - printk("\n"); 124 + pr_info("ES%x", (system_rev >> 12) & 0xf); 125 + pr_info("\n"); 126 + 270 127 } 271 128
+37 -2
include/asm-arm/arch-omap/cpu.h
··· 3 3 * 4 4 * OMAP cpu type detection 5 5 * 6 - * Copyright (C) 2004 Nokia Corporation 6 + * Copyright (C) 2004, 2008 Nokia Corporation 7 7 * 8 8 * Written by Tony Lindgren <tony.lindgren@nokia.com> 9 9 * ··· 25 25 26 26 #ifndef __ASM_ARCH_OMAP_CPU_H 27 27 #define __ASM_ARCH_OMAP_CPU_H 28 + 29 + struct omap_chip_id { 30 + u8 oc; 31 + }; 32 + 33 + #define OMAP_CHIP_INIT(x) { .oc = x } 28 34 29 35 extern unsigned int system_rev; 30 36 ··· 351 345 #define OMAP2430_REV_ES1_0 0x24300000 352 346 #define OMAP3430_REV_ES1_0 0x34300000 353 347 #define OMAP3430_REV_ES2_0 0x34301000 348 + #define OMAP3430_REV_ES2_1 0x34302000 349 + #define OMAP3430_REV_ES2_2 0x34303000 350 + 351 + /* 352 + * omap_chip bits 353 + * 354 + * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is 355 + * valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates 356 + * something that is only valid on that particular ES revision. 357 + * 358 + * These bits may be ORed together to indicate structures that are 359 + * available on multiple chip types. 360 + * 361 + * To test whether a particular structure matches the current OMAP chip type, 362 + * use omap_chip_is(). 363 + * 364 + */ 365 + #define CHIP_IS_OMAP2420 (1 << 0) 366 + #define CHIP_IS_OMAP2430 (1 << 1) 367 + #define CHIP_IS_OMAP3430 (1 << 2) 368 + #define CHIP_IS_OMAP3430ES1 (1 << 3) 369 + #define CHIP_IS_OMAP3430ES2 (1 << 4) 370 + 371 + #define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) 372 + 373 + int omap_chip_is(struct omap_chip_id oci); 374 + 354 375 355 376 /* 356 377 * Macro to detect device type i.e. EMU/HS/TST/GP/BAD ··· 395 362 #define is_device_type_gp() (get_device_type() == DEVICE_TYPE_GP) 396 363 #define is_device_type_bad() (get_device_type() == DEVICE_TYPE_BAD) 397 364 398 - #endif 365 + void omap2_check_revision(void); 366 + 367 + #endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */ 399 368 400 369 #endif