1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * arch/sh/kernel/cpu/sh3/clock-sh7712.c 4 * 5 * SH7712 support for the clock framework 6 * 7 * Copyright (C) 2007 Andrew Murray <amurray@mpc-data.co.uk> 8 * 9 * Based on arch/sh/kernel/cpu/sh3/clock-sh3.c 10 * Copyright (C) 2005 Paul Mundt 11 */ 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <asm/clock.h> 15 #include <asm/freq.h> 16 #include <asm/io.h> 17 18 static int multipliers[] = { 1, 2, 3 }; 19 static int divisors[] = { 1, 2, 3, 4, 6 }; 20 21 static void master_clk_init(struct clk *clk) 22 { 23 int frqcr = __raw_readw(FRQCR); 24 int idx = (frqcr & 0x0300) >> 8; 25 26 clk->rate *= multipliers[idx]; 27 } 28 29 static struct sh_clk_ops sh7712_master_clk_ops = { 30 .init = master_clk_init, 31 }; 32 33 static unsigned long module_clk_recalc(struct clk *clk) 34 { 35 int frqcr = __raw_readw(FRQCR); 36 int idx = frqcr & 0x0007; 37 38 return clk->parent->rate / divisors[idx]; 39 } 40 41 static struct sh_clk_ops sh7712_module_clk_ops = { 42 .recalc = module_clk_recalc, 43 }; 44 45 static unsigned long cpu_clk_recalc(struct clk *clk) 46 { 47 int frqcr = __raw_readw(FRQCR); 48 int idx = (frqcr & 0x0030) >> 4; 49 50 return clk->parent->rate / divisors[idx]; 51 } 52 53 static struct sh_clk_ops sh7712_cpu_clk_ops = { 54 .recalc = cpu_clk_recalc, 55 }; 56 57 static struct sh_clk_ops *sh7712_clk_ops[] = { 58 &sh7712_master_clk_ops, 59 &sh7712_module_clk_ops, 60 &sh7712_cpu_clk_ops, 61 }; 62 63 void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx) 64 { 65 if (idx < ARRAY_SIZE(sh7712_clk_ops)) 66 *ops = sh7712_clk_ops[idx]; 67 } 68 69