From: Mark A. Greer <[email protected]>

The Davinci cpu_is_davinci_*() macros use the SoC part number
and variant retrieved from the JTAG ID register to determine the
type of cpu that the kernel is running on.  Currently, the code to
read the JTAG ID register assumes that the register is always at
the same base address.  This isn't true on some newer SoCs.

To solve this, have the SoC-specific code set the JTAG ID register
base address in 'davinci_soc_info' and add a 'cpu_id' member to
'davinci_soc_info' which will be used by the cpu_is_davinci_*()
macros.  Also move the info used to identify the cpu type into
the SoC-specific code to keep all SoC-specific code together.

The common code will read the JTAG ID register, search through
an array of davinci_id structures to identify the cpu type.
Once identified, it will set the 'cpu_id' member of
'davinci_soc_info' to the proper value and the cpu_is_davinci_*()
macros will now work.

Signed-off-by: Mark A. Greer <[email protected]>
---
 arch/arm/mach-davinci/Makefile              |    2 +-
 arch/arm/mach-davinci/common.c              |   32 +++++++-
 arch/arm/mach-davinci/dm355.c               |   14 +++
 arch/arm/mach-davinci/dm644x.c              |   15 +++-
 arch/arm/mach-davinci/dm646x.c              |   14 +++
 arch/arm/mach-davinci/id.c                  |  116 ---------------------------
 arch/arm/mach-davinci/include/mach/common.h |    6 +-
 arch/arm/mach-davinci/include/mach/cpu.h    |   25 +++++--
 8 files changed, 97 insertions(+), 127 deletions(-)
 delete mode 100644 arch/arm/mach-davinci/id.c

diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index ca2ceef..b8e54ac 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -4,7 +4,7 @@
 #
 
 # Common objects
-obj-y                  := time.o irq.o clock.o serial.o io.o id.o psc.o \
+obj-y                  := time.o irq.o clock.o serial.o io.o psc.o \
                           gpio.o devices.o usb.o dma.o iram.o common.o
 
 obj-$(CONFIG_DAVINCI_MUX)              += mux.o
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index e2d035a..376ae47 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -15,13 +15,31 @@
 #include <asm/mach/map.h>
 
 #include <mach/common.h>
+#include <mach/cpu.h>
 
 struct davinci_soc_info *davinci_soc_info;
 EXPORT_SYMBOL(davinci_soc_info);
 
+static struct davinci_id * __init davinci_get_id(u32 jtag_id)
+{
+       int i;
+       struct davinci_id *dip;
+       u8 variant = (jtag_id & 0xf0000000) >> 28;
+       u16 part_no = (jtag_id & 0x0ffff000) >> 12;
+
+       for (i = 0, dip = davinci_soc_info->ids; i < davinci_soc_info->ids_num;
+                       i++, dip++)
+               /* Don't care about the manufacturer right now */
+               if ((dip->part_no == part_no) && (dip->variant == variant))
+                       return dip;
+
+       return NULL;
+}
+
 int __init davinci_common_init(struct davinci_soc_info *soc_info)
 {
        int ret;
+       struct davinci_id *dip;
 
        if (!soc_info) {
                ret = -EINVAL;
@@ -41,10 +59,20 @@ int __init davinci_common_init(struct davinci_soc_info 
*soc_info)
        local_flush_tlb_all();
        flush_cache_all();
 
-       /* We want to check CPU revision early for cpu_is_xxxx() macros.
+       /*
+        * We want to check CPU revision early for cpu_is_xxxx() macros.
         * IO space mapping must be initialized before we can do that.
         */
-       davinci_check_revision();
+       davinci_soc_info->jtag_id = __raw_readl(davinci_soc_info->jtag_id_base);
+
+       dip = davinci_get_id(davinci_soc_info->jtag_id);
+       if (!dip) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       davinci_soc_info->cpu_id = dip->cpu_id;
+       printk(KERN_INFO "DaVinci %s variant 0x%x\n", dip->name, dip->variant);
 
        return 0;
 
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index f454e24..b6691dd 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -534,9 +534,23 @@ static struct map_desc dm355_io_desc[] = {
        },
 };
 
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm355_ids[] = {
+       {
+               .variant        = 0x0,
+               .part_no        = 0xb73b,
+               .manufacturer   = 0x00f,
+               .cpu_id         = DAVINCI_CPU_ID_DM355,
+               .name           = "dm355",
+       },
+};
+
 static struct davinci_soc_info davinci_soc_info_dm355 = {
        .io_desc                = dm355_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm355_io_desc),
+       .jtag_id_base           = IO_ADDRESS(0x01c40028),
+       .ids                    = dm355_ids,
+       .ids_num                = ARRAY_SIZE(dm355_ids),
 };
 
 struct davinci_soc_info *dm355_get_soc_info(void)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index ecfcdb2..72ce6fb 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -388,7 +388,6 @@ MUX_CFG(DM644X, LOEEN,              0,   24,    1,    1,    
 true)
 MUX_CFG(DM644X, LFLDEN,                0,   25,    1,    1,     false)
 };
 
