From: Markus B. <sup...@go...> - 2007-08-08 22:38:20
|
Hello Paul, all clock-sh*.c in the sh3 folder seem to be the same except for the bitmasks and the mult/div tables. So I thought it would be a good thing to send code duplication to ifdef hell ;-) For that I created asm-sh/cpu-sh3/clock.h and defined the bitmasks there. I don't have a SH7712 datasheet, so I couldn't check it. btw, what about a datasheets page on the linux-sh wiki? I left clock-sh7709.c because it uses set_bus_parent, which isn't used by the other cpus. I don't know if that's important, but I don't want to break anything. It would be great if there will be a "#else #error" in clock.h if all CPUs are in. Because: 1. this would make things easier if an old cpu will be removed 2. you can be sure the cpu is supported, or not. This patch is only tested on SH7720, but doesn't make any "real" changes. Signed-off by: Markus Brunner <sup...@gm...> Signed-off by: Mark Jonas <to...@gm...> --- arch/sh/kernel/cpu/sh3/Makefile | 3 - arch/sh/kernel/cpu/sh3/clock-sh3.c | 31 ++++++++---- arch/sh/kernel/cpu/sh3/clock-sh7705.c | 84 ---------------------------------- arch/sh/kernel/cpu/sh3/clock-sh7706.c | 84 ---------------------------------- arch/sh/kernel/cpu/sh3/clock-sh7710.c | 78 ------------------------------- include/asm-sh/cpu-sh3/clock.h | 81 ++++++++++++++++++++++++++++++++ 6 files changed, 101 insertions(+), 260 deletions(-) diff -upNr sh-2.6-orig/arch/sh/kernel/cpu/sh3/Makefile sh-2.6-mod/arch/sh/kernel/cpu/sh3/Makefile --- sh-2.6-orig/arch/sh/kernel/cpu/sh3/Makefile 2007-07-31 12:11:46.000000000 +0200 +++ sh-2.6-mod/arch/sh/kernel/cpu/sh3/Makefile 2007-08-08 23:57:56.000000000 +0200 @@ -15,9 +15,6 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setu # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o -clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o -clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o -clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o obj-y += $(clock-y) diff -upNr sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh3.c sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh3.c --- sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh3.c 2007-07-04 21:46:25.000000000 +0200 +++ sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh3.c 2007-08-09 00:16:34.000000000 +0200 @@ -21,16 +21,19 @@ #include <asm/clock.h> #include <asm/freq.h> #include <asm/io.h> +#include <asm/cpu/clock.h> -static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; -static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; -static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; +static int stc_multipliers[] = STC_MULTIPLIERS; +static int ifc_divisors[] = IFC_DIVISORS; +static int pfc_divisors[] = PFC_DIVISORS; static void master_clk_init(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - + int idx = (frqcr & PFC_BITS) >> PFC_BITS_SHIFT; +#ifdef PFC_BITS_H + idx |= (frqcr & PFC_BITS_H) >> PFC_BITS_H_SHIFT; +#endif clk->rate *= pfc_divisors[idx]; } @@ -41,8 +44,10 @@ static struct clk_ops sh3_master_clk_ops static void module_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - + int idx = (frqcr & PFC_BITS) >> PFC_BITS_SHIFT; +#ifdef PFC_BITS_H + idx |= (frqcr & PFC_BITS_H) >> PFC_BITS_H_SHIFT; +#endif clk->rate = clk->parent->rate / pfc_divisors[idx]; } @@ -53,8 +58,10 @@ static struct clk_ops sh3_module_clk_ops static void bus_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); - + int idx = (frqcr & STC_BITS) >> STC_BITS_SHIFT; +#ifdef STC_BITS_H + idx |= (frqcr & STC_BITS_H) >> STC_BITS_H_SHIFT; +#endif clk->rate = clk->parent->rate / stc_multipliers[idx]; } @@ -65,8 +72,10 @@ static struct clk_ops sh3_bus_clk_ops = static void cpu_clk_recalc(struct clk *clk) { int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); - + int idx = (frqcr & IFC_BITS) >> IFC_BITS_SHIFT; +#ifdef IFC_BITS_H + idx |= ((frqcr & IFC_BITS_H) >> IFC_BITS_H_SHIFT) | +#endif clk->rate = clk->parent->rate / ifc_divisors[idx]; } diff -upNr sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh7705.c sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh7705.c --- sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh7705.c 2007-07-04 21:46:25.000000000 +0200 +++ sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh7705.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,84 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh3/clock-sh7705.c - * - * SH7705 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 <pr...@tu...> - * Copyright (C) 2002, 2003, 2004 Paul Mundt - * Copyright (C) 2002 M. R. Brown <mr...@li...> - * - * 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> - -/* - * SH7705 uses the same divisors as the generic SH-3 case, it's just the - * FRQCR layout that is a bit different.. - */ -static int stc_multipliers[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; -static int ifc_divisors[] = { 1, 2, 3, 4, 1, 1, 1, 1 }; -static int pfc_divisors[] = { 1, 2, 3, 4, 6, 1, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= pfc_divisors[ctrl_inw(FRQCR) & 0x0003]; -} - -static struct clk_ops sh7705_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = ctrl_inw(FRQCR) & 0x0003; - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7705_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inw(FRQCR) & 0x0300) >> 8; - clk->rate = clk->parent->rate / stc_multipliers[idx]; -} - -static struct clk_ops sh7705_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inw(FRQCR) & 0x0030) >> 4; - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7705_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7705_clk_ops[] = { - &sh7705_master_clk_ops, - &sh7705_module_clk_ops, - &sh7705_bus_clk_ops, - &sh7705_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7705_clk_ops)) - *ops = sh7705_clk_ops[idx]; -} - diff -upNr sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh7706.c sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh7706.c --- sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh7706.c 2007-07-04 21:46:25.000000000 +0200 +++ sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh7706.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,84 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh3/clock-sh7706.c - * - * SH7706 support for the clock framework - * - * Copyright (C) 2006 Takashi YOSHII - * - * Based on arch/sh/kernel/cpu/sh3/clock-sh7709.c - * Copyright (C) 2005 Andriy Skulysh - * - * 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 stc_multipliers[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; -static int ifc_divisors[] = { 1, 2, 4, 1, 3, 1, 1, 1 }; -static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - - clk->rate *= pfc_divisors[idx]; -} - -static struct clk_ops sh7706_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7706_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); - - clk->rate = clk->parent->rate / stc_multipliers[idx]; -} - -static struct clk_ops sh7706_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); - - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7706_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7706_clk_ops[] = { - &sh7706_master_clk_ops, - &sh7706_module_clk_ops, - &sh7706_bus_clk_ops, - &sh7706_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7706_clk_ops)) - *ops = sh7706_clk_ops[idx]; -} diff -upNr sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh7710.c sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh7710.c --- sh-2.6-orig/arch/sh/kernel/cpu/sh3/clock-sh7710.c 2007-07-31 12:11:46.000000000 +0200 +++ sh-2.6-mod/arch/sh/kernel/cpu/sh3/clock-sh7710.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,78 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh3/clock-sh7710.c - * - * SH7710 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 <pr...@tu...> - * Copyright (C) 2002, 2003, 2004 Paul Mundt - * Copyright (C) 2002 M. R. Brown <mr...@li...> - * - * 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 md_table[] = { 1, 2, 3, 4, 6, 8, 12 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= md_table[ctrl_inw(FRQCR) & 0x0007]; -} - -static struct clk_ops sh7710_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inw(FRQCR) & 0x0007); - clk->rate = clk->parent->rate / md_table[idx]; -} - -static struct clk_ops sh7710_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inw(FRQCR) & 0x0700) >> 8; - clk->rate = clk->parent->rate / md_table[idx]; -} - -static struct clk_ops sh7710_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inw(FRQCR) & 0x0070) >> 4; - clk->rate = clk->parent->rate / md_table[idx]; -} - -static struct clk_ops sh7710_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7710_clk_ops[] = { - &sh7710_master_clk_ops, - &sh7710_module_clk_ops, - &sh7710_bus_clk_ops, - &sh7710_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7710_clk_ops)) - *ops = sh7710_clk_ops[idx]; -} - diff -upNr sh-2.6-orig/include/asm-sh/cpu-sh3/clock.h sh-2.6-mod/include/asm-sh/cpu-sh3/clock.h --- sh-2.6-orig/include/asm-sh/cpu-sh3/clock.h 1970-01-01 01:00:00.000000000 +0100 +++ sh-2.6-mod/include/asm-sh/cpu-sh3/clock.h 2007-08-09 00:09:15.000000000 +0200 @@ -0,0 +1,81 @@ +/* + * include/asm-sh/cpu-sh3/clock.h + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Multipliers and divisors for the SH3 clock + * + * 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. + */ + +#ifndef _CPU_SH3_CLOCK_H +#define _CPU_SH3_CLOCK_H + +#if defined(CONFIG_CPU_SUBTYPE_SH7705) +#define PFC_BITS 0x0003 +#define PFC_BITS_SHIFT 0 +#define STC_BITS 0x0300 +#define STC_BITS_SHIFT 8 +#define IFC_BITS 0x0030 +#define IFC_BITS_SHIFT 4 + +#elif defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7708) +/* only SH7708, SH7708S and not SH7708R are supported */ +#define PFC_BITS 0x0003 +#define PFC_BITS_SHIFT 0 +#define STC_BITS 0x0030 +#define STC_BITS_SHIFT 4 +#define IFC_BITS 0x000c +#define IFC_BITS_SHIFT 2 + +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) +#define PFC_BITS 0x0007 +#define PFC_BITS_SHIFT 0 +#define STC_BITS 0x0700 +#define STC_BITS_SHIFT 8 +#define IFC_BITS 0x0070 +#define IFC_BITS_SHIFT 4 + +#else +/* CONFIG_CPU_SUBTYPE_SH7706 */ +#define PFC_BITS_H 0x2000 +#define PFC_BITS_H_SHIFT 11 +#define PFC_BITS 0x0003 +#define PFC_BITS_SHIFT 0 +#define STC_BITS_H 0x8000 +#define STC_BITS_H_SHIFT 13 +#define STC_BITS 0x0030 +#define STC_BITS_SHIFT 4 +#define IFC_BITS_H 0x4000 +#define IFC_BITS_H_SHIFT 12 +#define IFC_BITS 0x000c +#define IFC_BITS_SHIFT 2 +#endif + +/* + * Multipliers and Divisor tables + */ + +#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7708) +#define STC_MULTIPLIERS { 1, 2, 4, 1, 3, 6, 1, 1 } +#define IFC_DIVISORS { 1, 2, 4, 1, 3, 1, 1, 1 } +#define PFC_DIVISORS STC_MULTIPLIERS + +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) +#define STC_MULTIPLIERS { 1, 2, 3, 4, 6, 8, 12 } +#define IFC_DIVISORS STC_MULTIPLIERS +#define PFC_DIVISORS STC_MULTIPLIERS + +#else +/* CONFIG_CPU_SUBTYPE_SH7705 */ +#define STC_MULTIPLIERS { 1, 2, 3, 4, 6, 1, 1, 1 } +#define IFC_DIVISORS { 1, 2, 3, 4, 1, 1, 1, 1 } +#define PFC_DIVISORS STC_MULTIPLIERS +#endif + +#endif /* _CPU_SH3_CLOCK_H */ |