diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-11-10 07:06:22 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-12-07 17:02:07 -0500 |
commit | f59c811f8c44e60a59783e3337594da638a48dff (patch) | |
tree | 673e070d8affa4703b3c6c686b4a93b366b68a4c /arch/mips/alchemy/devboards/db1000.c | |
parent | 6f7c8623db005889ee35a602e0c2564ea06cd3ff (diff) |
MIPS: Alchemy: one kernel for DB1000/DB1500/DB1100
These 3 boards are very similar; with this patch a single kernel image
which runs on all three can be built.
Tested on DB1500 and DB1100.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/2872/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/alchemy/devboards/db1000.c')
-rw-r--r-- | arch/mips/alchemy/devboards/db1000.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c new file mode 100644 index 000000000000..57ed5f1c4919 --- /dev/null +++ b/arch/mips/alchemy/devboards/db1000.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | * DBAu1000/1500/1100 board support | ||
3 | * | ||
4 | * Copyright 2000, 2008 MontaVista Software Inc. | ||
5 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/pm.h> | ||
28 | #include <asm/mach-au1x00/au1000.h> | ||
29 | #include <asm/mach-au1x00/au1000_dma.h> | ||
30 | #include <asm/mach-db1x00/bcsr.h> | ||
31 | #include <asm/reboot.h> | ||
32 | #include <prom.h> | ||
33 | #include "platform.h" | ||
34 | |||
35 | #define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT) | ||
36 | |||
37 | struct pci_dev; | ||
38 | |||
39 | static const char *board_type_str(void) | ||
40 | { | ||
41 | switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { | ||
42 | case BCSR_WHOAMI_DB1000: | ||
43 | return "DB1000"; | ||
44 | case BCSR_WHOAMI_DB1500: | ||
45 | return "DB1500"; | ||
46 | case BCSR_WHOAMI_DB1100: | ||
47 | return "DB1100"; | ||
48 | default: | ||
49 | return "(unknown)"; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | const char *get_system_type(void) | ||
54 | { | ||
55 | return board_type_str(); | ||
56 | } | ||
57 | |||
58 | void __init board_setup(void) | ||
59 | { | ||
60 | /* initialize board register space */ | ||
61 | bcsr_init(DB1000_BCSR_PHYS_ADDR, | ||
62 | DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS); | ||
63 | |||
64 | printk(KERN_INFO "AMD Alchemy %s Board\n", board_type_str()); | ||
65 | |||
66 | #if defined(CONFIG_IRDA) && defined(CONFIG_AU1000_FIR) | ||
67 | { | ||
68 | u32 pin_func; | ||
69 | |||
70 | /* Set IRFIRSEL instead of GPIO15 */ | ||
71 | pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF; | ||
72 | au_writel(pin_func, SYS_PINFUNC); | ||
73 | /* Power off until the driver is in use */ | ||
74 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK, | ||
75 | BCSR_RESETS_IRDA_MODE_OFF); | ||
76 | } | ||
77 | #endif | ||
78 | bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */ | ||
79 | |||
80 | /* Enable GPIO[31:0] inputs */ | ||
81 | alchemy_gpio1_input_enable(); | ||
82 | } | ||
83 | |||
84 | |||
85 | static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
86 | { | ||
87 | if ((slot < 12) || (slot > 13) || pin == 0) | ||
88 | return -1; | ||
89 | if (slot == 12) | ||
90 | return (pin == 1) ? AU1500_PCI_INTA : 0xff; | ||
91 | if (slot == 13) { | ||
92 | switch (pin) { | ||
93 | case 1: return AU1500_PCI_INTA; | ||
94 | case 2: return AU1500_PCI_INTB; | ||
95 | case 3: return AU1500_PCI_INTC; | ||
96 | case 4: return AU1500_PCI_INTD; | ||
97 | } | ||
98 | } | ||
99 | return -1; | ||
100 | } | ||
101 | |||
102 | static struct resource alchemy_pci_host_res[] = { | ||
103 | [0] = { | ||
104 | .start = AU1500_PCI_PHYS_ADDR, | ||
105 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
106 | .flags = IORESOURCE_MEM, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | static struct alchemy_pci_platdata db1500_pci_pd = { | ||
111 | .board_map_irq = db1500_map_pci_irq, | ||
112 | }; | ||
113 | |||
114 | static struct platform_device db1500_pci_host_dev = { | ||
115 | .dev.platform_data = &db1500_pci_pd, | ||
116 | .name = "alchemy-pci", | ||
117 | .id = 0, | ||
118 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
119 | .resource = alchemy_pci_host_res, | ||
120 | }; | ||
121 | |||
122 | static int __init db1500_pci_init(void) | ||
123 | { | ||
124 | if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1500) | ||
125 | return platform_device_register(&db1500_pci_host_dev); | ||
126 | return 0; | ||
127 | } | ||
128 | /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ | ||
129 | arch_initcall(db1500_pci_init); | ||
130 | |||
131 | |||
132 | static struct resource au1100_lcd_resources[] = { | ||
133 | [0] = { | ||
134 | .start = AU1100_LCD_PHYS_ADDR, | ||
135 | .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1, | ||
136 | .flags = IORESOURCE_MEM, | ||
137 | }, | ||
138 | [1] = { | ||
139 | .start = AU1100_LCD_INT, | ||
140 | .end = AU1100_LCD_INT, | ||
141 | .flags = IORESOURCE_IRQ, | ||
142 | } | ||
143 | }; | ||
144 | |||
145 | static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); | ||
146 | |||
147 | static struct platform_device au1100_lcd_device = { | ||
148 | .name = "au1100-lcd", | ||
149 | .id = 0, | ||
150 | .dev = { | ||
151 | .dma_mask = &au1100_lcd_dmamask, | ||
152 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
153 | }, | ||
154 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
155 | .resource = au1100_lcd_resources, | ||
156 | }; | ||
157 | |||
158 | static struct resource alchemy_ac97c_res[] = { | ||
159 | [0] = { | ||
160 | .start = AU1000_AC97_PHYS_ADDR, | ||
161 | .end = AU1000_AC97_PHYS_ADDR + 0xfff, | ||
162 | .flags = IORESOURCE_MEM, | ||
163 | }, | ||
164 | [1] = { | ||
165 | .start = DMA_ID_AC97C_TX, | ||
166 | .end = DMA_ID_AC97C_TX, | ||
167 | .flags = IORESOURCE_DMA, | ||
168 | }, | ||
169 | [2] = { | ||
170 | .start = DMA_ID_AC97C_RX, | ||
171 | .end = DMA_ID_AC97C_RX, | ||
172 | .flags = IORESOURCE_DMA, | ||
173 | }, | ||
174 | }; | ||
175 | |||
176 | static struct platform_device alchemy_ac97c_dev = { | ||
177 | .name = "alchemy-ac97c", | ||
178 | .id = -1, | ||
179 | .resource = alchemy_ac97c_res, | ||
180 | .num_resources = ARRAY_SIZE(alchemy_ac97c_res), | ||
181 | }; | ||
182 | |||
183 | static struct platform_device alchemy_ac97c_dma_dev = { | ||
184 | .name = "alchemy-pcm-dma", | ||
185 | .id = 0, | ||
186 | }; | ||
187 | |||
188 | static struct platform_device db1x00_codec_dev = { | ||
189 | .name = "ac97-codec", | ||
190 | .id = -1, | ||
191 | }; | ||
192 | |||
193 | static struct platform_device db1x00_audio_dev = { | ||
194 | .name = "db1000-audio", | ||
195 | }; | ||
196 | |||
197 | static struct platform_device *db1x00_devs[] = { | ||
198 | &db1x00_codec_dev, | ||
199 | &alchemy_ac97c_dma_dev, | ||
200 | &alchemy_ac97c_dev, | ||
201 | &db1x00_audio_dev, | ||
202 | }; | ||
203 | |||
204 | static struct platform_device *db1100_devs[] = { | ||
205 | &au1100_lcd_device, | ||
206 | }; | ||
207 | |||
208 | static int __init db1000_dev_init(void) | ||
209 | { | ||
210 | int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | ||
211 | int c0, c1, d0, d1, s0, s1; | ||
212 | |||
213 | if (board == BCSR_WHOAMI_DB1500) { | ||
214 | c0 = AU1500_GPIO2_INT; | ||
215 | c1 = AU1500_GPIO5_INT; | ||
216 | d0 = AU1500_GPIO0_INT; | ||
217 | d1 = AU1500_GPIO3_INT; | ||
218 | s0 = AU1500_GPIO1_INT; | ||
219 | s1 = AU1500_GPIO4_INT; | ||
220 | } else if (board == BCSR_WHOAMI_DB1100) { | ||
221 | c0 = AU1100_GPIO2_INT; | ||
222 | c1 = AU1100_GPIO5_INT; | ||
223 | d0 = AU1100_GPIO0_INT; | ||
224 | d1 = AU1100_GPIO3_INT; | ||
225 | s0 = AU1100_GPIO1_INT; | ||
226 | s1 = AU1100_GPIO4_INT; | ||
227 | platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); | ||
228 | } else if (board == BCSR_WHOAMI_DB1000) { | ||
229 | c0 = AU1000_GPIO2_INT; | ||
230 | c1 = AU1000_GPIO5_INT; | ||
231 | d0 = AU1000_GPIO0_INT; | ||
232 | d1 = AU1000_GPIO3_INT; | ||
233 | s0 = AU1000_GPIO1_INT; | ||
234 | s1 = AU1000_GPIO4_INT; | ||
235 | } else | ||
236 | return 0; /* unknown board, no further dev setup to do */ | ||
237 | |||
238 | irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH); | ||
239 | irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH); | ||
240 | irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW); | ||
241 | irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW); | ||
242 | irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW); | ||
243 | irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW); | ||
244 | |||
245 | db1x_register_pcmcia_socket( | ||
246 | AU1000_PCMCIA_ATTR_PHYS_ADDR, | ||
247 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | ||
248 | AU1000_PCMCIA_MEM_PHYS_ADDR, | ||
249 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | ||
250 | AU1000_PCMCIA_IO_PHYS_ADDR, | ||
251 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | ||
252 | c0, d0, /*s0*/0, 0, 0); | ||
253 | |||
254 | db1x_register_pcmcia_socket( | ||
255 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | ||
256 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, | ||
257 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, | ||
258 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, | ||
259 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, | ||
260 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, | ||
261 | c1, d1, /*s1*/0, 0, 1); | ||
262 | |||
263 | platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs)); | ||
264 | db1x_register_norflash(32 << 20, 4 /* 32bit */, F_SWAPPED); | ||
265 | return 0; | ||
266 | } | ||
267 | device_initcall(db1000_dev_init); | ||