aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy/devboards/db1200.c
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@googlemail.com>2011-11-10 07:06:22 -0500
committerRalf Baechle <ralf@linux-mips.org>2011-12-07 17:02:07 -0500
commit6f7c8623db005889ee35a602e0c2564ea06cd3ff (patch)
treeac2dc899a66b6328ed3b10ce9bc88083c5ea0ec9 /arch/mips/alchemy/devboards/db1200.c
parenta9b71a8f0f42efe1a21154667ca02305c950d30a (diff)
MIPS: Alchemy: Merge PB1200 support into DB1200 code.
The PB1200 is basically a DB1200 with additional MMC and camera sockets and different base addresses for external hardware (CPLD, IDE, Net, NAND). This patch implements the missing PB1200 features in DB1200 support code and runtime board detection. Tested on DB1200 only. Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com> To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2880/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/alchemy/devboards/db1200.c')
-rw-r--r--arch/mips/alchemy/devboards/db1200.c245
1 files changed, 227 insertions, 18 deletions
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c
index e2cc5f921538..ec481f33aecc 100644
--- a/arch/mips/alchemy/devboards/db1200.c
+++ b/arch/mips/alchemy/devboards/db1200.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * DBAu1200 board platform device registration 2 * DBAu1200/PBAu1200 board platform device registration
3 * 3 *
4 * Copyright (C) 2008-2011 Manuel Lauss 4 * Copyright (C) 2008-2011 Manuel Lauss
5 * 5 *
@@ -44,10 +44,41 @@
44 44
45#include "platform.h" 45#include "platform.h"
46 46
47static const char *board_type_str(void)
48{
49 switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
50 case BCSR_WHOAMI_PB1200_DDR1:
51 case BCSR_WHOAMI_PB1200_DDR2:
52 return "PB1200";
53 case BCSR_WHOAMI_DB1200:
54 return "DB1200";
55 default:
56 return "(unknown)";
57 }
58}
47 59
48const char *get_system_type(void) 60const char *get_system_type(void)
49{ 61{
50 return "DB1200"; 62 return board_type_str();
63}
64
65static int __init detect_board(void)
66{
67 int bid;
68
69 /* try the PB1200 first */
70 bcsr_init(PB1200_BCSR_PHYS_ADDR,
71 PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
72 bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
73 if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
74 (bid == BCSR_WHOAMI_PB1200_DDR2))
75 return 0;
76
77 /* okay, try the DB1200 then */
78 bcsr_init(DB1200_BCSR_PHYS_ADDR,
79 DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
80 bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
81 return bid == BCSR_WHOAMI_DB1200 ? 0 : 1;
51} 82}
52 83
53void __init board_setup(void) 84void __init board_setup(void)
@@ -55,12 +86,14 @@ void __init board_setup(void)
55 unsigned long freq0, clksrc, div, pfc; 86 unsigned long freq0, clksrc, div, pfc;
56 unsigned short whoami; 87 unsigned short whoami;
57 88
58 bcsr_init(DB1200_BCSR_PHYS_ADDR, 89 if (detect_board()) {
59 DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS); 90 printk(KERN_ERR "NOT running on a DB1200/PB1200 board!\n");
91 return;
92 }
60 93
61 whoami = bcsr_read(BCSR_WHOAMI); 94 whoami = bcsr_read(BCSR_WHOAMI);
62 printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d" 95 printk(KERN_INFO "Alchemy/AMD/RMI %s Board, CPLD Rev %d"
63 " Board-ID %d Daughtercard ID %d\n", 96 " Board-ID %d Daughtercard ID %d\n", board_type_str(),
64 (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); 97 (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
65 98
66 /* SMBus/SPI on PSC0, Audio on PSC1 */ 99 /* SMBus/SPI on PSC0, Audio on PSC1 */
@@ -96,7 +129,7 @@ void __init board_setup(void)
96 129
97static struct mtd_partition db1200_spiflash_parts[] = { 130static struct mtd_partition db1200_spiflash_parts[] = {
98 { 131 {
99 .name = "DB1200 SPI flash", 132 .name = "spi_flash",
100 .offset = 0, 133 .offset = 0,
101 .size = MTDPART_SIZ_FULL, 134 .size = MTDPART_SIZ_FULL,
102 }, 135 },
@@ -376,12 +409,109 @@ static struct led_classdev db1200_mmc_led = {
376 .brightness_set = db1200_mmcled_set, 409 .brightness_set = db1200_mmcled_set,
377}; 410};
378 411
379static struct au1xmmc_platform_data db1200mmc_platdata = { 412/* -- */
380 .cd_setup = db1200_mmc_cd_setup, 413
381 .set_power = db1200_mmc_set_power, 414static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr)
382 .card_inserted = db1200_mmc_card_inserted, 415{
383 .card_readonly = db1200_mmc_card_readonly, 416 void(*mmc_cd)(struct mmc_host *, unsigned long);
384 .led = &db1200_mmc_led, 417
418 if (irq == PB1200_SD1_INSERT_INT) {
419 disable_irq_nosync(PB1200_SD1_INSERT_INT);
420 enable_irq(PB1200_SD1_EJECT_INT);
421 } else {
422 disable_irq_nosync(PB1200_SD1_EJECT_INT);
423 enable_irq(PB1200_SD1_INSERT_INT);
424 }
425
426 /* link against CONFIG_MMC=m */
427 mmc_cd = symbol_get(mmc_detect_change);
428 if (mmc_cd) {
429 mmc_cd(ptr, msecs_to_jiffies(500));
430 symbol_put(mmc_detect_change);
431 }
432
433 return IRQ_HANDLED;
434}
435
436static int pb1200_mmc1_cd_setup(void *mmc_host, int en)
437{
438 int ret;
439
440 if (en) {
441 ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0,
442 "sd1_insert", mmc_host);
443 if (ret)
444 goto out;
445
446 ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0,
447 "sd1_eject", mmc_host);
448 if (ret) {
449 free_irq(PB1200_SD1_INSERT_INT, mmc_host);
450 goto out;
451 }
452
453 if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT)
454 enable_irq(PB1200_SD1_EJECT_INT);
455 else
456 enable_irq(PB1200_SD1_INSERT_INT);
457
458 } else {
459 free_irq(PB1200_SD1_INSERT_INT, mmc_host);
460 free_irq(PB1200_SD1_EJECT_INT, mmc_host);
461 }
462 ret = 0;
463out:
464 return ret;
465}
466
467static void pb1200_mmc1led_set(struct led_classdev *led,
468 enum led_brightness brightness)
469{
470 if (brightness != LED_OFF)
471 bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
472 else
473 bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
474}
475
476static struct led_classdev pb1200_mmc1_led = {
477 .brightness_set = pb1200_mmc1led_set,
478};
479
480static void pb1200_mmc1_set_power(void *mmc_host, int state)
481{
482 if (state) {
483 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
484 msleep(400); /* stabilization time */
485 } else
486 bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
487}
488
489static int pb1200_mmc1_card_readonly(void *mmc_host)
490{
491 return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
492}
493
494static int pb1200_mmc1_card_inserted(void *mmc_host)
495{
496 return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
497}
498
499
500static struct au1xmmc_platform_data db1200_mmc_platdata[2] = {
501 [0] = {
502 .cd_setup = db1200_mmc_cd_setup,
503 .set_power = db1200_mmc_set_power,
504 .card_inserted = db1200_mmc_card_inserted,
505 .card_readonly = db1200_mmc_card_readonly,
506 .led = &db1200_mmc_led,
507 },
508 [1] = {
509 .cd_setup = pb1200_mmc1_cd_setup,
510 .set_power = pb1200_mmc1_set_power,
511 .card_inserted = pb1200_mmc1_card_inserted,
512 .card_readonly = pb1200_mmc1_card_readonly,
513 .led = &pb1200_mmc1_led,
514 },
385}; 515};
386 516
387static struct resource au1200_mmc0_resources[] = { 517static struct resource au1200_mmc0_resources[] = {
@@ -415,12 +545,47 @@ static struct platform_device db1200_mmc0_dev = {
415 .dev = { 545 .dev = {
416 .dma_mask = &au1xxx_mmc_dmamask, 546 .dma_mask = &au1xxx_mmc_dmamask,
417 .coherent_dma_mask = DMA_BIT_MASK(32), 547 .coherent_dma_mask = DMA_BIT_MASK(32),
418 .platform_data = &db1200mmc_platdata, 548 .platform_data = &db1200_mmc_platdata[0],
419 }, 549 },
420 .num_resources = ARRAY_SIZE(au1200_mmc0_resources), 550 .num_resources = ARRAY_SIZE(au1200_mmc0_resources),
421 .resource = au1200_mmc0_resources, 551 .resource = au1200_mmc0_resources,
422}; 552};
423 553
554static struct resource au1200_mmc1_res[] = {
555 [0] = {
556 .start = AU1100_SD1_PHYS_ADDR,
557 .end = AU1100_SD1_PHYS_ADDR + 0xfff,
558 .flags = IORESOURCE_MEM,
559 },
560 [1] = {
561 .start = AU1200_SD_INT,
562 .end = AU1200_SD_INT,
563 .flags = IORESOURCE_IRQ,
564 },
565 [2] = {
566 .start = AU1200_DSCR_CMD0_SDMS_TX1,
567 .end = AU1200_DSCR_CMD0_SDMS_TX1,
568 .flags = IORESOURCE_DMA,
569 },
570 [3] = {
571 .start = AU1200_DSCR_CMD0_SDMS_RX1,
572 .end = AU1200_DSCR_CMD0_SDMS_RX1,
573 .flags = IORESOURCE_DMA,
574 }
575};
576
577static struct platform_device pb1200_mmc1_dev = {
578 .name = "au1xxx-mmc",
579 .id = 1,
580 .dev = {
581 .dma_mask = &au1xxx_mmc_dmamask,
582 .coherent_dma_mask = DMA_BIT_MASK(32),
583 .platform_data = &db1200_mmc_platdata[1],
584 },
585 .num_resources = ARRAY_SIZE(au1200_mmc1_res),
586 .resource = au1200_mmc1_res,
587};
588
424/**********************************************************************/ 589/**********************************************************************/
425 590
426static int db1200fb_panel_index(void) 591static int db1200fb_panel_index(void)
@@ -598,14 +763,50 @@ static struct platform_device *db1200_devs[] __initdata = {
598 &db1200_sound_dev, 763 &db1200_sound_dev,
599}; 764};
600 765
766static struct platform_device *pb1200_devs[] __initdata = {
767 &pb1200_mmc1_dev,
768};
769
770/* Some peripheral base addresses differ on the PB1200 */
771static int __init pb1200_res_fixup(void)
772{
773 /* CPLD Revs earlier than 4 cause problems */
774 if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
775 printk(KERN_ERR "WARNING!!!\n");
776 printk(KERN_ERR "WARNING!!!\n");
777 printk(KERN_ERR "PB1200 must be at CPLD rev 4. Please have\n");
778 printk(KERN_ERR "the board updated to latest revisions.\n");
779 printk(KERN_ERR "This software will not work reliably\n");
780 printk(KERN_ERR "on anything older than CPLD rev 4.!\n");
781 printk(KERN_ERR "WARNING!!!\n");
782 printk(KERN_ERR "WARNING!!!\n");
783 return 1;
784 }
785
786 db1200_nand_res[0].start = PB1200_NAND_PHYS_ADDR;
787 db1200_nand_res[0].end = PB1200_NAND_PHYS_ADDR + 0xff;
788 db1200_ide_res[0].start = PB1200_IDE_PHYS_ADDR;
789 db1200_ide_res[0].end = PB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1;
790 db1200_eth_res[0].start = PB1200_ETH_PHYS_ADDR;
791 db1200_eth_res[0].end = PB1200_ETH_PHYS_ADDR + 0xff;
792 return 0;
793}
794
601static int __init db1200_dev_init(void) 795static int __init db1200_dev_init(void)
602{ 796{
603 unsigned long pfc; 797 unsigned long pfc;
604 unsigned short sw; 798 unsigned short sw;
605 int swapped; 799 int swapped, bid;
800
801 bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
802 if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
803 (bid == BCSR_WHOAMI_PB1200_DDR2)) {
804 if (pb1200_res_fixup())
805 return -ENODEV;
806 }
606 807
607 /* GPIO7 is low-level triggered CPLD cascade */ 808 /* GPIO7 is low-level triggered CPLD cascade */
608 irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW); 809 irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW);
609 bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); 810 bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
610 811
611 /* insert/eject pairs: one of both is always screaming. To avoid 812 /* insert/eject pairs: one of both is always screaming. To avoid
@@ -626,6 +827,7 @@ static int __init db1200_dev_init(void)
626 827
627 /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI) 828 /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI)
628 * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S) 829 * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
830 * or S12 on the PB1200.
629 */ 831 */
630 832
631 /* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however 833 /* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however
@@ -640,7 +842,7 @@ static int __init db1200_dev_init(void)
640 gpio_request(215, "otg-vbus"); 842 gpio_request(215, "otg-vbus");
641 gpio_direction_output(215, 1); 843 gpio_direction_output(215, 1);
642 844
643 printk(KERN_INFO "DB1200 device configuration:\n"); 845 printk(KERN_INFO "%s device configuration:\n", board_type_str());
644 846
645 sw = bcsr_read(BCSR_SWITCHES); 847 sw = bcsr_read(BCSR_SWITCHES);
646 if (sw & BCSR_SWITCHES_DIP_8) { 848 if (sw & BCSR_SWITCHES_DIP_8) {
@@ -707,6 +909,13 @@ static int __init db1200_dev_init(void)
707 swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; 909 swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
708 db1x_register_norflash(64 << 20, 2, swapped); 910 db1x_register_norflash(64 << 20, 2, swapped);
709 911
710 return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs)); 912 platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
913
914 /* PB1200 is a DB1200 with a 2nd MMC and Camera connector */
915 if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
916 (bid == BCSR_WHOAMI_PB1200_DDR2))
917 platform_add_devices(pb1200_devs, ARRAY_SIZE(pb1200_devs));
918
919 return 0;
711} 920}
712device_initcall(db1200_dev_init); 921device_initcall(db1200_dev_init);