-
 /*----------------------------------------------------------------------*/
 
 static const s8 dma_chan_dm644x_no_event[] = {
@@ -475,9 +474,23 @@ static struct map_desc dm644x_io_desc[] = {
        },
 };
 
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm644x_ids[] = {
+       {
+               .variant        = 0x0,
+               .part_no        = 0xb700,
+               .manufacturer   = 0x017,
+               .cpu_id         = DAVINCI_CPU_ID_DM6446,
+               .name           = "dm6446",
+       },
+};
+
 static struct davinci_soc_info davinci_soc_info_dm644x = {
        .io_desc                = dm644x_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm644x_io_desc),
+       .jtag_id_base           = IO_ADDRESS(0x01c40028),
+       .ids                    = dm644x_ids,
+       .ids_num                = ARRAY_SIZE(dm644x_ids),
 };
 
 struct davinci_soc_info *dm644x_get_soc_info(void)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 8c7d2e7..c9a73cc 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -454,9 +454,23 @@ static struct map_desc dm646x_io_desc[] = {
        },
 };
 
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm646x_ids[] = {
+       {
+               .variant        = 0x0,
+               .part_no        = 0xb770,
+               .manufacturer   = 0x017,
+               .cpu_id         = DAVINCI_CPU_ID_DM6467,
+               .name           = "dm6467",
+       },
+};
+
 static struct davinci_soc_info davinci_soc_info_dm646x = {
        .io_desc                = dm646x_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm646x_io_desc),
+       .jtag_id_base           = IO_ADDRESS(0x01c40028),
+       .ids                    = dm646x_ids,
+       .ids_num                = ARRAY_SIZE(dm646x_ids),
 };
 
 struct davinci_soc_info *dm646x_get_soc_info(void)
