MIPS: TXx9: Add DMAC support
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Wed, 22 Apr 2009 15:40:31 +0000 (00:40 +0900)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 17 Jun 2009 10:06:25 +0000 (11:06 +0100)
Add platform support for DMAC of TXx9 SoCs.

Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/txx9/dmac.h
arch/mips/include/asm/txx9/tx4927.h
arch/mips/include/asm/txx9/tx4938.h
arch/mips/include/asm/txx9/tx4939.h
arch/mips/txx9/generic/setup.c
arch/mips/txx9/generic/setup_tx4927.c
arch/mips/txx9/generic/setup_tx4938.c
arch/mips/txx9/generic/setup_tx4939.c
arch/mips/txx9/rbtx4927/setup.c
arch/mips/txx9/rbtx4938/setup.c
arch/mips/txx9/rbtx4939/setup.c

index a87d1c3e4f5b544369c23c779d65db5b8c3fdf01..5e9151fccbb4e9be24b6cec77ef7255185d1b20c 100644 (file)
@@ -45,4 +45,7 @@ struct txx9dmac_slave {
        unsigned int    reg_width;
 };
 
+void txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+                   const struct txx9dmac_platform_data *pdata);
+
 #endif /* __ASM_TXX9_DMAC_H */
index 7d813f1cb98d17ea8b19fa0e52ed7e2bda937a70..d92ae07000d38d731a2847d5d3f71219b3355932 100644 (file)
@@ -41,6 +41,7 @@
 
 #define TX4927_SDRAMC_REG      (TX4927_REG_BASE + 0x8000)
 #define TX4927_EBUSC_REG       (TX4927_REG_BASE + 0x9000)
+#define TX4927_DMA_REG         (TX4927_REG_BASE + 0xb000)
 #define TX4927_PCIC_REG                (TX4927_REG_BASE + 0xd000)
 #define TX4927_CCFG_REG                (TX4927_REG_BASE + 0xe000)
 #define TX4927_IRC_REG         (TX4927_REG_BASE + 0xf600)
@@ -265,5 +266,6 @@ int tx4927_pciclk66_setup(void);
 void tx4927_setup_pcierr_irq(void);
 void tx4927_irq_init(void);
 void tx4927_mtd_init(int ch);
+void tx4927_dmac_init(int memcpy_chan);
 
 #endif /* __ASM_TXX9_TX4927_H */
index cd8bc2021755e8be084c2170371f3eaedf9d9fff..0758a0c411b123c64c8022e8646494af9d73f3ec 100644 (file)
@@ -305,5 +305,6 @@ struct tx4938ide_platform_info {
 };
 
 void tx4938_ata_init(unsigned int irq, unsigned int shift, int tune);
+void tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1);
 
 #endif
index f02c50b3abfbd205f29dbd51aa828c7f5996b165..1be9798a26b5806263a4bf7d6c809b3a94f2c0be 100644 (file)
@@ -544,5 +544,6 @@ void tx4939_ata_init(void);
 void tx4939_rtc_init(void);
 void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
                       unsigned char ch_mask, unsigned char wide_mask);
+void tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1);
 
 #endif /* __ASM_TXX9_TX4939_H */
index 8a266c6a3f58eb68151d9b5139f4572d378ee95d..369d8637217d6baf391f682cc6b3f4e6bcab57ba 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/txx9/pci.h>
 #include <asm/txx9tmr.h>
 #include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
 #ifdef CONFIG_CPU_TX49XX
 #include <asm/txx9/tx4938.h>
 #endif
@@ -821,3 +822,57 @@ void __init txx9_iocled_init(unsigned long baseaddr,
 {
 }
 #endif /* CONFIG_LEDS_GPIO */
+
+void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+                          const struct txx9dmac_platform_data *pdata)
+{
+#if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE)
+       struct resource res[] = {
+               {
+                       .start = baseaddr,
+                       .end = baseaddr + 0x800 - 1,
+                       .flags = IORESOURCE_MEM,
+#ifndef CONFIG_MACH_TX49XX
+               }, {
+                       .start = irq,
+                       .flags = IORESOURCE_IRQ,
+#endif
+               }
+       };
+#ifdef CONFIG_MACH_TX49XX
+       struct resource chan_res[] = {
+               {
+                       .flags = IORESOURCE_IRQ,
+               }
+       };
+#endif
+       struct platform_device *pdev = platform_device_alloc("txx9dmac", id);
+       struct txx9dmac_chan_platform_data cpdata;
+       int i;
+
+       if (!pdev ||
+           platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
+           platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+           platform_device_add(pdev)) {
+               platform_device_put(pdev);
+               return;
+       }
+       memset(&cpdata, 0, sizeof(cpdata));
+       cpdata.dmac_dev = pdev;
+       for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
+#ifdef CONFIG_MACH_TX49XX
+               chan_res[0].start = irq + i;
+#endif
+               pdev = platform_device_alloc("txx9dmac-chan",
+                                            id * TXX9_DMA_MAX_NR_CHANNELS + i);
+               if (!pdev ||
+#ifdef CONFIG_MACH_TX49XX
+                   platform_device_add_resources(pdev, chan_res,
+                                                 ARRAY_SIZE(chan_res)) ||
+#endif
+                   platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) ||
+                   platform_device_add(pdev))
+                       platform_device_put(pdev);
+       }
+#endif
+}
index 1093549df1a8f07a78d80ac58842402a432791a1..6b681cd7f8fb6c74204b668f5babd26f156f2294 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/txx9tmr.h>
 #include <asm/txx9pio.h>
 #include <asm/txx9/generic.h>
