diff options
Diffstat (limited to 'arch/sh/kernel/cpu/sh4a')
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 15 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-shx3.c | 135 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 185 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 216 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 18 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-shx3.c | 85 |
7 files changed, 603 insertions, 53 deletions
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index ab7422f8f82..40062328648 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o +obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o @@ -17,5 +18,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o +clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 51b386d454d..a0fd8bb21f7 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -387,9 +387,24 @@ out_err: return err; } +static long sh7722_frqcr_round_rate(struct clk *clk, unsigned long rate) +{ + unsigned long parent_rate = clk->parent->rate; + int div; + + /* look for multiplier/divisor pair */ + div = sh7722_find_divisors(parent_rate, rate); + if (div < 0) + return clk->rate; + + /* calculate new value of clock rate */ + return parent_rate * 2 / div; +} + static struct clk_ops sh7722_frqcr_clk_ops = { .recalc = sh7722_frqcr_recalc, .set_rate = sh7722_frqcr_set_rate, + .round_rate = sh7722_frqcr_round_rate, }; /* diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c new file mode 100644 index 00000000000..c630b29e06a --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c @@ -0,0 +1,135 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-shx3.c + * + * SH-X3 support for the clock framework + * + * Copyright (C) 2006-2007 Renesas Technology Corp. + * Copyright (C) 2006-2007 Renesas Solutions Corp. + * Copyright (C) 2006-2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <asm/clock.h> +#include <asm/freq.h> +#include <asm/io.h> + +static int ifc_divisors[] = { 1, 2, 4 ,6 }; +static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 }; +static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, 24, 32, 36, 48 }; +static int cfc_divisors[] = { 1, 1, 4, 6 }; + +#define IFC_POS 28 +#define IFC_MSK 0x0003 +#define BFC_MSK 0x000f +#define PFC_MSK 0x000f +#define CFC_MSK 0x0003 +#define BFC_POS 16 +#define PFC_POS 0 +#define CFC_POS 20 + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK]; +} + +static struct clk_ops shx3_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> PFC_POS) & PFC_MSK); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops shx3_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> BFC_POS) & BFC_MSK); + clk->rate = clk->parent->rate / bfc_divisors[idx]; +} + +static struct clk_ops shx3_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> IFC_POS) & IFC_MSK); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops shx3_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *shx3_clk_ops[] = { + &shx3_master_clk_ops, + &shx3_module_clk_ops, + &shx3_bus_clk_ops, + &shx3_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(shx3_clk_ops)) + *ops = shx3_clk_ops[idx]; +} + +static void shyway_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> CFC_POS) & CFC_MSK); + clk->rate = clk->parent->rate / cfc_divisors[idx]; +} + +static struct clk_ops shx3_shyway_clk_ops = { + .recalc = shyway_clk_recalc, +}; + +static struct clk shx3_shyway_clk = { + .name = "shyway_clk", + .flags = CLK_ALWAYS_ENABLED, + .ops = &shx3_shyway_clk_ops, +}; + +/* + * Additional SHx3-specific on-chip clocks that aren't already part of the + * clock framework + */ +static struct clk *shx3_onchip_clocks[] = { + &shx3_shyway_clk, +}; + +static int __init shx3_clk_init(void) +{ + struct clk *clk = clk_get(NULL, "master_clk"); + int i; + + for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) { + struct clk *clkp = shx3_onchip_clocks[i]; + + clkp->parent = clk; + clk_register(clkp); + clk_enable(clkp); + } + + /* + * Now that we have the rest of the clocks registered, we need to + * force the parent clock to propagate so that these clocks will + * automatically figure out their rate. We cheat by handing the + * parent clock its current rate and forcing child propagation. + */ + clk_set_rate(clk, clk_get_rate(clk)); + + clk_put(clk); + + return 0; +} +arch_initcall(shx3_clk_init); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 1143fbf65fa..25b913e07e2 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -1,7 +1,7 @@ /* * SH7722 Setup * - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006 - 2007 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -10,6 +10,8 @@ #include <linux/platform_device.h> #include <linux/init.h> #include <linux/serial.h> +#include <linux/mm.h> +#include <asm/mmzone.h> #include <asm/sci.h> static struct plat_sci_port sci_platform_data[] = { @@ -17,8 +19,21 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 80, 81, 83, 82 }, - }, { + .irqs = { 80, 80, 80, 80 }, + }, + { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + }, + { + .mapbase = 0xffe20000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 82, 82, 82, 82 }, + }, + { .flags = 0, } }; @@ -42,39 +57,149 @@ static int __init sh7722_devices_setup(void) } __initcall(sh7722_devices_setup); -static struct ipr_data sh7722_ipr_map[] = { - /* IRQ, IPR-idx, shift, prio */ - { 16, 0, 12, 2 }, /* TMU0 */ - { 17, 0, 8, 2 }, /* TMU1 */ - { 80, 6, 12, 3 }, /* SCIF ERI */ - { 81, 6, 12, 3 }, /* SCIF RXI */ - { 82, 6, 12, 3 }, /* SCIF BRI */ - { 83, 6, 12, 3 }, /* SCIF TXI */ +enum { + UNUSED=0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, + HUDI, + SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI, + RTC_ATI, RTC_PRI, RTC_CUI, + DMAC0, DMAC1, DMAC2, DMAC3, + VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU, + VPU, TPU, + USB_USBI0, USB_USBI1, + DMAC4, DMAC5, DMAC_DADERR, + KEYSC, + SCIF0, SCIF1, SCIF2, SIOF0, SIOF1, SIO, + FLCTL_FLSTEI, FLCTL_FLENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I, + I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI, + SDHI0, SDHI1, SDHI2, SDHI3, + CMT, TSIF, SIU, TWODG, + TMU0, TMU1, TMU2, + IRDA, JPU, LCDC, + + /* interrupt groups */ + + SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI, +}; + +static struct intc_vect vectors[] = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0), + INTC_VECT(SIM_ERI, 0x700), INTC_VECT(SIM_RXI, 0x720), + INTC_VECT(SIM_TXI, 0x740), INTC_VECT(SIM_TEI, 0x760), + INTC_VECT(RTC_ATI, 0x780), INTC_VECT(RTC_PRI, 0x7a0), + INTC_VECT(RTC_CUI, 0x7c0), + INTC_VECT(DMAC0, 0x800), INTC_VECT(DMAC1, 0x820), + INTC_VECT(DMAC2, 0x840), INTC_VECT(DMAC3, 0x860), + INTC_VECT(VIO_CEUI, 0x880), INTC_VECT(VIO_BEUI, 0x8a0), + INTC_VECT(VIO_VEUI, 0x8c0), INTC_VECT(VOU, 0x8e0), + INTC_VECT(VPU, 0x980), INTC_VECT(TPU, 0x9a0), + INTC_VECT(USB_USBI0, 0xa20), INTC_VECT(USB_USBI1, 0xa40), + INTC_VECT(DMAC4, 0xb80), INTC_VECT(DMAC5, 0xba0), + INTC_VECT(DMAC_DADERR, 0xbc0), INTC_VECT(KEYSC, 0xbe0), + INTC_VECT(SCIF0, 0xc00), INTC_VECT(SCIF1, 0xc20), + INTC_VECT(SCIF2, 0xc40), INTC_VECT(SIOF0, 0xc80), + INTC_VECT(SIOF1, 0xca0), INTC_VECT(SIO, 0xd00), + INTC_VECT(FLCTL_FLSTEI, 0xd80), INTC_VECT(FLCTL_FLENDI, 0xda0), + INTC_VECT(FLCTL_FLTREQ0I, 0xdc0), INTC_VECT(FLCTL_FLTREQ1I, 0xde0), + INTC_VECT(I2C_ALI, 0xe00), INTC_VECT(I2C_TACKI, 0xe20), + INTC_VECT(I2C_WAITI, 0xe40), INTC_VECT(I2C_DTEI, 0xe60), + INTC_VECT(SDHI0, 0xe80), INTC_VECT(SDHI1, 0xea0), + INTC_VECT(SDHI2, 0xec0), INTC_VECT(SDHI3, 0xee0), + INTC_VECT(CMT, 0xf00), INTC_VECT(TSIF, 0xf20), + INTC_VECT(SIU, 0xf80), INTC_VECT(TWODG, 0xfa0), + INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), + INTC_VECT(TMU2, 0x440), INTC_VECT(IRDA, 0x480), + INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580), +}; + +static struct intc_group groups[] = { + INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI), + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3), + INTC_GROUP(VIOVOU, VIO_CEUI, VIO_BEUI, VIO_VEUI, VOU), + INTC_GROUP(USB, USB_USBI0, USB_USBI1), + INTC_GROUP(DMAC45, DMAC4, DMAC5, DMAC_DADERR), + INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLENDI, + FLCTL_FLTREQ0I, FLCTL_FLTREQ1I), + INTC_GROUP(I2C, I2C_ALI, I2C_TACKI, I2C_WAITI, I2C_DTEI), + INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), +}; + +static struct intc_prio priorities[] = { + INTC_PRIO(SCIF0, 3), + INTC_PRIO(SCIF1, 3), + INTC_PRIO(SCIF2, 3), + INTC_PRIO(TMU0, 2), + INTC_PRIO(TMU1, 2), +}; + +static struct intc_mask_reg mask_registers[] = { + { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ + { } }, + { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ + { VOU, VIO_VEUI, VIO_BEUI, VIO_CEUI, DMAC3, DMAC2, DMAC1, DMAC0 } }, + { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ + { 0, 0, 0, VPU, } }, + { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */ + { SIM_TEI, SIM_TXI, SIM_RXI, SIM_ERI, 0, 0, 0, IRDA } }, + { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */ + { 0, TMU2, TMU1, TMU0, JPU, 0, 0, LCDC } }, + { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */ + { KEYSC, DMAC_DADERR, DMAC5, DMAC4, 0, SCIF2, SCIF1, SCIF0 } }, + { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */ + { 0, 0, 0, SIO, 0, 0, SIOF1, SIOF0 } }, + { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */ + { I2C_DTEI, I2C_WAITI, I2C_TACKI, I2C_ALI, + FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLENDI, FLCTL_FLSTEI } }, + { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ + { SDHI3, SDHI2, SDHI1, SDHI0, 0, 0, TWODG, SIU } }, + { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ + { 0, 0, 0, CMT, 0, USB_USBI1, USB_USBI0, } }, + { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ + { } }, + { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */ + { 0, RTC_CUI, RTC_PRI, RTC_ATI, 0, TPU, 0, TSIF } }, + { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static unsigned long ipr_offsets[] = { - 0xa4080000, /* 0: IPRA */ - 0xa4080004, /* 1: IPRB */ - 0xa4080008, /* 2: IPRC */ - 0xa408000c, /* 3: IPRD */ - 0xa4080010, /* 4: IPRE */ - 0xa4080014, /* 5: IPRF */ - 0xa4080018, /* 6: IPRG */ - 0xa408001c, /* 7: IPRH */ - 0xa4080020, /* 8: IPRI */ - 0xa4080024, /* 9: IPRJ */ - 0xa4080028, /* 10: IPRK */ - 0xa408002c, /* 11: IPRL */ +static struct intc_prio_reg prio_registers[] = { + { 0xa4080000, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, + { 0xa4080004, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, + { 0xa4080008, 16, 4, /* IPRC */ { } }, + { 0xa408000c, 16, 4, /* IPRD */ { } }, + { 0xa4080010, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, + { 0xa4080014, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, + { 0xa4080018, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, + { 0xa408001c, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, + { 0xa4080020, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, + { 0xa4080024, 16, 4, /* IPRJ */ { 0, 0, SIU } }, + { 0xa4080028, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, + { 0xa408002c, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, + { 0xa4140010, 32, 4, /* INTPRI00 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -unsigned int map_ipridx_to_addr(int idx) +static struct intc_sense_reg sense_registers[] = { + { 0xa414001c, 16, 2, /* ICR1 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7722", vectors, groups, priorities, + mask_registers, prio_registers, sense_registers); + +void __init plat_irq_setup(void) { - if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) - return 0; - return ipr_offsets[idx]; + register_intc_controller(&intc_desc); } -void __init init_IRQ_ipr(void) +void __init plat_mem_setup(void) { - make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); + /* Register the URAM space as Node 1 */ + setup_bootmem_node(1, 0x055f0000, 0x05610000); } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 9aeaa2ddaa2..a4127ec1520 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -30,7 +30,7 @@ static struct resource rtc_resources[] = { }, [3] = { /* Alarm IRQ */ - .start = 23, + .start = 20, .flags = IORESOURCE_IRQ, }, }; @@ -78,31 +78,205 @@ static int __init sh7780_devices_setup(void) } __initcall(sh7780_devices_setup); -static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ +enum { + UNUSED = 0, - { 21, 1, 0, 0, 2, 2 }, - { 22, 1, 1, 0, 2, 2 }, - { 23, 1, 2, 0, 2, 2 }, + /* interrupt sources */ - { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ - { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ - { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ - { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ + IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, + IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, + IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, + IRL_HHLL, IRL_HHLH, IRL_HHHL, - { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ - { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ - { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ - { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, + RTC_ATI, RTC_PRI, RTC_CUI, + WDT, + TMU0, TMU1, TMU2, TMU2_TICPI, + HUDI, + DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + DMAC0_DMINT4, DMAC0_DMINT5, DMAC1_DMINT6, DMAC1_DMINT7, + CMT, HAC, + PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, + PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + SIOF, HSPI, + MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY, + DMAC1_DMINT8, DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, + TMU3, TMU4, TMU5, + SSI, + FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1, + GPIOI0, GPIOI1, GPIOI2, GPIOI3, - { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ - { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ - { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ - { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ - { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ + /* interrupt groups */ + + RTC, TMU012, DMAC0, SCIF0, DMAC45, DMAC1, + PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO, +}; + +static struct intc_vect vectors[] = { + INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), + INTC_VECT(RTC_CUI, 0x4c0), + INTC_VECT(WDT, 0x560), + INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0), + INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0), + INTC_VECT(HUDI, 0x600), + INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660), + INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0), + INTC_VECT(DMAC0_DMAE, 0x6c0), + INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720), + INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), + INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0), + INTC_VECT(DMAC1_DMINT6, 0x7c0), INTC_VECT(DMAC1_DMINT7, 0x7e0), + INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980), + INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20), + INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60), + INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0), + INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0), + INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20), + INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0), + INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0), + INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80), + INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20), + INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60), + INTC_VECT(DMAC1_DMINT8, 0xd80), INTC_VECT(DMAC1_DMINT9, 0xda0), + INTC_VECT(DMAC1_DMINT10, 0xdc0), INTC_VECT(DMAC1_DMINT11, 0xde0), + INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20), + INTC_VECT(TMU5, 0xe40), + INTC_VECT(SSI, 0xe80), + INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20), + INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60), + INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0), + INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), +}; + +static struct intc_group groups[] = { + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), + INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, + DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, + DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11), + INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0), + INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), + INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY), + INTC_GROUP(TMU345, TMU3, TMU4, TMU5), + INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND, + FLCTL_FLTRQ0, FLCTL_FLTRQ1), + INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), +}; + +static struct intc_prio priorities[] = { + INTC_PRIO(SCIF0, 3), + INTC_PRIO(SCIF1, 3), +}; + +static struct intc_mask_reg mask_registers[] = { + { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ + { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, + SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, + PCIINTA, PCISERR, HAC, CMT, 0, 0, DMAC1, DMAC0, + HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, }; -void __init init_IRQ_intc2(void) +static struct intc_prio_reg prio_registers[] = { + { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, + { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, + { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, + { 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, + { 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } }, + { 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, + PCIINTD, PCIC5 } }, + { 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, + { 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, + mask_registers, prio_registers, NULL); + +/* Support for external interrupt pins in IRQ mode */ + +static struct intc_vect irq_vectors[] = { + INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), + INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), + INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), + INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), +}; + +static struct intc_mask_reg irq_mask_registers[] = { + { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static struct intc_prio_reg irq_prio_registers[] = { + { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static struct intc_sense_reg irq_sense_registers[] = { + { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, + NULL, NULL, irq_mask_registers, irq_prio_registers, + irq_sense_registers); + +/* External interrupt pins in IRL mode */ + +static struct intc_vect irl_vectors[] = { + INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), + INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), + INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), + INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0), + INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320), + INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360), + INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0), + INTC_VECT(IRL_HHHL, 0x3c0), +}; + +static struct intc_mask_reg irl3210_mask_registers[] = { + { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ + { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, + IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, + IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, + IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, +}; + +static struct intc_mask_reg irl7654_mask_registers[] = { + { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, + IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, + IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, + IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, +}; + +static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors, + NULL, NULL, irl7654_mask_registers, NULL, NULL); + +static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, + NULL, NULL, irl3210_mask_registers, NULL, NULL); + +void __init plat_irq_setup(void) { - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); + register_intc_controller(&intc_desc); +} + +void __init plat_irq_setup_pins(int mode) +{ + switch (mode) { + case IRQ_MODE_IRQ: + register_intc_controller(&intc_irq_desc); + break; + case IRQ_MODE_IRL7654: + register_intc_controller(&intc_irl7654_desc); + break; + case IRQ_MODE_IRL3210: + register_intc_controller(&intc_irl3210_desc); + break; + default: + BUG(); + } } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 07b0de82cfe..cf047562e43 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -97,7 +97,21 @@ static struct intc2_data intc2_irq_table[] = { { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ }; -void __init init_IRQ_intc2(void) +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0xffd40000, + .msk_base = 0xffd40038, + .mskclr_base = 0xffd4003c, + + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), + + .chip = { + .name = "INTC2-sh7785", + }, +}; + +void __init plat_irq_setup(void) { - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); + register_intc2_controller(&intc2_irq_desc); } + diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c new file mode 100644 index 00000000000..704c064f70d --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -0,0 +1,85 @@ +/* + * SH-X3 Setup + * + * Copyright (C) 2007 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/platform_device.h> +#include <linux/init.h> +#include <linux/serial.h> +#include <linux/io.h> +#include <asm/sci.h> + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffc30000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, + }, { + .mapbase = 0xffc40000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 44, 45, 47, 46 }, + }, { + .mapbase = 0xffc50000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 48, 49, 51, 50 }, + }, { + .mapbase = 0xffc60000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 52, 53, 55, 54 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *shx3_devices[] __initdata = { + &sci_device, +}; + +static int __init shx3_devices_setup(void) +{ + return platform_add_devices(shx3_devices, + ARRAY_SIZE(shx3_devices)); +} +__initcall(shx3_devices_setup); + +static struct intc2_data intc2_irq_table[] = { + { 16, 0, 0, 0, 1, 2 }, /* TMU0 */ + { 40, 4, 0, 0x20, 0, 3 }, /* SCIF0 ERI */ + { 41, 4, 0, 0x20, 1, 3 }, /* SCIF0 RXI */ + { 42, 4, 0, 0x20, 2, 3 }, /* SCIF0 BRI */ + { 43, 4, 0, 0x20, 3, 3 }, /* SCIF0 TXI */ +}; + +static struct intc2_desc intc2_irq_desc __read_mostly = { + .prio_base = 0xfe410000, + .msk_base = 0xfe410820, + .mskclr_base = 0xfe410850, + + .intc2_data = intc2_irq_table, + .nr_irqs = ARRAY_SIZE(intc2_irq_table), + + .chip = { + .name = "INTC2-SHX3", + }, +}; + +void __init plat_irq_setup(void) +{ + register_intc2_controller(&intc2_irq_desc); +} |