davinci: Support JTAG ID register at any address
authorMark A. Greer <mgreer@mvista.com>
Wed, 15 Apr 2009 19:39:09 +0000 (12:39 -0700)
committerKevin Hilman <khilman@deeprootsystems.com>
Tue, 26 May 2009 15:14:56 +0000 (08:14 -0700)
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 soc_info structure and add a 'cpu_id' member to it.
'cpu_id' will be used by the cpu_is_davinci_*() macros to match
the cpu id.  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 the soc_info
structure to the proper value and the cpu_is_davinci_*() macros
will now work.

Signed-off-by: Mark A. Greer <mgreer@mvista.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/common.c
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/id.c [deleted file]
arch/arm/mach-davinci/include/mach/common.h
arch/arm/mach-davinci/include/mach/cputype.h

index 74d25f6..a65d03b 100644 (file)
@@ -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 dma.o usb.o common.o
 
 obj-$(CONFIG_DAVINCI_MUX)              += mux.o
index 9a5486f..29b3a8d 100644 (file)
 #include <asm/mach/map.h>
 
 #include <mach/common.h>
+#include <mach/cputype.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;
+}
+
 void __init davinci_common_init(struct davinci_soc_info *soc_info)
 {
        int ret;
+       struct davinci_id *dip;
 
        if (!soc_info) {
                ret = -EINVAL;
@@ -46,7 +64,16 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
         * 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;
+       pr_info("DaVinci %s variant 0x%x\n", dip->name, dip->variant);
 
        return;
 
index 6d1abfd..0f724c0 100644 (file)
@@ -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),
 };
 
 void __init dm355_init(void)
index 79f1136..9bcd98c 100644 (file)
@@ -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),
 };
 
 void __init dm644x_init(void)
index 8547ec0..cd86bb7 100644 (file)
@@ -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),
 };
 
 void __init dm646x_init(void)
diff --git a/arch/arm/mach-davinci/id.c b/arch/arm/mach-davinci/id.c
deleted file mode 100644 (file)
index 018b994..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Davinci CPU identification code
- *
- * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com>
- *
- * 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);
-}
index 770a1ba..ece1cd4 100644 (file)
@@ -28,11 +28,15 @@ 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 void davinci_common_init(struct davinci_soc_info *soc_info);
-extern void davinci_check_revision(void);
 
 #endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
index 27cfb1b..d12a5ed 100644 (file)
 #ifndef _ASM_ARCH_CPU_H
 #define _ASM_ARCH_CPU_H
 
-extern unsigned int davinci_rev(void);
+#include <mach/common.h>
 
-#define IS_DAVINCI_CPU(type, id)                       \
-static inline int is_davinci_dm ##type(void)           \
-{                                                      \
-       return (davinci_rev() == (id)) ? 1 : 0;         \
+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_ ##type(void)                             \
+{                                                                      \
+       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()