+#include <asm/txx9/dmac.h>
 #include <asm/txx9/tx4927.h>
 
 static void __init tx4927_wdr_init(void)
@@ -253,6 +254,17 @@ void __init tx4927_mtd_init(int ch)
        txx9_physmap_flash_init(ch, start, size, &pdata);
 }
 
+void __init tx4927_dmac_init(int memcpy_chan)
+{
+       struct txx9dmac_platform_data plat_data = {
+               .memcpy_chan = memcpy_chan,
+               .have_64bit_regs = true,
+       };
+
+       txx9_dmac_init(0, TX4927_DMA_REG & 0xfffffffffULL,
+                      TXX9_IRQ_BASE + TX4927_IR_DMA(0), &plat_data);
+}
+
 static void __init tx4927_stop_unused_modules(void)
 {
        __u64 pcfg, rst = 0, ckd = 0;
index 3925219b89730f266bce5f3a151e18952d6a0772..b2b85293cd4444bc4a86f13dae2ca9a28c611640 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/txx9pio.h>
 #include <asm/txx9/generic.h>
 #include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
 #include <asm/txx9/tx4938.h>
 
 static void __init tx4938_wdr_init(void)
@@ -239,11 +240,6 @@ void __init tx4938_setup(void)
        for (i = 0; i < TX4938_NR_TMR; i++)
                txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
 
-       /* DMA */
-       for (i = 0; i < 2; i++)
-               ____raw_writeq(TX4938_DMA_MCR_MSTEN,
-                              (void __iomem *)(TX4938_DMA_REG(i) + 0x50));
-
        /* PIO */
        txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO);
        __raw_writel(0, &tx4938_pioptr->maskcpu);
@@ -403,6 +399,21 @@ void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
                txx9_ndfmc_init(baseaddr, &plat_data);
 }
 
+void __init tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+       struct txx9dmac_platform_data plat_data = {
+               .have_64bit_regs = true,
+       };
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+               txx9_dmac_init(i, TX4938_DMA_REG(i) & 0xfffffffffULL,
+                              TXX9_IRQ_BASE + TX4938_IR_DMA(i, 0),
+                              &plat_data);
+       }
+}
+
 static void __init tx4938_stop_unused_modules(void)
 {
        __u64 pcfg, rst = 0, ckd = 0;
index c2bf150c883898a1c126d8c8c37be404c87ff2fb..98effef64fdb1966b7ee21165a28d9792d3a0e6d 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/txx9tmr.h>
 #include <asm/txx9/generic.h>
 #include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
 #include <asm/txx9/tx4939.h>
 
 static void __init tx4939_wdr_init(void)
@@ -259,11 +260,6 @@ void __init tx4939_setup(void)
        for (i = 0; i < TX4939_NR_TMR; i++)
                txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL);
 
-       /* DMA */
-       for (i = 0; i < 2; i++)
-               ____raw_writeq(TX4938_DMA_MCR_MSTEN,
-                              (void __iomem *)(TX4939_DMA_REG(i) + 0x50));
-
        /* set PCIC1 reset (required to prevent hangup on BIST) */
        txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
        pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
@@ -474,6 +470,21 @@ void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
        txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
 }
 
+void __init tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+       struct txx9dmac_platform_data plat_data = {
+               .have_64bit_regs = true,
+       };
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+               txx9_dmac_init(i, TX4939_DMA_REG(i) & 0xfffffffffULL,
+                              TXX9_IRQ_BASE + TX4939_IR_DMA(i, 0),
+                              &plat_data);
+       }
+}
+
 static void __init tx4939_stop_unused_modules(void)
 {
        __u64 pcfg, rst = 0, ckd = 0;
index 01129a9d50fa183ee8167a5c3419b59082953ae4..332cdbc7fcef628a6938c60800a83bc9b3f13086 100644 (file)
@@ -337,6 +337,10 @@ static void __init rbtx4927_device_init(void)
        rbtx4927_ne_init();
        tx4927_wdt_init();
        rbtx4927_mtd_init();
+       if (TX4927_REV_PCODE() == 0x4927)
+               tx4927_dmac_init(2);
+       else
+               tx4938_dmac_init(0, 2);
        txx9_iocled_init(RBTX4927_LED_ADDR - IO_BASE, -1, 3, 1, "green", NULL);
        rbtx4927_gpioled_init();
 }
index 65d13df8878aabaafdb260dc87ef7d34f0a87108..37c5e3d20287c287a74390b526d1b9353809bcdf 100644 (file)
@@ -355,6 +355,7 @@ static void __init rbtx4938_device_init(void)
        /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
        tx4938_ndfmc_init(10, 35);
        tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
+       tx4938_dmac_init(0, 2);
        txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
 }
 
index 4199c6fd4d1d3c13392863f755aa74f3c6b96c01..91f2ec8fa2734c9afaa5f7b3223ace2950224010 100644 (file)
@@ -498,6 +498,7 @@ static void __init rbtx4939_device_init(void)
        tx4939_wdt_init();
        tx4939_ata_init();
        tx4939_rtc_init();
+       tx4939_dmac_init(0, 2);
 }
 
 static void __init rbtx4939_setup(void)