diff --git a/arch/arm/mach-davinci/id.c b/arch/arm/mach-davinci/id.c
deleted file mode 100644
index 018b994..0000000
--- a/arch/arm/mach-davinci/id.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Davinci CPU identification code
- *
- * Copyright (C) 2006 Komal Shah <[email protected]>
- *
- * Derived from OMAP1 CPU identification code.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#define JTAG_ID_BASE           IO_ADDRESS(0x01c40028)
-
-static unsigned int davinci_revision;
-
-struct davinci_id {
-       u8      variant;        /* JTAG ID bits 31:28 */
-       u16     part_no;        /* JTAG ID bits 27:12 */
-       u32     manufacturer;   /* JTAG ID bits 11:1 */
-       u32     type;           /* Cpu id bits [31:8], cpu class bits [7:0] */
-};
-
-/* Register values to detect the DaVinci version */
-static struct davinci_id davinci_ids[] __initdata = {
-       {
-               /* DM6446 */
-               .part_no      = 0xb700,
-               .variant      = 0x0,
-               .manufacturer = 0x017,
-               .type         = 0x64460000,
-       },
-       {
-               /* DM646X */
-               .part_no      = 0xb770,
-               .variant      = 0x0,
-               .manufacturer = 0x017,
-               .type         = 0x64670000,
-       },
-       {
-               /* DM355 */
-               .part_no        = 0xb73b,
-               .variant        = 0x0,
-               .manufacturer   = 0x00f,
-               .type           = 0x03550000,
-       },
-};
-
-/*
- * Get Device Part No. from JTAG ID register
- */
-static u16 __init davinci_get_part_no(void)
-{
-       u32 dev_id, part_no;
-
-       dev_id = __raw_readl(JTAG_ID_BASE);
-
-       part_no = ((dev_id >> 12) & 0xffff);
-
-       return part_no;
-}
-
-/*
- * Get Device Revision from JTAG ID register
- */
-static u8 __init davinci_get_variant(void)
-{
-       u32 variant;
-
-       variant = __raw_readl(JTAG_ID_BASE);
-
-       variant = (variant >> 28) & 0xf;
-
-       return variant;
-}
-
-unsigned int davinci_rev(void)
-{
-       return davinci_revision >> 16;
-}
-EXPORT_SYMBOL(davinci_rev);
-
-void __init davinci_check_revision(void)
-{
-       int i;
-       u16 part_no;
-       u8 variant;
-
-       part_no = davinci_get_part_no();
-       variant = davinci_get_variant();
-
-       /* First check only the major version in a safe way */
-       for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
-               if (part_no == (davinci_ids[i].part_no)) {
-                       davinci_revision = davinci_ids[i].type;
-                       break;
-               }
-       }
-
-       /* Check if we can find the dev revision */
-       for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
-               if (part_no == davinci_ids[i].part_no &&
-                   variant == davinci_ids[i].variant) {
-                       davinci_revision = davinci_ids[i].type;
-                       break;
-               }
-       }
-
-       printk(KERN_INFO "DaVinci DM%04x variant 0x%x\n",
-              davinci_rev(), variant);
-}
diff --git a/arch/arm/mach-davinci/include/mach/common.h 
b/arch/arm/mach-davinci/include/mach/common.h
index a754365..49d8701 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -28,10 +28,14 @@ extern void setup_usb(unsigned mA, unsigned potpgt_msec);
 struct davinci_soc_info {
        struct map_desc                 *io_desc;
        unsigned long                   io_desc_num;
+       u32                             cpu_id;
+       u32                             jtag_id;
+       void __iomem                    *jtag_id_base;
+       struct davinci_id               *ids;
+       unsigned long                   ids_num;
 };
 
 extern struct davinci_soc_info *davinci_soc_info;
 extern int davinci_common_init(struct davinci_soc_info *soc_info);
-extern void davinci_check_revision(void);
 
 #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
diff --git a/arch/arm/mach-davinci/include/mach/cpu.h 
b/arch/arm/mach-davinci/include/mach/cpu.h
index 99c73da..ff68cb0 100644
--- a/arch/arm/mach-davinci/include/mach/cpu.h
+++ b/arch/arm/mach-davinci/include/mach/cpu.h
@@ -16,17 +16,30 @@
 #ifndef _ASM_ARCH_CPU_H
 #define _ASM_ARCH_CPU_H
 
-extern unsigned int davinci_rev(void);
+#include <mach/common.h>
+
+struct davinci_id {
+       u8      variant;        /* JTAG ID bits 31:28 */
+       u16     part_no;        /* JTAG ID bits 27:12 */
+       u16     manufacturer;   /* JTAG ID bits 11:1 */
+       u32     cpu_id;
+       char    *name;
+};
+
+/* Can use lower 16 bits of cpu id  for a variant when required */
+#define        DAVINCI_CPU_ID_DM6446           0x64460000
+#define        DAVINCI_CPU_ID_DM6467           0x64670000
+#define        DAVINCI_CPU_ID_DM355            0x03550000
 
 #define IS_DAVINCI_CPU(type, id)                       \
-static inline int is_davinci_dm ##type(void)           \
+static inline int is_davinci_ ##type(void)             \
 {                                                      \
-       return (davinci_rev() == (id)) ? 1 : 0;         \
+       return (davinci_soc_info->cpu_id == (id));      \
 }
 
-IS_DAVINCI_CPU(644x, 0x6446)
-IS_DAVINCI_CPU(646x, 0x6467)
-IS_DAVINCI_CPU(355, 0x355)
+IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446)
+IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467)
+IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
 
 #ifdef CONFIG_ARCH_DAVINCI_DM644x
 #define cpu_is_davinci_dm644x() is_davinci_dm644x()
-- 
1.6.0.3


_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to