Path: blob/master/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
26498 views
// SPDX-License-Identifier: GPL-2.01/*2* SH7780 Setup3*4* Copyright (C) 2006 Paul Mundt5*/6#include <linux/platform_device.h>7#include <linux/init.h>8#include <linux/serial.h>9#include <linux/io.h>10#include <linux/serial_sci.h>11#include <linux/sh_dma.h>12#include <linux/sh_timer.h>13#include <linux/sh_intc.h>14#include <cpu/dma-register.h>15#include <asm/platform_early.h>1617static struct plat_sci_port scif0_platform_data = {18.scscr = SCSCR_REIE | SCSCR_CKE1,19.type = PORT_SCIF,20.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,21};2223static struct resource scif0_resources[] = {24DEFINE_RES_MEM(0xffe00000, 0x100),25DEFINE_RES_IRQ(evt2irq(0x700)),26};2728static struct platform_device scif0_device = {29.name = "sh-sci",30.id = 0,31.resource = scif0_resources,32.num_resources = ARRAY_SIZE(scif0_resources),33.dev = {34.platform_data = &scif0_platform_data,35},36};3738static struct plat_sci_port scif1_platform_data = {39.scscr = SCSCR_REIE | SCSCR_CKE1,40.type = PORT_SCIF,41.regtype = SCIx_SH4_SCIF_FIFODATA_REGTYPE,42};4344static struct resource scif1_resources[] = {45DEFINE_RES_MEM(0xffe10000, 0x100),46DEFINE_RES_IRQ(evt2irq(0xb80)),47};4849static struct platform_device scif1_device = {50.name = "sh-sci",51.id = 1,52.resource = scif1_resources,53.num_resources = ARRAY_SIZE(scif1_resources),54.dev = {55.platform_data = &scif1_platform_data,56},57};5859static struct sh_timer_config tmu0_platform_data = {60.channels_mask = 7,61};6263static struct resource tmu0_resources[] = {64DEFINE_RES_MEM(0xffd80000, 0x30),65DEFINE_RES_IRQ(evt2irq(0x580)),66DEFINE_RES_IRQ(evt2irq(0x5a0)),67DEFINE_RES_IRQ(evt2irq(0x5c0)),68};6970static struct platform_device tmu0_device = {71.name = "sh-tmu",72.id = 0,73.dev = {74.platform_data = &tmu0_platform_data,75},76.resource = tmu0_resources,77.num_resources = ARRAY_SIZE(tmu0_resources),78};7980static struct sh_timer_config tmu1_platform_data = {81.channels_mask = 7,82};8384static struct resource tmu1_resources[] = {85DEFINE_RES_MEM(0xffdc0000, 0x2c),86DEFINE_RES_IRQ(evt2irq(0xe00)),87DEFINE_RES_IRQ(evt2irq(0xe20)),88DEFINE_RES_IRQ(evt2irq(0xe40)),89};9091static struct platform_device tmu1_device = {92.name = "sh-tmu",93.id = 1,94.dev = {95.platform_data = &tmu1_platform_data,96},97.resource = tmu1_resources,98.num_resources = ARRAY_SIZE(tmu1_resources),99};100101static struct resource rtc_resources[] = {102[0] = {103.start = 0xffe80000,104.end = 0xffe80000 + 0x58 - 1,105.flags = IORESOURCE_IO,106},107[1] = {108/* Shared Period/Carry/Alarm IRQ */109.start = evt2irq(0x480),110.flags = IORESOURCE_IRQ,111},112};113114static struct platform_device rtc_device = {115.name = "sh-rtc",116.id = -1,117.num_resources = ARRAY_SIZE(rtc_resources),118.resource = rtc_resources,119};120121/* DMA */122static const struct sh_dmae_channel sh7780_dmae0_channels[] = {123{124.offset = 0,125.dmars = 0,126.dmars_bit = 0,127}, {128.offset = 0x10,129.dmars = 0,130.dmars_bit = 8,131}, {132.offset = 0x20,133.dmars = 4,134.dmars_bit = 0,135}, {136.offset = 0x30,137.dmars = 4,138.dmars_bit = 8,139}, {140.offset = 0x50,141.dmars = 8,142.dmars_bit = 0,143}, {144.offset = 0x60,145.dmars = 8,146.dmars_bit = 8,147}148};149150static const struct sh_dmae_channel sh7780_dmae1_channels[] = {151{152.offset = 0,153}, {154.offset = 0x10,155}, {156.offset = 0x20,157}, {158.offset = 0x30,159}, {160.offset = 0x50,161}, {162.offset = 0x60,163}164};165166static const unsigned int ts_shift[] = TS_SHIFT;167168static struct sh_dmae_pdata dma0_platform_data = {169.channel = sh7780_dmae0_channels,170.channel_num = ARRAY_SIZE(sh7780_dmae0_channels),171.ts_low_shift = CHCR_TS_LOW_SHIFT,172.ts_low_mask = CHCR_TS_LOW_MASK,173.ts_high_shift = CHCR_TS_HIGH_SHIFT,174.ts_high_mask = CHCR_TS_HIGH_MASK,175.ts_shift = ts_shift,176.ts_shift_num = ARRAY_SIZE(ts_shift),177.dmaor_init = DMAOR_INIT,178};179180static struct sh_dmae_pdata dma1_platform_data = {181.channel = sh7780_dmae1_channels,182.channel_num = ARRAY_SIZE(sh7780_dmae1_channels),183.ts_low_shift = CHCR_TS_LOW_SHIFT,184.ts_low_mask = CHCR_TS_LOW_MASK,185.ts_high_shift = CHCR_TS_HIGH_SHIFT,186.ts_high_mask = CHCR_TS_HIGH_MASK,187.ts_shift = ts_shift,188.ts_shift_num = ARRAY_SIZE(ts_shift),189.dmaor_init = DMAOR_INIT,190};191192static struct resource sh7780_dmae0_resources[] = {193[0] = {194/* Channel registers and DMAOR */195.start = 0xfc808020,196.end = 0xfc80808f,197.flags = IORESOURCE_MEM,198},199[1] = {200/* DMARSx */201.start = 0xfc809000,202.end = 0xfc80900b,203.flags = IORESOURCE_MEM,204},205{206/*207* Real DMA error vector is 0x6c0, and channel208* vectors are 0x640-0x6a0, 0x780-0x7a0209*/210.name = "error_irq",211.start = evt2irq(0x640),212.end = evt2irq(0x640),213.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,214},215};216217static struct resource sh7780_dmae1_resources[] = {218[0] = {219/* Channel registers and DMAOR */220.start = 0xfc818020,221.end = 0xfc81808f,222.flags = IORESOURCE_MEM,223},224/* DMAC1 has no DMARS */225{226/*227* Real DMA error vector is 0x6c0, and channel228* vectors are 0x7c0-0x7e0, 0xd80-0xde0229*/230.name = "error_irq",231.start = evt2irq(0x7c0),232.end = evt2irq(0x7c0),233.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE,234},235};236237static struct platform_device dma0_device = {238.name = "sh-dma-engine",239.id = 0,240.resource = sh7780_dmae0_resources,241.num_resources = ARRAY_SIZE(sh7780_dmae0_resources),242.dev = {243.platform_data = &dma0_platform_data,244},245};246247static struct platform_device dma1_device = {248.name = "sh-dma-engine",249.id = 1,250.resource = sh7780_dmae1_resources,251.num_resources = ARRAY_SIZE(sh7780_dmae1_resources),252.dev = {253.platform_data = &dma1_platform_data,254},255};256257static struct platform_device *sh7780_devices[] __initdata = {258&scif0_device,259&scif1_device,260&tmu0_device,261&tmu1_device,262&rtc_device,263&dma0_device,264&dma1_device,265};266267static int __init sh7780_devices_setup(void)268{269return platform_add_devices(sh7780_devices,270ARRAY_SIZE(sh7780_devices));271}272arch_initcall(sh7780_devices_setup);273274static struct platform_device *sh7780_early_devices[] __initdata = {275&scif0_device,276&scif1_device,277&tmu0_device,278&tmu1_device,279};280281void __init plat_early_device_setup(void)282{283if (mach_is_sh2007()) {284scif0_platform_data.scscr &= ~SCSCR_CKE1;285scif1_platform_data.scscr &= ~SCSCR_CKE1;286}287288sh_early_platform_add_devices(sh7780_early_devices,289ARRAY_SIZE(sh7780_early_devices));290}291292enum {293UNUSED = 0,294295/* interrupt sources */296297IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,298IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,299IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,300IRL_HHLL, IRL_HHLH, IRL_HHHL,301302IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,303RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,304HUDI, DMAC0, SCIF0, DMAC1, CMT, HAC,305PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,306SCIF1, SIOF, HSPI, MMCIF, TMU3, TMU4, TMU5, SSI, FLCTL, GPIO,307308/* interrupt groups */309310TMU012, TMU345,311};312313static struct intc_vect vectors[] __initdata = {314INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),315INTC_VECT(RTC, 0x4c0),316INTC_VECT(WDT, 0x560),317INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),318INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),319INTC_VECT(HUDI, 0x600),320INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),321INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),322INTC_VECT(DMAC0, 0x6c0),323INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),324INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),325INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),326INTC_VECT(DMAC1, 0x7c0), INTC_VECT(DMAC1, 0x7e0),327INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980),328INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),329INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),330INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),331INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),332INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),333INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),334INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),335INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80),336INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),337INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),338INTC_VECT(DMAC1, 0xd80), INTC_VECT(DMAC1, 0xda0),339INTC_VECT(DMAC1, 0xdc0), INTC_VECT(DMAC1, 0xde0),340INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),341INTC_VECT(TMU5, 0xe40),342INTC_VECT(SSI, 0xe80),343INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),344INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),345INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),346INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),347};348349static struct intc_group groups[] __initdata = {350INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),351INTC_GROUP(TMU345, TMU3, TMU4, TMU5),352};353354static struct intc_mask_reg mask_registers[] __initdata = {355{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */356{ 0, 0, 0, 0, 0, 0, GPIO, FLCTL,357SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB,358PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0,359HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } },360};361362static struct intc_prio_reg prio_registers[] __initdata = {363{ 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1,364TMU2, TMU2_TICPI } },365{ 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } },366{ 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } },367{ 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } },368{ 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC,369PCISERR, PCIINTA, } },370{ 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC,371PCIINTD, PCIC5 } },372{ 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } },373{ 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } },374};375376static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups,377mask_registers, prio_registers, NULL);378379/* Support for external interrupt pins in IRQ mode */380381static struct intc_vect irq_vectors[] __initdata = {382INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),383INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),384INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),385INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),386};387388static struct intc_mask_reg irq_mask_registers[] __initdata = {389{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */390{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },391};392393static struct intc_prio_reg irq_prio_registers[] __initdata = {394{ 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,395IRQ4, IRQ5, IRQ6, IRQ7 } },396};397398static struct intc_sense_reg irq_sense_registers[] __initdata = {399{ 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,400IRQ4, IRQ5, IRQ6, IRQ7 } },401};402403static struct intc_mask_reg irq_ack_registers[] __initdata = {404{ 0xffd00024, 0, 32, /* INTREQ */405{ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },406};407408static DECLARE_INTC_DESC_ACK(intc_irq_desc, "sh7780-irq", irq_vectors,409NULL, irq_mask_registers, irq_prio_registers,410irq_sense_registers, irq_ack_registers);411412/* External interrupt pins in IRL mode */413414static struct intc_vect irl_vectors[] __initdata = {415INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),416INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),417INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),418INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),419INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),420INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),421INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),422INTC_VECT(IRL_HHHL, 0x3c0),423};424425static struct intc_mask_reg irl3210_mask_registers[] __initdata = {426{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */427{ IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,428IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,429IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,430IRL_HHLL, IRL_HHLH, IRL_HHHL, } },431};432433static struct intc_mask_reg irl7654_mask_registers[] __initdata = {434{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */435{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,436IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,437IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,438IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,439IRL_HHLL, IRL_HHLH, IRL_HHHL, } },440};441442static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors,443NULL, irl7654_mask_registers, NULL, NULL);444445static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors,446NULL, irl3210_mask_registers, NULL, NULL);447448#define INTC_ICR0 0xffd00000449#define INTC_INTMSK0 0xffd00044450#define INTC_INTMSK1 0xffd00048451#define INTC_INTMSK2 0xffd40080452#define INTC_INTMSKCLR1 0xffd00068453#define INTC_INTMSKCLR2 0xffd40084454455void __init plat_irq_setup(void)456{457/* disable IRQ7-0 */458__raw_writel(0xff000000, INTC_INTMSK0);459460/* disable IRL3-0 + IRL7-4 */461__raw_writel(0xc0000000, INTC_INTMSK1);462__raw_writel(0xfffefffe, INTC_INTMSK2);463464/* select IRL mode for IRL3-0 + IRL7-4 */465__raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);466467/* disable holding function, ie enable "SH-4 Mode" */468__raw_writel(__raw_readl(INTC_ICR0) | 0x00200000, INTC_ICR0);469470register_intc_controller(&intc_desc);471}472473void __init plat_irq_setup_pins(int mode)474{475switch (mode) {476case IRQ_MODE_IRQ:477/* select IRQ mode for IRL3-0 + IRL7-4 */478__raw_writel(__raw_readl(INTC_ICR0) | 0x00c00000, INTC_ICR0);479register_intc_controller(&intc_irq_desc);480break;481case IRQ_MODE_IRL7654:482/* enable IRL7-4 but don't provide any masking */483__raw_writel(0x40000000, INTC_INTMSKCLR1);484__raw_writel(0x0000fffe, INTC_INTMSKCLR2);485break;486case IRQ_MODE_IRL3210:487/* enable IRL0-3 but don't provide any masking */488__raw_writel(0x80000000, INTC_INTMSKCLR1);489__raw_writel(0xfffe0000, INTC_INTMSKCLR2);490break;491case IRQ_MODE_IRL7654_MASK:492/* enable IRL7-4 and mask using cpu intc controller */493__raw_writel(0x40000000, INTC_INTMSKCLR1);494register_intc_controller(&intc_irl7654_desc);495break;496case IRQ_MODE_IRL3210_MASK:497/* enable IRL0-3 and mask using cpu intc controller */498__raw_writel(0x80000000, INTC_INTMSKCLR1);499register_intc_controller(&intc_irl3210_desc);500break;501default:502BUG();503}504}505506507