Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6
[pandora-kernel.git] / arch / avr32 / boards / hammerhead / flash.c
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);