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/delay.h> 19 20#include <mach/portmux.h> 21#include <mach/at32ap700x.h> 22#include <mach/smc.h> 23 24#include "../../mach-at32ap/clock.h" 25#include "flash.h" 26 27 28#define HAMMERHEAD_USB_PERIPH_GCLK0 0x40000000 29#define HAMMERHEAD_USB_PERIPH_CS2 0x02000000 30#define HAMMERHEAD_USB_PERIPH_EXTINT0 0x02000000 31 32#define HAMMERHEAD_FPGA_PERIPH_MOSI 0x00000002 33#define HAMMERHEAD_FPGA_PERIPH_SCK 0x00000020 34#define HAMMERHEAD_FPGA_PERIPH_EXTINT3 0x10000000 35 36static struct smc_timing flash_timing __initdata = { 37 .ncs_read_setup = 0, 38 .nrd_setup = 40, 39 .ncs_write_setup = 0, 40 .nwe_setup = 10, 41 42 .ncs_read_pulse = 80, 43 .nrd_pulse = 40, 44 .ncs_write_pulse = 65, 45 .nwe_pulse = 55, 46 47 .read_cycle = 120, 48 .write_cycle = 120, 49}; 50 51static struct smc_config flash_config __initdata = { 52 .bus_width = 2, 53 .nrd_controlled = 1, 54 .nwe_controlled = 1, 55 .byte_write = 1, 56}; 57 58static struct mtd_partition flash_parts[] = { 59 { 60 .name = "u-boot", 61 .offset = 0x00000000, 62 .size = 0x00020000, /* 128 KiB */ 63 .mask_flags = MTD_WRITEABLE, 64 }, 65 { 66 .name = "root", 67 .offset = 0x00020000, 68 .size = 0x007d0000, 69 }, 70 { 71 .name = "env", 72 .offset = 0x007f0000, 73 .size = 0x00010000, 74 .mask_flags = MTD_WRITEABLE, 75 }, 76}; 77 78static struct physmap_flash_data flash_data = { 79 .width = 2, 80 .nr_parts = ARRAY_SIZE(flash_parts), 81 .parts = flash_parts, 82}; 83 84static struct resource flash_resource = { 85 .start = 0x00000000, 86 .end = 0x007fffff, 87 .flags = IORESOURCE_MEM, 88}; 89 90static struct platform_device flash_device = { 91 .name = "physmap-flash", 92 .id = 0, 93 .resource = &flash_resource, 94 .num_resources = 1, 95 .dev = { .platform_data = &flash_data, }, 96}; 97 98#ifdef CONFIG_BOARD_HAMMERHEAD_USB 99 100static struct smc_timing isp1160_timing __initdata = { 101 .ncs_read_setup = 75, 102 .nrd_setup = 75, 103 .ncs_write_setup = 75, 104 .nwe_setup = 75, 105 106 107 /* We use conservative timing settings, as the minimal settings aren't 108 stable. There may be room for tweaking. */ 109 .ncs_read_pulse = 75, /* min. 33ns */ 110 .nrd_pulse = 75, /* min. 33ns */ 111 .ncs_write_pulse = 75, /* min. 26ns */ 112 .nwe_pulse = 75, /* min. 26ns */ 113 114 .read_cycle = 225, /* min. 143ns */ 115 .write_cycle = 225, /* min. 136ns */ 116}; 117 118static struct smc_config isp1160_config __initdata = { 119 .bus_width = 2, 120 .nrd_controlled = 1, 121 .nwe_controlled = 1, 122 .byte_write = 0, 123}; 124 125/* 126 * The platform delay function is only used to enforce the strange 127 * read to write delay. This can not be configured in the SMC. All other 128 * timings are controlled by the SMC (see timings obove) 129 * So in isp116x-hcd.c we should comment out USE_PLATFORM_DELAY 130 */ 131void isp116x_delay(struct device *dev, int delay) 132{ 133 if (delay > 150) 134 ndelay(delay - 150); 135} 136 137static struct isp116x_platform_data isp1160_data = { 138 .sel15Kres = 1, /* use internal downstream resistors */ 139 .oc_enable = 0, /* external overcurrent detection */ 140 .int_edge_triggered = 0, /* interrupt is level triggered */ 141 .int_act_high = 0, /* interrupt is active low */ 142 .delay = isp116x_delay, /* platform delay function */ 143}; 144 145static struct resource isp1160_resource[] = { 146 { 147 .start = 0x08000000, 148 .end = 0x08000001, 149 .flags = IORESOURCE_MEM, 150 }, 151 { 152 .start = 0x08000002, 153 .end = 0x08000003, 154 .flags = IORESOURCE_MEM, 155 }, 156 { 157 .start = 64, 158 .flags = IORESOURCE_IRQ, 159 }, 160}; 161 162static struct platform_device isp1160_device = { 163 .name = "isp116x-hcd", 164 .id = 0, 165 .resource = isp1160_resource, 166 .num_resources = 3, 167 .dev = { 168 .platform_data = &isp1160_data, 169 }, 170}; 171#endif 172 173#ifdef CONFIG_BOARD_HAMMERHEAD_USB 174static int __init hammerhead_usbh_init(void) 175{ 176 struct clk *gclk; 177 struct clk *osc; 178 179 int ret; 180 181 /* setup smc for usbh */ 182 smc_set_timing(&isp1160_config, &isp1160_timing); 183 ret = smc_set_configuration(2, &isp1160_config); 184 185 if (ret < 0) { 186 printk(KERN_ERR 187 "hammerhead: failed to set ISP1160 USBH timing\n"); 188 return ret; 189 } 190 191 /* setup gclk0 to run from osc1 */ 192 gclk = clk_get(NULL, "gclk0"); 193 if (IS_ERR(gclk)) { 194 ret = PTR_ERR(gclk); 195 goto err_gclk; 196 } 197 198 osc = clk_get(NULL, "osc1"); 199 if (IS_ERR(osc)) { 200 ret = PTR_ERR(osc); 201 goto err_osc; 202 } 203 204 ret = clk_set_parent(gclk, osc); 205 if (ret < 0) { 206 pr_debug("hammerhead: failed to set osc1 for USBH clock\n"); 207 goto err_set_clk; 208 } 209 210 /* set clock to 6MHz */ 211 clk_set_rate(gclk, 6000000); 212 213 /* and enable */ 214 clk_enable(gclk); 215 216 /* select GCLK0 peripheral function */ 217 at32_select_periph(GPIO_PIOA_BASE, HAMMERHEAD_USB_PERIPH_GCLK0, 218 GPIO_PERIPH_A, 0); 219 220 /* enable CS2 peripheral function */ 221 at32_select_periph(GPIO_PIOE_BASE, HAMMERHEAD_USB_PERIPH_CS2, 222 GPIO_PERIPH_A, 0); 223 224 /* H_WAKEUP must be driven low */ 225 at32_select_gpio(GPIO_PIN_PA(8), AT32_GPIOF_OUTPUT); 226 227 /* Select EXTINT0 for PB25 */ 228 at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_USB_PERIPH_EXTINT0, 229 GPIO_PERIPH_A, 0); 230 231 /* register usbh device driver */ 232 platform_device_register(&isp1160_device); 233 234 err_set_clk: 235 clk_put(osc); 236 err_osc: 237 clk_put(gclk); 238 err_gclk: 239 return ret; 240} 241#endif 242 243#ifdef CONFIG_BOARD_HAMMERHEAD_FPGA 244static struct smc_timing fpga_timing __initdata = { 245 .ncs_read_setup = 16, 246 .nrd_setup = 32, 247 .ncs_read_pulse = 48, 248 .nrd_pulse = 32, 249 .read_cycle = 64, 250 251 .ncs_write_setup = 16, 252 .nwe_setup = 16, 253 .ncs_write_pulse = 32, 254 .nwe_pulse = 32, 255 .write_cycle = 64, 256}; 257 258static struct smc_config fpga_config __initdata = { 259 .bus_width = 4, 260 .nrd_controlled = 1, 261 .nwe_controlled = 1, 262 .byte_write = 0, 263}; 264 265static struct resource hh_fpga0_resource[] = { 266 { 267 .start = 0xffe00400, 268 .end = 0xffe00400 + 0x3ff, 269 .flags = IORESOURCE_MEM, 270 }, 271 { 272 .start = 4, 273 .end = 4, 274 .flags = IORESOURCE_IRQ, 275 }, 276 { 277 .start = 0x0c000000, 278 .end = 0x0c000100, 279 .flags = IORESOURCE_MEM, 280 }, 281 { 282 .start = 67, 283 .end = 67, 284 .flags = IORESOURCE_IRQ, 285 }, 286}; 287 288static u64 hh_fpga0_dma_mask = DMA_BIT_MASK(32); 289static struct platform_device hh_fpga0_device = { 290 .name = "hh_fpga", 291 .id = 0, 292 .dev = { 293 .dma_mask = &hh_fpga0_dma_mask, 294 .coherent_dma_mask = DMA_BIT_MASK(32), 295 }, 296 .resource = hh_fpga0_resource, 297 .num_resources = ARRAY_SIZE(hh_fpga0_resource), 298}; 299 300static struct clk hh_fpga0_spi_clk = { 301 .name = "spi_clk", 302 .dev = &hh_fpga0_device.dev, 303 .mode = pba_clk_mode, 304 .get_rate = pba_clk_get_rate, 305 .index = 1, 306}; 307 308struct platform_device *__init at32_add_device_hh_fpga(void) 309{ 310 /* Select peripheral functionallity for SPI SCK and MOSI */ 311 at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_SCK, 312 GPIO_PERIPH_B, 0); 313 at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_MOSI, 314 GPIO_PERIPH_B, 0); 315 316 /* reserve all other needed gpio 317 * We have on board pull ups, so there is no need 318 * to enable gpio pull ups */ 319 /* INIT_DONE (input) */ 320 at32_select_gpio(GPIO_PIN_PB(0), 0); 321 322 /* nSTATUS (input) */ 323 at32_select_gpio(GPIO_PIN_PB(2), 0); 324 325 /* nCONFIG (output, low) */ 326 at32_select_gpio(GPIO_PIN_PB(3), AT32_GPIOF_OUTPUT); 327 328 /* CONF_DONE (input) */ 329 at32_select_gpio(GPIO_PIN_PB(4), 0); 330 331 /* Select EXTINT3 for PB28 (Interrupt from FPGA) */ 332 at32_select_periph(GPIO_PIOB_BASE, HAMMERHEAD_FPGA_PERIPH_EXTINT3, 333 GPIO_PERIPH_A, 0); 334 335 /* Get our parent clock */ 336 hh_fpga0_spi_clk.parent = clk_get(NULL, "pba"); 337 clk_put(hh_fpga0_spi_clk.parent); 338 339 /* Register clock in at32 clock tree */ 340 at32_clk_register(&hh_fpga0_spi_clk); 341 342 platform_device_register(&hh_fpga0_device); 343 return &hh_fpga0_device; 344} 345#endif 346 347/* This needs to be called after the SMC has been initialized */ 348static int __init hammerhead_flash_init(void) 349{ 350 int ret; 351 352 smc_set_timing(&flash_config, &flash_timing); 353 ret = smc_set_configuration(0, &flash_config); 354 355 if (ret < 0) { 356 printk(KERN_ERR "hammerhead: failed to set NOR flash timing\n"); 357 return ret; 358 } 359 360 platform_device_register(&flash_device); 361 362#ifdef CONFIG_BOARD_HAMMERHEAD_USB 363 hammerhead_usbh_init(); 364#endif 365 366#ifdef CONFIG_BOARD_HAMMERHEAD_FPGA 367 /* Setup SMC for FPGA interface */ 368 smc_set_timing(&fpga_config, &fpga_timing); 369 ret = smc_set_configuration(3, &fpga_config); 370#endif 371 372 373 if (ret < 0) { 374 printk(KERN_ERR "hammerhead: failed to set FPGA timing\n"); 375 return ret; 376 } 377 378 return 0; 379} 380 381device_initcall(hammerhead_flash_init); 382