0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/clk.h>
0010 #include <linux/dma-mapping.h>
0011 #include <linux/gpio.h>
0012 #include <linux/gpio/machine.h>
0013 #include <linux/init.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/leds.h>
0016 #include <linux/mmc/host.h>
0017 #include <linux/module.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/pm.h>
0020 #include <linux/spi/spi.h>
0021 #include <linux/spi/spi_gpio.h>
0022 #include <linux/spi/ads7846.h>
0023 #include <asm/mach-au1x00/au1000.h>
0024 #include <asm/mach-au1x00/gpio-au1000.h>
0025 #include <asm/mach-au1x00/au1000_dma.h>
0026 #include <asm/mach-au1x00/au1100_mmc.h>
0027 #include <asm/mach-db1x00/bcsr.h>
0028 #include <asm/reboot.h>
0029 #include <prom.h>
0030 #include "platform.h"
0031
0032 #define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
0033
0034 const char *get_system_type(void);
0035
0036 int __init db1000_board_setup(void)
0037 {
0038
0039 bcsr_init(DB1000_BCSR_PHYS_ADDR,
0040 DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
0041
0042 switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
0043 case BCSR_WHOAMI_DB1000:
0044 case BCSR_WHOAMI_DB1500:
0045 case BCSR_WHOAMI_DB1100:
0046 case BCSR_WHOAMI_PB1500:
0047 case BCSR_WHOAMI_PB1500R2:
0048 case BCSR_WHOAMI_PB1100:
0049 pr_info("AMD Alchemy %s Board\n", get_system_type());
0050 return 0;
0051 }
0052 return -ENODEV;
0053 }
0054
0055 static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
0056 {
0057 if ((slot < 12) || (slot > 13) || pin == 0)
0058 return -1;
0059 if (slot == 12)
0060 return (pin == 1) ? AU1500_PCI_INTA : 0xff;
0061 if (slot == 13) {
0062 switch (pin) {
0063 case 1: return AU1500_PCI_INTA;
0064 case 2: return AU1500_PCI_INTB;
0065 case 3: return AU1500_PCI_INTC;
0066 case 4: return AU1500_PCI_INTD;
0067 }
0068 }
0069 return -1;
0070 }
0071
0072 static u64 au1xxx_all_dmamask = DMA_BIT_MASK(32);
0073
0074 static struct resource alchemy_pci_host_res[] = {
0075 [0] = {
0076 .start = AU1500_PCI_PHYS_ADDR,
0077 .end = AU1500_PCI_PHYS_ADDR + 0xfff,
0078 .flags = IORESOURCE_MEM,
0079 },
0080 };
0081
0082 static struct alchemy_pci_platdata db1500_pci_pd = {
0083 .board_map_irq = db1500_map_pci_irq,
0084 };
0085
0086 static struct platform_device db1500_pci_host_dev = {
0087 .dev.platform_data = &db1500_pci_pd,
0088 .name = "alchemy-pci",
0089 .id = 0,
0090 .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
0091 .resource = alchemy_pci_host_res,
0092 };
0093
0094 int __init db1500_pci_setup(void)
0095 {
0096 return platform_device_register(&db1500_pci_host_dev);
0097 }
0098
0099 static struct resource au1100_lcd_resources[] = {
0100 [0] = {
0101 .start = AU1100_LCD_PHYS_ADDR,
0102 .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
0103 .flags = IORESOURCE_MEM,
0104 },
0105 [1] = {
0106 .start = AU1100_LCD_INT,
0107 .end = AU1100_LCD_INT,
0108 .flags = IORESOURCE_IRQ,
0109 }
0110 };
0111
0112 static struct platform_device au1100_lcd_device = {
0113 .name = "au1100-lcd",
0114 .id = 0,
0115 .dev = {
0116 .dma_mask = &au1xxx_all_dmamask,
0117 .coherent_dma_mask = DMA_BIT_MASK(32),
0118 },
0119 .num_resources = ARRAY_SIZE(au1100_lcd_resources),
0120 .resource = au1100_lcd_resources,
0121 };
0122
0123 static struct resource alchemy_ac97c_res[] = {
0124 [0] = {
0125 .start = AU1000_AC97_PHYS_ADDR,
0126 .end = AU1000_AC97_PHYS_ADDR + 0xfff,
0127 .flags = IORESOURCE_MEM,
0128 },
0129 [1] = {
0130 .start = DMA_ID_AC97C_TX,
0131 .end = DMA_ID_AC97C_TX,
0132 .flags = IORESOURCE_DMA,
0133 },
0134 [2] = {
0135 .start = DMA_ID_AC97C_RX,
0136 .end = DMA_ID_AC97C_RX,
0137 .flags = IORESOURCE_DMA,
0138 },
0139 };
0140
0141 static struct platform_device alchemy_ac97c_dev = {
0142 .name = "alchemy-ac97c",
0143 .id = -1,
0144 .resource = alchemy_ac97c_res,
0145 .num_resources = ARRAY_SIZE(alchemy_ac97c_res),
0146 };
0147
0148 static struct platform_device alchemy_ac97c_dma_dev = {
0149 .name = "alchemy-pcm-dma",
0150 .id = 0,
0151 };
0152
0153 static struct platform_device db1x00_codec_dev = {
0154 .name = "ac97-codec",
0155 .id = -1,
0156 };
0157
0158 static struct platform_device db1x00_audio_dev = {
0159 .name = "db1000-audio",
0160 .dev = {
0161 .dma_mask = &au1xxx_all_dmamask,
0162 .coherent_dma_mask = DMA_BIT_MASK(32),
0163 },
0164 };
0165
0166
0167
0168 static irqreturn_t db1100_mmc_cd(int irq, void *ptr)
0169 {
0170 void (*mmc_cd)(struct mmc_host *, unsigned long);
0171
0172 mmc_cd = symbol_get(mmc_detect_change);
0173 mmc_cd(ptr, msecs_to_jiffies(500));
0174 symbol_put(mmc_detect_change);
0175
0176 return IRQ_HANDLED;
0177 }
0178
0179 static int db1100_mmc_cd_setup(void *mmc_host, int en)
0180 {
0181 int ret = 0, irq;
0182
0183 if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
0184 irq = AU1100_GPIO19_INT;
0185 else
0186 irq = AU1100_GPIO14_INT;
0187
0188 if (en) {
0189 irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
0190 ret = request_irq(irq, db1100_mmc_cd, 0,
0191 "sd0_cd", mmc_host);
0192 } else
0193 free_irq(irq, mmc_host);
0194 return ret;
0195 }
0196
0197 static int db1100_mmc1_cd_setup(void *mmc_host, int en)
0198 {
0199 int ret = 0, irq;
0200
0201 if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
0202 irq = AU1100_GPIO20_INT;
0203 else
0204 irq = AU1100_GPIO15_INT;
0205
0206 if (en) {
0207 irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
0208 ret = request_irq(irq, db1100_mmc_cd, 0,
0209 "sd1_cd", mmc_host);
0210 } else
0211 free_irq(irq, mmc_host);
0212 return ret;
0213 }
0214
0215 static int db1100_mmc_card_readonly(void *mmc_host)
0216 {
0217
0218 return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1;
0219 }
0220
0221 static int db1100_mmc_card_inserted(void *mmc_host)
0222 {
0223 return !alchemy_gpio_get_value(19);
0224 }
0225
0226 static void db1100_mmc_set_power(void *mmc_host, int state)
0227 {
0228 int bit;
0229
0230 if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
0231 bit = BCSR_BOARD_SD0PWR;
0232 else
0233 bit = BCSR_BOARD_PB1100_SD0PWR;
0234
0235 if (state) {
0236 bcsr_mod(BCSR_BOARD, 0, bit);
0237 msleep(400);
0238 } else
0239 bcsr_mod(BCSR_BOARD, bit, 0);
0240 }
0241
0242 static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b)
0243 {
0244 if (b != LED_OFF)
0245 bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
0246 else
0247 bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
0248 }
0249
0250 static struct led_classdev db1100_mmc_led = {
0251 .brightness_set = db1100_mmcled_set,
0252 };
0253
0254 static int db1100_mmc1_card_readonly(void *mmc_host)
0255 {
0256 return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0;
0257 }
0258
0259 static int db1100_mmc1_card_inserted(void *mmc_host)
0260 {
0261 return !alchemy_gpio_get_value(20);
0262 }
0263
0264 static void db1100_mmc1_set_power(void *mmc_host, int state)
0265 {
0266 int bit;
0267
0268 if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100)
0269 bit = BCSR_BOARD_SD1PWR;
0270 else
0271 bit = BCSR_BOARD_PB1100_SD1PWR;
0272
0273 if (state) {
0274 bcsr_mod(BCSR_BOARD, 0, bit);
0275 msleep(400);
0276 } else
0277 bcsr_mod(BCSR_BOARD, bit, 0);
0278 }
0279
0280 static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b)
0281 {
0282 if (b != LED_OFF)
0283 bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
0284 else
0285 bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
0286 }
0287
0288 static struct led_classdev db1100_mmc1_led = {
0289 .brightness_set = db1100_mmc1led_set,
0290 };
0291
0292 static struct au1xmmc_platform_data db1100_mmc_platdata[2] = {
0293 [0] = {
0294 .cd_setup = db1100_mmc_cd_setup,
0295 .set_power = db1100_mmc_set_power,
0296 .card_inserted = db1100_mmc_card_inserted,
0297 .card_readonly = db1100_mmc_card_readonly,
0298 .led = &db1100_mmc_led,
0299 },
0300 [1] = {
0301 .cd_setup = db1100_mmc1_cd_setup,
0302 .set_power = db1100_mmc1_set_power,
0303 .card_inserted = db1100_mmc1_card_inserted,
0304 .card_readonly = db1100_mmc1_card_readonly,
0305 .led = &db1100_mmc1_led,
0306 },
0307 };
0308
0309 static struct resource au1100_mmc0_resources[] = {
0310 [0] = {
0311 .start = AU1100_SD0_PHYS_ADDR,
0312 .end = AU1100_SD0_PHYS_ADDR + 0xfff,
0313 .flags = IORESOURCE_MEM,
0314 },
0315 [1] = {
0316 .start = AU1100_SD_INT,
0317 .end = AU1100_SD_INT,
0318 .flags = IORESOURCE_IRQ,
0319 },
0320 [2] = {
0321 .start = DMA_ID_SD0_TX,
0322 .end = DMA_ID_SD0_TX,
0323 .flags = IORESOURCE_DMA,
0324 },
0325 [3] = {
0326 .start = DMA_ID_SD0_RX,
0327 .end = DMA_ID_SD0_RX,
0328 .flags = IORESOURCE_DMA,
0329 }
0330 };
0331
0332 static struct platform_device db1100_mmc0_dev = {
0333 .name = "au1xxx-mmc",
0334 .id = 0,
0335 .dev = {
0336 .dma_mask = &au1xxx_all_dmamask,
0337 .coherent_dma_mask = DMA_BIT_MASK(32),
0338 .platform_data = &db1100_mmc_platdata[0],
0339 },
0340 .num_resources = ARRAY_SIZE(au1100_mmc0_resources),
0341 .resource = au1100_mmc0_resources,
0342 };
0343
0344 static struct resource au1100_mmc1_res[] = {
0345 [0] = {
0346 .start = AU1100_SD1_PHYS_ADDR,
0347 .end = AU1100_SD1_PHYS_ADDR + 0xfff,
0348 .flags = IORESOURCE_MEM,
0349 },
0350 [1] = {
0351 .start = AU1100_SD_INT,
0352 .end = AU1100_SD_INT,
0353 .flags = IORESOURCE_IRQ,
0354 },
0355 [2] = {
0356 .start = DMA_ID_SD1_TX,
0357 .end = DMA_ID_SD1_TX,
0358 .flags = IORESOURCE_DMA,
0359 },
0360 [3] = {
0361 .start = DMA_ID_SD1_RX,
0362 .end = DMA_ID_SD1_RX,
0363 .flags = IORESOURCE_DMA,
0364 }
0365 };
0366
0367 static struct platform_device db1100_mmc1_dev = {
0368 .name = "au1xxx-mmc",
0369 .id = 1,
0370 .dev = {
0371 .dma_mask = &au1xxx_all_dmamask,
0372 .coherent_dma_mask = DMA_BIT_MASK(32),
0373 .platform_data = &db1100_mmc_platdata[1],
0374 },
0375 .num_resources = ARRAY_SIZE(au1100_mmc1_res),
0376 .resource = au1100_mmc1_res,
0377 };
0378
0379
0380
0381 static struct ads7846_platform_data db1100_touch_pd = {
0382 .model = 7846,
0383 .vref_mv = 3300,
0384 .gpio_pendown = 21,
0385 };
0386
0387 static struct spi_gpio_platform_data db1100_spictl_pd = {
0388 .num_chipselect = 1,
0389 };
0390
0391 static struct spi_board_info db1100_spi_info[] __initdata = {
0392 [0] = {
0393 .modalias = "ads7846",
0394 .max_speed_hz = 3250000,
0395 .bus_num = 0,
0396 .chip_select = 0,
0397 .mode = 0,
0398 .irq = AU1100_GPIO21_INT,
0399 .platform_data = &db1100_touch_pd,
0400 },
0401 };
0402
0403 static struct platform_device db1100_spi_dev = {
0404 .name = "spi_gpio",
0405 .id = 0,
0406 .dev = {
0407 .platform_data = &db1100_spictl_pd,
0408 .dma_mask = &au1xxx_all_dmamask,
0409 .coherent_dma_mask = DMA_BIT_MASK(32),
0410 },
0411 };
0412
0413
0414
0415
0416
0417 static struct gpiod_lookup_table db1100_spi_gpiod_table = {
0418 .dev_id = "spi_gpio",
0419 .table = {
0420 GPIO_LOOKUP("alchemy-gpio2", 9,
0421 "sck", GPIO_ACTIVE_HIGH),
0422 GPIO_LOOKUP("alchemy-gpio2", 8,
0423 "mosi", GPIO_ACTIVE_HIGH),
0424 GPIO_LOOKUP("alchemy-gpio2", 7,
0425 "miso", GPIO_ACTIVE_HIGH),
0426 GPIO_LOOKUP("alchemy-gpio2", 10,
0427 "cs", GPIO_ACTIVE_HIGH),
0428 { },
0429 },
0430 };
0431
0432 static struct platform_device *db1x00_devs[] = {
0433 &db1x00_codec_dev,
0434 &alchemy_ac97c_dma_dev,
0435 &alchemy_ac97c_dev,
0436 &db1x00_audio_dev,
0437 };
0438
0439 static struct platform_device *db1100_devs[] = {
0440 &au1100_lcd_device,
0441 &db1100_mmc0_dev,
0442 &db1100_mmc1_dev,
0443 };
0444
0445 int __init db1000_dev_setup(void)
0446 {
0447 int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
0448 int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1;
0449 unsigned long pfc;
0450 struct clk *c, *p;
0451
0452 if (board == BCSR_WHOAMI_DB1500) {
0453 c0 = AU1500_GPIO2_INT;
0454 c1 = AU1500_GPIO5_INT;
0455 d0 = 0;
0456 d1 = 3;
0457 s0 = AU1500_GPIO1_INT;
0458 s1 = AU1500_GPIO4_INT;
0459 } else if (board == BCSR_WHOAMI_DB1100) {
0460 c0 = AU1100_GPIO2_INT;
0461 c1 = AU1100_GPIO5_INT;
0462 d0 = 0;
0463 d1 = 3;
0464 s0 = AU1100_GPIO1_INT;
0465 s1 = AU1100_GPIO4_INT;
0466
0467 gpio_request(19, "sd0_cd");
0468 gpio_request(20, "sd1_cd");
0469 gpio_direction_input(19);
0470 gpio_direction_input(20);
0471
0472
0473 pfc = alchemy_rdsys(AU1000_SYS_PINFUNC);
0474 pfc |= (1 << 0);
0475 alchemy_wrsys(pfc, AU1000_SYS_PINFUNC);
0476
0477 spi_register_board_info(db1100_spi_info,
0478 ARRAY_SIZE(db1100_spi_info));
0479
0480
0481 p = clk_get(NULL, "auxpll_clk");
0482 c = clk_get(NULL, "lcd_intclk");
0483 if (!IS_ERR(c) && !IS_ERR(p)) {
0484 clk_set_parent(c, p);
0485 clk_set_rate(c, clk_get_rate(p));
0486 }
0487 if (!IS_ERR(c))
0488 clk_put(c);
0489 if (!IS_ERR(p))
0490 clk_put(p);
0491
0492 platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
0493 gpiod_add_lookup_table(&db1100_spi_gpiod_table);
0494 platform_device_register(&db1100_spi_dev);
0495 } else if (board == BCSR_WHOAMI_DB1000) {
0496 c0 = AU1000_GPIO2_INT;
0497 c1 = AU1000_GPIO5_INT;
0498 d0 = 0;
0499 d1 = 3;
0500 s0 = AU1000_GPIO1_INT;
0501 s1 = AU1000_GPIO4_INT;
0502 } else if ((board == BCSR_WHOAMI_PB1500) ||
0503 (board == BCSR_WHOAMI_PB1500R2)) {
0504 c0 = AU1500_GPIO203_INT;
0505 d0 = 1;
0506 s0 = AU1500_GPIO202_INT;
0507 twosocks = 0;
0508 flashsize = 64;
0509
0510 irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_LOW);
0511 irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
0512
0513
0514
0515
0516 } else if (board == BCSR_WHOAMI_PB1100) {
0517 c0 = AU1100_GPIO11_INT;
0518 d0 = 9;
0519 s0 = AU1100_GPIO10_INT;
0520 twosocks = 0;
0521 flashsize = 64;
0522
0523 irq_set_irq_type(AU1100_GPIO8_INT, IRQ_TYPE_LEVEL_LOW);
0524 irq_set_irq_type(AU1100_GPIO12_INT, IRQ_TYPE_LEVEL_LOW);
0525 irq_set_irq_type(AU1100_GPIO13_INT, IRQ_TYPE_LEVEL_LOW);
0526
0527
0528
0529
0530
0531 platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
0532 } else
0533 return 0;
0534
0535 irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW);
0536 irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW);
0537
0538 db1x_register_pcmcia_socket(
0539 AU1000_PCMCIA_ATTR_PHYS_ADDR,
0540 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
0541 AU1000_PCMCIA_MEM_PHYS_ADDR,
0542 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
0543 AU1000_PCMCIA_IO_PHYS_ADDR,
0544 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
0545 c0, d0, 0, 0, 0);
0546
0547 if (twosocks) {
0548 irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
0549 irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
0550
0551 db1x_register_pcmcia_socket(
0552 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
0553 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
0554 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
0555 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
0556 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
0557 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
0558 c1, d1, 0, 0, 1);
0559 }
0560
0561 platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs));
0562 db1x_register_norflash(flashsize << 20, 4 , F_SWAPPED);
0563 return 0;
0564 }