diff options
Diffstat (limited to 'arch/arm/mach-shmobile/setup-r8a7778.c')
| -rw-r--r-- | arch/arm/mach-shmobile/setup-r8a7778.c | 376 | 
1 files changed, 272 insertions, 104 deletions
diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 6a2657ebd19..d311ef903b3 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -24,6 +24,7 @@  #include <linux/irqchip/arm-gic.h>  #include <linux/of.h>  #include <linux/of_platform.h> +#include <linux/platform_data/dma-rcar-hpbdma.h>  #include <linux/platform_data/gpio-rcar.h>  #include <linux/platform_data/irq-renesas-intc-irqpin.h>  #include <linux/platform_device.h> @@ -43,81 +44,92 @@  #include <asm/hardware/cache-l2x0.h>  /* SCIF */ -#define SCIF_INFO(baseaddr, irq)				\ -{								\ -	.mapbase	= baseaddr,				\ +#define R8A7778_SCIF(index, baseaddr, irq)			\ +static struct plat_sci_port scif##index##_platform_data = {	\  	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,	\  	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,	\ -	.scbrr_algo_id	= SCBRR_ALGO_2,				\  	.type		= PORT_SCIF,				\ -	.irqs		= SCIx_IRQ_MUXED(irq),			\ +};								\ +								\ +static struct resource scif##index##_resources[] = {		\ +	DEFINE_RES_MEM(baseaddr, 0x100),			\ +	DEFINE_RES_IRQ(irq),					\  } -static struct plat_sci_port scif_platform_data[] __initdata = { -	SCIF_INFO(0xffe40000, gic_iid(0x66)), -	SCIF_INFO(0xffe41000, gic_iid(0x67)), -	SCIF_INFO(0xffe42000, gic_iid(0x68)), -	SCIF_INFO(0xffe43000, gic_iid(0x69)), -	SCIF_INFO(0xffe44000, gic_iid(0x6a)), -	SCIF_INFO(0xffe45000, gic_iid(0x6b)), -}; +R8A7778_SCIF(0, 0xffe40000, gic_iid(0x66)); +R8A7778_SCIF(1, 0xffe41000, gic_iid(0x67)); +R8A7778_SCIF(2, 0xffe42000, gic_iid(0x68)); +R8A7778_SCIF(3, 0xffe43000, gic_iid(0x69)); +R8A7778_SCIF(4, 0xffe44000, gic_iid(0x6a)); +R8A7778_SCIF(5, 0xffe45000, gic_iid(0x6b)); -/* TMU */ -static struct resource sh_tmu0_resources[] __initdata = { -	DEFINE_RES_MEM(0xffd80008, 12), -	DEFINE_RES_IRQ(gic_iid(0x40)), -}; +#define r8a7778_register_scif(index)					       \ +	platform_device_register_resndata(&platform_bus, "sh-sci", index,      \ +					  scif##index##_resources,	       \ +					  ARRAY_SIZE(scif##index##_resources), \ +					  &scif##index##_platform_data,	       \ +					  sizeof(scif##index##_platform_data)) -static struct sh_timer_config sh_tmu0_platform_data __initdata = { -	.name			= "TMU00", -	.channel_offset		= 0x4, -	.timer_bit		= 0, -	.clockevent_rating	= 200, +/* TMU */ +static struct sh_timer_config sh_tmu0_platform_data = { +	.channels_mask = 7,  }; -static struct resource sh_tmu1_resources[] __initdata = { -	DEFINE_RES_MEM(0xffd80014, 12), +static struct resource sh_tmu0_resources[] = { +	DEFINE_RES_MEM(0xffd80000, 0x30), +	DEFINE_RES_IRQ(gic_iid(0x40)),  	DEFINE_RES_IRQ(gic_iid(0x41)), -}; - -static struct sh_timer_config sh_tmu1_platform_data __initdata = { -	.name			= "TMU01", -	.channel_offset		= 0x10, -	.timer_bit		= 1, -	.clocksource_rating	= 200, +	DEFINE_RES_IRQ(gic_iid(0x42)),  };  #define r8a7778_register_tmu(idx)			\  	platform_device_register_resndata(		\ -		&platform_bus, "sh_tmu", idx,		\ +		&platform_bus, "sh-tmu", idx,		\  		sh_tmu##idx##_resources,		\  		ARRAY_SIZE(sh_tmu##idx##_resources),	\  		&sh_tmu##idx##_platform_data,		\  		sizeof(sh_tmu##idx##_platform_data)) -/* USB */ -static struct usb_phy *phy; +int r8a7778_usb_phy_power(bool enable) +{ +	static struct usb_phy *phy = NULL; +	int ret = 0; + +	if (!phy) +		phy = usb_get_phy(USB_PHY_TYPE_USB2); + +	if (IS_ERR(phy)) { +		pr_err("kernel doesn't have usb phy driver\n"); +		return PTR_ERR(phy); +	} + +	if (enable) +		ret = usb_phy_init(phy); +	else +		usb_phy_shutdown(phy); +	return ret; +} + +/* USB */  static int usb_power_on(struct platform_device *pdev)  { -	if (IS_ERR(phy)) -		return PTR_ERR(phy); +	int ret = r8a7778_usb_phy_power(true); + +	if (ret) +		return ret;  	pm_runtime_enable(&pdev->dev);  	pm_runtime_get_sync(&pdev->dev); -	usb_phy_init(phy); -  	return 0;  }  static void usb_power_off(struct platform_device *pdev)  { -	if (IS_ERR(phy)) +	if (r8a7778_usb_phy_power(false))  		return; -	usb_phy_shutdown(phy); -  	pm_runtime_put_sync(&pdev->dev);  	pm_runtime_disable(&pdev->dev);  } @@ -174,20 +186,6 @@ static struct platform_device_info hci##_info __initdata = {	\  USB_PLATFORM_INFO(ehci);  USB_PLATFORM_INFO(ohci); -/* Ether */ -static struct resource ether_resources[] __initdata = { -	DEFINE_RES_MEM(0xfde00000, 0x400), -	DEFINE_RES_IRQ(gic_iid(0x89)), -}; - -void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata) -{ -	platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1, -					  ether_resources, -					  ARRAY_SIZE(ether_resources), -					  pdata, sizeof(*pdata)); -} -  /* PFC/GPIO */  static struct resource pfc_resources[] __initdata = {  	DEFINE_RES_MEM(0xfffc0000, 0x118), @@ -272,7 +270,7 @@ static struct resource hspi_resources[] __initdata = {  	DEFINE_RES_IRQ(gic_iid(0x75)),  }; -void __init r8a7778_register_hspi(int id) +static void __init r8a7778_register_hspi(int id)  {  	BUG_ON(id < 0 || id > 2); @@ -281,62 +279,228 @@ void __init r8a7778_register_hspi(int id)  		hspi_resources + (2 * id), 2);  } -/* VIN */ -#define R8A7778_VIN(idx)						\ -static struct resource vin##idx##_resources[] __initdata = {		\ -	DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000),		\ -	DEFINE_RES_IRQ(gic_iid(0x5a)),					\ -};									\ -									\ -static struct platform_device_info vin##idx##_info __initdata = {	\ -	.parent		= &platform_bus,				\ -	.name		= "r8a7778-vin",				\ -	.id		= idx,						\ -	.res		= vin##idx##_resources,				\ -	.num_res	= ARRAY_SIZE(vin##idx##_resources),		\ -	.dma_mask	= DMA_BIT_MASK(32),				\ -} - -R8A7778_VIN(0); -R8A7778_VIN(1); - -static struct platform_device_info *vin_info_table[] __initdata = { -	&vin0_info, -	&vin1_info, -}; - -void __init r8a7778_add_vin_device(int id, struct rcar_vin_platform_data *pdata) -{ -	BUG_ON(id < 0 || id > 1); - -	vin_info_table[id]->data = pdata; -	vin_info_table[id]->size_data = sizeof(*pdata); - -	platform_device_register_full(vin_info_table[id]); -} -  void __init r8a7778_add_dt_devices(void)  { -	int i; -  #ifdef CONFIG_CACHE_L2X0  	void __iomem *base = ioremap_nocache(0xf0100000, 0x1000);  	if (base) {  		/* -		 * Early BRESP enable, Shared attribute override enable, 64K*16way +		 * Shared attribute override enable, 64K*16way  		 * don't call iounmap(base)  		 */ -		l2x0_init(base, 0x40470000, 0x82000fff); +		l2x0_init(base, 0x00400000, 0xc20f0fff);  	}  #endif -	for (i = 0; i < ARRAY_SIZE(scif_platform_data); i++) -		platform_device_register_data(&platform_bus, "sh-sci", i, -					      &scif_platform_data[i], -					      sizeof(struct plat_sci_port)); - +	r8a7778_register_scif(0); +	r8a7778_register_scif(1); +	r8a7778_register_scif(2); +	r8a7778_register_scif(3); +	r8a7778_register_scif(4); +	r8a7778_register_scif(5);  	r8a7778_register_tmu(0); -	r8a7778_register_tmu(1); +} + +/* HPB-DMA */ + +/* Asynchronous mode register (ASYNCMDR) bits */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK	BIT(2)	/* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE	BIT(2)	/* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI	0	/* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK	BIT(1)	/* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE	BIT(1)	/* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI	0	/* SDHI0 */ + +#define HPBDMA_SSI(_id)				\ +{						\ +	.id	= HPBDMA_SLAVE_SSI## _id ##_TX,	\ +	.addr	= 0xffd91008 + (_id * 0x40),	\ +	.dcr	= HPB_DMAE_DCR_CT |		\ +		  HPB_DMAE_DCR_DIP |		\ +		  HPB_DMAE_DCR_SPDS_32BIT |	\ +		  HPB_DMAE_DCR_DMDL |		\ +		  HPB_DMAE_DCR_DPDS_32BIT,	\ +	.port   = _id + (_id << 8),		\ +	.dma_ch = (28 + _id),			\ +}, {						\ +	.id	= HPBDMA_SLAVE_SSI## _id ##_RX,	\ +	.addr	= 0xffd9100c + (_id * 0x40),	\ +	.dcr	= HPB_DMAE_DCR_CT |		\ +		  HPB_DMAE_DCR_DIP |		\ +		  HPB_DMAE_DCR_SMDL |		\ +		  HPB_DMAE_DCR_SPDS_32BIT |	\ +		  HPB_DMAE_DCR_DPDS_32BIT,	\ +	.port   = _id + (_id << 8),		\ +	.dma_ch = (28 + _id),			\ +} + +#define HPBDMA_HPBIF(_id)				\ +{							\ +	.id	= HPBDMA_SLAVE_HPBIF## _id ##_TX,	\ +	.addr	= 0xffda0000 + (_id * 0x1000),		\ +	.dcr	= HPB_DMAE_DCR_CT |			\ +		  HPB_DMAE_DCR_DIP |			\ +		  HPB_DMAE_DCR_SPDS_32BIT |		\ +		  HPB_DMAE_DCR_DMDL |			\ +		  HPB_DMAE_DCR_DPDS_32BIT,		\ +	.port   = 0x1111,				\ +	.dma_ch = (28 + _id),				\ +}, {							\ +	.id	= HPBDMA_SLAVE_HPBIF## _id ##_RX,	\ +	.addr	= 0xffda0000 + (_id * 0x1000),		\ +	.dcr	= HPB_DMAE_DCR_CT |			\ +		  HPB_DMAE_DCR_DIP |			\ +		  HPB_DMAE_DCR_SMDL |			\ +		  HPB_DMAE_DCR_SPDS_32BIT |		\ +		  HPB_DMAE_DCR_DPDS_32BIT,		\ +	.port   = 0x1111,				\ +	.dma_ch = (28 + _id),				\ +} + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { +	{ +		.id	= HPBDMA_SLAVE_SDHI0_TX, +		.addr	= 0xffe4c000 + 0x30, +		.dcr	= HPB_DMAE_DCR_SPDS_16BIT | +			  HPB_DMAE_DCR_DMDL | +			  HPB_DMAE_DCR_DPDS_16BIT, +		.rstr	= HPB_DMAE_ASYNCRSTR_ASRST21 | +			  HPB_DMAE_ASYNCRSTR_ASRST22 | +			  HPB_DMAE_ASYNCRSTR_ASRST23, +		.mdr	= HPB_DMAE_ASYNCMDR_ASMD21_MULTI, +		.mdm	= HPB_DMAE_ASYNCMDR_ASMD21_MASK, +		.port	= 0x0D0C, +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, +		.dma_ch	= 21, +	}, { +		.id	= HPBDMA_SLAVE_SDHI0_RX, +		.addr	= 0xffe4c000 + 0x30, +		.dcr	= HPB_DMAE_DCR_SMDL | +			  HPB_DMAE_DCR_SPDS_16BIT | +			  HPB_DMAE_DCR_DPDS_16BIT, +		.rstr	= HPB_DMAE_ASYNCRSTR_ASRST21 | +			  HPB_DMAE_ASYNCRSTR_ASRST22 | +			  HPB_DMAE_ASYNCRSTR_ASRST23, +		.mdr	= HPB_DMAE_ASYNCMDR_ASMD22_MULTI, +		.mdm	= HPB_DMAE_ASYNCMDR_ASMD22_MASK, +		.port	= 0x0D0C, +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, +		.dma_ch	= 22, +	}, { +		.id	= HPBDMA_SLAVE_USBFUNC_TX, /* for D0 */ +		.addr	= 0xffe60018, +		.dcr	= HPB_DMAE_DCR_SPDS_32BIT | +			  HPB_DMAE_DCR_DMDL | +			  HPB_DMAE_DCR_DPDS_32BIT, +		.port	= 0x0000, +		.dma_ch	= 14, +	}, { +		.id	= HPBDMA_SLAVE_USBFUNC_RX, /* for D1 */ +		.addr	= 0xffe6001c, +		.dcr	= HPB_DMAE_DCR_SMDL | +			  HPB_DMAE_DCR_SPDS_32BIT | +			  HPB_DMAE_DCR_DPDS_32BIT, +		.port	= 0x0101, +		.dma_ch	= 15, +	}, + +	HPBDMA_SSI(0), +	HPBDMA_SSI(1), +	HPBDMA_SSI(2), +	HPBDMA_SSI(3), +	HPBDMA_SSI(4), +	HPBDMA_SSI(5), +	HPBDMA_SSI(6), +	HPBDMA_SSI(7), +	HPBDMA_SSI(8), + +	HPBDMA_HPBIF(0), +	HPBDMA_HPBIF(1), +	HPBDMA_HPBIF(2), +	HPBDMA_HPBIF(3), +	HPBDMA_HPBIF(4), +	HPBDMA_HPBIF(5), +	HPBDMA_HPBIF(6), +	HPBDMA_HPBIF(7), +	HPBDMA_HPBIF(8), +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { +	HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_TX), /* ch. 14 */ +	HPB_DMAE_CHANNEL(0x7c, HPBDMA_SLAVE_USBFUNC_RX), /* ch. 15 */ +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_TX),   /* ch. 28 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI0_RX),   /* ch. 28 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_TX), /* ch. 28 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF0_RX), /* ch. 28 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_TX),   /* ch. 29 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI1_RX),   /* ch. 29 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_TX), /* ch. 29 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF1_RX), /* ch. 29 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_TX),   /* ch. 30 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI2_RX),   /* ch. 30 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_TX), /* ch. 30 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF2_RX), /* ch. 30 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_TX),   /* ch. 31 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI3_RX),   /* ch. 31 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_TX), /* ch. 31 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF3_RX), /* ch. 31 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_TX),   /* ch. 32 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI4_RX),   /* ch. 32 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_TX), /* ch. 32 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF4_RX), /* ch. 32 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_TX),   /* ch. 33 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI5_RX),   /* ch. 33 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_TX), /* ch. 33 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF5_RX), /* ch. 33 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_TX),   /* ch. 34 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI6_RX),   /* ch. 34 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_TX), /* ch. 34 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF6_RX), /* ch. 34 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_TX),   /* ch. 35 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI7_RX),   /* ch. 35 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_TX), /* ch. 35 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF7_RX), /* ch. 35 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_TX),   /* ch. 36 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_SSI8_RX),   /* ch. 36 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_TX), /* ch. 36 */ +	HPB_DMAE_CHANNEL(0x7f, HPBDMA_SLAVE_HPBIF8_RX), /* ch. 36 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { +	.slaves			= hpb_dmae_slaves, +	.num_slaves		= ARRAY_SIZE(hpb_dmae_slaves), +	.channels		= hpb_dmae_channels, +	.num_channels		= ARRAY_SIZE(hpb_dmae_channels), +	.ts_shift		= { +		[XMIT_SZ_8BIT]	= 0, +		[XMIT_SZ_16BIT]	= 1, +		[XMIT_SZ_32BIT]	= 2, +	}, +	.num_hw_channels	= 39, +}; + +static struct resource hpb_dmae_resources[] __initdata = { +	/* Channel registers */ +	DEFINE_RES_MEM(0xffc08000, 0x1000), +	/* Common registers */ +	DEFINE_RES_MEM(0xffc09000, 0x170), +	/* Asynchronous reset registers */ +	DEFINE_RES_MEM(0xffc00300, 4), +	/* Asynchronous mode registers */ +	DEFINE_RES_MEM(0xffc00400, 4), +	/* IRQ for DMA channels */ +	DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7778_register_hpb_dmae(void) +{ +	platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, +					  hpb_dmae_resources, +					  ARRAY_SIZE(hpb_dmae_resources), +					  &dma_platform_data, +					  sizeof(dma_platform_data));  }  void __init r8a7778_add_standard_devices(void) @@ -349,12 +513,12 @@ void __init r8a7778_add_standard_devices(void)  	r8a7778_register_hspi(0);  	r8a7778_register_hspi(1);  	r8a7778_register_hspi(2); + +	r8a7778_register_hpb_dmae();  }  void __init r8a7778_init_late(void)  { -	phy = usb_get_phy(USB_PHY_TYPE_USB2); -  	platform_device_register_full(&ehci_info);  	platform_device_register_full(&ohci_info);  } @@ -376,7 +540,7 @@ static struct resource irqpin_resources[] __initdata = {  	DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */  }; -void __init r8a7778_init_irq_extpin(int irlm) +void __init r8a7778_init_irq_extpin_dt(int irlm)  {  	void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);  	unsigned long tmp; @@ -394,7 +558,11 @@ void __init r8a7778_init_irq_extpin(int irlm)  	tmp |= (1 << 21); /* LVLMODE = 1 */  	iowrite32(tmp, icr0);  	iounmap(icr0); +} +void __init r8a7778_init_irq_extpin(int irlm) +{ +	r8a7778_init_irq_extpin_dt(irlm);  	if (irlm)  		platform_device_register_resndata(  			&platform_bus, "renesas_intc_irqpin", -1,  | 
