* [PATCH 0/6] Omap2 updates for 2.6.29 merge window
@ 2008-12-05 2:38 Tony Lindgren
2008-12-05 2:39 ` [PATCH 1/6] ARM: OMAP2: Prepare cpu detection for further improvements Tony Lindgren
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-05 2:38 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: linux-omap
Hi,
Here are some omap2 updates for review. Some of these patches also
affect omap3 as the code is shared.
Regards,
Tony
---
David Brownell (1):
ARM: OMAP2: bard-h4: list those eeproms
Lauri Leukkunen (1):
ARM: OMAP2: Use omap_rev() instead of system_rev
Paul Walmsley (2):
ARM: OMAP2: skip unnecessary TLDR write during non-autoreload for gptimer
ARM: OMAP2: drop redundant pending write check for gptimer
Tony Lindgren (2):
ARM: OMAP2: Fix cpu detection
ARM: OMAP2: Prepare cpu detection for further improvements
arch/arm/mach-omap1/id.c | 53 ++--
arch/arm/mach-omap1/pm.c | 6
arch/arm/mach-omap2/board-h4.c | 14 +
arch/arm/mach-omap2/clock34xx.c | 2
arch/arm/mach-omap2/id.c | 305 ++++++++++-------------
arch/arm/plat-omap/dmtimer.c | 11 -
arch/arm/plat-omap/include/mach/board-apollon.h | 4
arch/arm/plat-omap/include/mach/cpu.h | 82 ++----
arch/arm/plat-omap/sram.c | 3
9 files changed, 219 insertions(+), 261 deletions(-)
--
Signature
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/6] ARM: OMAP2: Prepare cpu detection for further improvements
2008-12-05 2:38 [PATCH 0/6] Omap2 updates for 2.6.29 merge window Tony Lindgren
@ 2008-12-05 2:39 ` Tony Lindgren
2008-12-05 2:39 ` [PATCH 2/6] ARM: OMAP2: Fix cpu detection Tony Lindgren
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-05 2:39 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: linux-omap
Rename omap2_check_revision to omap24xx_check_revision.
Then next patch will split if further and add omap34xx_check_revision.
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/id.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index bf45ff3..b6ee18c 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -191,7 +191,7 @@ static void __init _set_omap_chip(void)
}
-void __init omap2_check_revision(void)
+void __init omap24xx_check_revision(void)
{
int i, j;
u32 idcode;
@@ -266,6 +266,11 @@ void __init omap2_check_revision(void)
}
+void __init omap2_check_revision(void)
+{
+ omap24xx_check_revision();
+}
+
void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
{
class = omap2_globals->class;
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/6] ARM: OMAP2: Fix cpu detection
2008-12-05 2:38 [PATCH 0/6] Omap2 updates for 2.6.29 merge window Tony Lindgren
2008-12-05 2:39 ` [PATCH 1/6] ARM: OMAP2: Prepare cpu detection for further improvements Tony Lindgren
@ 2008-12-05 2:39 ` Tony Lindgren
2008-12-05 2:40 ` [PATCH 3/6] ARM: OMAP2: Use omap_rev() instead of system_rev Tony Lindgren
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-05 2:39 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: linux-omap
At some point omap2 changed the bits for GET_OMAP_CLASS, which
broke 15xx detection on 730 as noticed by Russell King.
This patch fixes omap2 cpu detection to respect the original
GET_OMAP_CLASS, and simplifies the detection for 34xx.
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap1/id.c | 3
arch/arm/mach-omap2/clock34xx.c | 2
arch/arm/mach-omap2/id.c | 290 ++++++++++++++-------------------
arch/arm/plat-omap/include/mach/cpu.h | 76 +++------
4 files changed, 145 insertions(+), 226 deletions(-)
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
index 13083d7..d6110fe 100644
--- a/arch/arm/mach-omap1/id.c
+++ b/arch/arm/mach-omap1/id.c
@@ -178,9 +178,6 @@ void __init omap_check_revision(void)
case 0x17:
system_rev |= 0x16;
break;
- case 0x24:
- system_rev |= 0x24;
- break;
default:
printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
}
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 084e110..3c2f665 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -475,7 +475,7 @@ int __init omap2_clk_init(void)
* Update this if there are further clock changes between ES2
* and production parts
*/
- if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) {
+ if (system_rev == OMAP3430_REV_ES1_0) {
/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
cpu_clkflg |= CLOCK_IN_OMAP3430ES1;
} else {
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index b6ee18c..d4e3a38 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -22,39 +22,6 @@
#include <mach/control.h>
#include <mach/cpu.h>
-static u32 class;
-static void __iomem *tap_base;
-static u16 tap_prod_id;
-
-#define OMAP_TAP_IDCODE 0x0204
-#define OMAP_TAP_DIE_ID_0 0x0218
-#define OMAP_TAP_DIE_ID_1 0x021C
-#define OMAP_TAP_DIE_ID_2 0x0220
-#define OMAP_TAP_DIE_ID_3 0x0224
-
-/* system_rev fields for OMAP2 processors:
- * CPU id bits [31:16],
- * CPU device type [15:12], (unprg,normal,POP)
- * CPU revision [11:08]
- * CPU class bits [07:00]
- */
-
-struct omap_id {
- u16 hawkeye; /* Silicon type (Hawkeye id) */
- u8 dev; /* Device type from production_id reg */
- u32 type; /* combined type id copied to system_rev */
-};
-
-/* Register values to detect the OMAP version */
-static struct omap_id omap_ids[] __initdata = {
- { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200000 },
- { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201000 },
- { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202000 },
- { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220000 },
- { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230000 },
- { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 },
-};
-
static struct omap_chip_id omap_chip;
/**
@@ -70,135 +37,41 @@ int omap_chip_is(struct omap_chip_id oci)
}
EXPORT_SYMBOL(omap_chip_is);
-static u32 __init read_tap_reg(int reg)
-{
- unsigned int regval = 0;
- u32 cpuid;
+/*----------------------------------------------------------------------------*/
- /* Reading the IDCODE register on 3430 ES1 results in a
- * data abort as the register is not exposed on the OCP
- * Hence reading the Cortex Rev
- */
- cpuid = read_cpuid(CPUID_ID);
-
- /* If the processor type is Cortex-A8 and the revision is 0x0
- * it means its Cortex r0p0 which is 3430 ES1
- */
- if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) {
-
- if (reg == tap_prod_id) {
- regval = 0x000F00F0;
- goto out;
- }
-
- switch (reg) {
- case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break;
- /* Making DevType as 0xF in ES1 to differ from ES2 */
- case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break;
- case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break;
- case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break;
- case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break;
- }
- } else
- regval = __raw_readl(tap_base + reg);
-
-out:
- return regval;
-
-}
-
-/*
- * _set_system_rev - set the system_rev global based on current OMAP chip type
- *
- * Set the system_rev global. This is primarily used by the cpu_is_omapxxxx()
- * macros.
- */
-static void __init _set_system_rev(u32 type, u8 rev)
-{
- u32 i, ctrl_status;
-
- /*
- * system_rev encoding is as follows
- * system_rev & 0xff000000 -> Omap Class (24xx/34xx)
- * system_rev & 0xfff00000 -> Omap Sub Class (242x/343x)
- * system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430)
- * system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 )
- * system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD )
- * system_rev & 0x000000c0 -> IDCODE revision[6:7]
- * system_rev & 0x0000003f -> sys_boot[0:5]
- */
- /* Embedding the ES revision info in type field */
- system_rev = type;
- /* Also add IDCODE revision info only two lower bits */
- system_rev |= ((rev & 0x3) << 6);
-
- /* Add in the device type and sys_boot fields (see above) */
- if (cpu_is_omap24xx()) {
- i = OMAP24XX_CONTROL_STATUS;
- } else if (cpu_is_omap343x()) {
- i = OMAP343X_CONTROL_STATUS;
- } else {
- printk(KERN_ERR "id: unknown CPU type\n");
- BUG();
- }
- ctrl_status = omap_ctrl_readl(i);
- system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK |
- OMAP2_SYSBOOT_4_MASK |
- OMAP2_SYSBOOT_3_MASK |
- OMAP2_SYSBOOT_2_MASK |
- OMAP2_SYSBOOT_1_MASK |
- OMAP2_SYSBOOT_0_MASK));
- system_rev |= (ctrl_status & OMAP2_DEVICETYPE_MASK);
-}
-
-
-/*
- * _set_omap_chip - set the omap_chip global based on OMAP chip type
- *
- * Build the omap_chip bits. This variable is used by powerdomain and
- * clockdomain code to indicate whether structures are applicable for
- * the current OMAP chip type by ANDing it against a 'platform' bitfield
- * in the structure.
- */
-static void __init _set_omap_chip(void)
-{
- if (cpu_is_omap343x()) {
-
- omap_chip.oc = CHIP_IS_OMAP3430;
- if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0))
- omap_chip.oc |= CHIP_IS_OMAP3430ES1;
- else if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0))
- omap_chip.oc |= CHIP_IS_OMAP3430ES2;
-
- } else if (cpu_is_omap243x()) {
-
- /* Currently only supports 2430ES2.1 and 2430-all */
- omap_chip.oc |= CHIP_IS_OMAP2430;
-
- } else if (cpu_is_omap242x()) {
-
- /* Currently only supports 2420ES2.1.1 and 2420-all */
- omap_chip.oc |= CHIP_IS_OMAP2420;
+#define OMAP_TAP_IDCODE 0x0204
+#define OMAP_TAP_DIE_ID_0 0x0218
+#define OMAP_TAP_DIE_ID_1 0x021C
+#define OMAP_TAP_DIE_ID_2 0x0220
+#define OMAP_TAP_DIE_ID_3 0x0224
- } else {
+#define read_tap_reg(reg) __raw_readl(tap_base + (reg))
- /* Current CPU not supported by this code. */
- printk(KERN_WARNING "OMAP chip type code does not yet support "
- "this CPU type.\n");
- WARN_ON(1);
+struct omap_id {
+ u16 hawkeye; /* Silicon type (Hawkeye id) */
+ u8 dev; /* Device type from production_id reg */
+ u32 type; /* Combined type id copied to system_rev */
+};
- }
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] __initdata = {
+ { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
+ { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
+ { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
+ { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
+ { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
+ { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
+};
-}
+static void __iomem *tap_base;
+static u16 tap_prod_id;
void __init omap24xx_check_revision(void)
{
int i, j;
- u32 idcode;
- u32 prod_id;
+ u32 idcode, prod_id;
u16 hawkeye;
- u8 dev_type;
- u8 rev;
+ u8 dev_type, rev;
idcode = read_tap_reg(OMAP_TAP_IDCODE);
prod_id = read_tap_reg(tap_prod_id);
@@ -220,18 +93,6 @@ void __init omap24xx_check_revision(void)
pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
prod_id, dev_type);
- /*
- * Detection for 34xx ES2.0 and above can be done with just
- * hawkeye and rev. See TRM 1.5.2 Device Identification.
- * Note that rev cannot be used directly as ES1.0 uses value 0.
- */
- if (hawkeye == 0xb7ae) {
- system_rev = 0x34300000 | ((1 + rev) << 12);
- pr_info("OMAP%04x ES2.%i\n", system_rev >> 16, rev);
- _set_omap_chip();
- return;
- }
-
/* Check hawkeye ids */
for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
if (hawkeye == omap_ids[i].hawkeye)
@@ -255,28 +116,115 @@ void __init omap24xx_check_revision(void)
j = i;
}
- _set_system_rev(omap_ids[j].type, rev);
-
- _set_omap_chip();
-
pr_info("OMAP%04x", system_rev >> 16);
if ((system_rev >> 8) & 0x0f)
pr_info("ES%x", (system_rev >> 12) & 0xf);
pr_info("\n");
+}
+
+void __init omap34xx_check_revision(void)
+{
+ u32 cpuid, idcode;
+ u16 hawkeye;
+ u8 rev;
+ char *rev_name = "ES1.0";
+
+ /*
+ * We cannot access revision registers on ES1.0.
+ * If the processor type is Cortex-A8 and the revision is 0x0
+ * it means its Cortex r0p0 which is 3430 ES1.0.
+ */
+ cpuid = read_cpuid(CPUID_ID);
+ if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
+ system_rev = OMAP3430_REV_ES1_0;
+ goto out;
+ }
+
+ /*
+ * Detection for 34xx ES2.0 and above can be done with just
+ * hawkeye and rev. See TRM 1.5.2 Device Identification.
+ * Note that rev does not map directly to our defined processor
+ * revision numbers as ES1.0 uses value 0.
+ */
+ idcode = read_tap_reg(OMAP_TAP_IDCODE);
+ hawkeye = (idcode >> 12) & 0xffff;
+ rev = (idcode >> 28) & 0xff;
+ if (hawkeye == 0xb7ae) {
+ switch (rev) {
+ case 0:
+ system_rev = OMAP3430_REV_ES2_0;
+ rev_name = "ES2.0";
+ break;
+ case 2:
+ system_rev = OMAP3430_REV_ES2_1;
+ rev_name = "ES2.1";
+ break;
+ case 3:
+ system_rev = OMAP3430_REV_ES3_0;
+ rev_name = "ES3.0";
+ break;
+ default:
+ /* Use the latest known revision as default */
+ system_rev = OMAP3430_REV_ES3_0;
+ rev_name = "Unknown revision\n";
+ }
+ }
+
+out:
+ pr_info("OMAP%04x %s\n", system_rev >> 16, rev_name);
}
+/*
+ * Try to detect the exact revision of the omap we're running on
+ */
void __init omap2_check_revision(void)
{
- omap24xx_check_revision();
+ /*
+ * At this point we have an idea about the processor revision set
+ * earlier with omap2_set_globals_tap().
+ */
+ if (cpu_is_omap24xx())
+ omap24xx_check_revision();
+ else if (cpu_is_omap34xx())
+ omap34xx_check_revision();
+ else
+ pr_err("OMAP revision unknown, please fix!\n");
+
+ /*
+ * OK, now we know the exact revision. Initialize omap_chip bits
+ * for powerdowmain and clockdomain code.
+ */
+ if (cpu_is_omap243x()) {
+ /* Currently only supports 2430ES2.1 and 2430-all */
+ omap_chip.oc |= CHIP_IS_OMAP2430;
+ } else if (cpu_is_omap242x()) {
+ /* Currently only supports 2420ES2.1.1 and 2420-all */
+ omap_chip.oc |= CHIP_IS_OMAP2420;
+ } else if (cpu_is_omap343x()) {
+ omap_chip.oc = CHIP_IS_OMAP3430;
+ if (system_rev == OMAP3430_REV_ES1_0)
+ omap_chip.oc |= CHIP_IS_OMAP3430ES1;
+ else if (system_rev > OMAP3430_REV_ES1_0)
+ omap_chip.oc |= CHIP_IS_OMAP3430ES2;
+ } else {
+ pr_err("Uninitialized omap_chip, please fix!\n");
+ }
}
+/*
+ * Set up things for map_io and processor detection later on. Gets called
+ * pretty much first thing from board init. For multi-omap, this gets
+ * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
+ * detect the exact revision later on in omap2_detect_revision() once map_io
+ * is done.
+ */
void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
{
- class = omap2_globals->class;
+ system_rev = omap2_globals->class;
tap_base = omap2_globals->tap;
- if (class == 0x3430)
+ if (cpu_is_omap34xx())
tap_prod_id = 0x0210;
else
tap_prod_id = 0x0208;
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index e046418..4325bbc 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -28,14 +28,19 @@
struct omap_chip_id {
u8 oc;
+ u8 type;
};
#define OMAP_CHIP_INIT(x) { .oc = x }
+/*
+ * system_rev bits:
+ * CPU id bits (0730, 1510, 1710, 2422...) [31:16]
+ * CPU revision (See _REV_ defined in cpu.h) [15:08]
+ * CPU class bits (15xx, 16xx, 24xx, 34xx...) [07:00]
+ */
extern unsigned int system_rev;
-#define omap2_cpu_rev() ((system_rev >> 12) & 0x0f)
-
/*
* Test if multicore OMAP support is needed
*/
@@ -108,7 +113,7 @@ extern unsigned int system_rev;
* cpu_is_omap243x(): True for OMAP2430
* cpu_is_omap343x(): True for OMAP3430
*/
-#define GET_OMAP_CLASS ((system_rev >> 24) & 0xff)
+#define GET_OMAP_CLASS (system_rev & 0xff)
#define IS_OMAP_CLASS(class, id) \
static inline int is_omap ##class (void) \
@@ -320,44 +325,20 @@ IS_OMAP_TYPE(3430, 0x3430)
#define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx())
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-/*
- * Macros to detect silicon revision of OMAP2/3 processors.
- * is_sil_rev_greater_than: true if passed cpu type & its rev is greater.
- * is_sil_rev_lesser_than: true if passed cpu type & its rev is lesser.
- * is_sil_rev_equal_to: true if passed cpu type & its rev is equal.
- * get_sil_rev: return the silicon rev value.
- */
-#define get_sil_omap_type(rev) ((rev & 0xffff0000) >> 16)
-#define get_sil_revision(rev) ((rev & 0x0000f000) >> 12)
-#define is_sil_rev_greater_than(rev) \
- ((get_sil_omap_type(system_rev) == get_sil_omap_type(rev)) && \
- (get_sil_revision(system_rev) > get_sil_revision(rev)))
+/* Various silicon revisions for omap2 */
+#define OMAP242X_CLASS 0x24200024
+#define OMAP2420_REV_ES1_0 0x24200024
+#define OMAP2420_REV_ES2_0 0x24201024
-#define is_sil_rev_less_than(rev) \
- ((get_sil_omap_type(system_rev) == get_sil_omap_type(rev)) && \
- (get_sil_revision(system_rev) < get_sil_revision(rev)))
+#define OMAP243X_CLASS 0x24300024
+#define OMAP2430_REV_ES1_0 0x24300024
-#define is_sil_rev_equal_to(rev) \
- ((get_sil_omap_type(system_rev) == get_sil_omap_type(rev)) && \
- (get_sil_revision(system_rev) == get_sil_revision(rev)))
-
-#define get_sil_rev() \
- get_sil_revision(system_rev)
-
-/* Various silicon macros defined here */
-#define OMAP242X_CLASS 0x24200000
-#define OMAP2420_REV_ES1_0 0x24200000
-#define OMAP2420_REV_ES2_0 0x24201000
-
-#define OMAP243X_CLASS 0x24300000
-#define OMAP2430_REV_ES1_0 0x24300000
-
-#define OMAP343X_CLASS 0x34300000
-#define OMAP3430_REV_ES1_0 0x34300000
-#define OMAP3430_REV_ES2_0 0x34301000
-#define OMAP3430_REV_ES2_1 0x34302000
-#define OMAP3430_REV_ES2_2 0x34303000
+#define OMAP343X_CLASS 0x34300034
+#define OMAP3430_REV_ES1_0 0x34300034
+#define OMAP3430_REV_ES2_0 0x34301034
+#define OMAP3430_REV_ES2_1 0x34302034
+#define OMAP3430_REV_ES3_0 0x34303034
/*
* omap_chip bits
@@ -382,23 +363,16 @@ IS_OMAP_TYPE(3430, 0x3430)
#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
int omap_chip_is(struct omap_chip_id oci);
-
+int omap_type(void);
/*
* Macro to detect device type i.e. EMU/HS/TST/GP/BAD
*/
-#define DEVICE_TYPE_TEST 0
-#define DEVICE_TYPE_EMU 1
-#define DEVICE_TYPE_SEC 2
-#define DEVICE_TYPE_GP 3
-#define DEVICE_TYPE_BAD 4
-
-#define get_device_type() ((system_rev & 0x700) >> 8)
-#define is_device_type_test() (get_device_type() == DEVICE_TYPE_TEST)
-#define is_device_type_emu() (get_device_type() == DEVICE_TYPE_EMU)
-#define is_device_type_sec() (get_device_type() == DEVICE_TYPE_SEC)
-#define is_device_type_gp() (get_device_type() == DEVICE_TYPE_GP)
-#define is_device_type_bad() (get_device_type() == DEVICE_TYPE_BAD)
+#define OMAP2_DEVICE_TYPE_TEST 0
+#define OMAP2_DEVICE_TYPE_EMU 1
+#define OMAP2_DEVICE_TYPE_SEC 2
+#define OMAP2_DEVICE_TYPE_GP 3
+#define OMAP2_DEVICE_TYPE_BAD 4
void omap2_check_revision(void);
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/6] ARM: OMAP2: Use omap_rev() instead of system_rev
2008-12-05 2:38 [PATCH 0/6] Omap2 updates for 2.6.29 merge window Tony Lindgren
2008-12-05 2:39 ` [PATCH 1/6] ARM: OMAP2: Prepare cpu detection for further improvements Tony Lindgren
2008-12-05 2:39 ` [PATCH 2/6] ARM: OMAP2: Fix cpu detection Tony Lindgren
@ 2008-12-05 2:40 ` Tony Lindgren
2008-12-05 2:40 ` [PATCH 4/6] ARM: OMAP2: bard-h4: list those eeproms Tony Lindgren
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-05 2:40 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: linux-omap, Lauri Leukkunen
From: Lauri Leukkunen <lauri.leukkunen@nokia.com>
system_rev is meant for board revision, this patch changes
all relevant instances to use the new omap_rev() function
liberating system_rev to be used with ATAG_REVISION as it
has been designed.
Signed-off-by: Lauri Leukkunen <lauri.leukkunen@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap1/id.c | 50 ++++++++++++++---------
arch/arm/mach-omap1/pm.c | 6 ++-
arch/arm/mach-omap2/clock34xx.c | 2 -
arch/arm/mach-omap2/id.c | 34 ++++++++++------
arch/arm/plat-omap/include/mach/board-apollon.h | 4 +-
arch/arm/plat-omap/include/mach/cpu.h | 10 ++---
arch/arm/plat-omap/sram.c | 3 +
7 files changed, 66 insertions(+), 43 deletions(-)
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
index d6110fe..89bb875 100644
--- a/arch/arm/mach-omap1/id.c
+++ b/arch/arm/mach-omap1/id.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <mach/cpu.h>
#define OMAP_DIE_ID_0 0xfffe1800
#define OMAP_DIE_ID_1 0xfffe1804
@@ -30,6 +31,8 @@ struct omap_id {
u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */
};
+static unsigned int omap_revision;
+
/* Register values to detect the OMAP version */
static struct omap_id omap_ids[] __initdata = {
{ .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
@@ -53,6 +56,12 @@ static struct omap_id omap_ids[] __initdata = {
{ .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
};
+unsigned int omap_rev(void)
+{
+ return omap_revision;
+}
+EXPORT_SYMBOL(omap_rev);
+
/*
* Get OMAP type from PROD_ID.
* 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
@@ -121,17 +130,18 @@ void __init omap_check_revision(void)
omap_id = omap_readl(OMAP32_ID_0);
#ifdef DEBUG
- printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
- printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
+ printk(KERN_DEBUG "OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
+ printk(KERN_DEBUG "OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
omap_readl(OMAP_DIE_ID_1),
(omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
- printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0));
- printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
+ printk(KERN_DEBUG "OMAP_PRODUCTION_ID_0: 0x%08x\n",
+ omap_readl(OMAP_PRODUCTION_ID_0));
+ printk(KERN_DEBUG "OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
omap_readl(OMAP_PRODUCTION_ID_1),
omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
- printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
- printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
- printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
+ printk(KERN_DEBUG "OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
+ printk(KERN_DEBUG "OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
+ printk(KERN_DEBUG "JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
#endif
system_serial_high = omap_readl(OMAP_DIE_ID_0);
@@ -140,7 +150,7 @@ void __init omap_check_revision(void)
/* First check only the major version in a safe way */
for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
if (jtag_id == (omap_ids[i].jtag_id)) {
- system_rev = omap_ids[i].type;
+ omap_revision = omap_ids[i].type;
break;
}
}
@@ -148,7 +158,7 @@ void __init omap_check_revision(void)
/* Check if we can find the die revision */
for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
- system_rev = omap_ids[i].type;
+ omap_revision = omap_ids[i].type;
break;
}
}
@@ -158,35 +168,35 @@ void __init omap_check_revision(void)
if (jtag_id == omap_ids[i].jtag_id
&& die_rev == omap_ids[i].die_rev
&& omap_id == omap_ids[i].omap_id) {
- system_rev = omap_ids[i].type;
+ omap_revision = omap_ids[i].type;
break;
}
}
/* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
- cpu_type = system_rev >> 24;
+ cpu_type = omap_revision >> 24;
switch (cpu_type) {
case 0x07:
- system_rev |= 0x07;
+ omap_revision |= 0x07;
break;
case 0x03:
case 0x15:
- system_rev |= 0x15;
+ omap_revision |= 0x15;
break;
case 0x16:
case 0x17:
- system_rev |= 0x16;
+ omap_revision |= 0x16;
break;
default:
- printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
+ printk(KERN_INFO "Unknown OMAP cpu type: 0x%02x\n", cpu_type);
}
- printk("OMAP%04x", system_rev >> 16);
- if ((system_rev >> 8) & 0xff)
- printk("%x", (system_rev >> 8) & 0xff);
- printk(" revision %i handled as %02xxx id: %08x%08x\n",
- die_rev, system_rev & 0xff, system_serial_low,
+ printk(KERN_INFO "OMAP%04x", omap_revision >> 16);
+ if ((omap_revision >> 8) & 0xff)
+ printk(KERN_INFO "%x", (omap_revision >> 8) & 0xff);
+ printk(KERN_INFO " revision %i handled as %02xxx id: %08x%08x\n",
+ die_rev, omap_revision & 0xff, system_serial_low,
system_serial_high);
}
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 770d256..9774c1f 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -226,7 +226,8 @@ void omap_pm_suspend(void)
{
unsigned long arg0 = 0, arg1 = 0;
- printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
+ printk(KERN_INFO "PM: OMAP%x is trying to enter deep sleep...\n",
+ omap_rev());
omap_serial_wake_trigger(1);
@@ -421,7 +422,8 @@ void omap_pm_suspend(void)
omap_serial_wake_trigger(0);
- printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
+ printk(KERN_INFO "PM: OMAP%x is re-starting from deep sleep...\n",
+ omap_rev());
}
#if defined(DEBUG) && defined(CONFIG_PROC_FS)
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 3c2f665..31bb701 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -475,7 +475,7 @@ int __init omap2_clk_init(void)
* Update this if there are further clock changes between ES2
* and production parts
*/
- if (system_rev == OMAP3430_REV_ES1_0) {
+ if (omap_rev() == OMAP3430_REV_ES1_0) {
/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
cpu_clkflg |= CLOCK_IN_OMAP3430ES1;
} else {
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index d4e3a38..b0f8e7d 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -23,6 +23,14 @@
#include <mach/cpu.h>
static struct omap_chip_id omap_chip;
+static unsigned int omap_revision;
+
+
+unsigned int omap_rev(void)
+{
+ return omap_revision;
+}
+EXPORT_SYMBOL(omap_rev);
/**
* omap_chip_is - test whether currently running OMAP matches a chip type
@@ -50,7 +58,7 @@ EXPORT_SYMBOL(omap_chip_is);
struct omap_id {
u16 hawkeye; /* Silicon type (Hawkeye id) */
u8 dev; /* Device type from production_id reg */
- u32 type; /* Combined type id copied to system_rev */
+ u32 type; /* Combined type id copied to omap_revision */
};
/* Register values to detect the OMAP version */
@@ -116,9 +124,9 @@ void __init omap24xx_check_revision(void)
j = i;
}
- pr_info("OMAP%04x", system_rev >> 16);
- if ((system_rev >> 8) & 0x0f)
- pr_info("ES%x", (system_rev >> 12) & 0xf);
+ pr_info("OMAP%04x", omap_rev() >> 16);
+ if ((omap_rev() >> 8) & 0x0f)
+ pr_info("ES%x", (omap_rev() >> 12) & 0xf);
pr_info("\n");
}
@@ -136,7 +144,7 @@ void __init omap34xx_check_revision(void)
*/
cpuid = read_cpuid(CPUID_ID);
if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
- system_rev = OMAP3430_REV_ES1_0;
+ omap_revision = OMAP3430_REV_ES1_0;
goto out;
}
@@ -153,26 +161,26 @@ void __init omap34xx_check_revision(void)
if (hawkeye == 0xb7ae) {
switch (rev) {
case 0:
- system_rev = OMAP3430_REV_ES2_0;
+ omap_revision = OMAP3430_REV_ES2_0;
rev_name = "ES2.0";
break;
case 2:
- system_rev = OMAP3430_REV_ES2_1;
+ omap_revision = OMAP3430_REV_ES2_1;
rev_name = "ES2.1";
break;
case 3:
- system_rev = OMAP3430_REV_ES3_0;
+ omap_revision = OMAP3430_REV_ES3_0;
rev_name = "ES3.0";
break;
default:
/* Use the latest known revision as default */
- system_rev = OMAP3430_REV_ES3_0;
+ omap_revision = OMAP3430_REV_ES3_0;
rev_name = "Unknown revision\n";
}
}
out:
- pr_info("OMAP%04x %s\n", system_rev >> 16, rev_name);
+ pr_info("OMAP%04x %s\n", omap_rev() >> 16, rev_name);
}
/*
@@ -203,9 +211,9 @@ void __init omap2_check_revision(void)
omap_chip.oc |= CHIP_IS_OMAP2420;
} else if (cpu_is_omap343x()) {
omap_chip.oc = CHIP_IS_OMAP3430;
- if (system_rev == OMAP3430_REV_ES1_0)
+ if (omap_rev() == OMAP3430_REV_ES1_0)
omap_chip.oc |= CHIP_IS_OMAP3430ES1;
- else if (system_rev > OMAP3430_REV_ES1_0)
+ else if (omap_rev() > OMAP3430_REV_ES1_0)
omap_chip.oc |= CHIP_IS_OMAP3430ES2;
} else {
pr_err("Uninitialized omap_chip, please fix!\n");
@@ -221,7 +229,7 @@ void __init omap2_check_revision(void)
*/
void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
{
- system_rev = omap2_globals->class;
+ omap_revision = omap2_globals->class;
tap_base = omap2_globals->tap;
if (cpu_is_omap34xx())
diff --git a/arch/arm/plat-omap/include/mach/board-apollon.h b/arch/arm/plat-omap/include/mach/board-apollon.h
index 731c858..61bd5e8 100644
--- a/arch/arm/plat-omap/include/mach/board-apollon.h
+++ b/arch/arm/plat-omap/include/mach/board-apollon.h
@@ -29,12 +29,14 @@
#ifndef __ASM_ARCH_OMAP_APOLLON_H
#define __ASM_ARCH_OMAP_APOLLON_H
+#include <mach/cpu.h>
+
extern void apollon_mmc_init(void);
static inline int apollon_plus(void)
{
/* The apollon plus has IDCODE revision 5 */
- return system_rev & 0xc0;
+ return omap_rev() & 0xc0;
}
/* Placeholder for APOLLON specific defines */
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index 4325bbc..b2062f1 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -34,12 +34,12 @@ struct omap_chip_id {
#define OMAP_CHIP_INIT(x) { .oc = x }
/*
- * system_rev bits:
+ * omap_rev bits:
* CPU id bits (0730, 1510, 1710, 2422...) [31:16]
* CPU revision (See _REV_ defined in cpu.h) [15:08]
* CPU class bits (15xx, 16xx, 24xx, 34xx...) [07:00]
*/
-extern unsigned int system_rev;
+unsigned int omap_rev(void);
/*
* Test if multicore OMAP support is needed
@@ -113,7 +113,7 @@ extern unsigned int system_rev;
* cpu_is_omap243x(): True for OMAP2430
* cpu_is_omap343x(): True for OMAP3430
*/
-#define GET_OMAP_CLASS (system_rev & 0xff)
+#define GET_OMAP_CLASS (omap_rev() & 0xff)
#define IS_OMAP_CLASS(class, id) \
static inline int is_omap ##class (void) \
@@ -121,7 +121,7 @@ static inline int is_omap ##class (void) \
return (GET_OMAP_CLASS == (id)) ? 1 : 0; \
}
-#define GET_OMAP_SUBCLASS ((system_rev >> 20) & 0x0fff)
+#define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff)
#define IS_OMAP_SUBCLASS(subclass, id) \
static inline int is_omap ##subclass (void) \
@@ -231,7 +231,7 @@ IS_OMAP_SUBCLASS(343x, 0x343)
* cpu_is_omap2430(): True for OMAP2430
* cpu_is_omap3430(): True for OMAP3430
*/
-#define GET_OMAP_TYPE ((system_rev >> 16) & 0xffff)
+#define GET_OMAP_TYPE ((omap_rev() >> 16) & 0xffff)
#define IS_OMAP_TYPE(type, id) \
static inline int is_omap ##type (void) \
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 9f9a921..e1556f8 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -24,6 +24,7 @@
#include <mach/sram.h>
#include <mach/board.h>
+#include <mach/cpu.h>
#include <mach/control.h>
@@ -87,7 +88,7 @@ static int is_sram_locked(void)
int type = 0;
if (cpu_is_omap242x())
- type = system_rev & OMAP2_DEVICETYPE_MASK;
+ type = omap_rev() & OMAP2_DEVICETYPE_MASK;
if (type == GP_DEVICE) {
/* RAMFW: R/W access to all initiators for all qualifier sets */
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/6] ARM: OMAP2: bard-h4: list those eeproms
2008-12-05 2:38 [PATCH 0/6] Omap2 updates for 2.6.29 merge window Tony Lindgren
` (2 preceding siblings ...)
2008-12-05 2:40 ` [PATCH 3/6] ARM: OMAP2: Use omap_rev() instead of system_rev Tony Lindgren
@ 2008-12-05 2:40 ` Tony Lindgren
2008-12-05 2:41 ` [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer Tony Lindgren
2008-12-05 2:41 ` [PATCH 6/6] ARM: OMAP2: skip unnecessary TLDR write during non-autoreload " Tony Lindgren
5 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-05 2:40 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: David Brownell, linux-omap
From: David Brownell <dbrownell@users.sourceforge.net>
Declare the two 1Kbit EEPROMs included in the H4 board stack.
One is on the CPU card; the other is on the mainboard.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/board-h4.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 2fef2c8..7de0506 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -19,6 +19,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
#include <linux/input.h>
#include <linux/err.h>
#include <linux/clk.h>
@@ -392,11 +393,24 @@ static struct omap_board_config_kernel h4_config[] = {
{ OMAP_TAG_LCD, &h4_lcd_config },
};
+static struct at24_platform_data m24c01 = {
+ .byte_len = SZ_1K / 8,
+ .page_size = 16,
+};
+
static struct i2c_board_info __initdata h4_i2c_board_info[] = {
{
I2C_BOARD_INFO("isp1301_omap", 0x2d),
.irq = OMAP_GPIO_IRQ(125),
},
+ { /* EEPROM on mainboard */
+ I2C_BOARD_INFO("24c01", 0x52),
+ .platform_data = &m24c01,
+ },
+ { /* EEPROM on cpu card */
+ I2C_BOARD_INFO("24c01", 0x57),
+ .platform_data = &m24c01,
+ },
};
static void __init omap_h4_init(void)
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer
2008-12-05 2:38 [PATCH 0/6] Omap2 updates for 2.6.29 merge window Tony Lindgren
` (3 preceding siblings ...)
2008-12-05 2:40 ` [PATCH 4/6] ARM: OMAP2: bard-h4: list those eeproms Tony Lindgren
@ 2008-12-05 2:41 ` Tony Lindgren
2008-12-07 11:25 ` Russell King - ARM Linux
2008-12-05 2:41 ` [PATCH 6/6] ARM: OMAP2: skip unnecessary TLDR write during non-autoreload " Tony Lindgren
5 siblings, 1 reply; 12+ messages in thread
From: Tony Lindgren @ 2008-12-05 2:41 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Kevin Hilman, Paul Walmsley, linux-omap, Richard Woodruff
From: Paul Walmsley <paul@pwsan.com>
omap_dm_timer_write_reg() already waits for pending writes to complete,
so the extra wait in omap_dm_timer_set_load() is superfluous.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/plat-omap/dmtimer.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 963c31c..595e3d5 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -539,10 +539,6 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
- /* REVISIT: hw feature, ttgr overtaking tldr? */
- while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff)))
- cpu_relax();
-
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
}
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 6/6] ARM: OMAP2: skip unnecessary TLDR write during non-autoreload for gptimer
2008-12-05 2:38 [PATCH 0/6] Omap2 updates for 2.6.29 merge window Tony Lindgren
` (4 preceding siblings ...)
2008-12-05 2:41 ` [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer Tony Lindgren
@ 2008-12-05 2:41 ` Tony Lindgren
5 siblings, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-05 2:41 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Kevin Hilman, Paul Walmsley, linux-omap, Richard Woodruff
From: Paul Walmsley <paul@pwsan.com>
The GPTIMER TLDR register does not need to be written if the GPTIMER
is not in autoreload mode. This is the usual case for dynamic tick-enabled
kernels.
Simulation data indicate that skipping the read that occurs as part of
the write should save at least 300-320 ns for each GPTIMER1 timer
reprogram. (This assumes L4-Wakeup is at 19MHz and GPTIMER write
posting is enabled.) Skipping the write itself probably won't have
much impact since it should be posted on the OCP interconnect.
Tested on 2430SDP and 3430SDP.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/plat-omap/dmtimer.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 595e3d5..e4f0ce0 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -549,14 +549,15 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
u32 l;
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
- if (autoreload)
+ if (autoreload) {
l |= OMAP_TIMER_CTRL_AR;
- else
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
+ } else {
l &= ~OMAP_TIMER_CTRL_AR;
+ }
l |= OMAP_TIMER_CTRL_ST;
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
- omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer
2008-12-05 2:41 ` [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer Tony Lindgren
@ 2008-12-07 11:25 ` Russell King - ARM Linux
2008-12-07 14:55 ` Woodruff, Richard
0 siblings, 1 reply; 12+ messages in thread
From: Russell King - ARM Linux @ 2008-12-07 11:25 UTC (permalink / raw)
To: Tony Lindgren
Cc: linux-arm-kernel, Kevin Hilman, Paul Walmsley, linux-omap,
Richard Woodruff
On Thu, Dec 04, 2008 at 06:41:21PM -0800, Tony Lindgren wrote:
> omap_dm_timer_write_reg() already waits for pending writes to complete,
> so the extra wait in omap_dm_timer_set_load() is superfluous.
Is this right? I mean - do you have to wait for each individual write
to each register to complete before writing the next (and different)
register?
Given that the code waits for every write to complete, no wonder Richard
Woodruff is complaining that the NOHZ code is poor (it isn't) - with three
writes each waiting for the previous to complete- what was it, 78us each,
to complete? That's 234us just to reprogram the timer hardware with the
CPU spinning waiting for each of the posted writes to complete.
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer
2008-12-07 11:25 ` Russell King - ARM Linux
@ 2008-12-07 14:55 ` Woodruff, Richard
2008-12-07 17:06 ` Russell King - ARM Linux
0 siblings, 1 reply; 12+ messages in thread
From: Woodruff, Richard @ 2008-12-07 14:55 UTC (permalink / raw)
To: Russell King - ARM Linux, Tony Lindgren
Cc: linux-arm-kernel@lists.arm.linux.org.uk, Kevin Hilman,
Paul Walmsley, linux-omap@vger.kernel.org
> On Thu, Dec 04, 2008 at 06:41:21PM -0800, Tony Lindgren wrote:
> > omap_dm_timer_write_reg() already waits for pending writes to complete,
> > so the extra wait in omap_dm_timer_set_load() is superfluous.
>
> Is this right? I mean - do you have to wait for each individual write
> to each register to complete before writing the next (and different)
> register?
No, the effect is not as your guessing.
Each effected register has a posting bit in 3430 which is tracked (see TWPS register). You must be careful with reads or re-writes of the _same_ register.
> Given that the code waits for every write to complete, no wonder Richard
> Woodruff is complaining that the NOHZ code is poor (it isn't) - with three
> writes each waiting for the previous to complete- what was it, 78us each,
> to complete? That's 234us just to reprogram the timer hardware with the
> CPU spinning waiting for each of the posted writes to complete.
In the above hack a while back I was wondering if 1 write was overtaking another causing some issue. That hack kept it working at that time and it doesn't affect functionality.
Yes, NOHZ is _poor_ today in respect to needless reprogramming. Code can be improved. I have sent Thomas a patch for the same which is in the MM tree for a while now.
Today on every interrupt entry (> 2.6.27) and exit (all versions) it can potentially reprogram the hardware with the _same_ event. If interrupts come in fast from a device (like MUSB) this will cause backing up at the posting during needless reprograms. You never get all the way out of the NOHZ code before another interrupt comes. This effect drops USB performance by 3x as shown by usbtest. A simple and correct tweak recovers that lost 3x in performance.
Regards,
Richard W.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer
2008-12-07 14:55 ` Woodruff, Richard
@ 2008-12-07 17:06 ` Russell King - ARM Linux
2008-12-07 20:54 ` Tony Lindgren
2008-12-11 22:14 ` Paul Walmsley
0 siblings, 2 replies; 12+ messages in thread
From: Russell King - ARM Linux @ 2008-12-07 17:06 UTC (permalink / raw)
To: Woodruff, Richard
Cc: Tony Lindgren, linux-arm-kernel@lists.arm.linux.org.uk,
Kevin Hilman, Paul Walmsley, linux-omap@vger.kernel.org
On Sun, Dec 07, 2008 at 08:55:54AM -0600, Woodruff, Richard wrote:
> Yes, NOHZ is _poor_ today in respect to needless reprogramming. Code can
> be improved. I have sent Thomas a patch for the same which is in the MM
> tree for a while now.
When I discussed this problem with Thomas, his reaction was rather
negative due to there being conflicting requirements between this and
ia64. And quite frankly I think that the OMAP behaviour is utter
madness - taking as long as it does to update the timer registers
means that no matter what you do, you _will_ be paying a penalty
for that hardware.
Let's hope that later OMAP designs sanitise the timer hardware so
it doesn't take stupid amounts of time to write to the registers,
posted mode or not.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer
2008-12-07 17:06 ` Russell King - ARM Linux
@ 2008-12-07 20:54 ` Tony Lindgren
2008-12-11 22:14 ` Paul Walmsley
1 sibling, 0 replies; 12+ messages in thread
From: Tony Lindgren @ 2008-12-07 20:54 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Woodruff, Richard, linux-arm-kernel@lists.arm.linux.org.uk,
Kevin Hilman, Paul Walmsley, linux-omap@vger.kernel.org
* Russell King - ARM Linux <linux@arm.linux.org.uk> [081207 09:06]:
> On Sun, Dec 07, 2008 at 08:55:54AM -0600, Woodruff, Richard wrote:
> > Yes, NOHZ is _poor_ today in respect to needless reprogramming. Code can
> > be improved. I have sent Thomas a patch for the same which is in the MM
> > tree for a while now.
>
> When I discussed this problem with Thomas, his reaction was rather
> negative due to there being conflicting requirements between this and
> ia64. And quite frankly I think that the OMAP behaviour is utter
> madness - taking as long as it does to update the timer registers
> means that no matter what you do, you _will_ be paying a penalty
> for that hardware.
Well still the timer code should be optimized for slower systems.
The timer should not be reprogrammed during every device interrupt
if the change is less than a jiffy. And going through the
timer lists is not always needed, so Richard's patch tries to
optimize that [1].
> Let's hope that later OMAP designs sanitise the timer hardware so
> it doesn't take stupid amounts of time to write to the registers,
> posted mode or not.
Yeah. Richard has some profiling data showing you how much time is
spent doing that, maybe post that again for reference? It's very
interesting data.
Tony
[1] http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.28-rc2/2.6.28-rc2-mm1/broken-out/tick-schedc-suppress-needless-timer-reprogramming.patch
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer
2008-12-07 17:06 ` Russell King - ARM Linux
2008-12-07 20:54 ` Tony Lindgren
@ 2008-12-11 22:14 ` Paul Walmsley
1 sibling, 0 replies; 12+ messages in thread
From: Paul Walmsley @ 2008-12-11 22:14 UTC (permalink / raw)
To: tglx
Cc: Russell King - ARM Linux, Woodruff, Richard, Tony Lindgren, akpm,
linux-arm-kernel@lists.arm.linux.org.uk, Kevin Hilman,
linux-omap@vger.kernel.org
Hello Thomas,
On Sun, 7 Dec 2008, Russell King - ARM Linux wrote:
> On Sun, Dec 07, 2008 at 08:55:54AM -0600, Woodruff, Richard wrote:
> > Yes, NOHZ is _poor_ today in respect to needless reprogramming. Code can
> > be improved. I have sent Thomas a patch for the same which is in the MM
> > tree for a while now.
>
> When I discussed this problem with Thomas, his reaction was rather
> negative due to there being conflicting requirements between this and
> ia64.
Could you comment further on the problems with this patch from Richard
Woodruff, linked at [1]? Looks like you had some comments which were not
addressed, so, the patch at the bottom of this message reimplements
Richard's original patch to try to take those into account. Does this
updated patch address your concerns? Implementing something like this
is a major win for OMAP and probably other platforms also.
...
1. http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.28-rc2/2.6.28-rc2-mm1/broken-out/tick-schedc-suppress-needless-timer-reprogramming.patch
- Paul
[PATCH] Suppress needless timer reprogramming (version 2)
<paul@pwsan.com>: patch reimplemented to respond to tglx comments from
http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.28-rc2/2.6.28-rc2-mm1/broken-out/tick-schedc-
This new patch has not been tested to determine whether it works as well
as the original patch, will try to get Richard to confirm this.
...
From: "Woodruff, Richard" <r-woodruff2@ti.com>
In my device I get many interrupts from a high speed USB device in a very
short period of time. The system spends a lot of time reprogramming the
hardware timer which is in a slower timing domain as compared to the CPU.
This results in the CPU spending a huge amount of time waiting for the
timer posting to be done. All of this reprogramming is useless as the
wake up time has not changed.
As measured using ETM trace this drops my reprogramming penalty from
almost 60% CPU load down to 15% during high interrupt rate. I can send
traces to show this.
Suppress setting of duplicate timer event when timer already stopped.
Timer programming can be very costly and can result in long cpu stall/wait
times.
---
kernel/time/tick-sched.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 342fc9c..0255cb1 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -346,8 +346,18 @@ void tick_nohz_stop_sched_tick(int inidle)
/* Check, if the timer was already in the past */
if (hrtimer_active(&ts->sched_timer))
goto out;
- } else if (!tick_program_event(expires, 0))
- goto out;
+ } else if (ktime_equal(expires, dev->next_event)) {
+ /*
+ * No point in reprogramming the timer, since
+ * we'd be reprogramming it with the same
+ * expiration. [On some platforms (e.g., OMAP)
+ * timer reprogramming is costly.]
+ */
+ goto out;
+ } else if (!tick_program_event(expires, 0)) {
+ goto out;
+ }
+
/*
* We are past the event already. So we crossed a
* jiffie boundary. Update jiffies and raise the
^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2008-12-11 22:14 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-05 2:38 [PATCH 0/6] Omap2 updates for 2.6.29 merge window Tony Lindgren
2008-12-05 2:39 ` [PATCH 1/6] ARM: OMAP2: Prepare cpu detection for further improvements Tony Lindgren
2008-12-05 2:39 ` [PATCH 2/6] ARM: OMAP2: Fix cpu detection Tony Lindgren
2008-12-05 2:40 ` [PATCH 3/6] ARM: OMAP2: Use omap_rev() instead of system_rev Tony Lindgren
2008-12-05 2:40 ` [PATCH 4/6] ARM: OMAP2: bard-h4: list those eeproms Tony Lindgren
2008-12-05 2:41 ` [PATCH 5/6] ARM: OMAP2: drop redundant pending write check for gptimer Tony Lindgren
2008-12-07 11:25 ` Russell King - ARM Linux
2008-12-07 14:55 ` Woodruff, Richard
2008-12-07 17:06 ` Russell King - ARM Linux
2008-12-07 20:54 ` Tony Lindgren
2008-12-11 22:14 ` Paul Walmsley
2008-12-05 2:41 ` [PATCH 6/6] ARM: OMAP2: skip unnecessary TLDR write during non-autoreload " Tony Lindgren
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox