aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy/devboards
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
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')
-rw-r--r--arch/mips/alchemy/devboards/Makefile1
-rw-r--r--arch/mips/alchemy/devboards/db1200.c245
-rw-r--r--arch/mips/alchemy/devboards/pb1200.c471
3 files changed, 227 insertions, 490 deletions
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index f5628523c694..2fbf17909200 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -5,7 +5,6 @@
5obj-y += prom.o bcsr.o platform.o 5obj-y += prom.o bcsr.o platform.o
6obj-$(CONFIG_PM) += pm.o 6obj-$(CONFIG_PM) += pm.o
7obj-$(CONFIG_MIPS_PB1100) += pb1100.o 7obj-$(CONFIG_MIPS_PB1100) += pb1100.o
8obj-$(CONFIG_MIPS_PB1200) += pb1200.o
9obj-$(CONFIG_MIPS_PB1500) += pb1500.o 8obj-$(CONFIG_MIPS_PB1500) += pb1500.o
10obj-$(CONFIG_MIPS_PB1550) += pb1550.o 9obj-$(CONFIG_MIPS_PB1550) += pb1550.o
11obj-$(CONFIG_MIPS_DB1000) += db1x00.o 10obj-$(CONFIG_MIPS_DB1000) += db1x00.o
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);
diff --git a/arch/mips/alchemy/devboards/pb1200.c b/arch/mips/alchemy/devboards/pb1200.c
deleted file mode 100644
index a2676c95053b..000000000000
--- a/arch/mips/alchemy/devboards/pb1200.c
+++ /dev/null
@@ -1,471 +0,0 @@
1/*
2 * Pb1200/DBAu1200 board platform device registration
3 *
4 * Copyright (C) 2008 MontaVista Software Inc. <source@mvista.com>
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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <linux/dma-mapping.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/leds.h>
25#include <linux/platform_device.h>
26#include <linux/smc91x.h>
27#include <asm/mach-au1x00/au1000.h>
28#include <asm/mach-au1x00/au1100_mmc.h>
29#include <asm/mach-au1x00/au1200fb.h>
30#include <asm/mach-au1x00/au1xxx_dbdma.h>
31#include <asm/mach-db1x00/bcsr.h>
32#include <asm/mach-pb1x00/pb1200.h>
33#include <prom.h>
34#include "platform.h"
35
36
37const char *get_system_type(void)
38{
39 return "PB1200";
40}
41
42void __init board_setup(void)
43{
44 printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
45 bcsr_init(PB1200_BCSR_PHYS_ADDR,
46 PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
47
48#if 0
49 {
50 u32 pin_func;
51
52 /*
53 * Enable PSC1 SYNC for AC97. Normaly done in audio driver,
54 * but it is board specific code, so put it here.
55 */
56 pin_func = au_readl(SYS_PINFUNC);
57 au_sync();
58 pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
59 au_writel(pin_func, SYS_PINFUNC);
60
61 au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
62 au_sync();
63 }
64#endif
65
66#if defined(CONFIG_I2C_AU1550)
67 {
68 u32 freq0, clksrc;
69 u32 pin_func;
70
71 /* Select SMBus in CPLD */
72 bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
73
74 pin_func = au_readl(SYS_PINFUNC);
75 au_sync();
76 pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
77 /* Set GPIOs correctly */
78 pin_func |= 2 << 17;
79 au_writel(pin_func, SYS_PINFUNC);
80 au_sync();
81
82 /* The I2C driver depends on 50 MHz clock */
83 freq0 = au_readl(SYS_FREQCTRL0);
84 au_sync();
85 freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
86 freq0 |= 3 << SYS_FC_FRDIV1_BIT;
87 /* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
88 au_writel(freq0, SYS_FREQCTRL0);
89 au_sync();
90 freq0 |= SYS_FC_FE1;
91 au_writel(freq0, SYS_FREQCTRL0);
92 au_sync();
93
94 clksrc = au_readl(SYS_CLKSRC);
95 au_sync();
96 clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
97 /* Bit 22 is EXTCLK0 for PSC0 */
98 clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
99 au_writel(clksrc, SYS_CLKSRC);
100 au_sync();
101 }
102#endif
103
104 /*
105 * The Pb1200 development board uses external MUX for PSC0 to
106 * support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
107 */
108#ifdef CONFIG_I2C_AU1550
109 bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
110#endif
111 au_sync();
112}
113
114/******************************************************************************/
115
116static int mmc_activity;
117
118static void pb1200mmc0_set_power(void *mmc_host, int state)
119{
120 if (state)
121 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
122 else
123 bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
124
125 msleep(1);
126}
127
128static int pb1200mmc0_card_readonly(void *mmc_host)
129{
130 return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
131}
132
133static int pb1200mmc0_card_inserted(void *mmc_host)
134{
135 return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
136}
137
138static void pb1200_mmcled_set(struct led_classdev *led,
139 enum led_brightness brightness)
140{
141 if (brightness != LED_OFF) {
142 if (++mmc_activity == 1)
143 bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
144 } else {
145 if (--mmc_activity == 0)
146 bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
147 }
148}
149
150static struct led_classdev pb1200mmc_led = {
151 .brightness_set = pb1200_mmcled_set,
152};
153
154static void pb1200mmc1_set_power(void *mmc_host, int state)
155{
156 if (state)
157 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
158 else
159 bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
160
161 msleep(1);
162}
163
164static int pb1200mmc1_card_readonly(void *mmc_host)
165{
166 return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
167}
168
169static int pb1200mmc1_card_inserted(void *mmc_host)
170{
171 return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
172}
173
174static struct au1xmmc_platform_data pb1200mmc_platdata[2] = {
175 [0] = {
176 .set_power = pb1200mmc0_set_power,
177 .card_inserted = pb1200mmc0_card_inserted,
178 .card_readonly = pb1200mmc0_card_readonly,
179 .cd_setup = NULL, /* use poll-timer in driver */
180 .led = &pb1200mmc_led,
181 },
182 [1] = {
183 .set_power = pb1200mmc1_set_power,
184 .card_inserted = pb1200mmc1_card_inserted,
185 .card_readonly = pb1200mmc1_card_readonly,
186 .cd_setup = NULL, /* use poll-timer in driver */
187 .led = &pb1200mmc_led,
188 },
189};
190
191static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
192
193static struct resource au1200_mmc0_res[] = {
194 [0] = {
195 .start = AU1100_SD0_PHYS_ADDR,
196 .end = AU1100_SD0_PHYS_ADDR + 0xfff,
197 .flags = IORESOURCE_MEM,
198 },
199 [1] = {
200 .start = AU1200_SD_INT,
201 .end = AU1200_SD_INT,
202 .flags = IORESOURCE_IRQ,
203 },
204 [2] = {
205 .start = AU1200_DSCR_CMD0_SDMS_TX0,
206 .end = AU1200_DSCR_CMD0_SDMS_TX0,
207 .flags = IORESOURCE_DMA,
208 },
209 [3] = {
210 .start = AU1200_DSCR_CMD0_SDMS_RX0,
211 .end = AU1200_DSCR_CMD0_SDMS_RX0,
212 .flags = IORESOURCE_DMA,
213 }
214};
215
216static struct platform_device pb1200_mmc0_dev = {
217 .name = "au1xxx-mmc",
218 .id = 0,
219 .dev = {
220 .dma_mask = &au1xxx_mmc_dmamask,
221 .coherent_dma_mask = DMA_BIT_MASK(32),
222 .platform_data = &pb1200mmc_platdata[0],
223 },
224 .num_resources = ARRAY_SIZE(au1200_mmc0_res),
225 .resource = au1200_mmc0_res,
226};
227
228static struct resource au1200_mmc1_res[] = {
229 [0] = {
230 .start = AU1100_SD1_PHYS_ADDR,
231 .end = AU1100_SD1_PHYS_ADDR + 0xfff,
232 .flags = IORESOURCE_MEM,
233 },
234 [1] = {
235 .start = AU1200_SD_INT,
236 .end = AU1200_SD_INT,
237 .flags = IORESOURCE_IRQ,
238 },
239 [2] = {
240 .start = AU1200_DSCR_CMD0_SDMS_TX1,
241 .end = AU1200_DSCR_CMD0_SDMS_TX1,
242 .flags = IORESOURCE_DMA,
243 },
244 [3] = {
245 .start = AU1200_DSCR_CMD0_SDMS_RX1,
246 .end = AU1200_DSCR_CMD0_SDMS_RX1,
247 .flags = IORESOURCE_DMA,
248 }
249};
250
251static struct platform_device pb1200_mmc1_dev = {
252 .name = "au1xxx-mmc",
253 .id = 1,
254 .dev = {
255 .dma_mask = &au1xxx_mmc_dmamask,
256 .coherent_dma_mask = DMA_BIT_MASK(32),
257 .platform_data = &pb1200mmc_platdata[1],
258 },
259 .num_resources = ARRAY_SIZE(au1200_mmc1_res),
260 .resource = au1200_mmc1_res,
261};
262
263
264static struct resource ide_resources[] = {
265 [0] = {
266 .start = IDE_PHYS_ADDR,
267 .end = IDE_PHYS_ADDR + IDE_PHYS_LEN - 1,
268 .flags = IORESOURCE_MEM
269 },
270 [1] = {
271 .start = IDE_INT,
272 .end = IDE_INT,
273 .flags = IORESOURCE_IRQ
274 },
275 [2] = {
276 .start = AU1200_DSCR_CMD0_DMA_REQ1,
277 .end = AU1200_DSCR_CMD0_DMA_REQ1,
278 .flags = IORESOURCE_DMA,
279 },
280};
281
282static u64 au1200_ide_dmamask = DMA_BIT_MASK(32);
283
284static struct platform_device ide_device = {
285 .name = "au1200-ide",
286 .id = 0,
287 .dev = {
288 .dma_mask = &au1200_ide_dmamask,
289 .coherent_dma_mask = DMA_BIT_MASK(32),
290 },
291 .num_resources = ARRAY_SIZE(ide_resources),
292 .resource = ide_resources
293};
294
295static struct smc91x_platdata smc_data = {
296 .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
297 .leda = RPC_LED_100_10,
298 .ledb = RPC_LED_TX_RX,
299};
300
301static struct resource smc91c111_resources[] = {
302 [0] = {
303 .name = "smc91x-regs",
304 .start = SMC91C111_PHYS_ADDR,
305 .end = SMC91C111_PHYS_ADDR + 0xf,
306 .flags = IORESOURCE_MEM
307 },
308 [1] = {
309 .start = SMC91C111_INT,
310 .end = SMC91C111_INT,
311 .flags = IORESOURCE_IRQ
312 },
313};
314
315static struct platform_device smc91c111_device = {
316 .dev = {
317 .platform_data = &smc_data,
318 },
319 .name = "smc91x",
320 .id = -1,
321 .num_resources = ARRAY_SIZE(smc91c111_resources),
322 .resource = smc91c111_resources
323};
324
325static struct resource au1200_psc0_res[] = {
326 [0] = {
327 .start = AU1550_PSC0_PHYS_ADDR,
328 .end = AU1550_PSC0_PHYS_ADDR + 0xfff,
329 .flags = IORESOURCE_MEM,
330 },
331 [1] = {
332 .start = AU1200_PSC0_INT,
333 .end = AU1200_PSC0_INT,
334 .flags = IORESOURCE_IRQ,
335 },
336 [2] = {
337 .start = AU1200_DSCR_CMD0_PSC0_TX,
338 .end = AU1200_DSCR_CMD0_PSC0_TX,
339 .flags = IORESOURCE_DMA,
340 },
341 [3] = {
342 .start = AU1200_DSCR_CMD0_PSC0_RX,
343 .end = AU1200_DSCR_CMD0_PSC0_RX,
344 .flags = IORESOURCE_DMA,
345 },
346};
347
348static struct platform_device pb1200_i2c_dev = {
349 .name = "au1xpsc_smbus",
350 .id = 0, /* bus number */
351 .num_resources = ARRAY_SIZE(au1200_psc0_res),
352 .resource = au1200_psc0_res,
353};
354
355static int pb1200fb_panel_index(void)
356{
357 return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
358}
359
360static int pb1200fb_panel_init(void)
361{
362 /* Apply power */
363 bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
364 BCSR_BOARD_LCDBL);
365 return 0;
366}
367
368static int pb1200fb_panel_shutdown(void)
369{
370 /* Remove power */
371 bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
372 BCSR_BOARD_LCDBL, 0);
373 return 0;
374}
375
376static struct au1200fb_platdata pb1200fb_pd = {
377 .panel_index = pb1200fb_panel_index,
378 .panel_init = pb1200fb_panel_init,
379 .panel_shutdown = pb1200fb_panel_shutdown,
380};
381
382static struct resource au1200_lcd_res[] = {
383 [0] = {
384 .start = AU1200_LCD_PHYS_ADDR,
385 .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
386 .flags = IORESOURCE_MEM,
387 },
388 [1] = {
389 .start = AU1200_LCD_INT,
390 .end = AU1200_LCD_INT,
391 .flags = IORESOURCE_IRQ,
392 }
393};
394
395static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
396
397static struct platform_device pb1200_lcd_dev = {
398 .name = "au1200-lcd",
399 .id = 0,
400 .dev = {
401 .dma_mask = &au1200_lcd_dmamask,
402 .coherent_dma_mask = DMA_BIT_MASK(32),
403 .platform_data = &pb1200fb_pd,
404 },
405 .num_resources = ARRAY_SIZE(au1200_lcd_res),
406 .resource = au1200_lcd_res,
407};
408
409static struct platform_device *board_platform_devices[] __initdata = {
410 &ide_device,
411 &smc91c111_device,
412 &pb1200_i2c_dev,
413 &pb1200_mmc0_dev,
414 &pb1200_mmc1_dev,
415 &pb1200_lcd_dev,
416};
417
418static int __init board_register_devices(void)
419{
420 int swapped;
421
422 /* We have a problem with CPLD rev 3. */
423 if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
424 printk(KERN_ERR "WARNING!!!\n");
425 printk(KERN_ERR "WARNING!!!\n");
426 printk(KERN_ERR "WARNING!!!\n");
427 printk(KERN_ERR "WARNING!!!\n");
428 printk(KERN_ERR "WARNING!!!\n");
429 printk(KERN_ERR "WARNING!!!\n");
430 printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
431 printk(KERN_ERR "updated to latest revision. This software will\n");
432 printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
433 printk(KERN_ERR "WARNING!!!\n");
434 printk(KERN_ERR "WARNING!!!\n");
435 printk(KERN_ERR "WARNING!!!\n");
436 printk(KERN_ERR "WARNING!!!\n");
437 printk(KERN_ERR "WARNING!!!\n");
438 printk(KERN_ERR "WARNING!!!\n");
439 panic("Game over. Your score is 0.");
440 }
441
442 irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
443 bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT);
444
445 db1x_register_pcmcia_socket(
446 AU1000_PCMCIA_ATTR_PHYS_ADDR,
447 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
448 AU1000_PCMCIA_MEM_PHYS_ADDR,
449 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
450 AU1000_PCMCIA_IO_PHYS_ADDR,
451 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
452 PB1200_PC0_INT, PB1200_PC0_INSERT_INT,
453 /*PB1200_PC0_STSCHG_INT*/0, PB1200_PC0_EJECT_INT, 0);
454
455 db1x_register_pcmcia_socket(
456 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
457 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
458 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
459 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
460 AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
461 AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
462 PB1200_PC1_INT, PB1200_PC1_INSERT_INT,
463 /*PB1200_PC1_STSCHG_INT*/0, PB1200_PC1_EJECT_INT, 1);
464
465 swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
466 db1x_register_norflash(128 * 1024 * 1024, 2, swapped);
467
468 return platform_add_devices(board_platform_devices,
469 ARRAY_SIZE(board_platform_devices));
470}
471device_initcall(board_register_devices);