diff options
Diffstat (limited to 'arch/avr32/boards')
-rw-r--r-- | arch/avr32/boards/hammerhead/Kconfig | 43 | ||||
-rw-r--r-- | arch/avr32/boards/hammerhead/Makefile | 1 | ||||
-rw-r--r-- | arch/avr32/boards/hammerhead/flash.c | 377 | ||||
-rw-r--r-- | arch/avr32/boards/hammerhead/flash.h | 6 | ||||
-rw-r--r-- | arch/avr32/boards/hammerhead/setup.c | 236 |
5 files changed, 663 insertions, 0 deletions
diff --git a/arch/avr32/boards/hammerhead/Kconfig b/arch/avr32/boards/hammerhead/Kconfig new file mode 100644 index 000000000000..fda2331f9789 --- /dev/null +++ b/arch/avr32/boards/hammerhead/Kconfig | |||
@@ -0,0 +1,43 @@ | |||
1 | # Hammerhead customization | ||
2 | |||
3 | if BOARD_HAMMERHEAD | ||
4 | |||
5 | config BOARD_HAMMERHEAD_USB | ||
6 | bool "Philips ISP116x-hcd USB support" | ||
7 | help | ||
8 | This enables USB support for Hammerheads internal ISP116x | ||
9 | controller from Philips. | ||
10 | |||
11 | Choose 'Y' here if you want to have your board USB driven. | ||
12 | |||
13 | config BOARD_HAMMERHEAD_LCD | ||
14 | bool "Atmel AT91/AT32 LCD support" | ||
15 | help | ||
16 | This enables LCD support for the Hammerhead board. You may | ||
17 | also add support for framebuffer devices (AT91/AT32 LCD Controller) | ||
18 | and framebuffer console support to get the most out of your LCD. | ||
19 | |||
20 | Choose 'Y' here if you have ordered a Corona daugther board and | ||
21 | want to have support for your Hantronix HDA-351T-LV LCD. | ||
22 | |||
23 | config BOARD_HAMMERHEAD_SND | ||
24 | bool "Atmel AC97 Sound support" | ||
25 | help | ||
26 | This enables Sound support for the Hammerhead board. You may | ||
27 | also go trough the ALSA settings to get it working. | ||
28 | |||
29 | Choose 'Y' here if you have ordered a Corona daugther board and | ||
30 | want to make your board funky. | ||
31 | |||
32 | config BOARD_HAMMERHEAD_FPGA | ||
33 | bool "Hammerhead FPGA Support" | ||
34 | default y | ||
35 | help | ||
36 | This adds support for the Cyclone III FPGA from Altera | ||
37 | found on Miromico's Hammerhead board. | ||
38 | |||
39 | Choose 'Y' here if you want to have FPGA support enabled. | ||
40 | You will have to choose the "Hammerhead FPGA Device Support" in | ||
41 | Device Drivers->Misc to be able to use FPGA functionality. | ||
42 | |||
43 | endif # BOARD_ATNGW100 | ||
diff --git a/arch/avr32/boards/hammerhead/Makefile b/arch/avr32/boards/hammerhead/Makefile new file mode 100644 index 000000000000..c740aa116755 --- /dev/null +++ b/arch/avr32/boards/hammerhead/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-y += setup.o flash.o | |||
diff --git a/arch/avr32/boards/hammerhead/flash.c b/arch/avr32/boards/hammerhead/flash.c new file mode 100644 index 000000000000..a98c6dd3a028 --- /dev/null +++ b/arch/avr32/boards/hammerhead/flash.c | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | * Hammerhead board-specific flash initialization | ||
3 | * | ||
4 | * Copyright (C) 2008 Miromico AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mtd/mtd.h> | ||
14 | #include <linux/mtd/partitions.h> | ||
15 | #include <linux/mtd/physmap.h> | ||
16 | #include <linux/usb/isp116x.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | #include <mach/portmux.h> | ||
22 | #include <mach/at32ap700x.h> | ||
23 | #include <mach/smc.h> | ||
24 | |||
25 | #include "../../mach-at32ap/clock.h" | ||
26 | #include "flash.h" | ||
27 | |||
28 | |||
29 | #define HAMMERHEAD_USB_PERIPH_GCLK0 0x40000000 | ||
30 | #define HAMMERHEAD_USB_PERIPH_CS2 0x02000000 | ||
31 | #define HAMMERHEAD_USB_PERIPH_EXTINT0 0x02000000 | ||
32 | |||
33 | #define HAMMERHEAD_FPGA_PERIPH_MOSI 0x00000002 | ||
34 | #define HAMMERHEAD_FPGA_PERIPH_SCK 0x00000020 | ||
35 | #define HAMMERHEAD_FPGA_PERIPH_EXTINT3 0x10000000 | ||
36 | |||
37 | static struct smc_timing flash_timing __initdata = { | ||
38 | .ncs_read_setup = 0, | ||
39 | .nrd_setup = 40, | ||
40 | .ncs_write_setup = 0, | ||
41 | .nwe_setup = 10, | ||
42 | |||
43 | .ncs_read_pulse = 80, | ||
44 | .nrd_pulse = 40, | ||
45 | .ncs_write_pulse = 65, | ||
46 | .nwe_pulse = 55, | ||
47 | |||
48 | .read_cycle = 120, | ||
49 | .write_cycle = 120, | ||
50 | }; | ||
51 | |||
52 | static struct smc_config flash_config __initdata = { | ||
53 | .bus_width = 2, | ||
54 | .nrd_controlled = 1, | ||
55 | .nwe_controlled = 1, | ||
56 | .byte_write = 1, | ||
57 | }; | ||
58 | |||
59 | static struct mtd_partition flash_parts[] = { | ||
60 | { | ||
61 | .name = "u-boot", | ||
62 | .offset = 0x00000000, | ||
63 | .size = 0x00020000, /* 128 KiB */ | ||
64 | .mask_flags = MTD_WRITEABLE, | ||
65 | }, | ||
66 | { | ||
67 | .name = "root", | ||
68 | .offset = 0x00020000, | ||
69 | .size = 0x007d0000, | ||
70 | }, | ||
71 | { | ||
72 | .name = "env", | ||
73 | .offset = 0x007f0000, | ||
74 | .size = 0x00010000, | ||
75 | .mask_flags = MTD_WRITEABLE, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | static struct physmap_flash_data flash_data = { | ||
80 | .width = 2, | ||
81 | .nr_parts = ARRAY_SIZE(flash_parts), | ||
82 | .parts = flash_parts, | ||
83 | }; | ||
84 | |||
85 | static struct resource flash_resource = { | ||
86 | .start = 0x00000000, | ||
87 | .end = 0x007fffff, | ||
88 | .flags = IORESOURCE_MEM, | ||
89 | }; | ||
90 | |||
91 | static struct platform_device flash_device = { | ||
92 | .name = "physmap-flash", | ||
93 | .id = 0, | ||
94 | .resource = &flash_resource, | ||
95 | .num_resources = 1, | ||
96 | .dev = { .platform_data = &flash_data, }, | ||
97 | }; | ||
98 | |||
99 | #ifdef CONFIG_BOARD_HAMMERHEAD_USB | ||
100 | |||
101 | static struct smc_timing isp1160_timing __initdata = { | ||
102 | .ncs_read_setup = 75, | ||
103 | .nrd_setup = 75, | ||
104 | .ncs_write_setup = 75, | ||
105 | .nwe_setup = 75, | ||
106 | |||
107 | |||
108 | /* We use conservative timing settings, as the minimal settings aren't | ||
109 | stable. There may be room for tweaking. */ | ||
110 | .ncs_read_pulse = 75, /* min. 33ns */ | ||
111 | .nrd_pulse = 75, /* min. 33ns */ | ||
112 | .ncs_write_pulse = 75, /* min. 26ns */ | ||
113 | .nwe_pulse = 75, /* min. 26ns */ | ||
114 | |||
115 | .read_cycle = 225, /* min. 143ns */ | ||
116 | .write_cycle = 225, /* min. 136ns */ | ||
117 | }; | ||
118 | |||
119 | static struct smc_config isp1160_config __initdata = { | ||
120 | .bus_width = 2, | ||
121 | .nrd_controlled = 1, | ||
122 | .nwe_controlled = 1, | ||
123 | .byte_write = 0, | ||
124 | }; | ||
125 | |||
126 | /* | ||
127 | * The platform delay function is only used to enforce the strange | ||
128 | * read to write delay. This can not be configured in the SMC. All other | ||
129 | * timings are controlled by the SMC (see timings obove) | ||
130 | * So in isp116x-hcd.c we should comment out USE_PLATFORM_DELAY | ||
131 | */ | ||
132 | void isp116x_delay(struct device *dev, int delay) | ||
133 | { | ||
134 | if (delay > 150) | ||
135 | ndelay(delay - 150); | ||
136 | } | ||
137 | |||
138 | static struct isp116x_platform_data isp1160_data = { | ||
139 | .sel15Kres = 1, /* use internal downstream resistors */ | ||
140 | .oc_enable = 0, /* external overcurrent detection */ | ||
141 | .int_edge_triggered = 0, /* interrupt is level triggered */ | ||
142 | .int_act_high = 0, /* interrupt is active low */ | ||
143 | .delay = isp116x_delay, /* platform delay function */ | ||
144 | }; | ||
145 | |||
146 | static struct resource isp1160_resource[] = { | ||
147 | { | ||
148 | .start = 0x08000000, | ||
149 | .end = 0x08000001, | ||
150 | .flags = IORESOURCE_MEM, | ||
151 | }, | ||
152 | { | ||
153 | .start = 0x08000002, | ||
154 | .end = 0x08000003, | ||
155 | .flags = IORESOURCE_MEM, | ||
156 | }, | ||
157 | { | ||
158 | .start = 64, | ||
159 | .flags = IORESOURCE_IRQ, | ||
160 | }, | ||
161 | }; | ||
162 | |||
163 | static struct platform_device isp1160_device = { | ||
164 | .name = "isp116x-hcd", | ||
165 | .id = 0, | ||
166 | .resource = isp1160_resource, | ||
167 | .num_resources = 3, | ||
168 | .dev = { | ||
169 | .platform_data = &isp1160_data, | ||
170 | }, | ||
171 | }; | ||
172 | #endif | ||
173 | |||
174 | #ifdef CONFIG_BOARD_HAMMERHEAD_USB | ||
175 | static int __init hammerhead_usbh_init(void) | ||
176 | { | ||
177 | struct clk *gclk; | ||
178 | struct clk *osc; | ||
179 | |||
180 | int ret; | ||
181 | |||
182 | /* setup smc for usbh */ | ||
183 | smc_set_timing(&isp1160_config, &isp1160_timing); | ||
184 | ret = smc_set_configuration(2, &isp1160_config); | ||
185 | |||
186 | if (ret < 0) { | ||
187 | printk(KERN_ERR | ||
188 | "hammerhead: failed to set ISP1160 USBH timing\n"); | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | /* setup gclk0 to run from osc1 */ | ||
193 | gclk = clk_get(NULL, "gclk0"); | ||
194 | if (IS_ERR(gclk)) | ||
195 | goto err_gclk; | ||
196 | |||
197 | osc = clk_get(NULL, "osc1"); | ||
198 | if (IS_ERR(osc)) | ||
199 | goto err_osc; | ||
200 | |||
201 | if (clk_set_parent(gclk, osc)) { | ||
202 | pr_debug("hammerhead: failed to set osc1 for USBH clock\n"); | ||
203 | goto err_set_clk; | ||
204 | } | ||
205 | |||
206 | /* set clock to 6MHz */ | ||
207 | clk_set_rate(gclk, 6000000); | ||
208 | |||
209 | /* and enable */ | ||
210 | clk_enable(gclk); | ||
211 | |||
212 | /* select GCLK0 peripheral function */ | ||
213 | at32_select_periph(GPIO_PIOA_BASE, HAMMERHEAD_USB_PERIPH_GCLK0, | ||
214 | GPIO_PERIPH_A, 0); | ||
215 | |||
216 | /* enable CS2 peripheral function */ | ||
217 | at32_select_periph(GPIO_PIOE_BASE, HAMMERHEAD_USB_PERIPH_CS2, | ||
218 | GPIO_PERIPH_A, 0); | ||
219 | |||
220 | /* H_WAKEUP must be driven low */ | ||
221 | at32_select_gpio(GPIO_PIN_PA(8), AT32_GPIOF_OUTPUT); | ||
222 | |||
223 | /* Select EXTINT0 for PB25 */ | ||
224 | at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_USB_PERIPH_EXTINT0, | ||
225 | GPIO_PERIPH_A, 0); | ||
226 | |||
227 | /* register usbh device driver */ | ||
228 | platform_device_register(&isp1160_device); | ||
229 | |||
230 | err_set_clk: | ||
231 | clk_put(osc); | ||
232 | err_osc: | ||
233 | clk_put(gclk); | ||
234 | err_gclk: | ||
235 | return ret; | ||
236 | } | ||
237 | #endif | ||
238 | |||
239 | #ifdef CONFIG_BOARD_HAMMERHEAD_FPGA | ||
240 | static struct smc_timing fpga_timing __initdata = { | ||
241 | .ncs_read_setup = 16, | ||
242 | .nrd_setup = 32, | ||
243 | .ncs_read_pulse = 48, | ||
244 | .nrd_pulse = 32, | ||
245 | .read_cycle = 64, | ||
246 | |||
247 | .ncs_write_setup = 16, | ||
248 | .nwe_setup = 16, | ||
249 | .ncs_write_pulse = 32, | ||
250 | .nwe_pulse = 32, | ||
251 | .write_cycle = 64, | ||
252 | }; | ||
253 | |||
254 | static struct smc_config fpga_config __initdata = { | ||
255 | .bus_width = 4, | ||
256 | .nrd_controlled = 1, | ||
257 | .nwe_controlled = 1, | ||
258 | .byte_write = 0, | ||
259 | }; | ||
260 | |||
261 | static struct resource hh_fpga0_resource[] = { | ||
262 | { | ||
263 | .start = 0xffe00400, | ||
264 | .end = 0xffe00400 + 0x3ff, | ||
265 | .flags = IORESOURCE_MEM, | ||
266 | }, | ||
267 | { | ||
268 | .start = 4, | ||
269 | .end = 4, | ||
270 | .flags = IORESOURCE_IRQ, | ||
271 | }, | ||
272 | { | ||
273 | .start = 0x0c000000, | ||
274 | .end = 0x0c000100, | ||
275 | .flags = IORESOURCE_MEM, | ||
276 | }, | ||
277 | { | ||
278 | .start = 67, | ||
279 | .end = 67, | ||
280 | .flags = IORESOURCE_IRQ, | ||
281 | }, | ||
282 | }; | ||
283 | |||
284 | static u64 hh_fpga0_dma_mask = DMA_32BIT_MASK; | ||
285 | static struct platform_device hh_fpga0_device = { | ||
286 | .name = "hh_fpga", | ||
287 | .id = 0, | ||
288 | .dev = { | ||
289 | .dma_mask = &hh_fpga0_dma_mask, | ||
290 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
291 | }, | ||
292 | .resource = hh_fpga0_resource, | ||
293 | .num_resources = ARRAY_SIZE(hh_fpga0_resource), | ||
294 | }; | ||
295 | |||
296 | static struct clk hh_fpga0_spi_clk = { | ||
297 | .name = "spi_clk", | ||
298 | .dev = &hh_fpga0_device.dev, | ||
299 | .mode = pba_clk_mode, | ||
300 | .get_rate = pba_clk_get_rate, | ||
301 | .index = 1, | ||
302 | }; | ||
303 | |||
304 | struct platform_device *__init at32_add_device_hh_fpga(void) | ||
305 | { | ||
306 | /* Select peripheral functionallity for SPI SCK and MOSI */ | ||
307 | at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_SCK, | ||
308 | GPIO_PERIPH_B, 0); | ||
309 | at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_MOSI, | ||
310 | GPIO_PERIPH_B, 0); | ||
311 | |||
312 | /* reserve all other needed gpio | ||
313 | * We have on board pull ups, so there is no need | ||
314 | * to enable gpio pull ups */ | ||
315 | /* INIT_DONE (input) */ | ||
316 | at32_select_gpio(GPIO_PIN_PB(0), 0); | ||
317 | |||
318 | /* nSTATUS (input) */ | ||
319 | at32_select_gpio(GPIO_PIN_PB(2), 0); | ||
320 | |||
321 | /* nCONFIG (output, low) */ | ||
322 | at32_select_gpio(GPIO_PIN_PB(3), AT32_GPIOF_OUTPUT); | ||
323 | |||
324 | /* CONF_DONE (input) */ | ||
325 | at32_select_gpio(GPIO_PIN_PB(4), 0); | ||
326 | |||
327 | /* Select EXTINT3 for PB28 (Interrupt from FPGA) */ | ||
328 | at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_EXTINT3, | ||
329 | GPIO_PERIPH_A, 0); | ||
330 | |||
331 | /* Get our parent clock */ | ||
332 | hh_fpga0_spi_clk.parent = clk_get(NULL, "pba"); | ||
333 | clk_put(hh_fpga0_spi_clk.parent); | ||
334 | |||
335 | /* Register clock in at32 clock tree */ | ||
336 | at32_clk_register(&hh_fpga0_spi_clk); | ||
337 | |||
338 | platform_device_register(&hh_fpga0_device); | ||
339 | return &hh_fpga0_device; | ||
340 | } | ||
341 | #endif | ||
342 | |||
343 | /* This needs to be called after the SMC has been initialized */ | ||
344 | static int __init hammerhead_flash_init(void) | ||
345 | { | ||
346 | int ret; | ||
347 | |||
348 | smc_set_timing(&flash_config, &flash_timing); | ||
349 | ret = smc_set_configuration(0, &flash_config); | ||
350 | |||
351 | if (ret < 0) { | ||
352 | printk(KERN_ERR "hammerhead: failed to set NOR flash timing\n"); | ||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | platform_device_register(&flash_device); | ||
357 | |||
358 | #ifdef CONFIG_BOARD_HAMMERHEAD_USB | ||
359 | hammerhead_usbh_init(); | ||
360 | #endif | ||
361 | |||
362 | #ifdef CONFIG_BOARD_HAMMERHEAD_FPGA | ||
363 | /* Setup SMC for FPGA interface */ | ||
364 | smc_set_timing(&fpga_config, &fpga_timing); | ||
365 | ret = smc_set_configuration(3, &fpga_config); | ||
366 | #endif | ||
367 | |||
368 | |||
369 | if (ret < 0) { | ||
370 | printk(KERN_ERR "hammerhead: failed to set FPGA timing\n"); | ||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | device_initcall(hammerhead_flash_init); | ||
diff --git a/arch/avr32/boards/hammerhead/flash.h b/arch/avr32/boards/hammerhead/flash.h new file mode 100644 index 000000000000..ea70c626587b --- /dev/null +++ b/arch/avr32/boards/hammerhead/flash.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __BOARDS_HAMMERHEAD_FLASH_H | ||
2 | #define __BOARDS_HAMMERHEAD_FLASH_H | ||
3 | |||
4 | struct platform_device *at32_add_device_hh_fpga(void); | ||
5 | |||
6 | #endif /* __BOARDS_HAMMERHEAD_FLASH_H */ | ||
diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c new file mode 100644 index 000000000000..af45c26c5ff9 --- /dev/null +++ b/arch/avr32/boards/hammerhead/setup.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /* | ||
2 | * Board-specific setup code for the Miromico Hammerhead board | ||
3 | * | ||
4 | * Copyright (C) 2008 Miromico AG | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/fb.h> | ||
12 | #include <linux/etherdevice.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/i2c-gpio.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/linkage.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | |||
21 | #include <video/atmel_lcdc.h> | ||
22 | |||
23 | #include <linux/io.h> | ||
24 | #include <asm/setup.h> | ||
25 | |||
26 | #include <mach/at32ap700x.h> | ||
27 | #include <mach/board.h> | ||
28 | #include <mach/init.h> | ||
29 | #include <mach/portmux.h> | ||
30 | |||
31 | #include "../../mach-at32ap/clock.h" | ||
32 | #include "flash.h" | ||
33 | |||
34 | /* Oscillator frequencies. These are board-specific */ | ||
35 | unsigned long at32_board_osc_rates[3] = { | ||
36 | [0] = 32768, /* 32.768 kHz on RTC osc */ | ||
37 | [1] = 25000000, /* 25MHz on osc0 */ | ||
38 | [2] = 12000000, /* 12 MHz on osc1 */ | ||
39 | }; | ||
40 | |||
41 | /* Initialized by bootloader-specific startup code. */ | ||
42 | struct tag *bootloader_tags __initdata; | ||
43 | |||
44 | #ifdef CONFIG_BOARD_HAMMERHEAD_LCD | ||
45 | static struct fb_videomode __initdata hda350tlv_modes[] = { | ||
46 | { | ||
47 | .name = "320x240 @ 75", | ||
48 | .refresh = 75, | ||
49 | .xres = 320, | ||
50 | .yres = 240, | ||
51 | .pixclock = KHZ2PICOS(6891), | ||
52 | |||
53 | .left_margin = 48, | ||
54 | .right_margin = 18, | ||
55 | .upper_margin = 18, | ||
56 | .lower_margin = 4, | ||
57 | .hsync_len = 20, | ||
58 | .vsync_len = 2, | ||
59 | |||
60 | .sync = 0, | ||
61 | .vmode = FB_VMODE_NONINTERLACED, | ||
62 | }, | ||
63 | }; | ||
64 | |||
65 | static struct fb_monspecs __initdata hammerhead_hda350t_monspecs = { | ||
66 | .manufacturer = "HAN", | ||
67 | .monitor = "HDA350T-LV", | ||
68 | .modedb = hda350tlv_modes, | ||
69 | .modedb_len = ARRAY_SIZE(hda350tlv_modes), | ||
70 | .hfmin = 14900, | ||
71 | .hfmax = 22350, | ||
72 | .vfmin = 60, | ||
73 | .vfmax = 90, | ||
74 | .dclkmax = 10000000, | ||
75 | }; | ||
76 | |||
77 | struct atmel_lcdfb_info __initdata hammerhead_lcdc_data = { | ||
78 | .default_bpp = 24, | ||
79 | .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN, | ||
80 | .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT | ||
81 | | ATMEL_LCDC_INVCLK | ||
82 | | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE | ||
83 | | ATMEL_LCDC_MEMOR_BIG), | ||
84 | .default_monspecs = &hammerhead_hda350t_monspecs, | ||
85 | .guard_time = 2, | ||
86 | }; | ||
87 | #endif | ||
88 | |||
89 | struct eth_addr { | ||
90 | u8 addr[6]; | ||
91 | }; | ||
92 | |||
93 | static struct eth_addr __initdata hw_addr[1]; | ||
94 | static struct eth_platform_data __initdata eth_data[1]; | ||
95 | |||
96 | /* | ||
97 | * The next two functions should go away as the boot loader is | ||
98 | * supposed to initialize the macb address registers with a valid | ||
99 | * ethernet address. But we need to keep it around for a while until | ||
100 | * we can be reasonably sure the boot loader does this. | ||
101 | * | ||
102 | * The phy_id is ignored as the driver will probe for it. | ||
103 | */ | ||
104 | static int __init parse_tag_ethernet(struct tag *tag) | ||
105 | { | ||
106 | int i = tag->u.ethernet.mac_index; | ||
107 | |||
108 | if (i < ARRAY_SIZE(hw_addr)) | ||
109 | memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, | ||
110 | sizeof(hw_addr[i].addr)); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | __tagtable(ATAG_ETHERNET, parse_tag_ethernet); | ||
115 | |||
116 | static void __init set_hw_addr(struct platform_device *pdev) | ||
117 | { | ||
118 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
119 | const u8 *addr; | ||
120 | void __iomem *regs; | ||
121 | struct clk *pclk; | ||
122 | |||
123 | if (!res) | ||
124 | return; | ||
125 | |||
126 | if (pdev->id >= ARRAY_SIZE(hw_addr)) | ||
127 | return; | ||
128 | |||
129 | addr = hw_addr[pdev->id].addr; | ||
130 | |||
131 | if (!is_valid_ether_addr(addr)) | ||
132 | return; | ||
133 | |||
134 | /* | ||
135 | * Since this is board-specific code, we'll cheat and use the | ||
136 | * physical address directly as we happen to know that it's | ||
137 | * the same as the virtual address. | ||
138 | */ | ||
139 | regs = (void __iomem __force *)res->start; | ||
140 | pclk = clk_get(&pdev->dev, "pclk"); | ||
141 | |||
142 | if (!pclk) | ||
143 | return; | ||
144 | |||
145 | clk_enable(pclk); | ||
146 | |||
147 | __raw_writel((addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | | ||
148 | addr[0], regs + 0x98); | ||
149 | __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); | ||
150 | |||
151 | clk_disable(pclk); | ||
152 | clk_put(pclk); | ||
153 | } | ||
154 | |||
155 | void __init setup_board(void) | ||
156 | { | ||
157 | at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */ | ||
158 | at32_setup_serial_console(0); | ||
159 | } | ||
160 | |||
161 | static struct i2c_gpio_platform_data i2c_gpio_data = { | ||
162 | .sda_pin = GPIO_PIN_PA(6), | ||
163 | .scl_pin = GPIO_PIN_PA(7), | ||
164 | .sda_is_open_drain = 1, | ||
165 | .scl_is_open_drain = 1, | ||
166 | .udelay = 2, /* close to 100 kHz */ | ||
167 | }; | ||
168 | |||
169 | static struct platform_device i2c_gpio_device = { | ||
170 | .name = "i2c-gpio", | ||
171 | .id = 0, | ||
172 | .dev = { .platform_data = &i2c_gpio_data, }, | ||
173 | }; | ||
174 | |||
175 | static struct i2c_board_info __initdata i2c_info[] = {}; | ||
176 | |||
177 | #ifdef CONFIG_BOARD_HAMMERHEAD_SND | ||
178 | static struct ac97c_platform_data ac97c_data = { | ||
179 | .reset_pin = GPIO_PIN_PA(16), | ||
180 | }; | ||
181 | #endif | ||
182 | |||
183 | static int __init hammerhead_init(void) | ||
184 | { | ||
185 | /* | ||
186 | * Hammerhead uses 32-bit SDRAM interface. Reserve the | ||
187 | * SDRAM-specific pins so that nobody messes with them. | ||
188 | */ | ||
189 | at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL); | ||
190 | |||
191 | at32_add_device_usart(0); | ||
192 | |||
193 | /* Reserve PB29 (GCLK3). This pin is used as clock source | ||
194 | * for ETH PHY (25MHz). GCLK3 setup is done by U-Boot. | ||
195 | */ | ||
196 | at32_reserve_pin(GPIO_PIOB_BASE, (1<<29)); | ||
197 | |||
198 | /* | ||
199 | * Hammerhead uses only one ethernet port, so we don't set | ||
200 | * address of second port | ||
201 | */ | ||
202 | set_hw_addr(at32_add_device_eth(0, ð_data[0])); | ||
203 | |||
204 | #ifdef CONFIG_BOARD_HAMMERHEAD_FPGA | ||
205 | at32_add_device_hh_fpga(); | ||
206 | #endif | ||
207 | at32_add_device_mci(0, NULL); | ||
208 | |||
209 | #ifdef CONFIG_BOARD_HAMMERHEAD_USB | ||
210 | at32_add_device_usba(0, NULL); | ||
211 | #endif | ||
212 | #ifdef CONFIG_BOARD_HAMMERHEAD_LCD | ||
213 | at32_add_device_lcdc(0, &hammerhead_lcdc_data, fbmem_start, | ||
214 | fbmem_size, ATMEL_LCDC_PRI_24BIT); | ||
215 | #endif | ||
216 | |||
217 | at32_select_gpio(i2c_gpio_data.sda_pin, | ||
218 | AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | | ||
219 | AT32_GPIOF_HIGH); | ||
220 | at32_select_gpio(i2c_gpio_data.scl_pin, | ||
221 | AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | | ||
222 | AT32_GPIOF_HIGH); | ||
223 | platform_device_register(&i2c_gpio_device); | ||
224 | i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); | ||
225 | |||
226 | #ifdef CONFIG_BOARD_HAMMERHEAD_SND | ||
227 | at32_add_device_ac97c(0, &ac97c_data); | ||
228 | #endif | ||
229 | |||
230 | /* Select the Touchscreen interrupt pin mode */ | ||
231 | at32_select_periph(GPIO_PIOB_BASE, 0x08000000, GPIO_PERIPH_A, 0); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | postcore_initcall(hammerhead_init); | ||