From 41504c39726a7099e5a42508dd57fe561c8b4129 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 11 Dec 2006 20:28:03 +0900 Subject: sh: SH-MobileR SH7722 CPU support. This adds CPU support for the SH7722. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/Makefile | 1 + arch/sh/kernel/cpu/sh4/Makefile | 9 +-- arch/sh/kernel/cpu/sh4/clock-sh73180.c | 81 -------------------- arch/sh/kernel/cpu/sh4/clock-sh7770.c | 73 ------------------ arch/sh/kernel/cpu/sh4/clock-sh7780.c | 126 -------------------------------- arch/sh/kernel/cpu/sh4/probe.c | 9 +++ arch/sh/kernel/cpu/sh4/setup-sh73180.c | 43 ----------- arch/sh/kernel/cpu/sh4/setup-sh7343.c | 43 ----------- arch/sh/kernel/cpu/sh4/setup-sh7770.c | 53 -------------- arch/sh/kernel/cpu/sh4/setup-sh7780.c | 108 --------------------------- arch/sh/kernel/cpu/sh4a/Makefile | 19 +++++ arch/sh/kernel/cpu/sh4a/clock-sh73180.c | 81 ++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 99 +++++++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/clock-sh7770.c | 73 ++++++++++++++++++ arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 126 ++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh73180.c | 43 +++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 43 +++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 76 +++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 53 ++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 108 +++++++++++++++++++++++++++ arch/sh/kernel/setup.c | 14 ++-- arch/sh/mm/Kconfig | 12 ++- drivers/serial/sh-sci.c | 22 ++++++ drivers/serial/sh-sci.h | 14 ++++ include/asm-sh/bugs.h | 12 ++- include/asm-sh/cpu-sh4/cache.h | 2 +- include/asm-sh/cpu-sh4/freq.h | 2 +- include/asm-sh/irq.h | 5 +- include/asm-sh/processor.h | 8 +- 29 files changed, 811 insertions(+), 547 deletions(-) delete mode 100644 arch/sh/kernel/cpu/sh4/clock-sh73180.c delete mode 100644 arch/sh/kernel/cpu/sh4/clock-sh7770.c delete mode 100644 arch/sh/kernel/cpu/sh4/clock-sh7780.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh73180.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh7343.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh7770.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh7780.c create mode 100644 arch/sh/kernel/cpu/sh4a/Makefile create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh73180.c create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7343.c create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7770.c create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7780.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh73180.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7343.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7722.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7770.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7780.c diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 0582e6712b7..d055a3ea6b4 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_CPU_SH2) = sh2/ obj-$(CONFIG_CPU_SH2A) = sh2a/ obj-$(CONFIG_CPU_SH3) = sh3/ obj-$(CONFIG_CPU_SH4) = sh4/ +obj-$(CONFIG_CPU_SH4A) += sh4a/ obj-$(CONFIG_UBC_WAKEUP) += ubc.o obj-$(CONFIG_SH_ADC) += adc.o diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 6e415baf04b..19ca68c7188 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile @@ -12,17 +12,12 @@ obj-$(CONFIG_SH_STORE_QUEUES) += sq.o obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o -obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o -obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o -obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o -obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o # Primary on-chip clocks (common) +ifndef CONFIG_CPU_SH4A clock-$(CONFIG_CPU_SH4) := clock-sh4.o -clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o -clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o -clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o +endif # Additional clocks by subtype clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o diff --git a/arch/sh/kernel/cpu/sh4/clock-sh73180.c b/arch/sh/kernel/cpu/sh4/clock-sh73180.c deleted file mode 100644 index 2fa5cb2ae68..00000000000 --- a/arch/sh/kernel/cpu/sh4/clock-sh73180.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4/clock-sh73180.c - * - * SH73180 support for the clock framework - * - * Copyright (C) 2005 Paul Mundt - * - * FRQCR parsing hacked out of arch/sh/kernel/time.c - * - * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka - * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002, 2003, 2004 Paul Mundt - * Copyright (C) 2002 M. R. Brown - * - * 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 -#include -#include -#include -#include - -/* - * SH73180 uses a common set of divisors, so this is quite simple.. - */ -static int divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= divisors[ctrl_inl(FRQCR) & 0x0007]; -} - -static struct clk_ops sh73180_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) & 0x0007); - clk->rate = clk->parent->rate / divisors[idx]; -} - -static struct clk_ops sh73180_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) >> 12) & 0x0007; - clk->rate = clk->parent->rate / divisors[idx]; -} - -static struct clk_ops sh73180_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) >> 20) & 0x0007; - clk->rate = clk->parent->rate / divisors[idx]; -} - -static struct clk_ops sh73180_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh73180_clk_ops[] = { - &sh73180_master_clk_ops, - &sh73180_module_clk_ops, - &sh73180_bus_clk_ops, - &sh73180_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh73180_clk_ops)) - *ops = sh73180_clk_ops[idx]; -} - diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7770.c b/arch/sh/kernel/cpu/sh4/clock-sh7770.c deleted file mode 100644 index c8694bac647..00000000000 --- a/arch/sh/kernel/cpu/sh4/clock-sh7770.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4/clock-sh7770.c - * - * SH7770 support for the clock framework - * - * Copyright (C) 2005 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 -#include -#include -#include -#include - -static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 }; -static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 }; -static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; -} - -static struct clk_ops sh7770_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7770_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) & 0x000f); - clk->rate = clk->parent->rate / bfc_divisors[idx]; -} - -static struct clk_ops sh7770_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7770_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7770_clk_ops[] = { - &sh7770_master_clk_ops, - &sh7770_module_clk_ops, - &sh7770_bus_clk_ops, - &sh7770_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7770_clk_ops)) - *ops = sh7770_clk_ops[idx]; -} - diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/arch/sh/kernel/cpu/sh4/clock-sh7780.c deleted file mode 100644 index 9e6a216750c..00000000000 --- a/arch/sh/kernel/cpu/sh4/clock-sh7780.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4/clock-sh7780.c - * - * SH7780 support for the clock framework - * - * Copyright (C) 2005 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 -#include -#include -#include -#include - -static int ifc_divisors[] = { 2, 4 }; -static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 }; -static int pfc_divisors[] = { 1, 24, 24, 1 }; -static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; -} - -static struct clk_ops sh7780_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) & 0x0003); - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7780_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); - clk->rate = clk->parent->rate / bfc_divisors[idx]; -} - -static struct clk_ops sh7780_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7780_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7780_clk_ops[] = { - &sh7780_master_clk_ops, - &sh7780_module_clk_ops, - &sh7780_bus_clk_ops, - &sh7780_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7780_clk_ops)) - *ops = sh7780_clk_ops[idx]; -} - -static void shyway_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); - clk->rate = clk->parent->rate / cfc_divisors[idx]; -} - -static struct clk_ops sh7780_shyway_clk_ops = { - .recalc = shyway_clk_recalc, -}; - -static struct clk sh7780_shyway_clk = { - .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, - .ops = &sh7780_shyway_clk_ops, -}; - -/* - * Additional SH7780-specific on-chip clocks that aren't already part of the - * clock framework - */ -static struct clk *sh7780_onchip_clocks[] = { - &sh7780_shyway_clk, -}; - -static int __init sh7780_clk_init(void) -{ - struct clk *clk = clk_get(NULL, "master_clk"); - int i; - - for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { - struct clk *clkp = sh7780_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(sh7780_clk_init); - diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index afe0f1b1c03..9031a22a2ce 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -119,11 +119,20 @@ int __init detect_cpu_and_cache_system(void) break; case 0x3000: case 0x3003: + case 0x3009: cpu_data->type = CPU_SH7343; cpu_data->icache.ways = 4; cpu_data->dcache.ways = 4; cpu_data->flags |= CPU_HAS_LLSC; break; + case 0x3008: + if (prr == 0xa0) { + cpu_data->type = CPU_SH7722; + cpu_data->icache.ways = 4; + cpu_data->dcache.ways = 4; + cpu_data->flags |= CPU_HAS_LLSC; + } + break; case 0x8000: cpu_data->type = CPU_ST40RA; cpu_data->flags |= CPU_HAS_FPU; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh73180.c b/arch/sh/kernel/cpu/sh4/setup-sh73180.c deleted file mode 100644 index cc9ea1e2e5d..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh73180.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH73180 Setup - * - * Copyright (C) 2006 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 -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 81, 83, 82 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh73180_devices[] __initdata = { - &sci_device, -}; - -static int __init sh73180_devices_setup(void) -{ - return platform_add_devices(sh73180_devices, - ARRAY_SIZE(sh73180_devices)); -} -__initcall(sh73180_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7343.c b/arch/sh/kernel/cpu/sh4/setup-sh7343.c deleted file mode 100644 index 91d61cf91ba..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh7343.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH7343 Setup - * - * Copyright (C) 2006 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 -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 81, 83, 82 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7343_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7343_devices_setup(void) -{ - return platform_add_devices(sh7343_devices, - ARRAY_SIZE(sh7343_devices)); -} -__initcall(sh7343_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7770.c b/arch/sh/kernel/cpu/sh4/setup-sh7770.c deleted file mode 100644 index 6a04cc5f5ac..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh7770.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SH7770 Setup - * - * Copyright (C) 2006 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 -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xff923000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 61, 61, 61, 61 }, - }, { - .mapbase = 0xff924000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 62, 62, 62, 62 }, - }, { - .mapbase = 0xff925000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 63, 63, 63, 63 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7770_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7770_devices_setup(void) -{ - return platform_add_devices(sh7770_devices, - ARRAY_SIZE(sh7770_devices)); -} -__initcall(sh7770_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4/setup-sh7780.c deleted file mode 100644 index 9aeaa2ddaa2..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SH7780 Setup - * - * Copyright (C) 2006 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 -#include -#include -#include - -static struct resource rtc_resources[] = { - [0] = { - .start = 0xffe80000, - .end = 0xffe80000 + 0x58 - 1, - .flags = IORESOURCE_IO, - }, - [1] = { - /* Period IRQ */ - .start = 21, - .flags = IORESOURCE_IRQ, - }, - [2] = { - /* Carry IRQ */ - .start = 22, - .flags = IORESOURCE_IRQ, - }, - [3] = { - /* Alarm IRQ */ - .start = 23, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device rtc_device = { - .name = "sh-rtc", - .id = -1, - .num_resources = ARRAY_SIZE(rtc_resources), - .resource = rtc_resources, -}; - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 77, 79, 78 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7780_devices[] __initdata = { - &rtc_device, - &sci_device, -}; - -static int __init sh7780_devices_setup(void) -{ - return platform_add_devices(sh7780_devices, - ARRAY_SIZE(sh7780_devices)); -} -__initcall(sh7780_devices_setup); - -static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - - { 21, 1, 0, 0, 2, 2 }, - { 22, 1, 1, 0, 2, 2 }, - { 23, 1, 2, 0, 2, 2 }, - - { 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 */ - - { 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 */ - - { 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 */ -}; - -void __init init_IRQ_intc2(void) -{ - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); -} diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile new file mode 100644 index 00000000000..a8f493f2f21 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for the Linux/SuperH SH-4 backends. +# + +# CPU subtype setup +obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o +obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.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 + +# Primary on-chip clocks (common) +clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o +clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o +clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o +clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o +clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o + +obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh73180.c b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c new file mode 100644 index 00000000000..2fa5cb2ae68 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c @@ -0,0 +1,81 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh73180.c + * + * SH73180 support for the clock framework + * + * Copyright (C) 2005 Paul Mundt + * + * FRQCR parsing hacked out of arch/sh/kernel/time.c + * + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka + * Copyright (C) 2000 Philipp Rumpf + * Copyright (C) 2002, 2003, 2004 Paul Mundt + * Copyright (C) 2002 M. R. Brown + * + * 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 +#include +#include +#include +#include + +/* + * SH73180 uses a common set of divisors, so this is quite simple.. + */ +static int divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= divisors[ctrl_inl(FRQCR) & 0x0007]; +} + +static struct clk_ops sh73180_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x0007); + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh73180_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 12) & 0x0007; + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh73180_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 20) & 0x0007; + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh73180_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh73180_clk_ops[] = { + &sh73180_master_clk_ops, + &sh73180_module_clk_ops, + &sh73180_bus_clk_ops, + &sh73180_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh73180_clk_ops)) + *ops = sh73180_clk_ops[idx]; +} + diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c new file mode 100644 index 00000000000..1707a213f0c --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -0,0 +1,99 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh7343.c + * + * SH7343/SH7722 support for the clock framework + * + * Copyright (C) 2006 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 +#include +#include +#include +#include + +/* + * SH7343/SH7722 uses a common set of multipliers and divisors, so this + * is quite simple.. + */ +static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; + +#define pll_calc() (((ctrl_inl(FRQCR) >> 24) & 0x1f) + 1) + +static void master_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "cpu_clk"); +} + +static void master_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x000f); + clk->rate *= clk->parent->rate * multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_master_clk_ops = { + .init = master_clk_init, + .recalc = master_clk_recalc, +}; + +static void module_clk_init(struct clk *clk) +{ + clk->parent = NULL; + clk->rate = CONFIG_SH_PCLK_FREQ; +} + +static struct clk_ops sh7343_module_clk_ops = { + .init = module_clk_init, +}; + +static void bus_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "cpu_clk"); +} + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 8) & 0x000f; + clk->rate = clk->parent->rate * multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_bus_clk_ops = { + .init = bus_clk_init, + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "module_clk"); + clk->flags |= CLK_RATE_PROPAGATES; + clk_set_rate(clk, clk_get_rate(clk)); +} + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 20) & 0x000f; + clk->rate = clk->parent->rate * pll_calc() * + multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_cpu_clk_ops = { + .init = cpu_clk_init, + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7343_clk_ops[] = { + &sh7343_master_clk_ops, + &sh7343_module_clk_ops, + &sh7343_bus_clk_ops, + &sh7343_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7343_clk_ops)) + *ops = sh7343_clk_ops[idx]; +} diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c new file mode 100644 index 00000000000..c8694bac647 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c @@ -0,0 +1,73 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh7770.c + * + * SH7770 support for the clock framework + * + * Copyright (C) 2005 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 +#include +#include +#include +#include + +static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 }; +static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 }; +static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 }; + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; +} + +static struct clk_ops sh7770_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7770_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x000f); + clk->rate = clk->parent->rate / bfc_divisors[idx]; +} + +static struct clk_ops sh7770_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops sh7770_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7770_clk_ops[] = { + &sh7770_master_clk_ops, + &sh7770_module_clk_ops, + &sh7770_bus_clk_ops, + &sh7770_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7770_clk_ops)) + *ops = sh7770_clk_ops[idx]; +} + diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c new file mode 100644 index 00000000000..9e6a216750c --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -0,0 +1,126 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh7780.c + * + * SH7780 support for the clock framework + * + * Copyright (C) 2005 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 +#include +#include +#include +#include + +static int ifc_divisors[] = { 2, 4 }; +static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 }; +static int pfc_divisors[] = { 1, 24, 24, 1 }; +static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 }; + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; +} + +static struct clk_ops sh7780_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x0003); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7780_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); + clk->rate = clk->parent->rate / bfc_divisors[idx]; +} + +static struct clk_ops sh7780_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops sh7780_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7780_clk_ops[] = { + &sh7780_master_clk_ops, + &sh7780_module_clk_ops, + &sh7780_bus_clk_ops, + &sh7780_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7780_clk_ops)) + *ops = sh7780_clk_ops[idx]; +} + +static void shyway_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); + clk->rate = clk->parent->rate / cfc_divisors[idx]; +} + +static struct clk_ops sh7780_shyway_clk_ops = { + .recalc = shyway_clk_recalc, +}; + +static struct clk sh7780_shyway_clk = { + .name = "shyway_clk", + .flags = CLK_ALWAYS_ENABLED, + .ops = &sh7780_shyway_clk_ops, +}; + +/* + * Additional SH7780-specific on-chip clocks that aren't already part of the + * clock framework + */ +static struct clk *sh7780_onchip_clocks[] = { + &sh7780_shyway_clk, +}; + +static int __init sh7780_clk_init(void) +{ + struct clk *clk = clk_get(NULL, "master_clk"); + int i; + + for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { + struct clk *clkp = sh7780_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(sh7780_clk_init); + diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh73180.c b/arch/sh/kernel/cpu/sh4a/setup-sh73180.c new file mode 100644 index 00000000000..cc9ea1e2e5d --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh73180.c @@ -0,0 +1,43 @@ +/* + * SH73180 Setup + * + * Copyright (C) 2006 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 +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe80000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 81, 83, 82 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh73180_devices[] __initdata = { + &sci_device, +}; + +static int __init sh73180_devices_setup(void) +{ + return platform_add_devices(sh73180_devices, + ARRAY_SIZE(sh73180_devices)); +} +__initcall(sh73180_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c new file mode 100644 index 00000000000..91d61cf91ba --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -0,0 +1,43 @@ +/* + * SH7343 Setup + * + * Copyright (C) 2006 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 +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 81, 83, 82 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7343_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7343_devices_setup(void) +{ + return platform_add_devices(sh7343_devices, + ARRAY_SIZE(sh7343_devices)); +} +__initcall(sh7343_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c new file mode 100644 index 00000000000..7528fc6b0d6 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -0,0 +1,76 @@ +/* + * SH7722 Setup + * + * Copyright (C) 2006 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 +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 81, 83, 82 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7722_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7722_devices_setup(void) +{ + return platform_add_devices(sh7722_devices, + ARRAY_SIZE(sh7722_devices)); +} +__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 */ +}; + +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 */ +}; + +unsigned int map_ipridx_to_addr(int idx) +{ + if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) + return 0; + return ipr_offsets[idx]; +} + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); +} diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c new file mode 100644 index 00000000000..6a04cc5f5ac --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -0,0 +1,53 @@ +/* + * SH7770 Setup + * + * Copyright (C) 2006 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 +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xff923000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 61, 61, 61, 61 }, + }, { + .mapbase = 0xff924000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 62, 62, 62, 62 }, + }, { + .mapbase = 0xff925000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 63, 63, 63, 63 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7770_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7770_devices_setup(void) +{ + return platform_add_devices(sh7770_devices, + ARRAY_SIZE(sh7770_devices)); +} +__initcall(sh7770_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c new file mode 100644 index 00000000000..9aeaa2ddaa2 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -0,0 +1,108 @@ +/* + * SH7780 Setup + * + * Copyright (C) 2006 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 +#include +#include +#include + +static struct resource rtc_resources[] = { + [0] = { + .start = 0xffe80000, + .end = 0xffe80000 + 0x58 - 1, + .flags = IORESOURCE_IO, + }, + [1] = { + /* Period IRQ */ + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* Carry IRQ */ + .start = 22, + .flags = IORESOURCE_IRQ, + }, + [3] = { + /* Alarm IRQ */ + .start = 23, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, + }, { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 76, 77, 79, 78 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7780_devices[] __initdata = { + &rtc_device, + &sci_device, +}; + +static int __init sh7780_devices_setup(void) +{ + return platform_add_devices(sh7780_devices, + ARRAY_SIZE(sh7780_devices)); +} +__initcall(sh7780_devices_setup); + +static struct intc2_data intc2_irq_table[] = { + { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ + + { 21, 1, 0, 0, 2, 2 }, + { 22, 1, 1, 0, 2, 2 }, + { 23, 1, 2, 0, 2, 2 }, + + { 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 */ + + { 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 */ + + { 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 */ +}; + +void __init init_IRQ_intc2(void) +{ + make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); +} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f8dd6b7bfab..fe545bbb1e1 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -325,14 +325,18 @@ void __init setup_arch(char **cmdline_p) ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); if (&__rd_start != &__rd_end) { LOADER_TYPE = 1; - INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START; - INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start; + INITRD_START = PHYSADDR((unsigned long)&__rd_start) - + __MEMORY_START; + INITRD_SIZE = (unsigned long)&__rd_end - + (unsigned long)&__rd_start; } if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { - reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; + reserve_bootmem_node(NODE_DATA(0), INITRD_START + + __MEMORY_START, INITRD_SIZE); + initrd_start = INITRD_START + PAGE_OFFSET + + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " @@ -404,7 +408,7 @@ static const char *cpu_name[] = { [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", - [CPU_SH7785] = "SH7785", + [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 4e0362f5038..29f4ee35c6d 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -35,6 +35,9 @@ config CPU_SUBTYPE_ST40 select CPU_SH4 select CPU_HAS_INTC2_IRQ +config CPU_SHX2 + bool + # # Processor subtypes # @@ -180,6 +183,7 @@ config CPU_SUBTYPE_SH7780 config CPU_SUBTYPE_SH7785 bool "Support SH7785 processor" select CPU_SH4A + select CPU_SHX2 select CPU_HAS_INTC2_IRQ comment "SH4AL-DSP Processor Support" @@ -192,6 +196,12 @@ config CPU_SUBTYPE_SH7343 bool "Support SH7343 processor" select CPU_SH4AL_DSP +config CPU_SUBTYPE_SH7722 + bool "Support SH7722 processor" + select CPU_SH4AL_DSP + select CPU_SHX2 + select CPU_HAS_IPR_IRQ + endmenu menu "Memory management options" @@ -250,7 +260,7 @@ config 32BIT config X2TLB bool "Enable extended TLB mode" - depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL + depends on CPU_SHX2 && MMU && EXPERIMENTAL help Selecting this option will enable the extended mode of the SH-X2 TLB. For legacy SH-X behaviour and interoperability, say N. For diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 9031b57f12d..c53b69610a5 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -319,6 +319,28 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) sci_out(port, SCFCR, fcr_val); } +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) +static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +{ + unsigned int fcr_val = 0; + + if (cflag & CRTSCTS) { + fcr_val |= SCFCR_MCE; + + ctrl_outw(0x0000, PORT_PSCR); + } else { + unsigned short data; + + data = ctrl_inw(PORT_PSCR); + data &= 0x033f; + data |= 0x0400; + ctrl_outw(data, PORT_PSCR); + + ctrl_outw(ctrl_inw(SCSPTR0) & 0x17, SCSPTR0); + } + + sci_out(port, SCFCR, fcr_val); +} #else /* For SH7750 */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index d84c1f9f8a3..77f7d6351ab 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -90,6 +90,13 @@ # define SCSPTR3 0xffe30010 /* 16 bit SCIF */ # define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */ # define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) +# define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ +# define SCSPTR0 SCPDR0 +# define SCIF_ORER 0x0001 /* overrun error bit */ +# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +# define SCIF_ONLY +# define PORT_PSCR 0xA405011E #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ @@ -522,6 +529,13 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } +#elif defined(CONFIG_CPU_SUBTYPE_SH7722) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xffe00000) + return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) static inline int sci_rxd_in(struct uart_port *port) { diff --git a/include/asm-sh/bugs.h b/include/asm-sh/bugs.h index 795047da5e1..a294997a841 100644 --- a/include/asm-sh/bugs.h +++ b/include/asm-sh/bugs.h @@ -16,9 +16,8 @@ static void __init check_bugs(void) { - extern char *get_cpu_subtype(void); extern unsigned long loops_per_jiffy; - char *p= &init_utsname()->machine[2]; /* "sh" */ + char *p = &init_utsname()->machine[2]; /* "sh" */ cpu_data->loops_per_jiffy = loops_per_jiffy; @@ -40,6 +39,15 @@ static void __init check_bugs(void) *p++ = '4'; *p++ = 'a'; break; + case CPU_SH73180 ... CPU_SH7722: + *p++ = '4'; + *p++ = 'a'; + *p++ = 'l'; + *p++ = '-'; + *p++ = 'd'; + *p++ = 's'; + *p++ = 'p'; + break; default: *p++ = '?'; *p++ = '!'; diff --git a/include/asm-sh/cpu-sh4/cache.h b/include/asm-sh/cpu-sh4/cache.h index 6e9c7e6ee8e..f92b20a0983 100644 --- a/include/asm-sh/cpu-sh4/cache.h +++ b/include/asm-sh/cpu-sh4/cache.h @@ -22,7 +22,7 @@ #define CCR_CACHE_ICE 0x0100 /* Instruction Cache Enable */ #define CCR_CACHE_ICI 0x0800 /* IC Invalidate */ #define CCR_CACHE_IIX 0x8000 /* IC Index Enable */ -#ifndef CONFIG_CPU_SUBTYPE_SH7780 +#ifndef CONFIG_CPU_SH4A #define CCR_CACHE_EMODE 0x80000000 /* EMODE Enable */ #endif diff --git a/include/asm-sh/cpu-sh4/freq.h b/include/asm-sh/cpu-sh4/freq.h index ef2b9b1ae41..602d061ca2d 100644 --- a/include/asm-sh/cpu-sh4/freq.h +++ b/include/asm-sh/cpu-sh4/freq.h @@ -10,7 +10,7 @@ #ifndef __ASM_CPU_SH4_FREQ_H #define __ASM_CPU_SH4_FREQ_H -#if defined(CONFIG_CPU_SUBTYPE_SH73180) +#if defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7722) #define FRQCR 0xa4150000 #elif defined(CONFIG_CPU_SUBTYPE_SH7780) #define FRQCR 0xffc80000 diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h index fd576088e47..bff965ef4b9 100644 --- a/include/asm-sh/irq.h +++ b/include/asm-sh/irq.h @@ -37,7 +37,8 @@ # define ONCHIP_NR_IRQS 144 #elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \ defined(CONFIG_CPU_SUBTYPE_SH73180) || \ - defined(CONFIG_CPU_SUBTYPE_SH7343) + defined(CONFIG_CPU_SUBTYPE_SH7343) || \ + defined(CONFIG_CPU_SUBTYPE_SH7722) # define ONCHIP_NR_IRQS 109 #elif defined(CONFIG_CPU_SUBTYPE_SH7780) # define ONCHIP_NR_IRQS 111 @@ -79,6 +80,8 @@ # define OFFCHIP_NR_IRQS 16 #elif defined(CONFIG_SH_7343_SOLUTION_ENGINE) # define OFFCHIP_NR_IRQS 12 +#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE) +# define OFFCHIP_NR_IRQS 14 #elif defined(CONFIG_SH_UNKNOWN) # define OFFCHIP_NR_IRQS 16 /* Must also be last */ #else diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 6f1dd7ca1b1..e29f2abb92d 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -27,6 +27,8 @@ #define CCN_CVR 0xff000040 #define CCN_PRR 0xff000044 +const char *get_cpu_subtype(void); + /* * CPU type and hardware bug flags. Kept separately for each CPU. * @@ -52,8 +54,10 @@ enum cpu_type { CPU_SH7760, CPU_ST40RA, CPU_ST40GX1, CPU_SH4_202, CPU_SH4_501, /* SH-4A types */ - CPU_SH73180, CPU_SH7343, CPU_SH7770, CPU_SH7780, CPU_SH7781, - CPU_SH7785, + CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, + + /* SH4AL-DSP types */ + CPU_SH73180, CPU_SH7343, CPU_SH7722, /* Unknown subtype */ CPU_SH_NONE -- cgit v1.2.3