2010-02-05 11:14:58 +00:00
/*
* 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>
2010-05-04 14:07:15 +00:00
# include <linux/sh_dma.h>
2010-02-05 11:14:58 +00:00
# include <linux/sh_intc.h>
# include <linux/sh_timer.h>
# include <mach/hardware.h>
2010-05-04 14:07:15 +00:00
# include <mach/sh7372.h>
2010-02-05 11:14:58 +00:00
# include <asm/mach-types.h>
# include <asm/mach/arch.h>
2010-05-20 14:41:00 +00:00
/* SCIFA0 */
2010-02-05 11:14:58 +00:00
static struct plat_sci_port scif0_platform_data = {
. mapbase = 0xe6c40000 ,
. flags = UPF_BOOT_AUTOCONF ,
2010-05-23 16:39:17 +00:00
. type = PORT_SCIFA ,
2010-05-20 14:41:00 +00:00
. irqs = { evt2irq ( 0x0c00 ) , evt2irq ( 0x0c00 ) ,
evt2irq ( 0x0c00 ) , evt2irq ( 0x0c00 ) } ,
2010-02-05 11:14:58 +00:00
} ;
static struct platform_device scif0_device = {
. name = " sh-sci " ,
. id = 0 ,
. dev = {
. platform_data = & scif0_platform_data ,
} ,
} ;
2010-05-20 14:41:00 +00:00
/* SCIFA1 */
2010-02-05 11:14:58 +00:00
static struct plat_sci_port scif1_platform_data = {
. mapbase = 0xe6c50000 ,
. flags = UPF_BOOT_AUTOCONF ,
2010-05-23 16:39:17 +00:00
. type = PORT_SCIFA ,
2010-05-20 14:41:00 +00:00
. irqs = { evt2irq ( 0x0c20 ) , evt2irq ( 0x0c20 ) ,
evt2irq ( 0x0c20 ) , evt2irq ( 0x0c20 ) } ,
2010-02-05 11:14:58 +00:00
} ;
static struct platform_device scif1_device = {
. name = " sh-sci " ,
. id = 1 ,
. dev = {
. platform_data = & scif1_platform_data ,
} ,
} ;
2010-05-20 14:41:00 +00:00
/* SCIFA2 */
2010-02-05 11:14:58 +00:00
static struct plat_sci_port scif2_platform_data = {
. mapbase = 0xe6c60000 ,
. flags = UPF_BOOT_AUTOCONF ,
2010-05-23 16:39:17 +00:00
. type = PORT_SCIFA ,
2010-05-20 14:41:00 +00:00
. irqs = { evt2irq ( 0x0c40 ) , evt2irq ( 0x0c40 ) ,
evt2irq ( 0x0c40 ) , evt2irq ( 0x0c40 ) } ,
2010-02-05 11:14:58 +00:00
} ;
static struct platform_device scif2_device = {
. name = " sh-sci " ,
. id = 2 ,
. dev = {
. platform_data = & scif2_platform_data ,
} ,
} ;
2010-05-20 14:41:00 +00:00
/* SCIFA3 */
2010-02-05 11:14:58 +00:00
static struct plat_sci_port scif3_platform_data = {
. mapbase = 0xe6c70000 ,
. flags = UPF_BOOT_AUTOCONF ,
2010-05-23 16:39:17 +00:00
. type = PORT_SCIFA ,
2010-05-20 14:41:00 +00:00
. irqs = { evt2irq ( 0x0c60 ) , evt2irq ( 0x0c60 ) ,
evt2irq ( 0x0c60 ) , evt2irq ( 0x0c60 ) } ,
2010-02-05 11:14:58 +00:00
} ;
static struct platform_device scif3_device = {
. name = " sh-sci " ,
. id = 3 ,
. dev = {
. platform_data = & scif3_platform_data ,
} ,
} ;
2010-05-20 14:41:00 +00:00
/* SCIFA4 */
2010-02-05 11:14:58 +00:00
static struct plat_sci_port scif4_platform_data = {
. mapbase = 0xe6c80000 ,
. flags = UPF_BOOT_AUTOCONF ,
2010-05-23 16:39:17 +00:00
. type = PORT_SCIFA ,
2010-05-20 14:41:00 +00:00
. irqs = { evt2irq ( 0x0d20 ) , evt2irq ( 0x0d20 ) ,
evt2irq ( 0x0d20 ) , evt2irq ( 0x0d20 ) } ,
2010-02-05 11:14:58 +00:00
} ;
static struct platform_device scif4_device = {
. name = " sh-sci " ,
. id = 4 ,
. dev = {
. platform_data = & scif4_platform_data ,
} ,
} ;
2010-05-20 14:41:00 +00:00
/* SCIFA5 */
2010-02-05 11:14:58 +00:00
static struct plat_sci_port scif5_platform_data = {
. mapbase = 0xe6cb0000 ,
. flags = UPF_BOOT_AUTOCONF ,
2010-05-23 16:39:17 +00:00
. type = PORT_SCIFA ,
2010-05-20 14:41:00 +00:00
. irqs = { evt2irq ( 0x0d40 ) , evt2irq ( 0x0d40 ) ,
evt2irq ( 0x0d40 ) , evt2irq ( 0x0d40 ) } ,
2010-02-05 11:14:58 +00:00
} ;
static struct platform_device scif5_device = {
. name = " sh-sci " ,
. id = 5 ,
. dev = {
. platform_data = & scif5_platform_data ,
} ,
} ;
2010-05-20 14:41:00 +00:00
/* SCIFB */
2010-02-05 11:14:58 +00:00
static struct plat_sci_port scif6_platform_data = {
. mapbase = 0xe6c30000 ,
. flags = UPF_BOOT_AUTOCONF ,
2010-05-23 16:39:17 +00:00
. type = PORT_SCIFB ,
2010-05-20 14:41:00 +00:00
. irqs = { evt2irq ( 0x0d60 ) , evt2irq ( 0x0d60 ) ,
evt2irq ( 0x0d60 ) , evt2irq ( 0x0d60 ) } ,
2010-02-05 11:14:58 +00:00
} ;
static struct platform_device scif6_device = {
. name = " sh-sci " ,
. id = 6 ,
. dev = {
. platform_data = & scif6_platform_data ,
} ,
} ;
2010-03-11 10:42:47 +00:00
/* CMT */
2010-02-05 11:14:58 +00:00
static struct sh_timer_config cmt10_platform_data = {
. name = " CMT10 " ,
. channel_offset = 0x10 ,
. timer_bit = 0 ,
2010-05-12 14:21:34 +00:00
. clk = " cmt1 " ,
2010-02-05 11:14:58 +00:00
. clockevent_rating = 125 ,
. clocksource_rating = 125 ,
} ;
static struct resource cmt10_resources [ ] = {
[ 0 ] = {
. name = " CMT10 " ,
. start = 0xe6138010 ,
. end = 0xe613801b ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2010-05-20 14:41:00 +00:00
. start = evt2irq ( 0x0b00 ) , /* CMT1_CMT10 */
2010-02-05 11:14:58 +00:00
. 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 ) ,
} ;
2010-03-11 10:42:47 +00:00
/* I2C */
static struct resource iic0_resources [ ] = {
[ 0 ] = {
. name = " IIC0 " ,
. start = 0xFFF20000 ,
. end = 0xFFF20425 - 1 ,
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2010-05-20 14:41:00 +00:00
. start = intcs_evt2irq ( 0xe00 ) , /* IIC0_ALI0 */
. end = intcs_evt2irq ( 0xe60 ) , /* IIC0_DTEI0 */
2010-03-11 10:42:47 +00:00
. 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 ] = {
2010-05-20 14:41:00 +00:00
. start = evt2irq ( 0x780 ) , /* IIC1_ALI1 */
. end = evt2irq ( 0x7e0 ) , /* IIC1_DTEI1 */
2010-03-11 10:42:47 +00:00
. 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 ,
} ;
2010-05-04 14:07:15 +00:00
/* 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 [ ] = {
{
2010-05-23 16:39:24 +00:00
. 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 ,
} , {
2010-05-04 14:07:15 +00:00
. 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 = 246 ,
. end = 246 ,
. flags = IORESOURCE_IRQ ,
} ,
{
/* IRQ for channels 0-5 */
. start = 240 ,
. end = 245 ,
. 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 = 254 ,
. end = 254 ,
. flags = IORESOURCE_IRQ ,
} ,
{
/* IRQ for channels 0-5 */
. start = 248 ,
. end = 253 ,
. 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 = 262 ,
. end = 262 ,
. flags = IORESOURCE_IRQ ,
} ,
{
/* IRQ for channels 0-5 */
. start = 256 ,
. end = 261 ,
. 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 ,
} ,
} ;
2010-02-05 11:14:58 +00:00
static struct platform_device * sh7372_early_devices [ ] __initdata = {
& scif0_device ,
& scif1_device ,
& scif2_device ,
& scif3_device ,
& scif4_device ,
& scif5_device ,
& scif6_device ,
& cmt10_device ,
2010-03-11 10:42:47 +00:00
& iic0_device ,
& iic1_device ,
2010-05-04 14:07:15 +00:00
& dma0_device ,
& dma1_device ,
& dma2_device ,
2010-02-05 11:14:58 +00:00
} ;
void __init sh7372_add_standard_devices ( void )
{
platform_add_devices ( sh7372_early_devices ,
ARRAY_SIZE ( sh7372_early_devices ) ) ;
}
void __init sh7372_add_early_devices ( void )
{
early_platform_add_devices ( sh7372_early_devices ,
ARRAY_SIZE ( sh7372_early_devices ) ) ;
}