1
linux/arch/arm/mach-shmobile/setup-sh7372.c
Magnus Damm c6c049ecbc ARM: mach-shmobile: add TMU platform data for sh7372
This patch adds support for the two first channels of
the TMU0 timer block on sh7372. One channel is used
for clock event, the other for clock source.

Signed-off-by: Magnus Damm <damm@opensource.se>
Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
2010-10-15 20:16:45 +09:00

615 lines
14 KiB
C

/*
* sh7372 processor support
*
* Copyright (C) 2010 Magnus Damm
* Copyright (C) 2008 Yoshihiro Shimoda
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#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/sh7372.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
/* SCIFA0 */
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xe6c40000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { evt2irq(0x0c00), evt2irq(0x0c00),
evt2irq(0x0c00), evt2irq(0x0c00) },
};
static struct platform_device scif0_device = {
.name = "sh-sci",
.id = 0,
.dev = {
.platform_data = &scif0_platform_data,
},
};
/* SCIFA1 */
static struct plat_sci_port scif1_platform_data = {
.mapbase = 0xe6c50000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { evt2irq(0x0c20), evt2irq(0x0c20),
evt2irq(0x0c20), evt2irq(0x0c20) },
};
static struct platform_device scif1_device = {
.name = "sh-sci",
.id = 1,
.dev = {
.platform_data = &scif1_platform_data,
},
};
/* SCIFA2 */
static struct plat_sci_port scif2_platform_data = {
.mapbase = 0xe6c60000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { evt2irq(0x0c40), evt2irq(0x0c40),
evt2irq(0x0c40), evt2irq(0x0c40) },
};
static struct platform_device scif2_device = {
.name = "sh-sci",
.id = 2,
.dev = {
.platform_data = &scif2_platform_data,
},
};
/* SCIFA3 */
static struct plat_sci_port scif3_platform_data = {
.mapbase = 0xe6c70000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { evt2irq(0x0c60), evt2irq(0x0c60),
evt2irq(0x0c60), evt2irq(0x0c60) },
};
static struct platform_device scif3_device = {
.name = "sh-sci",
.id = 3,
.dev = {
.platform_data = &scif3_platform_data,
},
};
/* SCIFA4 */
static struct plat_sci_port scif4_platform_data = {
.mapbase = 0xe6c80000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { evt2irq(0x0d20), evt2irq(0x0d20),
evt2irq(0x0d20), evt2irq(0x0d20) },
};
static struct platform_device scif4_device = {
.name = "sh-sci",
.id = 4,
.dev = {
.platform_data = &scif4_platform_data,
},
};
/* SCIFA5 */
static struct plat_sci_port scif5_platform_data = {
.mapbase = 0xe6cb0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFA,
.irqs = { evt2irq(0x0d40), evt2irq(0x0d40),
evt2irq(0x0d40), evt2irq(0x0d40) },
};
static struct platform_device scif5_device = {
.name = "sh-sci",
.id = 5,
.dev = {
.platform_data = &scif5_platform_data,
},
};
/* SCIFB */
static struct plat_sci_port scif6_platform_data = {
.mapbase = 0xe6c30000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIFB,
.irqs = { evt2irq(0x0d60), evt2irq(0x0d60),
evt2irq(0x0d60), evt2irq(0x0d60) },
};
static struct platform_device scif6_device = {
.name = "sh-sci",
.id = 6,
.dev = {
.platform_data = &scif6_platform_data,
},
};
/* CMT */
static struct sh_timer_config cmt10_platform_data = {
.name = "CMT10",
.channel_offset = 0x10,
.timer_bit = 0,
.clockevent_rating = 125,
.clocksource_rating = 125,
};
static struct resource cmt10_resources[] = {
[0] = {
.name = "CMT10",
.start = 0xe6138010,
.end = 0xe613801b,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0x0b00), /* CMT1_CMT10 */
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device cmt10_device = {
.name = "sh_cmt",
.id = 10,
.dev = {
.platform_data = &cmt10_platform_data,
},
.resource = cmt10_resources,
.num_resources = ARRAY_SIZE(cmt10_resources),
};
/* TMU */
static struct sh_timer_config tmu00_platform_data = {
.name = "TMU00",
.channel_offset = 0x4,
.timer_bit = 0,
.clockevent_rating = 200,
};
static struct resource tmu00_resources[] = {
[0] = {
.name = "TMU00",
.start = 0xfff60008,
.end = 0xfff60013,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = intcs_evt2irq(0xe80), /* TMU_TUNI0 */
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device tmu00_device = {
.name = "sh_tmu",
.id = 0,
.dev = {
.platform_data = &tmu00_platform_data,
},
.resource = tmu00_resources,
.num_resources = ARRAY_SIZE(tmu00_resources),
};
static struct sh_timer_config tmu01_platform_data = {
.name = "TMU01",
.channel_offset = 0x10,
.timer_bit = 1,
.clocksource_rating = 200,
};
static struct resource tmu01_resources[] = {
[0] = {
.name = "TMU01",
.start = 0xfff60014,
.end = 0xfff6001f,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = intcs_evt2irq(0xea0), /* TMU_TUNI1 */
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device tmu01_device = {
.name = "sh_tmu",
.id = 1,
.dev = {
.platform_data = &tmu01_platform_data,
},
.resource = tmu01_resources,
.num_resources = ARRAY_SIZE(tmu01_resources),
};
/* I2C */
static struct resource iic0_resources[] = {
[0] = {
.name = "IIC0",
.start = 0xFFF20000,
.end = 0xFFF20425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = intcs_evt2irq(0xe00), /* IIC0_ALI0 */
.end = intcs_evt2irq(0xe60), /* IIC0_DTEI0 */
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device iic0_device = {
.name = "i2c-sh_mobile",
.id = 0, /* "i2c0" clock */
.num_resources = ARRAY_SIZE(iic0_resources),
.resource = iic0_resources,
};
static struct resource iic1_resources[] = {
[0] = {
.name = "IIC1",
.start = 0xE6C20000,
.end = 0xE6C20425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0x780), /* IIC1_ALI1 */
.end = evt2irq(0x7e0), /* IIC1_DTEI1 */
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device iic1_device = {
.name = "i2c-sh_mobile",
.id = 1, /* "i2c1" clock */
.num_resources = ARRAY_SIZE(iic1_resources),
.resource = iic1_resources,
};
/* DMA */
/* 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)))
static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
{
.slave_id = SHDMA_SLAVE_SCIF0_TX,
.addr = 0xe6c40020,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x21,
}, {
.slave_id = SHDMA_SLAVE_SCIF0_RX,
.addr = 0xe6c40024,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x22,
}, {
.slave_id = SHDMA_SLAVE_SCIF1_TX,
.addr = 0xe6c50020,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x25,
}, {
.slave_id = SHDMA_SLAVE_SCIF1_RX,
.addr = 0xe6c50024,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x26,
}, {
.slave_id = SHDMA_SLAVE_SCIF2_TX,
.addr = 0xe6c60020,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x29,
}, {
.slave_id = SHDMA_SLAVE_SCIF2_RX,
.addr = 0xe6c60024,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x2a,
}, {
.slave_id = SHDMA_SLAVE_SCIF3_TX,
.addr = 0xe6c70020,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x2d,
}, {
.slave_id = SHDMA_SLAVE_SCIF3_RX,
.addr = 0xe6c70024,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x2e,
}, {
.slave_id = SHDMA_SLAVE_SCIF4_TX,
.addr = 0xe6c80020,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x39,
}, {
.slave_id = SHDMA_SLAVE_SCIF4_RX,
.addr = 0xe6c80024,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x3a,
}, {
.slave_id = SHDMA_SLAVE_SCIF5_TX,
.addr = 0xe6cb0020,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x35,
}, {
.slave_id = SHDMA_SLAVE_SCIF5_RX,
.addr = 0xe6cb0024,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x36,
}, {
.slave_id = SHDMA_SLAVE_SCIF6_TX,
.addr = 0xe6c30040,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x3d,
}, {
.slave_id = SHDMA_SLAVE_SCIF6_RX,
.addr = 0xe6c30060,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
.mid_rid = 0x3e,
}, {
.slave_id = SHDMA_SLAVE_SDHI0_TX,
.addr = 0xe6850030,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xc1,
}, {
.slave_id = SHDMA_SLAVE_SDHI0_RX,
.addr = 0xe6850030,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xc2,
}, {
.slave_id = SHDMA_SLAVE_SDHI1_TX,
.addr = 0xe6860030,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xc9,
}, {
.slave_id = SHDMA_SLAVE_SDHI1_RX,
.addr = 0xe6860030,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xca,
}, {
.slave_id = SHDMA_SLAVE_SDHI2_TX,
.addr = 0xe6870030,
.chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xcd,
}, {
.slave_id = SHDMA_SLAVE_SDHI2_RX,
.addr = 0xe6870030,
.chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
.mid_rid = 0xce,
},
};
static const struct sh_dmae_channel sh7372_dmae_channels[] = {
{
.offset = 0,
.dmars = 0,
.dmars_bit = 0,
}, {
.offset = 0x10,
.dmars = 0,
.dmars_bit = 8,
}, {
.offset = 0x20,
.dmars = 4,
.dmars_bit = 0,
}, {
.offset = 0x30,
.dmars = 4,
.dmars_bit = 8,
}, {
.offset = 0x50,
.dmars = 8,
.dmars_bit = 0,
}, {
.offset = 0x60,
.dmars = 8,
.dmars_bit = 8,
}
};
static const unsigned int ts_shift[] = TS_SHIFT;
static struct sh_dmae_pdata dma_platform_data = {
.slave = sh7372_dmae_slaves,
.slave_num = ARRAY_SIZE(sh7372_dmae_slaves),
.channel = sh7372_dmae_channels,
.channel_num = ARRAY_SIZE(sh7372_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,
};
/* Resource order important! */
static struct resource sh7372_dmae0_resources[] = {
{
/* Channel registers and DMAOR */
.start = 0xfe008020,
.end = 0xfe00808f,
.flags = IORESOURCE_MEM,
},
{
/* DMARSx */
.start = 0xfe009000,
.end = 0xfe00900b,
.flags = IORESOURCE_MEM,
},
{
/* DMA error IRQ */
.start = evt2irq(0x20c0),
.end = evt2irq(0x20c0),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 0-5 */
.start = evt2irq(0x2000),
.end = evt2irq(0x20a0),
.flags = IORESOURCE_IRQ,
},
};
/* Resource order important! */
static struct resource sh7372_dmae1_resources[] = {
{
/* Channel registers and DMAOR */
.start = 0xfe018020,
.end = 0xfe01808f,
.flags = IORESOURCE_MEM,
},
{
/* DMARSx */
.start = 0xfe019000,
.end = 0xfe01900b,
.flags = IORESOURCE_MEM,
},
{
/* DMA error IRQ */
.start = evt2irq(0x21c0),
.end = evt2irq(0x21c0),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 0-5 */
.start = evt2irq(0x2100),
.end = evt2irq(0x21a0),
.flags = IORESOURCE_IRQ,
},
};
/* Resource order important! */
static struct resource sh7372_dmae2_resources[] = {
{
/* Channel registers and DMAOR */
.start = 0xfe028020,
.end = 0xfe02808f,
.flags = IORESOURCE_MEM,
},
{
/* DMARSx */
.start = 0xfe029000,
.end = 0xfe02900b,
.flags = IORESOURCE_MEM,
},
{
/* DMA error IRQ */
.start = evt2irq(0x22c0),
.end = evt2irq(0x22c0),
.flags = IORESOURCE_IRQ,
},
{
/* IRQ for channels 0-5 */
.start = evt2irq(0x2200),
.end = evt2irq(0x22a0),
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device dma0_device = {
.name = "sh-dma-engine",
.id = 0,
.resource = sh7372_dmae0_resources,
.num_resources = ARRAY_SIZE(sh7372_dmae0_resources),
.dev = {
.platform_data = &dma_platform_data,
},
};
static struct platform_device dma1_device = {
.name = "sh-dma-engine",
.id = 1,
.resource = sh7372_dmae1_resources,
.num_resources = ARRAY_SIZE(sh7372_dmae1_resources),
.dev = {
.platform_data = &dma_platform_data,
},
};
static struct platform_device dma2_device = {
.name = "sh-dma-engine",
.id = 2,
.resource = sh7372_dmae2_resources,
.num_resources = ARRAY_SIZE(sh7372_dmae2_resources),
.dev = {
.platform_data = &dma_platform_data,
},
};
static struct platform_device *sh7372_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
&scif2_device,
&scif3_device,
&scif4_device,
&scif5_device,
&scif6_device,
&cmt10_device,
&tmu00_device,
&tmu01_device,
};
static struct platform_device *sh7372_late_devices[] __initdata = {
&iic0_device,
&iic1_device,
&dma0_device,
&dma1_device,
&dma2_device,
};
void __init sh7372_add_standard_devices(void)
{
platform_add_devices(sh7372_early_devices,
ARRAY_SIZE(sh7372_early_devices));
platform_add_devices(sh7372_late_devices,
ARRAY_SIZE(sh7372_late_devices));
}
void __init sh7372_add_early_devices(void)
{
early_platform_add_devices(sh7372_early_devices,
ARRAY_SIZE(sh7372_early_devices));
}