1add5ca2cSKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
2bc49b6eaSMagnus Damm /*
3bc49b6eaSMagnus Damm  * arch/sh/kernel/cpu/sh4a/clock-sh7343.c
4bc49b6eaSMagnus Damm  *
5bc49b6eaSMagnus Damm  * SH7343 clock framework support
6bc49b6eaSMagnus Damm  *
7bc49b6eaSMagnus Damm  * Copyright (C) 2009 Magnus Damm
8bc49b6eaSMagnus Damm  */
9bc49b6eaSMagnus Damm #include <linux/init.h>
10bc49b6eaSMagnus Damm #include <linux/kernel.h>
11bc49b6eaSMagnus Damm #include <linux/io.h>
126d803ba7SJean-Christop PLAGNIOL-VILLARD #include <linux/clkdev.h>
13bc49b6eaSMagnus Damm #include <asm/clock.h>
14bc49b6eaSMagnus Damm 
15bc49b6eaSMagnus Damm /* SH7343 registers */
16bc49b6eaSMagnus Damm #define FRQCR		0xa4150000
17bc49b6eaSMagnus Damm #define VCLKCR		0xa4150004
18bc49b6eaSMagnus Damm #define SCLKACR		0xa4150008
19bc49b6eaSMagnus Damm #define SCLKBCR		0xa415000c
20bc49b6eaSMagnus Damm #define PLLCR		0xa4150024
21bc49b6eaSMagnus Damm #define MSTPCR0		0xa4150030
22bc49b6eaSMagnus Damm #define MSTPCR1		0xa4150034
23bc49b6eaSMagnus Damm #define MSTPCR2		0xa4150038
24bc49b6eaSMagnus Damm #define DLLFRQ		0xa4150050
25bc49b6eaSMagnus Damm 
26bc49b6eaSMagnus Damm /* Fixed 32 KHz root clock for RTC and Power Management purposes */
27bc49b6eaSMagnus Damm static struct clk r_clk = {
28bc49b6eaSMagnus Damm 	.rate           = 32768,
29bc49b6eaSMagnus Damm };
30bc49b6eaSMagnus Damm 
31bc49b6eaSMagnus Damm /*
32bc49b6eaSMagnus Damm  * Default rate for the root input clock, reset this with clk_set_rate()
33bc49b6eaSMagnus Damm  * from the platform code.
34bc49b6eaSMagnus Damm  */
35bc49b6eaSMagnus Damm struct clk extal_clk = {
36bc49b6eaSMagnus Damm 	.rate		= 33333333,
37bc49b6eaSMagnus Damm };
38bc49b6eaSMagnus Damm 
39bc49b6eaSMagnus Damm /* The dll block multiplies the 32khz r_clk, may be used instead of extal */
dll_recalc(struct clk * clk)40bc49b6eaSMagnus Damm static unsigned long dll_recalc(struct clk *clk)
41bc49b6eaSMagnus Damm {
42bc49b6eaSMagnus Damm 	unsigned long mult;
43bc49b6eaSMagnus Damm 
44bc49b6eaSMagnus Damm 	if (__raw_readl(PLLCR) & 0x1000)
45bc49b6eaSMagnus Damm 		mult = __raw_readl(DLLFRQ);
46bc49b6eaSMagnus Damm 	else
47bc49b6eaSMagnus Damm 		mult = 0;
48bc49b6eaSMagnus Damm 
49bc49b6eaSMagnus Damm 	return clk->parent->rate * mult;
50bc49b6eaSMagnus Damm }
51bc49b6eaSMagnus Damm 
5233cb61a4SMagnus Damm static struct sh_clk_ops dll_clk_ops = {
53bc49b6eaSMagnus Damm 	.recalc		= dll_recalc,
54bc49b6eaSMagnus Damm };
55bc49b6eaSMagnus Damm 
56bc49b6eaSMagnus Damm static struct clk dll_clk = {
57bc49b6eaSMagnus Damm 	.ops		= &dll_clk_ops,
58bc49b6eaSMagnus Damm 	.parent		= &r_clk,
59bc49b6eaSMagnus Damm 	.flags		= CLK_ENABLE_ON_INIT,
60bc49b6eaSMagnus Damm };
61bc49b6eaSMagnus Damm 
pll_recalc(struct clk * clk)62bc49b6eaSMagnus Damm static unsigned long pll_recalc(struct clk *clk)
63bc49b6eaSMagnus Damm {
64bc49b6eaSMagnus Damm 	unsigned long mult = 1;
65bc49b6eaSMagnus Damm 
66bc49b6eaSMagnus Damm 	if (__raw_readl(PLLCR) & 0x4000)
67bc49b6eaSMagnus Damm 		mult = (((__raw_readl(FRQCR) >> 24) & 0x1f) + 1);
68bc49b6eaSMagnus Damm 
69bc49b6eaSMagnus Damm 	return clk->parent->rate * mult;
70bc49b6eaSMagnus Damm }
71bc49b6eaSMagnus Damm 
7233cb61a4SMagnus Damm static struct sh_clk_ops pll_clk_ops = {
73bc49b6eaSMagnus Damm 	.recalc		= pll_recalc,
74bc49b6eaSMagnus Damm };
75bc49b6eaSMagnus Damm 
76bc49b6eaSMagnus Damm static struct clk pll_clk = {
77bc49b6eaSMagnus Damm 	.ops		= &pll_clk_ops,
78bc49b6eaSMagnus Damm 	.flags		= CLK_ENABLE_ON_INIT,
79bc49b6eaSMagnus Damm };
80bc49b6eaSMagnus Damm 
81bc49b6eaSMagnus Damm struct clk *main_clks[] = {
82bc49b6eaSMagnus Damm 	&r_clk,
83bc49b6eaSMagnus Damm 	&extal_clk,
84bc49b6eaSMagnus Damm 	&dll_clk,
85bc49b6eaSMagnus Damm 	&pll_clk,
86bc49b6eaSMagnus Damm };
87bc49b6eaSMagnus Damm 
88bc49b6eaSMagnus Damm static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
89bc49b6eaSMagnus Damm static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
90bc49b6eaSMagnus Damm 
910a5f337eSMagnus Damm static struct clk_div_mult_table div4_div_mult_table = {
92bc49b6eaSMagnus Damm 	.divisors = divisors,
93bc49b6eaSMagnus Damm 	.nr_divisors = ARRAY_SIZE(divisors),
94bc49b6eaSMagnus Damm 	.multipliers = multipliers,
95bc49b6eaSMagnus Damm 	.nr_multipliers = ARRAY_SIZE(multipliers),
96bc49b6eaSMagnus Damm };
97bc49b6eaSMagnus Damm 
980a5f337eSMagnus Damm static struct clk_div4_table div4_table = {
990a5f337eSMagnus Damm 	.div_mult_table = &div4_div_mult_table,
1000a5f337eSMagnus Damm };
1010a5f337eSMagnus Damm 
102bc49b6eaSMagnus Damm enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
103bc49b6eaSMagnus Damm        DIV4_SIUA, DIV4_SIUB, DIV4_NR };
104bc49b6eaSMagnus Damm 
105914ebf0bSMagnus Damm #define DIV4(_reg, _bit, _mask, _flags) \
106914ebf0bSMagnus Damm   SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
107bc49b6eaSMagnus Damm 
108bc49b6eaSMagnus Damm struct clk div4_clks[DIV4_NR] = {
109914ebf0bSMagnus Damm 	[DIV4_I] = DIV4(FRQCR, 20, 0x1fff, CLK_ENABLE_ON_INIT),
110914ebf0bSMagnus Damm 	[DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
111914ebf0bSMagnus Damm 	[DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
112914ebf0bSMagnus Damm 	[DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
113914ebf0bSMagnus Damm 	[DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
114914ebf0bSMagnus Damm 	[DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
115914ebf0bSMagnus Damm 	[DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
116914ebf0bSMagnus Damm 	[DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
117bc49b6eaSMagnus Damm };
118bc49b6eaSMagnus Damm 
119098ec49bSMagnus Damm enum { DIV6_V, DIV6_NR };
120098ec49bSMagnus Damm 
121098ec49bSMagnus Damm struct clk div6_clks[DIV6_NR] = {
1229e1985e1SMagnus Damm 	[DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
123bc49b6eaSMagnus Damm };
124bc49b6eaSMagnus Damm 
125c77a9c3eSMagnus Damm #define MSTP(_parent, _reg, _bit, _flags) \
126c77a9c3eSMagnus Damm   SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
127bc49b6eaSMagnus Damm 
128e8b96918SMagnus Damm enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026,
129e8b96918SMagnus Damm        MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016,
130e8b96918SMagnus Damm        MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010,
131e8b96918SMagnus Damm        MSTP007, MSTP006, MSTP005, MSTP004, MSTP003, MSTP002, MSTP001,
132e8b96918SMagnus Damm        MSTP109, MSTP108, MSTP100,
133e8b96918SMagnus Damm        MSTP225, MSTP224, MSTP218, MSTP217, MSTP216,
134e8b96918SMagnus Damm        MSTP214, MSTP213, MSTP212, MSTP211, MSTP208,
135e8b96918SMagnus Damm        MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
136e8b96918SMagnus Damm        MSTP_NR };
137bc49b6eaSMagnus Damm 
138e8b96918SMagnus Damm static struct clk mstp_clks[MSTP_NR] = {
139c77a9c3eSMagnus Damm 	[MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
140c77a9c3eSMagnus Damm 	[MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
141c77a9c3eSMagnus Damm 	[MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
142c77a9c3eSMagnus Damm 	[MSTP028] = MSTP(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
143c77a9c3eSMagnus Damm 	[MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
144c77a9c3eSMagnus Damm 	[MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
145c77a9c3eSMagnus Damm 	[MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
146c77a9c3eSMagnus Damm 	[MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
147c77a9c3eSMagnus Damm 	[MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
148c77a9c3eSMagnus Damm 	[MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
149c77a9c3eSMagnus Damm 	[MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
150c77a9c3eSMagnus Damm 	[MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
151c77a9c3eSMagnus Damm 	[MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0),
152c77a9c3eSMagnus Damm 	[MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0),
153c77a9c3eSMagnus Damm 	[MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
154c77a9c3eSMagnus Damm 	[MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
155c77a9c3eSMagnus Damm 	[MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
156c77a9c3eSMagnus Damm 	[MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
157c77a9c3eSMagnus Damm 	[MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
158c77a9c3eSMagnus Damm 	[MSTP004] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
159c77a9c3eSMagnus Damm 	[MSTP003] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
160c77a9c3eSMagnus Damm 	[MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
161c77a9c3eSMagnus Damm 	[MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
162bc49b6eaSMagnus Damm 
163c77a9c3eSMagnus Damm 	[MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
164c77a9c3eSMagnus Damm 	[MSTP108] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 8, 0),
165e8b96918SMagnus Damm 
166c77a9c3eSMagnus Damm 	[MSTP225] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 25, 0),
167c77a9c3eSMagnus Damm 	[MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
168c77a9c3eSMagnus Damm 	[MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
169c77a9c3eSMagnus Damm 	[MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0),
170c77a9c3eSMagnus Damm 	[MSTP216] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 16, 0),
171c77a9c3eSMagnus Damm 	[MSTP214] = MSTP(&r_clk, MSTPCR2, 14, 0),
172c77a9c3eSMagnus Damm 	[MSTP213] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 13, 0),
173c77a9c3eSMagnus Damm 	[MSTP212] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 12, 0),
174c77a9c3eSMagnus Damm 	[MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
175c77a9c3eSMagnus Damm 	[MSTP208] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
176c77a9c3eSMagnus Damm 	[MSTP206] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
177c77a9c3eSMagnus Damm 	[MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
178c77a9c3eSMagnus Damm 	[MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
179c77a9c3eSMagnus Damm 	[MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
180c77a9c3eSMagnus Damm 	[MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
181c77a9c3eSMagnus Damm 	[MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
182c77a9c3eSMagnus Damm 	[MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
183bc49b6eaSMagnus Damm };
184bc49b6eaSMagnus Damm 
185098ec49bSMagnus Damm static struct clk_lookup lookups[] = {
1868249a311SMagnus Damm 	/* main clocks */
1878249a311SMagnus Damm 	CLKDEV_CON_ID("rclk", &r_clk),
1888249a311SMagnus Damm 	CLKDEV_CON_ID("extal", &extal_clk),
1898249a311SMagnus Damm 	CLKDEV_CON_ID("dll_clk", &dll_clk),
1908249a311SMagnus Damm 	CLKDEV_CON_ID("pll_clk", &pll_clk),
1918249a311SMagnus Damm 
192f8ef178cSMagnus Damm 	/* DIV4 clocks */
193f8ef178cSMagnus Damm 	CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
194f8ef178cSMagnus Damm 	CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
195f8ef178cSMagnus Damm 	CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
196f8ef178cSMagnus Damm 	CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
197f8ef178cSMagnus Damm 	CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
198f8ef178cSMagnus Damm 	CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
199f8ef178cSMagnus Damm 	CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]),
200f8ef178cSMagnus Damm 	CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]),
201f8ef178cSMagnus Damm 
202098ec49bSMagnus Damm 	/* DIV6 clocks */
203098ec49bSMagnus Damm 	CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
20425637f7aSMagnus Damm 
20525637f7aSMagnus Damm 	/* MSTP32 clocks */
20625637f7aSMagnus Damm 	CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]),
20725637f7aSMagnus Damm 	CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]),
20825637f7aSMagnus Damm 	CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]),
20925637f7aSMagnus Damm 	CLKDEV_CON_ID("uram0", &mstp_clks[MSTP028]),
21025637f7aSMagnus Damm 	CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]),
21125637f7aSMagnus Damm 	CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]),
21225637f7aSMagnus Damm 	CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]),
21325637f7aSMagnus Damm 	CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]),
21425637f7aSMagnus Damm 	CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]),
21525637f7aSMagnus Damm 	CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
21625637f7aSMagnus Damm 	CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
21725637f7aSMagnus Damm 	CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
2189b17e48cSLaurent Pinchart 	CLKDEV_ICK_ID("fck", "sh-cmt-32.0", &mstp_clks[MSTP014]),
21925637f7aSMagnus Damm 	CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
22025637f7aSMagnus Damm 	CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
22125637f7aSMagnus Damm 	CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
222074fcdffSKuninori Morimoto 
223fa3d39bfSLaurent Pinchart 	CLKDEV_ICK_ID("fck", "sh-sci.0", &mstp_clks[MSTP007]),
224fa3d39bfSLaurent Pinchart 	CLKDEV_ICK_ID("fck", "sh-sci.1", &mstp_clks[MSTP006]),
225fa3d39bfSLaurent Pinchart 	CLKDEV_ICK_ID("fck", "sh-sci.2", &mstp_clks[MSTP005]),
226fa3d39bfSLaurent Pinchart 	CLKDEV_ICK_ID("fck", "sh-sci.3", &mstp_clks[MSTP004]),
227074fcdffSKuninori Morimoto 
22825637f7aSMagnus Damm 	CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]),
22925637f7aSMagnus Damm 	CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]),
23025637f7aSMagnus Damm 	CLKDEV_CON_ID("siof1", &mstp_clks[MSTP001]),
23136d1753aSKuninori Morimoto 	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP109]),
23236d1753aSKuninori Morimoto 	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP108]),
23325637f7aSMagnus Damm 	CLKDEV_CON_ID("tpu0", &mstp_clks[MSTP225]),
23425637f7aSMagnus Damm 	CLKDEV_CON_ID("irda0", &mstp_clks[MSTP224]),
23525637f7aSMagnus Damm 	CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]),
23625637f7aSMagnus Damm 	CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]),
23725637f7aSMagnus Damm 	CLKDEV_CON_ID("sim0", &mstp_clks[MSTP216]),
23825637f7aSMagnus Damm 	CLKDEV_CON_ID("keysc0", &mstp_clks[MSTP214]),
23925637f7aSMagnus Damm 	CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP213]),
24025637f7aSMagnus Damm 	CLKDEV_CON_ID("s3d40", &mstp_clks[MSTP212]),
24125637f7aSMagnus Damm 	CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]),
24225637f7aSMagnus Damm 	CLKDEV_CON_ID("siu0", &mstp_clks[MSTP208]),
24325637f7aSMagnus Damm 	CLKDEV_CON_ID("jpu0", &mstp_clks[MSTP206]),
24425637f7aSMagnus Damm 	CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]),
24525637f7aSMagnus Damm 	CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]),
24625637f7aSMagnus Damm 	CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]),
24725637f7aSMagnus Damm 	CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]),
24825637f7aSMagnus Damm 	CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]),
24925637f7aSMagnus Damm 	CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]),
250098ec49bSMagnus Damm };
251098ec49bSMagnus Damm 
arch_clk_init(void)252bc49b6eaSMagnus Damm int __init arch_clk_init(void)
253bc49b6eaSMagnus Damm {
254bc49b6eaSMagnus Damm 	int k, ret = 0;
255bc49b6eaSMagnus Damm 
256bc49b6eaSMagnus Damm 	/* autodetect extal or dll configuration */
257bc49b6eaSMagnus Damm 	if (__raw_readl(PLLCR) & 0x1000)
258bc49b6eaSMagnus Damm 		pll_clk.parent = &dll_clk;
259bc49b6eaSMagnus Damm 	else
260bc49b6eaSMagnus Damm 		pll_clk.parent = &extal_clk;
261bc49b6eaSMagnus Damm 
262bc49b6eaSMagnus Damm 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
263bc49b6eaSMagnus Damm 		ret = clk_register(main_clks[k]);
264bc49b6eaSMagnus Damm 
265098ec49bSMagnus Damm 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
266098ec49bSMagnus Damm 
267bc49b6eaSMagnus Damm 	if (!ret)
268bc49b6eaSMagnus Damm 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
269bc49b6eaSMagnus Damm 
270bc49b6eaSMagnus Damm 	if (!ret)
271098ec49bSMagnus Damm 		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
272bc49b6eaSMagnus Damm 
273bc49b6eaSMagnus Damm 	if (!ret)
274ad3337cbSNobuhiro Iwamatsu 		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
275bc49b6eaSMagnus Damm 
276bc49b6eaSMagnus Damm 	return ret;
277bc49b6eaSMagnus Damm }
278