diff options
Diffstat (limited to 'arch/sh/kernel/cpu/sh3')
-rw-r--r-- | arch/sh/kernel/cpu/sh3/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/clock-sh7712.c | 71 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/entry.S | 24 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/ex.S | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/probe.c | 9 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh7705.c | 10 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh770x.c | 11 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh7710.c | 16 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh7720.c | 78 |
9 files changed, 173 insertions, 50 deletions
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index 646eb693361..3ae4d9111f1 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o +obj-$(CONFIG_CPU_SUBTYPE_SH7721) += setup-sh7720.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o @@ -21,5 +22,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o +clock-$(CONFIG_CPU_SUBTYPE_SH7712) := clock-sh7712.o obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7712.c b/arch/sh/kernel/cpu/sh3/clock-sh7712.c new file mode 100644 index 00000000000..54f54df51ef --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/clock-sh7712.c @@ -0,0 +1,71 @@ +/* + * arch/sh/kernel/cpu/sh3/clock-sh7712.c + * + * SH7712 support for the clock framework + * + * Copyright (C) 2007 Andrew Murray <amurray@mpc-data.co.uk> + * + * Based on arch/sh/kernel/cpu/sh3/clock-sh3.c + * 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 <linux/init.h> +#include <linux/kernel.h> +#include <asm/clock.h> +#include <asm/freq.h> +#include <asm/io.h> + +static int multipliers[] = { 1, 2, 3 }; +static int divisors[] = { 1, 2, 3, 4, 6 }; + +static void master_clk_init(struct clk *clk) +{ + int frqcr = ctrl_inw(FRQCR); + int idx = (frqcr & 0x0300) >> 8; + + clk->rate *= multipliers[idx]; +} + +static struct clk_ops sh7712_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int frqcr = ctrl_inw(FRQCR); + int idx = frqcr & 0x0007; + + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh7712_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int frqcr = ctrl_inw(FRQCR); + int idx = (frqcr & 0x0030) >> 4; + + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh7712_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7712_clk_ops[] = { + &sh7712_master_clk_ops, + &sh7712_module_clk_ops, + &sh7712_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7712_clk_ops)) + *ops = sh7712_clk_ops[idx]; +} + diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 0d12a124055..4004073f98c 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -13,8 +13,9 @@ #include <linux/linkage.h> #include <asm/asm-offsets.h> #include <asm/thread_info.h> -#include <asm/cpu/mmu_context.h> #include <asm/unistd.h> +#include <asm/cpu/mmu_context.h> +#include <asm/page.h> ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address @@ -409,6 +410,27 @@ ENTRY(handle_exception) ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), ! save all registers onto stack. ! + +#ifdef CONFIG_GUSA + ! Check for roll back gRB (User and Kernel) + mov r15, k0 + shll k0 + bf/s 1f + shll k0 + bf/s 1f + stc spc, k1 + stc r0_bank, k0 + cmp/hs k0, k1 ! test k1 (saved PC) >= k0 (saved r0) + bt/s 2f + stc r1_bank, k1 + + add #-2, k0 + add r15, k0 + ldc k0, spc ! PC = saved r0 + r15 - 2 +2: mov k1, r15 ! SP = r1 +1: +#endif + stc ssr, k0 ! Is it from kernel space? shll k0 ! Check MD bit (bit30) by shifting it into... shll k0 ! ...the T bit diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index b6abf38d3a8..11b6d9c6eda 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S @@ -36,7 +36,7 @@ ENTRY(exception_handling_table) .long exception_error ! address error store /* 100 */ #endif #if defined(CONFIG_SH_FPU) - .long do_fpu_error /* 120 */ + .long fpu_error_trap_handler /* 120 */ #else .long exception_error /* 120 */ #endif diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index bf579e061e0..fcc80bb7bee 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -16,11 +16,11 @@ #include <asm/cache.h> #include <asm/io.h> -int __init detect_cpu_and_cache_system(void) +int __uses_jump_to_uncached detect_cpu_and_cache_system(void) { unsigned long addr0, addr1, data0, data1, data2, data3; - jump_to_P2(); + jump_to_uncached(); /* * Check if the entry shadows or not. * When shadowed, it's 128-entry system. @@ -48,7 +48,7 @@ int __init detect_cpu_and_cache_system(void) ctrl_outl(data0&~SH_CACHE_VALID, addr0); ctrl_outl(data2&~SH_CACHE_VALID, addr1); - back_to_P1(); + back_to_cached(); boot_cpu_data.dcache.ways = 4; boot_cpu_data.dcache.entry_shift = 4; @@ -84,6 +84,9 @@ int __init detect_cpu_and_cache_system(void) #if defined(CONFIG_CPU_SUBTYPE_SH7720) boot_cpu_data.type = CPU_SH7720; #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7721) + boot_cpu_data.type = CPU_SH7721; +#endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) boot_cpu_data.type = CPU_SH7705; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index f6c65f2659e..dd0a20a685f 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -66,12 +66,6 @@ static struct intc_group groups[] __initdata = { INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI), }; -static struct intc_prio priorities[] __initdata = { - INTC_PRIO(DMAC, 7), - INTC_PRIO(SCIF2, 3), - INTC_PRIO(SCIF0, 3), -}; - static struct intc_prio_reg prio_registers[] __initdata = { { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } }, @@ -85,7 +79,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { }; static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups, - priorities, NULL, prio_registers, NULL); + NULL, prio_registers, NULL); static struct intc_vect vectors_irq[] __initdata = { INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), @@ -93,7 +87,7 @@ static struct intc_vect vectors_irq[] __initdata = { }; static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL, - priorities, NULL, prio_registers, NULL); + NULL, prio_registers, NULL); static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 60b04b1f945..969804bb523 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -81,13 +81,6 @@ static struct intc_group groups[] __initdata = { INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), }; -static struct intc_prio priorities[] __initdata = { - INTC_PRIO(DMAC, 7), - INTC_PRIO(SCI, 3), - INTC_PRIO(SCIF2, 3), - INTC_PRIO(SCIF0, 3), -}; - static struct intc_prio_reg prio_registers[] __initdata = { { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } }, @@ -109,7 +102,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { }; static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups, - priorities, NULL, prio_registers, NULL); + NULL, prio_registers, NULL); #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ @@ -120,7 +113,7 @@ static struct intc_vect vectors_irq[] __initdata = { }; static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL, - priorities, NULL, prio_registers, NULL); + NULL, prio_registers, NULL); #endif static struct resource rtc_resources[] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 84e5629fa84..0cc0e2bf135 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -73,18 +73,6 @@ static struct intc_group groups[] __initdata = { INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI), }; -static struct intc_prio priorities[] __initdata = { - INTC_PRIO(DMAC1, 7), - INTC_PRIO(DMAC2, 7), - INTC_PRIO(SCIF0, 3), - INTC_PRIO(SCIF1, 3), - INTC_PRIO(SIOF0, 3), - INTC_PRIO(SIOF1, 3), - INTC_PRIO(EDMAC0, 5), - INTC_PRIO(EDMAC1, 5), - INTC_PRIO(EDMAC2, 5), -}; - static struct intc_prio_reg prio_registers[] __initdata = { { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, @@ -101,7 +89,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { }; static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, - priorities, NULL, prio_registers, NULL); + NULL, prio_registers, NULL); static struct intc_vect vectors_irq[] __initdata = { INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), @@ -109,7 +97,7 @@ static struct intc_vect vectors_irq[] __initdata = { }; static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL, - priorities, NULL, prio_registers, NULL); + NULL, prio_registers, NULL); static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index a0929b8a95a..3855ea4c21c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -85,9 +85,62 @@ static struct platform_device sci_device = { }, }; +static struct resource usb_ohci_resources[] = { + [0] = { + .start = 0xA4428000, + .end = 0xA44280FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 67, + .end = 67, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 usb_ohci_dma_mask = 0xffffffffUL; +static struct platform_device usb_ohci_device = { + .name = "sh_ohci", + .id = -1, + .dev = { + .dma_mask = &usb_ohci_dma_mask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(usb_ohci_resources), + .resource = usb_ohci_resources, +}; + +static struct resource usbf_resources[] = { + [0] = { + .name = "sh_udc", + .start = 0xA4420000, + .end = 0xA44200FF, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "sh_udc", + .start = 65, + .end = 65, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device usbf_device = { + .name = "sh_udc", + .id = -1, + .dev = { + .dma_mask = NULL, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(usbf_resources), + .resource = usbf_resources, +}; + static struct platform_device *sh7720_devices[] __initdata = { &rtc_device, &sci_device, + &usb_ohci_device, + &usbf_device, }; static int __init sh7720_devices_setup(void) @@ -127,8 +180,11 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800), INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840), INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900), - INTC_VECT(SSL, 0x980), INTC_VECT(USBFI0, 0xa20), - INTC_VECT(USBFI1, 0xa40), INTC_VECT(USBHI, 0xa60), +#if defined(CONFIG_CPU_SUBTYPE_SH7720) + INTC_VECT(SSL, 0x980), +#endif + INTC_VECT(USBFI0, 0xa20), INTC_VECT(USBFI1, 0xa40), + INTC_VECT(USBHI, 0xa60), INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0), INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00), INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80), @@ -153,22 +209,16 @@ static struct intc_group groups[] __initdata = { INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3), }; -static struct intc_prio priorities[] __initdata = { - INTC_PRIO(SCIF0, 2), - INTC_PRIO(SCIF1, 2), - INTC_PRIO(DMAC1, 1), - INTC_PRIO(DMAC2, 1), - INTC_PRIO(RTC, 2), - INTC_PRIO(TMU, 2), - INTC_PRIO(TPU, 2), -}; - static struct intc_prio_reg prio_registers[] __initdata = { { 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } }, { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } }, +#if defined(CONFIG_CPU_SUBTYPE_SH7720) { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } }, +#else + { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, 0 } }, +#endif { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } }, { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } }, { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } }, @@ -177,7 +227,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { }; static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups, - priorities, NULL, prio_registers, NULL); + NULL, prio_registers, NULL); static struct intc_sense_reg sense_registers[] __initdata = { { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, @@ -190,7 +240,7 @@ static struct intc_vect vectors_irq[] __initdata = { }; static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq, - NULL, priorities, NULL, prio_registers, sense_registers); + NULL, NULL, prio_registers, sense_registers); void __init plat_irq_setup_pins(int mode) { |