aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy/devboards
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@gmail.com>2012-09-14 08:47:10 -0400
committerRalf Baechle <ralf@linux-mips.org>2012-10-11 05:11:20 -0400
commit24e8c1a611a706f51d4d9dc39b2c9977e25a54c4 (patch)
tree91696346623fb7693b290730d65d2208fa47b88a /arch/mips/alchemy/devboards
parentbd8510df881f63a9e7768824cf0e33c4702dcde1 (diff)
MIPS: Alchemy: merge PB1550 support into DB1550 code
The PB1550 is more or less a DB1550 without the PCI IDE controller, a more complicated (read: configurable) Flash setup and some other minor changes. Like the DB1550 it can be automatically detected by reading the CPLD ID register bits. This patch adds PB1550 detection and setup to the DB1550 code. Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4337/ 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/db1235.c16
-rw-r--r--arch/mips/alchemy/devboards/db1550.c181
-rw-r--r--arch/mips/alchemy/devboards/pb1550.c244
4 files changed, 160 insertions, 282 deletions
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index f8a962498b2f..fad8a99c7b63 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -6,6 +6,5 @@ obj-y += 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_PB1500) += pb1500.o 8obj-$(CONFIG_MIPS_PB1500) += pb1500.o
9obj-$(CONFIG_MIPS_PB1550) += pb1550.o
10obj-$(CONFIG_MIPS_DB1000) += db1000.o 9obj-$(CONFIG_MIPS_DB1000) += db1000.o
11obj-$(CONFIG_MIPS_DB1235) += db1235.o db1200.o db1300.o db1550.o 10obj-$(CONFIG_MIPS_DB1235) += db1235.o db1200.o db1300.o db1550.o
diff --git a/arch/mips/alchemy/devboards/db1235.c b/arch/mips/alchemy/devboards/db1235.c
index 15003eb1f840..c76a90f78664 100644
--- a/arch/mips/alchemy/devboards/db1235.c
+++ b/arch/mips/alchemy/devboards/db1235.c
@@ -13,7 +13,7 @@ int __init db1300_board_setup(void);
13int __init db1300_dev_setup(void); 13int __init db1300_dev_setup(void);
14int __init db1550_board_setup(void); 14int __init db1550_board_setup(void);
15int __init db1550_dev_setup(void); 15int __init db1550_dev_setup(void);
16int __init db1550_pci_setup(void); 16int __init db1550_pci_setup(int);
17 17
18static const char *board_type_str(void) 18static const char *board_type_str(void)
19{ 19{
@@ -27,6 +27,9 @@ static const char *board_type_str(void)
27 return "DB1300"; 27 return "DB1300";
28 case BCSR_WHOAMI_DB1550: 28 case BCSR_WHOAMI_DB1550:
29 return "DB1550"; 29 return "DB1550";
30 case BCSR_WHOAMI_PB1550_SDR:
31 case BCSR_WHOAMI_PB1550_DDR:
32 return "PB1550";
30 default: 33 default:
31 return "(unknown)"; 34 return "(unknown)";
32 } 35 }
@@ -61,8 +64,13 @@ void __init board_setup(void)
61 64
62int __init db1235_arch_init(void) 65int __init db1235_arch_init(void)
63{ 66{
64 if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1550) 67 int id = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
65 return db1550_pci_setup(); 68 if (id == BCSR_WHOAMI_DB1550)
69 return db1550_pci_setup(0);
70 else if ((id == BCSR_WHOAMI_PB1550_SDR) ||
71 (id == BCSR_WHOAMI_PB1550_DDR))
72 return db1550_pci_setup(1);
73
66 return 0; 74 return 0;
67} 75}
68arch_initcall(db1235_arch_init); 76arch_initcall(db1235_arch_init);
@@ -77,6 +85,8 @@ int __init db1235_dev_init(void)
77 case BCSR_WHOAMI_DB1300: 85 case BCSR_WHOAMI_DB1300:
78 return db1300_dev_setup(); 86 return db1300_dev_setup();
79 case BCSR_WHOAMI_DB1550: 87 case BCSR_WHOAMI_DB1550:
88 case BCSR_WHOAMI_PB1550_SDR:
89 case BCSR_WHOAMI_PB1550_DDR:
80 return db1550_dev_setup(); 90 return db1550_dev_setup();
81 } 91 }
82 return 0; 92 return 0;
diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c
index 7664beed8fa2..5a9ae6095428 100644
--- a/arch/mips/alchemy/devboards/db1550.c
+++ b/arch/mips/alchemy/devboards/db1550.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Alchemy Db1550 board support 2 * Alchemy Db1550/Pb1550 board support
3 * 3 *
4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> 4 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
5 */ 5 */
@@ -17,11 +17,13 @@
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/spi/flash.h> 19#include <linux/spi/flash.h>
20#include <asm/bootinfo.h>
20#include <asm/mach-au1x00/au1000.h> 21#include <asm/mach-au1x00/au1000.h>
21#include <asm/mach-au1x00/au1xxx_eth.h> 22#include <asm/mach-au1x00/au1xxx_eth.h>
22#include <asm/mach-au1x00/au1xxx_dbdma.h> 23#include <asm/mach-au1x00/au1xxx_dbdma.h>
23#include <asm/mach-au1x00/au1xxx_psc.h> 24#include <asm/mach-au1x00/au1xxx_psc.h>
24#include <asm/mach-au1x00/au1550_spi.h> 25#include <asm/mach-au1x00/au1550_spi.h>
26#include <asm/mach-au1x00/au1550nd.h>
25#include <asm/mach-db1x00/bcsr.h> 27#include <asm/mach-db1x00/bcsr.h>
26#include <prom.h> 28#include <prom.h>
27#include "platform.h" 29#include "platform.h"
@@ -30,15 +32,14 @@ static void __init db1550_hw_setup(void)
30{ 32{
31 void __iomem *base; 33 void __iomem *base;
32 34
33 alchemy_gpio_direction_output(203, 0); /* red led on */
34
35 /* complete SPI setup: link psc0_intclk to a 48MHz source, 35 /* complete SPI setup: link psc0_intclk to a 48MHz source,
36 * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) 36 * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC
37 * for AC97 on PB1550.
37 */ 38 */
38 base = (void __iomem *)SYS_CLKSRC; 39 base = (void __iomem *)SYS_CLKSRC;
39 __raw_writel(__raw_readl(base) | 0x000001e0, base); 40 __raw_writel(__raw_readl(base) | 0x000001e0, base);
40 base = (void __iomem *)SYS_PINFUNC; 41 base = (void __iomem *)SYS_PINFUNC;
41 __raw_writel(__raw_readl(base) | 1, base); 42 __raw_writel(__raw_readl(base) | 1 | SYS_PF_PSC1_S1, base);
42 wmb(); 43 wmb();
43 44
44 /* reset the AC97 codec now, the reset time in the psc-ac97 driver 45 /* reset the AC97 codec now, the reset time in the psc-ac97 driver
@@ -51,8 +52,6 @@ static void __init db1550_hw_setup(void)
51 wmb(); 52 wmb();
52 __raw_writel(PSC_AC97RST_RST, base + PSC_AC97RST_OFFSET); 53 __raw_writel(PSC_AC97RST_RST, base + PSC_AC97RST_OFFSET);
53 wmb(); 54 wmb();
54
55 alchemy_gpio_direction_output(202, 0); /* green led on */
56} 55}
57 56
58int __init db1550_board_setup(void) 57int __init db1550_board_setup(void)
@@ -62,9 +61,14 @@ int __init db1550_board_setup(void)
62 bcsr_init(DB1550_BCSR_PHYS_ADDR, 61 bcsr_init(DB1550_BCSR_PHYS_ADDR,
63 DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS); 62 DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS);
64 63
65 whoami = bcsr_read(BCSR_WHOAMI); 64 whoami = bcsr_read(BCSR_WHOAMI); /* PB1550 hexled offset differs */
66 printk(KERN_INFO "Alchemy/AMD DB1550 Board, CPLD Rev %d" 65 if ((BCSR_WHOAMI_BOARD(whoami) == BCSR_WHOAMI_PB1550_SDR) ||
67 " Board-ID %d Daughtercard ID %d\n", 66 (BCSR_WHOAMI_BOARD(whoami) == BCSR_WHOAMI_PB1550_DDR))
67 bcsr_init(PB1550_BCSR_PHYS_ADDR,
68 PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
69
70 pr_info("Alchemy/AMD %s Board, CPLD Rev %d Board-ID %d " \
71 "Daughtercard ID %d\n", get_system_type(),
68 (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); 72 (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
69 73
70 db1550_hw_setup(); 74 db1550_hw_setup();
@@ -189,6 +193,39 @@ static struct platform_device db1550_nand_dev = {
189 } 193 }
190}; 194};
191 195
196static struct au1550nd_platdata pb1550_nand_pd = {
197 .parts = db1550_nand_parts,
198 .num_parts = ARRAY_SIZE(db1550_nand_parts),
199 .devwidth = 0, /* x8 NAND default, needs fixing up */
200};
201
202static struct platform_device pb1550_nand_dev = {
203 .name = "au1550-nand",
204 .id = -1,
205 .resource = db1550_nand_res,
206 .num_resources = ARRAY_SIZE(db1550_nand_res),
207 .dev = {
208 .platform_data = &pb1550_nand_pd,
209 },
210};
211
212static void __init pb1550_nand_setup(void)
213{
214 int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) |
215 ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
216
217 gpio_direction_input(206); /* de-assert NAND CS# */
218 switch (boot_swapboot) {
219 case 0: case 2: case 8: case 0xC: case 0xD:
220 /* x16 NAND Flash */
221 pb1550_nand_pd.devwidth = 1;
222 /* fallthrough */
223 case 1: case 3: case 9: case 0xE: case 0xF:
224 /* x8 NAND, already set up */
225 platform_device_register(&pb1550_nand_dev);
226 }
227}
228
192/**********************************************************************/ 229/**********************************************************************/
193 230
194static struct resource au1550_psc0_res[] = { 231static struct resource au1550_psc0_res[] = {
@@ -389,6 +426,29 @@ static int db1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
389 return -1; 426 return -1;
390} 427}
391 428
429static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
430{
431 if ((slot < 12) || (slot > 13) || pin == 0)
432 return -1;
433 if (slot == 12) {
434 switch (pin) {
435 case 1: return AU1500_PCI_INTB;
436 case 2: return AU1500_PCI_INTC;
437 case 3: return AU1500_PCI_INTD;
438 case 4: return AU1500_PCI_INTA;
439 }
440 }
441 if (slot == 13) {
442 switch (pin) {
443 case 1: return AU1500_PCI_INTA;
444 case 2: return AU1500_PCI_INTB;
445 case 3: return AU1500_PCI_INTC;
446 case 4: return AU1500_PCI_INTD;
447 }
448 }
449 return -1;
450}
451
392static struct resource alchemy_pci_host_res[] = { 452static struct resource alchemy_pci_host_res[] = {
393 [0] = { 453 [0] = {
394 .start = AU1500_PCI_PHYS_ADDR, 454 .start = AU1500_PCI_PHYS_ADDR,
@@ -412,7 +472,6 @@ static struct platform_device db1550_pci_host_dev = {
412/**********************************************************************/ 472/**********************************************************************/
413 473
414static struct platform_device *db1550_devs[] __initdata = { 474static struct platform_device *db1550_devs[] __initdata = {
415 &db1550_nand_dev,
416 &db1550_i2c_dev, 475 &db1550_i2c_dev,
417 &db1550_ac97_dev, 476 &db1550_ac97_dev,
418 &db1550_spi_dev, 477 &db1550_spi_dev,
@@ -425,14 +484,16 @@ static struct platform_device *db1550_devs[] __initdata = {
425}; 484};
426 485
427/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ 486/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
428int __init db1550_pci_setup(void) 487int __init db1550_pci_setup(int id)
429{ 488{
489 if (id)
490 db1550_pci_pd.board_map_irq = pb1550_map_pci_irq;
430 return platform_device_register(&db1550_pci_host_dev); 491 return platform_device_register(&db1550_pci_host_dev);
431} 492}
432 493
433int __init db1550_dev_setup(void) 494static void __init db1550_devices(void)
434{ 495{
435 int swapped; 496 alchemy_gpio_direction_output(203, 0); /* red led on */
436 497
437 irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_EDGE_BOTH); /* CD0# */ 498 irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_EDGE_BOTH); /* CD0# */
438 irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_EDGE_BOTH); /* CD1# */ 499 irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_EDGE_BOTH); /* CD1# */
@@ -441,6 +502,75 @@ int __init db1550_dev_setup(void)
441 irq_set_irq_type(AU1550_GPIO21_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG0# */ 502 irq_set_irq_type(AU1550_GPIO21_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG0# */
442 irq_set_irq_type(AU1550_GPIO22_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG1# */ 503 irq_set_irq_type(AU1550_GPIO22_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG1# */
443 504
505 db1x_register_pcmcia_socket(
506 AU1000_PCMCIA_ATTR_PHYS_ADDR,
507 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
508 AU1000_PCMCIA_MEM_PHYS_ADDR,
509 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
510 AU1000_PCMCIA_IO_PHYS_ADDR,
511 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
512 AU1550_GPIO3_INT, AU1550_GPIO0_INT,
513 /*AU1550_GPIO21_INT*/0, 0, 0);
514
515 db1x_register_pcmcia_socket(
516 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
517 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
518 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
519 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
520 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
521 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
522 AU1550_GPIO5_INT, AU1550_GPIO1_INT,
523 /*AU1550_GPIO22_INT*/0, 0, 1);
524
525 platform_device_register(&db1550_nand_dev);
526
527 alchemy_gpio_direction_output(202, 0); /* green led on */
528}
529
530static void __init pb1550_devices(void)
531{
532 irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_LEVEL_LOW);
533 irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_LEVEL_LOW);
534 irq_set_irq_type(AU1550_GPIO201_205_INT, IRQ_TYPE_LEVEL_HIGH);
535
536 /* enable both PCMCIA card irqs in the shared line */
537 alchemy_gpio2_enable_int(201); /* socket 0 card irq */
538 alchemy_gpio2_enable_int(202); /* socket 1 card irq */
539
540 /* Pb1550, like all others, also has statuschange irqs; however they're
541 * wired up on one of the Au1550's shared GPIO201_205 line, which also
542 * services the PCMCIA card interrupts. So we ignore statuschange and
543 * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
544 * drivers are used to shared irqs and b) statuschange isn't really use-
545 * ful anyway.
546 */
547 db1x_register_pcmcia_socket(
548 AU1000_PCMCIA_ATTR_PHYS_ADDR,
549 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
550 AU1000_PCMCIA_MEM_PHYS_ADDR,
551 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
552 AU1000_PCMCIA_IO_PHYS_ADDR,
553 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
554 AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0);
555
556 db1x_register_pcmcia_socket(
557 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
558 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
559 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
560 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
561 AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
562 AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
563 AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1);
564
565 pb1550_nand_setup();
566}
567
568int __init db1550_dev_setup(void)
569{
570 int swapped, id;
571
572 id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550);
573
444 i2c_register_board_info(0, db1550_i2c_devs, 574 i2c_register_board_info(0, db1550_i2c_devs,
445 ARRAY_SIZE(db1550_i2c_devs)); 575 ARRAY_SIZE(db1550_i2c_devs));
446 spi_register_board_info(db1550_spi_devs, 576 spi_register_board_info(db1550_spi_devs,
@@ -461,27 +591,10 @@ int __init db1550_dev_setup(void)
461 (void __iomem *)KSEG1ADDR(AU1550_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); 591 (void __iomem *)KSEG1ADDR(AU1550_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET);
462 wmb(); 592 wmb();
463 593
464 db1x_register_pcmcia_socket( 594 id ? pb1550_devices() : db1550_devices();
465 AU1000_PCMCIA_ATTR_PHYS_ADDR,
466 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
467 AU1000_PCMCIA_MEM_PHYS_ADDR,
468 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
469 AU1000_PCMCIA_IO_PHYS_ADDR,
470 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
471 AU1550_GPIO3_INT, AU1550_GPIO0_INT,
472 /*AU1550_GPIO21_INT*/0, 0, 0);
473
474 db1x_register_pcmcia_socket(
475 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
476 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
477 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
478 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
479 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
480 AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
481 AU1550_GPIO5_INT, AU1550_GPIO1_INT,
482 /*AU1550_GPIO22_INT*/0, 0, 1);
483 595
484 swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; 596 swapped = bcsr_read(BCSR_STATUS) &
597 (id ? BCSR_STATUS_PB1550_SWAPBOOT : BCSR_STATUS_DB1000_SWAPBOOT);
485 db1x_register_norflash(128 << 20, 4, swapped); 598 db1x_register_norflash(128 << 20, 4, swapped);
486 599
487 return platform_add_devices(db1550_devs, ARRAY_SIZE(db1550_devs)); 600 return platform_add_devices(db1550_devs, ARRAY_SIZE(db1550_devs));
diff --git a/arch/mips/alchemy/devboards/pb1550.c b/arch/mips/alchemy/devboards/pb1550.c
deleted file mode 100644
index b37e7de8d920..000000000000
--- a/arch/mips/alchemy/devboards/pb1550.c
+++ /dev/null
@@ -1,244 +0,0 @@
1/*
2 * Pb1550 board support.
3 *
4 * Copyright (C) 2009-2011 Manuel Lauss
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/platform_device.h>
25#include <asm/mach-au1x00/au1000.h>
26#include <asm/mach-au1x00/au1xxx_dbdma.h>
27#include <asm/mach-au1x00/au1550nd.h>
28#include <asm/mach-au1x00/gpio.h>
29#include <asm/mach-db1x00/bcsr.h>
30#include "platform.h"
31
32const char *get_system_type(void)
33{
34 return "PB1550";
35}
36
37void __init board_setup(void)
38{
39 u32 pin_func;
40
41 bcsr_init(PB1550_BCSR_PHYS_ADDR,
42 PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
43
44 alchemy_gpio2_enable();
45
46 /*
47 * Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
48 * but it is board specific code, so put it here.
49 */
50 pin_func = au_readl(SYS_PINFUNC);
51 au_sync();
52 pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
53 au_writel(pin_func, SYS_PINFUNC);
54
55 bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
56
57 printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
58}
59
60/******************************************************************************/
61
62static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
63{
64 if ((slot < 12) || (slot > 13) || pin == 0)
65 return -1;
66 if (slot == 12) {
67 switch (pin) {
68 case 1: return AU1500_PCI_INTB;
69 case 2: return AU1500_PCI_INTC;
70 case 3: return AU1500_PCI_INTD;
71 case 4: return AU1500_PCI_INTA;
72 }
73 }
74 if (slot == 13) {
75 switch (pin) {
76 case 1: return AU1500_PCI_INTA;
77 case 2: return AU1500_PCI_INTB;
78 case 3: return AU1500_PCI_INTC;
79 case 4: return AU1500_PCI_INTD;
80 }
81 }
82 return -1;
83}
84
85static struct resource alchemy_pci_host_res[] = {
86 [0] = {
87 .start = AU1500_PCI_PHYS_ADDR,
88 .end = AU1500_PCI_PHYS_ADDR + 0xfff,
89 .flags = IORESOURCE_MEM,
90 },
91};
92
93static struct alchemy_pci_platdata pb1550_pci_pd = {
94 .board_map_irq = pb1550_map_pci_irq,
95};
96
97static struct platform_device pb1550_pci_host = {
98 .dev.platform_data = &pb1550_pci_pd,
99 .name = "alchemy-pci",
100 .id = 0,
101 .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
102 .resource = alchemy_pci_host_res,
103};
104
105static struct resource au1550_psc2_res[] = {
106 [0] = {
107 .start = AU1550_PSC2_PHYS_ADDR,
108 .end = AU1550_PSC2_PHYS_ADDR + 0xfff,
109 .flags = IORESOURCE_MEM,
110 },
111 [1] = {
112 .start = AU1550_PSC2_INT,
113 .end = AU1550_PSC2_INT,
114 .flags = IORESOURCE_IRQ,
115 },
116 [2] = {
117 .start = AU1550_DSCR_CMD0_PSC2_TX,
118 .end = AU1550_DSCR_CMD0_PSC2_TX,
119 .flags = IORESOURCE_DMA,
120 },
121 [3] = {
122 .start = AU1550_DSCR_CMD0_PSC2_RX,
123 .end = AU1550_DSCR_CMD0_PSC2_RX,
124 .flags = IORESOURCE_DMA,
125 },
126};
127
128static struct platform_device pb1550_i2c_dev = {
129 .name = "au1xpsc_smbus",
130 .id = 0, /* bus number */
131 .num_resources = ARRAY_SIZE(au1550_psc2_res),
132 .resource = au1550_psc2_res,
133};
134
135static struct mtd_partition pb1550_nand_parts[] = {
136 [0] = {
137 .name = "NAND FS 0",
138 .offset = 0,
139 .size = 8 * 1024 * 1024,
140 },
141 [1] = {
142 .name = "NAND FS 1",
143 .offset = MTDPART_OFS_APPEND,
144 .size = MTDPART_SIZ_FULL,
145 },
146};
147
148static struct au1550nd_platdata pb1550_nand_pd = {
149 .parts = pb1550_nand_parts,
150 .num_parts = ARRAY_SIZE(pb1550_nand_parts),
151 .devwidth = 0, /* x8 NAND default, needs fixing up */
152};
153
154static struct resource pb1550_nand_res[] = {
155 [0] = {
156 .start = 0x20000000,
157 .end = 0x20000fff,
158 .flags = IORESOURCE_MEM,
159 },
160};
161
162static struct platform_device pb1550_nand_dev = {
163 .name = "au1550-nand",
164 .id = -1,
165 .resource = pb1550_nand_res,
166 .num_resources = ARRAY_SIZE(pb1550_nand_res),
167 .dev = {
168 .platform_data = &pb1550_nand_pd,
169 },
170};
171
172static void __init pb1550_nand_setup(void)
173{
174 int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) |
175 ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
176
177 switch (boot_swapboot) {
178 case 0:
179 case 2:
180 case 8:
181 case 0xC:
182 case 0xD:
183 /* x16 NAND Flash */
184 pb1550_nand_pd.devwidth = 1;
185 /* fallthrough */
186 case 1:
187 case 9:
188 case 3:
189 case 0xE:
190 case 0xF:
191 /* x8 NAND, already set up */
192 platform_device_register(&pb1550_nand_dev);
193 }
194}
195
196static int __init pb1550_dev_init(void)
197{
198 int swapped;
199
200 irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
201 irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
202 irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
203
204 /* enable both PCMCIA card irqs in the shared line */
205 alchemy_gpio2_enable_int(201);
206 alchemy_gpio2_enable_int(202);
207
208 /* Pb1550, like all others, also has statuschange irqs; however they're
209 * wired up on one of the Au1550's shared GPIO201_205 line, which also
210 * services the PCMCIA card interrupts. So we ignore statuschange and
211 * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
212 * drivers are used to shared irqs and b) statuschange isn't really use-
213 * ful anyway.
214 */
215 db1x_register_pcmcia_socket(
216 AU1000_PCMCIA_ATTR_PHYS_ADDR,
217 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
218 AU1000_PCMCIA_MEM_PHYS_ADDR,
219 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
220 AU1000_PCMCIA_IO_PHYS_ADDR,
221 AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
222 AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0);
223
224 db1x_register_pcmcia_socket(
225 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
226 AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
227 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
228 AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
229 AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
230 AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
231 AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1);
232
233 /* NAND setup */
234 gpio_direction_input(206); /* GPIO206 high */
235 pb1550_nand_setup();
236
237 swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
238 db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
239 platform_device_register(&pb1550_pci_host);
240 platform_device_register(&pb1550_i2c_dev);
241
242 return 0;
243}
244arch_initcall(pb1550_dev_init);