diff options
-rw-r--r-- | arch/mips/alchemy/common/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/alchemy/common/cputable.c | 52 | ||||
-rw-r--r-- | arch/mips/alchemy/common/setup.c | 26 | ||||
-rw-r--r-- | arch/mips/alchemy/common/time.c | 4 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-au1x00/au1000.h | 58 |
5 files changed, 42 insertions, 100 deletions
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index 28b8aebb35ea..d50d4764eafe 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | obj-y += prom.o irq.o puts.o time.o reset.o \ | 8 | obj-y += prom.o irq.o puts.o time.o reset.o \ |
9 | clocks.o platform.o power.o setup.o \ | 9 | clocks.o platform.o power.o setup.o \ |
10 | sleeper.o cputable.o dma.o dbdma.o gpio.o | 10 | sleeper.o dma.o dbdma.o gpio.o |
11 | 11 | ||
12 | obj-$(CONFIG_PCI) += pci.o | 12 | obj-$(CONFIG_PCI) += pci.o |
13 | 13 | ||
diff --git a/arch/mips/alchemy/common/cputable.c b/arch/mips/alchemy/common/cputable.c deleted file mode 100644 index ba6430bc2d03..000000000000 --- a/arch/mips/alchemy/common/cputable.c +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * arch/mips/au1000/common/cputable.c | ||
3 | * | ||
4 | * Copyright (C) 2004 Dan Malek (dan@embeddededge.com) | ||
5 | * Copied from PowerPC and updated for Alchemy Au1xxx processors. | ||
6 | * | ||
7 | * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <asm/mach-au1x00/au1000.h> | ||
16 | |||
17 | struct cpu_spec *cur_cpu_spec[NR_CPUS]; | ||
18 | |||
19 | /* With some thought, we can probably use the mask to reduce the | ||
20 | * size of the table. | ||
21 | */ | ||
22 | struct cpu_spec cpu_specs[] = { | ||
23 | { 0xffffffff, 0x00030100, "Au1000 DA", 1, 0, 1 }, | ||
24 | { 0xffffffff, 0x00030201, "Au1000 HA", 1, 0, 1 }, | ||
25 | { 0xffffffff, 0x00030202, "Au1000 HB", 1, 0, 1 }, | ||
26 | { 0xffffffff, 0x00030203, "Au1000 HC", 1, 1, 0 }, | ||
27 | { 0xffffffff, 0x00030204, "Au1000 HD", 1, 1, 0 }, | ||
28 | { 0xffffffff, 0x01030200, "Au1500 AB", 1, 1, 0 }, | ||
29 | { 0xffffffff, 0x01030201, "Au1500 AC", 0, 1, 0 }, | ||
30 | { 0xffffffff, 0x01030202, "Au1500 AD", 0, 1, 0 }, | ||
31 | { 0xffffffff, 0x02030200, "Au1100 AB", 1, 1, 0 }, | ||
32 | { 0xffffffff, 0x02030201, "Au1100 BA", 1, 1, 0 }, | ||
33 | { 0xffffffff, 0x02030202, "Au1100 BC", 1, 1, 0 }, | ||
34 | { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1, 0 }, | ||
35 | { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1, 0 }, | ||
36 | { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1, 0 }, | ||
37 | { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0, 0 }, | ||
38 | { 0xffffffff, 0x04030201, "Au1200 AC", 1, 0, 0 }, | ||
39 | { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 } | ||
40 | }; | ||
41 | |||
42 | void set_cpuspec(void) | ||
43 | { | ||
44 | struct cpu_spec *sp; | ||
45 | u32 prid; | ||
46 | |||
47 | prid = read_c0_prid(); | ||
48 | sp = cpu_specs; | ||
49 | while ((prid & sp->prid_mask) != sp->prid_value) | ||
50 | sp++; | ||
51 | cur_cpu_spec[0] = sp; | ||
52 | } | ||
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 9889ec3ba4c4..4d42be811e7f 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -44,37 +44,13 @@ extern void set_cpuspec(void); | |||
44 | 44 | ||
45 | void __init plat_mem_setup(void) | 45 | void __init plat_mem_setup(void) |
46 | { | 46 | { |
47 | struct cpu_spec *sp; | ||
48 | unsigned long prid, cpufreq, bclk; | ||
49 | |||
50 | set_cpuspec(); | ||
51 | sp = cur_cpu_spec[0]; | ||
52 | |||
53 | _machine_restart = au1000_restart; | 47 | _machine_restart = au1000_restart; |
54 | _machine_halt = au1000_halt; | 48 | _machine_halt = au1000_halt; |
55 | pm_power_off = au1000_power_off; | 49 | pm_power_off = au1000_power_off; |
56 | 50 | ||
57 | board_setup(); /* board specific setup */ | 51 | board_setup(); /* board specific setup */ |
58 | 52 | ||
59 | prid = read_c0_prid(); | 53 | if (au1xxx_cpu_needs_config_od()) |
60 | if (sp->cpu_pll_wo) | ||
61 | #ifdef CONFIG_SOC_AU1000_FREQUENCY | ||
62 | cpufreq = CONFIG_SOC_AU1000_FREQUENCY / 1000000; | ||
63 | #else | ||
64 | cpufreq = 396; | ||
65 | #endif | ||
66 | else | ||
67 | cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12; | ||
68 | printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq); | ||
69 | |||
70 | if (sp->cpu_bclk) { | ||
71 | /* Enable BCLK switching */ | ||
72 | bclk = au_readl(SYS_POWERCTRL); | ||
73 | au_writel(bclk | 0x60, SYS_POWERCTRL); | ||
74 | printk(KERN_INFO "BCLK switching enabled!\n"); | ||
75 | } | ||
76 | |||
77 | if (sp->cpu_od) | ||
78 | /* Various early Au1xx0 errata corrected by this */ | 54 | /* Various early Au1xx0 errata corrected by this */ |
79 | set_c0_config(1 << 19); /* Set Config[OD] */ | 55 | set_c0_config(1 << 19); /* Set Config[OD] */ |
80 | else | 56 | else |
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c index 68d714258e92..15185708ad8c 100644 --- a/arch/mips/alchemy/common/time.c +++ b/arch/mips/alchemy/common/time.c | |||
@@ -198,7 +198,7 @@ unsigned long calc_clock(void) | |||
198 | * silicon versions of Au1000 are not sold by AMD, we don't bend | 198 | * silicon versions of Au1000 are not sold by AMD, we don't bend |
199 | * over backwards trying to determine the frequency. | 199 | * over backwards trying to determine the frequency. |
200 | */ | 200 | */ |
201 | if (cur_cpu_spec[0]->cpu_pll_wo) | 201 | if (au1xxx_cpu_has_pll_wo()) |
202 | #ifdef CONFIG_SOC_AU1000_FREQUENCY | 202 | #ifdef CONFIG_SOC_AU1000_FREQUENCY |
203 | cpu_speed = CONFIG_SOC_AU1000_FREQUENCY; | 203 | cpu_speed = CONFIG_SOC_AU1000_FREQUENCY; |
204 | #else | 204 | #else |
@@ -221,7 +221,7 @@ void __init plat_time_init(void) | |||
221 | 221 | ||
222 | est_freq += 5000; /* round */ | 222 | est_freq += 5000; /* round */ |
223 | est_freq -= est_freq%10000; | 223 | est_freq -= est_freq%10000; |
224 | printk(KERN_INFO "CPU frequency %u.%02u MHz\n", | 224 | printk(KERN_INFO "(PRId %08x) @ %u.%02u MHz\n", read_c0_prid(), |
225 | est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); | 225 | est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); |
226 | set_au1x00_speed(est_freq); | 226 | set_au1x00_speed(est_freq); |
227 | 227 | ||
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index d07632e3230b..5db26e60a8c5 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h | |||
@@ -91,6 +91,44 @@ static inline u32 au_readl(unsigned long reg) | |||
91 | return *(volatile u32 *)reg; | 91 | return *(volatile u32 *)reg; |
92 | } | 92 | } |
93 | 93 | ||
94 | /* Early Au1000 have a write-only SYS_CPUPLL register. */ | ||
95 | static inline int au1xxx_cpu_has_pll_wo(void) | ||
96 | { | ||
97 | switch (read_c0_prid()) { | ||
98 | case 0x00030100: /* Au1000 DA */ | ||
99 | case 0x00030201: /* Au1000 HA */ | ||
100 | case 0x00030202: /* Au1000 HB */ | ||
101 | return 1; | ||
102 | } | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | /* does CPU need CONFIG[OD] set to fix tons of errata? */ | ||
107 | static inline int au1xxx_cpu_needs_config_od(void) | ||
108 | { | ||
109 | /* | ||
110 | * c0_config.od (bit 19) was write only (and read as 0) on the | ||
111 | * early revisions of Alchemy SOCs. It disables the bus trans- | ||
112 | * action overlapping and needs to be set to fix various errata. | ||
113 | */ | ||
114 | switch (read_c0_prid()) { | ||
115 | case 0x00030100: /* Au1000 DA */ | ||
116 | case 0x00030201: /* Au1000 HA */ | ||
117 | case 0x00030202: /* Au1000 HB */ | ||
118 | case 0x01030200: /* Au1500 AB */ | ||
119 | /* | ||
120 | * Au1100/Au1200 errata actually keep silence about this bit, | ||
121 | * so we set it just in case for those revisions that require | ||
122 | * it to be set according to the (now gone) cpu_table. | ||
123 | */ | ||
124 | case 0x02030200: /* Au1100 AB */ | ||
125 | case 0x02030201: /* Au1100 BA */ | ||
126 | case 0x02030202: /* Au1100 BC */ | ||
127 | case 0x04030201: /* Au1200 AC */ | ||
128 | return 1; | ||
129 | } | ||
130 | return 0; | ||
131 | } | ||
94 | 132 | ||
95 | /* arch/mips/au1000/common/clocks.c */ | 133 | /* arch/mips/au1000/common/clocks.c */ |
96 | extern void set_au1x00_speed(unsigned int new_freq); | 134 | extern void set_au1x00_speed(unsigned int new_freq); |
@@ -1739,24 +1777,4 @@ static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE; | |||
1739 | 1777 | ||
1740 | #endif | 1778 | #endif |
1741 | 1779 | ||
1742 | /* | ||
1743 | * Processor information based on PRID. | ||
1744 | * Copied from PowerPC. | ||
1745 | */ | ||
1746 | #ifndef _LANGUAGE_ASSEMBLY | ||
1747 | struct cpu_spec { | ||
1748 | /* CPU is matched via (PRID & prid_mask) == prid_value */ | ||
1749 | unsigned int prid_mask; | ||
1750 | unsigned int prid_value; | ||
1751 | |||
1752 | char *cpu_name; | ||
1753 | unsigned char cpu_od; /* Set Config[OD] */ | ||
1754 | unsigned char cpu_bclk; /* Enable BCLK switching */ | ||
1755 | unsigned char cpu_pll_wo; /* sys_cpupll reg. write-only */ | ||
1756 | }; | ||
1757 | |||
1758 | extern struct cpu_spec cpu_specs[]; | ||
1759 | extern struct cpu_spec *cur_cpu_spec[]; | ||
1760 | #endif | ||
1761 | |||
1762 | #endif | 1780 | #endif |