summaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorjuhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-07-19 09:11:59 +0000
committerjuhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-07-19 09:11:59 +0000
commit54ef805a9938552313fd11d9a29d3009e817a247 (patch)
tree57288457dae785a55d9bf118c9fec1f3e6f64e21 /target
parent5850aef15813422d7e63087b21d7670e015042eb (diff)
[ppc40x] add driver for the CF slot of the Magicbox v2/OpenRB boards
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@16910 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target')
-rw-r--r--target/linux/ppc40x/patches-2.6.30/100-magicbox-ide-driver.patch323
-rw-r--r--target/linux/ppc40x/patches-2.6.30/101-powerpc-add-EBC_BXCR_BW-defines.patch12
-rw-r--r--target/linux/ppc40x/patches-2.6.30/102-openrb-light-cf-card-fixup.patch39
-rw-r--r--target/linux/ppc40x/patches-2.6.30/103-openrb-light-add-cf-card-to-dts.patch17
-rw-r--r--target/linux/ppc40x/patches-2.6.30/104-magicboxv2-cf-card-fixup.patch47
-rw-r--r--target/linux/ppc40x/patches-2.6.30/105-magicboxv2-add-cf-card-to-dts.patch25
6 files changed, 463 insertions, 0 deletions
diff --git a/target/linux/ppc40x/patches-2.6.30/100-magicbox-ide-driver.patch b/target/linux/ppc40x/patches-2.6.30/100-magicbox-ide-driver.patch
new file mode 100644
index 0000000000..4d396bcdca
--- /dev/null
+++ b/target/linux/ppc40x/patches-2.6.30/100-magicbox-ide-driver.patch
@@ -0,0 +1,323 @@
+--- a/drivers/ide/Kconfig
++++ b/drivers/ide/Kconfig
+@@ -717,6 +717,11 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
+ endchoice
+
++config BLK_DEV_IDE_MAGICBOX
++ tristate "Magicbox CF card support"
++ depends on MAGICBOXV2 || OPENRB_LIGHT
++ select IDE_XFER_MODE
++
+ config BLK_DEV_IDE_TX4938
+ tristate "TX4938 internal IDE support"
+ depends on SOC_TX4938
+--- a/drivers/ide/Makefile
++++ b/drivers/ide/Makefile
+@@ -113,6 +113,7 @@ obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapi
+ obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o
+
+ obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
++obj-$(CONFIG_BLK_DEV_IDE_MAGICBOX) += magicbox_ide.o
+
+ obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o
+ obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o
+--- /dev/null
++++ b/drivers/ide/magicbox_ide.c
+@@ -0,0 +1,296 @@
++/*
++ * IDE driver for the MagicBox 2.0 onboard CompactFlash slot.
++ *
++ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
++ *
++ * Based on the original driver by Wojtek Kaniewski <wojtekka@toxygen.net>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ */
++
++#include <linux/types.h>
++#include <linux/ioport.h>
++#include <linux/of.h>
++#include <linux/of_device.h>
++#include <linux/of_platform.h>
++#include <linux/ide.h>
++
++#include <asm/dcr-native.h>
++
++#define DRV_DESC "IDE driver for Magicbox 2.0 onboard CF slot"
++#define DRV_NAME "magicbox_cf"
++
++static inline u8 magicbox_ide_inb(unsigned long port)
++{
++ return (u8) (readw((void __iomem *) port) >> 8) & 0xff;
++}
++
++static inline void magicbox_ide_outb(u8 value, unsigned long port)
++{
++ writew(value << 8, (void __iomem *) port);
++}
++
++static inline void magicbox_ide_insw(unsigned long port, void *addr, u32 count)
++{
++ u16 *ptr;
++
++ for (ptr = addr; count--; ptr++)
++ *ptr = readw((void __iomem *) port);
++}
++
++static inline void magicbox_ide_insl(unsigned long port, void *addr, u32 count)
++{
++ u32 *ptr;
++
++ for (ptr = addr; count--; ptr++)
++ *ptr = readl((void __iomem *) port);
++}
++
++static inline void magicbox_ide_outsw(unsigned long port, void *addr,
++ u32 count)
++{
++ u16 *ptr;
++
++ for (ptr = addr; count--; ptr++)
++ writew(*ptr, (void __iomem *) port);
++}
++
++static inline void magicbox_ide_outsl(unsigned long port, void *addr,
++ u32 count)
++{
++ u32 *ptr;
++
++ for (ptr = addr; count--; ptr++)
++ writel(*ptr, (void __iomem *) port);
++}
++
++static void magicbox_ide_exec_command(ide_hwif_t *hwif, u8 cmd)
++{
++ magicbox_ide_outb(cmd, hwif->io_ports.command_addr);
++}
++
++static u8 magicbox_ide_read_status(ide_hwif_t *hwif)
++{
++ return magicbox_ide_inb(hwif->io_ports.status_addr);
++}
++
++static u8 magicbox_ide_read_altstatus(ide_hwif_t *hwif)
++{
++ return magicbox_ide_inb(hwif->io_ports.ctl_addr);
++}
++
++static void magicbox_ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
++{
++ magicbox_ide_outb(ctl, hwif->io_ports.ctl_addr);
++}
++
++static void magicbox_ide_tf_load(ide_drive_t *drive, struct ide_taskfile *tf,
++ u8 valid)
++{
++ struct ide_io_ports *io_ports = &drive->hwif->io_ports;
++
++ if (valid & IDE_VALID_FEATURE)
++ magicbox_ide_outb(tf->feature, io_ports->feature_addr);
++ if (valid & IDE_VALID_NSECT)
++ magicbox_ide_outb(tf->nsect, io_ports->nsect_addr);
++ if (valid & IDE_VALID_LBAL)
++ magicbox_ide_outb(tf->lbal, io_ports->lbal_addr);
++ if (valid & IDE_VALID_LBAM)
++ magicbox_ide_outb(tf->lbam, io_ports->lbam_addr);
++ if (valid & IDE_VALID_LBAH)
++ magicbox_ide_outb(tf->lbah, io_ports->lbah_addr);
++
++ if (valid & IDE_VALID_DEVICE)
++ magicbox_ide_outb(tf->device, io_ports->device_addr);
++}
++
++static void magicbox_ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf,
++ u8 valid)
++{
++ struct ide_io_ports *io_ports = &drive->hwif->io_ports;
++
++ if (valid & IDE_VALID_NSECT)
++ tf->nsect = magicbox_ide_inb(io_ports->nsect_addr);
++ if (valid & IDE_VALID_LBAL)
++ tf->lbal = magicbox_ide_inb(io_ports->lbal_addr);
++ if (valid & IDE_VALID_LBAM)
++ tf->lbam = magicbox_ide_inb(io_ports->lbam_addr);
++ if (valid & IDE_VALID_LBAH)
++ tf->lbah = magicbox_ide_inb(io_ports->lbah_addr);
++ if (valid & IDE_VALID_DEVICE)
++ tf->device = magicbox_ide_inb(io_ports->device_addr);
++}
++
++static void magicbox_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
++ void *buf, unsigned int len)
++{
++ unsigned long port = drive->hwif->io_ports.data_addr;
++
++ len++;
++
++ if (drive->io_32bit) {
++ magicbox_ide_insl(port, buf, len / 4);
++
++ if ((len & 3) >= 2)
++ magicbox_ide_insw(port, (u8 *)buf + (len & ~3), 1);
++ } else {
++ magicbox_ide_insw(port, buf, len / 2);
++ }
++}
++
++static void magicbox_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
++ void *buf, unsigned int len)
++{
++ unsigned long port = drive->hwif->io_ports.data_addr;
++
++ len++;
++
++ if (drive->io_32bit) {
++ magicbox_ide_outsl(port, buf, len / 4);
++
++ if ((len & 3) >= 2)
++ magicbox_ide_outsw(port, (u8 *)buf + (len & ~3), 1);
++ } else {
++ magicbox_ide_outsw(port, buf, len / 2);
++ }
++}
++
++static void magicbox_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
++{
++}
++
++static u8 magicbox_ide_cable_detect(ide_hwif_t *hwif)
++{
++ return ATA_CBL_PATA40;
++}
++
++static const struct ide_tp_ops magicbox_ide_tp_ops = {
++ .exec_command = magicbox_ide_exec_command,
++ .read_status = magicbox_ide_read_status,
++ .read_altstatus = magicbox_ide_read_altstatus,
++ .write_devctl = magicbox_ide_write_devctl,
++
++ .dev_select = ide_dev_select,
++ .tf_load = magicbox_ide_tf_load,
++ .tf_read = magicbox_ide_tf_read,
++
++ .input_data = magicbox_ide_input_data,
++ .output_data = magicbox_ide_output_data,
++};
++
++static const struct ide_port_ops magicbox_ide_port_ops = {
++ .set_pio_mode = magicbox_ide_set_pio_mode,
++ .cable_detect = magicbox_ide_cable_detect,
++};
++
++static const struct ide_port_info magicbox_ide_port_info = {
++ .name = DRV_NAME,
++ .chipset = ide_generic,
++ .tp_ops = &magicbox_ide_tp_ops,
++ .port_ops = &magicbox_ide_port_ops,
++ .host_flags = IDE_HFLAG_SINGLE |
++ IDE_HFLAG_NO_DMA |
++ IDE_HFLAG_MMIO |
++ IDE_HFLAG_UNMASK_IRQS,
++ .pio_mask = ATA_PIO4,
++};
++
++static inline void magicbox_ide_setup_hw(hw_regs_t *hw, u16 __iomem *base,
++ u16 __iomem *ctrl, int irq)
++{
++ unsigned long port = (unsigned long) base;
++ int i;
++
++ memset(hw, 0, sizeof(*hw));
++ for (i = 0; i <= 7; i++)
++ hw->io_ports_array[i] = port + i * 2;
++
++ /*
++ * the IDE control register is at ATA address 6,
++ * with CS1 active instead of CS0
++ */
++ hw->io_ports.ctl_addr = (unsigned long)ctrl + (6 * 2);
++}
++
++static int __devinit magicbox_ide_of_probe(struct of_device *op,
++ const struct of_device_id *match)
++{
++ hw_regs_t hw;
++ hw_regs_t *hws[] = { &hw, NULL, NULL, NULL };
++ struct ide_host *host;
++ u16 __iomem *base;
++ u16 __iomem *ctrl;
++ int irq;
++ int ret = 0;
++
++ irq = irq_of_parse_and_map(op->node, 0);
++ if (irq < 0) {
++ dev_err(&op->dev, "invalid irq\n");
++ ret = -EINVAL;
++ goto err_exit;
++ }
++
++ base = of_iomap(op->node, 0);
++ if (base == NULL) {
++ ret = -ENOMEM;
++ goto err_exit;
++ }
++
++ ctrl = of_iomap(op->node, 1);
++ if (ctrl == NULL) {
++ ret = -ENOMEM;
++ goto err_unmap_base;
++ }
++
++ magicbox_ide_setup_hw(&hw, base, ctrl, irq);
++
++ hw.dev = &op->dev;
++ hw.irq = irq;
++ hw.chipset = ide_generic;
++ hw.ack_intr = NULL;
++
++ ret = ide_host_add(&magicbox_ide_port_info, hws, &host);
++ if (ret)
++ goto err_unmap_ctrl;
++
++ dev_set_drvdata(&op->dev, host);
++
++ return 0;
++
++ err_unmap_ctrl:
++ iounmap(ctrl);
++ err_unmap_base:
++ iounmap(base);
++ err_exit:
++ return ret;
++}
++
++static struct of_device_id magicbox_ide_of_match[] = {
++ { .compatible = "magicbox-cf", },
++ {},
++};
++
++static struct of_platform_driver magicbox_ide_of_platform_driver = {
++ .owner = THIS_MODULE,
++ .name = DRV_NAME,
++ .match_table = magicbox_ide_of_match,
++ .probe = magicbox_ide_of_probe,
++ .driver = {
++ .name = DRV_NAME,
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init magicbox_ide_init(void)
++{
++ return of_register_platform_driver(&magicbox_ide_of_platform_driver);
++}
++
++module_init(magicbox_ide_init);
++
++MODULE_DESCRIPTION(DRV_DESC);
++MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
++MODULE_LICENSE("GPL v2");
++MODULE_DEVICE_TABLE(of, magicbox_ide_of_match);
diff --git a/target/linux/ppc40x/patches-2.6.30/101-powerpc-add-EBC_BXCR_BW-defines.patch b/target/linux/ppc40x/patches-2.6.30/101-powerpc-add-EBC_BXCR_BW-defines.patch
new file mode 100644
index 0000000000..8e380c1c9c
--- /dev/null
+++ b/target/linux/ppc40x/patches-2.6.30/101-powerpc-add-EBC_BXCR_BW-defines.patch
@@ -0,0 +1,12 @@
+--- a/arch/powerpc/boot/dcr.h
++++ b/arch/powerpc/boot/dcr.h
+@@ -57,6 +57,9 @@ static const unsigned long sdram_bxcr[]
+ #define EBC_BXCR_BU_WO 0x00010000
+ #define EBC_BXCR_BU_RW 0x00018000
+ #define EBC_BXCR_BW 0x00006000
++#define EBC_BXCR_BW_8 0x00000000
++#define EBC_BXCR_BW_16 0x00002000
++#define EBC_BXCR_BW_32 0x00006000
+ #define EBC_B0AP 0x10
+ #define EBC_B1AP 0x11
+ #define EBC_B2AP 0x12
diff --git a/target/linux/ppc40x/patches-2.6.30/102-openrb-light-cf-card-fixup.patch b/target/linux/ppc40x/patches-2.6.30/102-openrb-light-cf-card-fixup.patch
new file mode 100644
index 0000000000..7e8d2ef36e
--- /dev/null
+++ b/target/linux/ppc40x/patches-2.6.30/102-openrb-light-cf-card-fixup.patch
@@ -0,0 +1,39 @@
+--- a/arch/powerpc/boot/cuboot-openrb-light.c
++++ b/arch/powerpc/boot/cuboot-openrb-light.c
+@@ -22,8 +22,36 @@
+
+ static bd_t bd;
+
++static void fixup_cf_card(void)
++{
++#define DCRN_CPC0_PCI_BASE 0xf9
++#define CF_CS0_BASE 0xff100000
++#define CF_CS1_BASE 0xff200000
++
++ /* Turn on PerWE instead of PCIsomething */
++ mtdcr(DCRN_CPC0_PCI_BASE,
++ mfdcr(DCRN_CPC0_PCI_BASE) | (0x80000000L >> 27));
++
++ /* PerCS1 (CF's CS0): base 0xff100000, 16-bit, rw */
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B1CR);
++ mtdcr(DCRN_EBC0_CFGDATA, CF_CS0_BASE | EBC_BXCR_BU_RW | EBC_BXCR_BW_16);
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B1AP);
++ mtdcr(DCRN_EBC0_CFGDATA, 0x080bd800);
++
++ /* PerCS2 (CF's CS1): base 0xff200000, 16-bit, rw */
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B2CR);
++ mtdcr(DCRN_EBC0_CFGDATA, CF_CS1_BASE | EBC_BXCR_BU_RW | EBC_BXCR_BW_16);
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B2AP);
++ mtdcr(DCRN_EBC0_CFGDATA, 0x080bd800);
++
++#undef DCRN_CPC0_PCI_BASE
++#undef CF_CS0_BASE
++#undef CF_CS1_BASE
++}
++
+ static void openrb_light_fixups(void)
+ {
++ fixup_cf_card();
+ ibm405ep_fixup_clocks(33333000);
+ ibm4xx_sdram_fixup_memsize();
+ dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr);
diff --git a/target/linux/ppc40x/patches-2.6.30/103-openrb-light-add-cf-card-to-dts.patch b/target/linux/ppc40x/patches-2.6.30/103-openrb-light-add-cf-card-to-dts.patch
new file mode 100644
index 0000000000..ee49aa1c9d
--- /dev/null
+++ b/target/linux/ppc40x/patches-2.6.30/103-openrb-light-add-cf-card-to-dts.patch
@@ -0,0 +1,17 @@
+--- a/arch/powerpc/boot/dts/openrb-light.dts
++++ b/arch/powerpc/boot/dts/openrb-light.dts
+@@ -177,6 +177,14 @@
+ */
+ clock-frequency = <0>; /* Filled in by zImage */
+
++ cf_card@ff100000 {
++ compatible = "magicbox-cf";
++ reg = <0x00000000 0xff100000 0x00001000
++ 0x00000000 0xff200000 0x00001000>;
++ interrupt-parent = <&UIC0>;
++ interrupts = <0x19 0x1 /* IRQ_TYPE_EDGE_RISING */ >;
++ };
++
+ nor_flash@ff800000 {
+ compatible = "cfi-flash";
+ bank-width = <2>;
diff --git a/target/linux/ppc40x/patches-2.6.30/104-magicboxv2-cf-card-fixup.patch b/target/linux/ppc40x/patches-2.6.30/104-magicboxv2-cf-card-fixup.patch
new file mode 100644
index 0000000000..56e337c281
--- /dev/null
+++ b/target/linux/ppc40x/patches-2.6.30/104-magicboxv2-cf-card-fixup.patch
@@ -0,0 +1,47 @@
+--- a/arch/powerpc/boot/cuboot-magicboxv2.c
++++ b/arch/powerpc/boot/cuboot-magicboxv2.c
+@@ -2,6 +2,7 @@
+ * Old U-boot compatibility for Magicbox v2
+ *
+ * Author: Imre Kaloz <kaloz@openwrt.org>
++ * Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+@@ -22,8 +23,36 @@
+
+ static bd_t bd;
+
++static void fixup_cf_card(void)
++{
++#define DCRN_CPC0_PCI_BASE 0xf9
++#define CF_CS0_BASE 0xff100000
++#define CF_CS1_BASE 0xff200000
++
++ /* Turn on PerWE instead of PCIsomething */
++ mtdcr(DCRN_CPC0_PCI_BASE,
++ mfdcr(DCRN_CPC0_PCI_BASE) | (0x80000000L >> 27));
++
++ /* PerCS1 (CF's CS0): base 0xff100000, 16-bit, rw */
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B1CR);
++ mtdcr(DCRN_EBC0_CFGDATA, CF_CS0_BASE | EBC_BXCR_BU_RW | EBC_BXCR_BW_16);
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B1AP);
++ mtdcr(DCRN_EBC0_CFGDATA, 0x080bd800);
++
++ /* PerCS2 (CF's CS1): base 0xff200000, 16-bit, rw */
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B2CR);
++ mtdcr(DCRN_EBC0_CFGDATA, CF_CS1_BASE | EBC_BXCR_BU_RW | EBC_BXCR_BW_16);
++ mtdcr(DCRN_EBC0_CFGADDR, EBC_B2AP);
++ mtdcr(DCRN_EBC0_CFGDATA, 0x080bd800);
++
++#undef DCRN_CPC0_PCI_BASE
++#undef CF_CS0_BASE
++#undef CF_CS1_BASE
++}
++
+ static void magicboxv2_fixups(void)
+ {
++ fixup_cf_card();
+ ibm405ep_fixup_clocks(25000000);
+ ibm4xx_sdram_fixup_memsize();
+ dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr);
diff --git a/target/linux/ppc40x/patches-2.6.30/105-magicboxv2-add-cf-card-to-dts.patch b/target/linux/ppc40x/patches-2.6.30/105-magicboxv2-add-cf-card-to-dts.patch
new file mode 100644
index 0000000000..97990909bf
--- /dev/null
+++ b/target/linux/ppc40x/patches-2.6.30/105-magicboxv2-add-cf-card-to-dts.patch
@@ -0,0 +1,25 @@
+--- a/arch/powerpc/boot/dts/magicboxv2.dts
++++ b/arch/powerpc/boot/dts/magicboxv2.dts
+@@ -2,6 +2,7 @@
+ * Device Tree Source for Magicbox v2
+ *
+ * Copyright 2008 Imre Kaloz <kaloz@openwrt.org>
++ * Copyright 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Based on walnut.dts
+ *
+@@ -183,6 +184,14 @@
+ */
+ clock-frequency = <0>; /* Filled in by zImage */
+
++ cf_card@ff100000 {
++ compatible = "magicbox-cf";
++ reg = <0x00000000 0xff100000 0x00001000
++ 0x00000000 0xff200000 0x00001000>;
++ interrupt-parent = <&UIC0>;
++ interrupts = <0x19 0x1 /* IRQ_TYPE_EDGE_RISING */ >;
++ };
++
+ nor_flash@ffc00000 {
+ compatible = "cfi-flash";
+ bank-width = <2>;