1 // SPDX-License-Identifier: GPL-2.0
3 * arch/sh/kernel/cpu/sh3/clock-sh3.c
5 * Generic SH-3 support for the clock framework
7 * Copyright (C) 2005 Paul Mundt
9 * FRQCR parsing hacked out of arch/sh/kernel/time.c
11 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
12 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
13 * Copyright (C) 2002, 2003, 2004 Paul Mundt
14 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <asm/clock.h>
22 static int stc_multipliers
[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
23 static int ifc_divisors
[] = { 1, 2, 3, 4, 1, 1, 1, 1 };
24 static int pfc_divisors
[] = { 1, 2, 3, 4, 6, 1, 1, 1 };
26 static void master_clk_init(struct clk
*clk
)
28 int frqcr
= __raw_readw(FRQCR
);
29 int idx
= ((frqcr
& 0x2000) >> 11) | (frqcr
& 0x0003);
31 clk
->rate
*= pfc_divisors
[idx
];
34 static struct sh_clk_ops sh3_master_clk_ops
= {
35 .init
= master_clk_init
,
38 static unsigned long module_clk_recalc(struct clk
*clk
)
40 int frqcr
= __raw_readw(FRQCR
);
41 int idx
= ((frqcr
& 0x2000) >> 11) | (frqcr
& 0x0003);
43 return clk
->parent
->rate
/ pfc_divisors
[idx
];
46 static struct sh_clk_ops sh3_module_clk_ops
= {
47 .recalc
= module_clk_recalc
,
50 static unsigned long bus_clk_recalc(struct clk
*clk
)
52 int frqcr
= __raw_readw(FRQCR
);
53 int idx
= ((frqcr
& 0x8000) >> 13) | ((frqcr
& 0x0030) >> 4);
55 return clk
->parent
->rate
/ stc_multipliers
[idx
];
58 static struct sh_clk_ops sh3_bus_clk_ops
= {
59 .recalc
= bus_clk_recalc
,
62 static unsigned long cpu_clk_recalc(struct clk
*clk
)
64 int frqcr
= __raw_readw(FRQCR
);
65 int idx
= ((frqcr
& 0x4000) >> 12) | ((frqcr
& 0x000c) >> 2);
67 return clk
->parent
->rate
/ ifc_divisors
[idx
];
70 static struct sh_clk_ops sh3_cpu_clk_ops
= {
71 .recalc
= cpu_clk_recalc
,
74 static struct sh_clk_ops
*sh3_clk_ops
[] = {
81 void __init
arch_init_clk_ops(struct sh_clk_ops
**ops
, int idx
)
83 if (idx
< ARRAY_SIZE(sh3_clk_ops
))
84 *ops
= sh3_clk_ops
[idx
];