aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci
diff options
context:
space:
mode:
authorMark A. Greer <mgreer@mvista.com>2009-04-15 15:39:09 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-05-26 11:14:56 -0400
commitb9ab12797e74d93a3656ea0bf5591f8b3e094fd5 (patch)
tree5900f0c6a70d9de793ab282dacd820e967f84272 /arch/arm/mach-davinci
parent79c3c0b729647a6246c120408f36e6804dab244e (diff)
davinci: Support JTAG ID register at any address
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>
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r--arch/arm/mach-davinci/Makefile2
-rw-r--r--arch/arm/mach-davinci/common.c29
-rw-r--r--arch/arm/mach-davinci/dm355.c14
-rw-r--r--arch/arm/mach-davinci/dm644x.c15
-rw-r--r--arch/arm/mach-davinci/dm646x.c14
-rw-r--r--arch/arm/mach-davinci/id.c116
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h6
-rw-r--r--arch/arm/mach-davinci/include/mach/cputype.h29
8 files changed, 97 insertions, 128 deletions
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 74d25f69934e..a65d03bb4679 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -4,7 +4,7 @@
4# 4#
5 5
6# Common objects 6# Common objects
7obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \ 7obj-y := time.o irq.o clock.o serial.o io.o psc.o \
8 gpio.o devices.o dma.o usb.o common.o 8 gpio.o devices.o dma.o usb.o common.o
9 9
10obj-$(CONFIG_DAVINCI_MUX) += mux.o 10obj-$(CONFIG_DAVINCI_MUX) += mux.o
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
index 9a5486f5519c..29b3a8d51211 100644
--- a/arch/arm/mach-davinci/common.c
+++ b/arch/arm/mach-davinci/common.c
@@ -15,13 +15,31 @@
15#include <asm/mach/map.h> 15#include <asm/mach/map.h>
16 16
17#include <mach/common.h> 17#include <mach/common.h>
18#include <mach/cputype.h>
18 19
19struct davinci_soc_info davinci_soc_info; 20struct davinci_soc_info davinci_soc_info;
20EXPORT_SYMBOL(davinci_soc_info); 21EXPORT_SYMBOL(davinci_soc_info);
21 22
23static struct davinci_id * __init davinci_get_id(u32 jtag_id)
24{
25 int i;
26 struct davinci_id *dip;
27 u8 variant = (jtag_id & 0xf0000000) >> 28;
28 u16 part_no = (jtag_id & 0x0ffff000) >> 12;
29
30 for (i = 0, dip = davinci_soc_info.ids; i < davinci_soc_info.ids_num;
31 i++, dip++)
32 /* Don't care about the manufacturer right now */
33 if ((dip->part_no == part_no) && (dip->variant == variant))
34 return dip;
35
36 return NULL;
37}
38
22void __init davinci_common_init(struct davinci_soc_info *soc_info) 39void __init davinci_common_init(struct davinci_soc_info *soc_info)
23{ 40{
24 int ret; 41 int ret;
42 struct davinci_id *dip;
25 43
26 if (!soc_info) { 44 if (!soc_info) {
27 ret = -EINVAL; 45 ret = -EINVAL;
@@ -46,7 +64,16 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
46 * We want to check CPU revision early for cpu_is_xxxx() macros. 64 * We want to check CPU revision early for cpu_is_xxxx() macros.
47 * IO space mapping must be initialized before we can do that. 65 * IO space mapping must be initialized before we can do that.
48 */ 66 */
49 davinci_check_revision(); 67 davinci_soc_info.jtag_id = __raw_readl(davinci_soc_info.jtag_id_base);
68
69 dip = davinci_get_id(davinci_soc_info.jtag_id);
70 if (!dip) {
71 ret = -EINVAL;
72 goto err;
73 }
74
75 davinci_soc_info.cpu_id = dip->cpu_id;
76 pr_info("DaVinci %s variant 0x%x\n", dip->name, dip->variant);
50 77
51 return; 78 return;
52 79
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 6d1abfdcfb72..0f724c060084 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[] = {
534 }, 534 },
535}; 535};
536 536
537/* Contents of JTAG ID register used to identify exact cpu type */
538static struct davinci_id dm355_ids[] = {
539 {
540 .variant = 0x0,
541 .part_no = 0xb73b,
542 .manufacturer = 0x00f,
543 .cpu_id = DAVINCI_CPU_ID_DM355,
544 .name = "dm355",
545 },
546};
547
537static struct davinci_soc_info davinci_soc_info_dm355 = { 548static struct davinci_soc_info davinci_soc_info_dm355 = {
538 .io_desc = dm355_io_desc, 549 .io_desc = dm355_io_desc,
539 .io_desc_num = ARRAY_SIZE(dm355_io_desc), 550 .io_desc_num = ARRAY_SIZE(dm355_io_desc),
551 .jtag_id_base = IO_ADDRESS(0x01c40028),
552 .ids = dm355_ids,
553 .ids_num = ARRAY_SIZE(dm355_ids),
540}; 554};
541 555
542void __init dm355_init(void) 556void __init dm355_init(void)
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 79f113698b0b..9bcd98c6820b 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)
388MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false) 388MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false)
389}; 389};
390 390
391
392/*----------------------------------------------------------------------*/ 391/*----------------------------------------------------------------------*/
393 392
394static const s8 dma_chan_dm644x_no_event[] = { 393static const s8 dma_chan_dm644x_no_event[] = {
@@ -475,9 +474,23 @@ static struct map_desc dm644x_io_desc[] = {
475 }, 474 },
476}; 475};
477 476
477/* Contents of JTAG ID register used to identify exact cpu type */
478static struct davinci_id dm644x_ids[] = {
479 {
480 .variant = 0x0,
481 .part_no = 0xb700,
482 .manufacturer = 0x017,
483 .cpu_id = DAVINCI_CPU_ID_DM6446,
484 .name = "dm6446",
485 },
486};
487
478static struct davinci_soc_info davinci_soc_info_dm644x = { 488static struct davinci_soc_info davinci_soc_info_dm644x = {
479 .io_desc = dm644x_io_desc, 489 .io_desc = dm644x_io_desc,
480 .io_desc_num = ARRAY_SIZE(dm644x_io_desc), 490 .io_desc_num = ARRAY_SIZE(dm644x_io_desc),
491 .jtag_id_base = IO_ADDRESS(0x01c40028),
492 .ids = dm644x_ids,
493 .ids_num = ARRAY_SIZE(dm644x_ids),
481}; 494};
482 495
483void __init dm644x_init(void) 496void __init dm644x_init(void)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 8547ec02c9e1..cd86bb78e0c1 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[] = {
454 }, 454 },
455}; 455};
456 456
457/* Contents of JTAG ID register used to identify exact cpu type */
458static struct davinci_id dm646x_ids[] = {
459 {
460 .variant = 0x0,
461 .part_no = 0xb770,
462 .manufacturer = 0x017,
463 .cpu_id = DAVINCI_CPU_ID_DM6467,
464 .name = "dm6467",
465 },
466};
467
457static struct davinci_soc_info davinci_soc_info_dm646x = { 468static struct davinci_soc_info davinci_soc_info_dm646x = {
458 .io_desc = dm646x_io_desc, 469 .io_desc = dm646x_io_desc,
459 .io_desc_num = ARRAY_SIZE(dm646x_io_desc), 470 .io_desc_num = ARRAY_SIZE(dm646x_io_desc),
471 .jtag_id_base = IO_ADDRESS(0x01c40028),
472 .ids = dm646x_ids,
473 .ids_num = ARRAY_SIZE(dm646x_ids),
460}; 474};
461 475
462void __init dm646x_init(void) 476void __init dm646x_init(void)
diff --git a/arch/arm/mach-davinci/id.c b/arch/arm/mach-davinci/id.c
deleted file mode 100644
index 018b994cd794..000000000000
--- a/arch/arm/mach-davinci/id.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/*
2 * Davinci CPU identification code
3 *
4 * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.com>
5 *
6 * Derived from OMAP1 CPU identification code.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/io.h>
17
18#define JTAG_ID_BASE IO_ADDRESS(0x01c40028)
19
20static unsigned int davinci_revision;
21
22struct davinci_id {
23 u8 variant; /* JTAG ID bits 31:28 */
24 u16 part_no; /* JTAG ID bits 27:12 */
25 u32 manufacturer; /* JTAG ID bits 11:1 */
26 u32 type; /* Cpu id bits [31:8], cpu class bits [7:0] */
27};
28
29/* Register values to detect the DaVinci version */
30static struct davinci_id davinci_ids[] __initdata = {
31 {
32 /* DM6446 */
33 .part_no = 0xb700,
34 .variant = 0x0,
35 .manufacturer = 0x017,
36 .type = 0x64460000,
37 },
38 {
39 /* DM646X */
40 .part_no = 0xb770,
41 .variant = 0x0,
42 .manufacturer = 0x017,
43 .type = 0x64670000,
44 },
45 {
46 /* DM355 */
47 .part_no = 0xb73b,
48 .variant = 0x0,
49 .manufacturer = 0x00f,
50 .type = 0x03550000,
51 },
52};
53
54/*
55 * Get Device Part No. from JTAG ID register
56 */
57static u16 __init davinci_get_part_no(void)
58{
59 u32 dev_id, part_no;
60
61 dev_id = __raw_readl(JTAG_ID_BASE);
62
63 part_no = ((dev_id >> 12) & 0xffff);
64
65 return part_no;
66}
67
68/*
69 * Get Device Revision from JTAG ID register
70 */
71static u8 __init davinci_get_variant(void)
72{
73 u32 variant;
74
75 variant = __raw_readl(JTAG_ID_BASE);
76
77 variant = (variant >> 28) & 0xf;
78
79 return variant;
80}
81
82unsigned int davinci_rev(void)
83{
84 return davinci_revision >> 16;
85}
86EXPORT_SYMBOL(davinci_rev);
87
88void __init davinci_check_revision(void)
89{
90 int i;
91 u16 part_no;
92 u8 variant;
93
94 part_no = davinci_get_part_no();
95 variant = davinci_get_variant();
96
97 /* First check only the major version in a safe way */
98 for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
99 if (part_no == (davinci_ids[i].part_no)) {
100 davinci_revision = davinci_ids[i].type;
101 break;
102 }
103 }
104
105 /* Check if we can find the dev revision */
106 for (i = 0; i < ARRAY_SIZE(davinci_ids); i++) {
107 if (part_no == davinci_ids[i].part_no &&
108 variant == davinci_ids[i].variant) {
109 davinci_revision = davinci_ids[i].type;
110 break;
111 }
112 }
113
114 printk(KERN_INFO "DaVinci DM%04x variant 0x%x\n",
115 davinci_rev(), variant);
116}
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index 770a1baa97dc..ece1cd42738f 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -28,11 +28,15 @@ extern void setup_usb(unsigned mA, unsigned potpgt_msec);
28struct davinci_soc_info { 28struct davinci_soc_info {
29 struct map_desc *io_desc; 29 struct map_desc *io_desc;
30 unsigned long io_desc_num; 30 unsigned long io_desc_num;
31 u32 cpu_id;
32 u32 jtag_id;
33 void __iomem *jtag_id_base;
34 struct davinci_id *ids;
35 unsigned long ids_num;
31}; 36};
32 37
33extern struct davinci_soc_info davinci_soc_info; 38extern struct davinci_soc_info davinci_soc_info;
34 39
35extern void davinci_common_init(struct davinci_soc_info *soc_info); 40extern void davinci_common_init(struct davinci_soc_info *soc_info);
36extern void davinci_check_revision(void);
37 41
38#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */ 42#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h
index 27cfb1b3a662..d12a5ed2959a 100644
--- a/arch/arm/mach-davinci/include/mach/cputype.h
+++ b/arch/arm/mach-davinci/include/mach/cputype.h
@@ -16,17 +16,30 @@
16#ifndef _ASM_ARCH_CPU_H 16#ifndef _ASM_ARCH_CPU_H
17#define _ASM_ARCH_CPU_H 17#define _ASM_ARCH_CPU_H
18 18
19extern unsigned int davinci_rev(void); 19#include <mach/common.h>
20 20
21#define IS_DAVINCI_CPU(type, id) \ 21struct davinci_id {
22static inline int is_davinci_dm ##type(void) \ 22 u8 variant; /* JTAG ID bits 31:28 */
23{ \ 23 u16 part_no; /* JTAG ID bits 27:12 */
24 return (davinci_rev() == (id)) ? 1 : 0; \ 24 u16 manufacturer; /* JTAG ID bits 11:1 */
25 u32 cpu_id;
26 char *name;
27};
28
29/* Can use lower 16 bits of cpu id for a variant when required */
30#define DAVINCI_CPU_ID_DM6446 0x64460000
31#define DAVINCI_CPU_ID_DM6467 0x64670000
32#define DAVINCI_CPU_ID_DM355 0x03550000
33
34#define IS_DAVINCI_CPU(type, id) \
35static inline int is_davinci_ ##type(void) \
36{ \
37 return (davinci_soc_info.cpu_id == (id)); \
25} 38}
26 39
27IS_DAVINCI_CPU(644x, 0x6446) 40IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446)
28IS_DAVINCI_CPU(646x, 0x6467) 41IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467)
29IS_DAVINCI_CPU(355, 0x355) 42IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
30 43
31#ifdef CONFIG_ARCH_DAVINCI_DM644x 44#ifdef CONFIG_ARCH_DAVINCI_DM644x
32#define cpu_is_davinci_dm644x() is_davinci_dm644x() 45#define cpu_is_davinci_dm644x() is_davinci_dm644x()