Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs...
[pandora-kernel.git] / arch / arm / mach-shmobile / setup-sh73a0.c
index 685c40a..e46821c 100644 (file)
 #include <linux/input.h>
 #include <linux/io.h>
 #include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/sh73a0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -392,6 +394,242 @@ static struct platform_device i2c4_device = {
        .num_resources  = ARRAY_SIZE(i2c4_resources),
 };
 
+/* Transmit sizes and respective CHCR register values */
+enum {
+       XMIT_SZ_8BIT            = 0,
+       XMIT_SZ_16BIT           = 1,
+       XMIT_SZ_32BIT           = 2,
+       XMIT_SZ_64BIT           = 7,
+       XMIT_SZ_128BIT          = 3,
+       XMIT_SZ_256BIT          = 4,
+       XMIT_SZ_512BIT          = 5,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+#define TS_SHIFT {                     \
+       [XMIT_SZ_8BIT]          = 0,    \
+       [XMIT_SZ_16BIT]         = 1,    \
+       [XMIT_SZ_32BIT]         = 2,    \
+       [XMIT_SZ_64BIT]         = 3,    \
+       [XMIT_SZ_128BIT]        = 4,    \
+       [XMIT_SZ_256BIT]        = 5,    \
+       [XMIT_SZ_512BIT]        = 6,    \
+}
+
+#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | (((i) & 0xc) << (20 - 2)))
+#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
+#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
+
+static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
+       {
+               .slave_id       = SHDMA_SLAVE_SCIF0_TX,
+               .addr           = 0xe6c40020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x21,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF0_RX,
+               .addr           = 0xe6c40024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x22,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF1_TX,
+               .addr           = 0xe6c50020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x25,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF1_RX,
+               .addr           = 0xe6c50024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x26,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF2_TX,
+               .addr           = 0xe6c60020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x29,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF2_RX,
+               .addr           = 0xe6c60024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x2a,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF3_TX,
+               .addr           = 0xe6c70020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x2d,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF3_RX,
+               .addr           = 0xe6c70024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x2e,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF4_TX,
+               .addr           = 0xe6c80020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x39,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF4_RX,
+               .addr           = 0xe6c80024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x3a,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF5_TX,
+               .addr           = 0xe6cb0020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x35,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF5_RX,
+               .addr           = 0xe6cb0024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x36,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF6_TX,
+               .addr           = 0xe6cc0020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x1d,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF6_RX,
+               .addr           = 0xe6cc0024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x1e,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF7_TX,
+               .addr           = 0xe6cd0020,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x19,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF7_RX,
+               .addr           = 0xe6cd0024,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x1a,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF8_TX,
+               .addr           = 0xe6c30040,
+               .chcr           = CHCR_TX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x3d,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SCIF8_RX,
+               .addr           = 0xe6c30060,
+               .chcr           = CHCR_RX(XMIT_SZ_8BIT),
+               .mid_rid        = 0x3e,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SDHI0_TX,
+               .addr           = 0xee100030,
+               .chcr           = CHCR_TX(XMIT_SZ_16BIT),
+               .mid_rid        = 0xc1,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SDHI0_RX,
+               .addr           = 0xee100030,
+               .chcr           = CHCR_RX(XMIT_SZ_16BIT),
+               .mid_rid        = 0xc2,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SDHI1_TX,
+               .addr           = 0xee120030,
+               .chcr           = CHCR_TX(XMIT_SZ_16BIT),
+               .mid_rid        = 0xc9,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SDHI1_RX,
+               .addr           = 0xee120030,
+               .chcr           = CHCR_RX(XMIT_SZ_16BIT),
+               .mid_rid        = 0xca,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SDHI2_TX,
+               .addr           = 0xee140030,
+               .chcr           = CHCR_TX(XMIT_SZ_16BIT),
+               .mid_rid        = 0xcd,
+       }, {
+               .slave_id       = SHDMA_SLAVE_SDHI2_RX,
+               .addr           = 0xee140030,
+               .chcr           = CHCR_RX(XMIT_SZ_16BIT),
+               .mid_rid        = 0xce,
+       }, {
+               .slave_id       = SHDMA_SLAVE_MMCIF_TX,
+               .addr           = 0xe6bd0034,
+               .chcr           = CHCR_TX(XMIT_SZ_32BIT),
+               .mid_rid        = 0xd1,
+       }, {
+               .slave_id       = SHDMA_SLAVE_MMCIF_RX,
+               .addr           = 0xe6bd0034,
+               .chcr           = CHCR_RX(XMIT_SZ_32BIT),
+               .mid_rid        = 0xd2,
+       },
+};
+
+#define DMAE_CHANNEL(_offset)                                  \
+       {                                                       \
+               .offset         = _offset - 0x20,               \
+               .dmars          = _offset - 0x20 + 0x40,        \
+       }
+
+static const struct sh_dmae_channel sh73a0_dmae_channels[] = {
+       DMAE_CHANNEL(0x8000),
+       DMAE_CHANNEL(0x8080),
+       DMAE_CHANNEL(0x8100),
+       DMAE_CHANNEL(0x8180),
+       DMAE_CHANNEL(0x8200),
+       DMAE_CHANNEL(0x8280),
+       DMAE_CHANNEL(0x8300),
+       DMAE_CHANNEL(0x8380),
+       DMAE_CHANNEL(0x8400),
+       DMAE_CHANNEL(0x8480),
+       DMAE_CHANNEL(0x8500),
+       DMAE_CHANNEL(0x8580),
+       DMAE_CHANNEL(0x8600),
+       DMAE_CHANNEL(0x8680),
+       DMAE_CHANNEL(0x8700),
+       DMAE_CHANNEL(0x8780),
+       DMAE_CHANNEL(0x8800),
+       DMAE_CHANNEL(0x8880),
+       DMAE_CHANNEL(0x8900),
+       DMAE_CHANNEL(0x8980),
+};
+
+static const unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata sh73a0_dmae_platform_data = {
+       .slave          = sh73a0_dmae_slaves,
+       .slave_num      = ARRAY_SIZE(sh73a0_dmae_slaves),
+       .channel        = sh73a0_dmae_channels,
+       .channel_num    = ARRAY_SIZE(sh73a0_dmae_channels),
+       .ts_low_shift   = 3,
+       .ts_low_mask    = 0x18,
+       .ts_high_shift  = (20 - 2),     /* 2 bits for shifted low TS */
+       .ts_high_mask   = 0x00300000,
+       .ts_shift       = ts_shift,
+       .ts_shift_num   = ARRAY_SIZE(ts_shift),
+       .dmaor_init     = DMAOR_DME,
+};
+
+static struct resource sh73a0_dmae_resources[] = {
+       {
+               /* Registers including DMAOR and channels including DMARSx */
+               .start  = 0xfe000020,
+               .end    = 0xfe008a00 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               /* DMA error IRQ */
+               .start  = gic_spi(129),
+               .end    = gic_spi(129),
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               /* IRQ for channels 0-19 */
+               .start  = gic_spi(109),
+               .end    = gic_spi(128),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device dma0_device = {
+       .name           = "sh-dma-engine",
+       .id             = 0,
+       .resource       = sh73a0_dmae_resources,
+       .num_resources  = ARRAY_SIZE(sh73a0_dmae_resources),
+       .dev            = {
+               .platform_data  = &sh73a0_dmae_platform_data,
+       },
+};
+
 static struct platform_device *sh73a0_early_devices[] __initdata = {
        &scif0_device,
        &scif1_device,
@@ -413,10 +651,16 @@ static struct platform_device *sh73a0_late_devices[] __initdata = {
        &i2c2_device,
        &i2c3_device,
        &i2c4_device,
+       &dma0_device,
 };
 
+#define SRCR2          0xe61580b0
+
 void __init sh73a0_add_standard_devices(void)
 {
+       /* Clear software reset bit on SY-DMAC module */
+       __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
+
        platform_add_devices(sh73a0_early_devices,
                            ARRAY_SIZE(sh73a0_early_devices));
        platform_add_devices(sh73a0_late_devices,