]> Git Repo - u-boot.git/blame - drivers/clk/exynos/clk-exynos7420.c
Merge tag 'dm-pull-14dec20' of git://git.denx.de/u-boot-dm into next
[u-boot.git] / drivers / clk / exynos / clk-exynos7420.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
166097e8
TA
2/*
3 * Samsung Exynos7420 clock driver.
4 * Copyright (C) 2016 Samsung Electronics
5 * Thomas Abraham <[email protected]>
166097e8
TA
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <errno.h>
135aa950 11#include <clk-uclass.h>
166097e8
TA
12#include <asm/io.h>
13#include <dt-bindings/clock/exynos7420-clk.h>
14#include "clk-pll.h"
15
166097e8
TA
16#define DIVIDER(reg, shift, mask) \
17 (((readl(reg) >> shift) & mask) + 1)
18
19/* CMU TOPC block device structure */
20struct exynos7420_clk_cmu_topc {
21 unsigned int rsvd1[68];
22 unsigned int bus0_pll_con[2];
23 unsigned int rsvd2[2];
24 unsigned int bus1_pll_con[2];
25 unsigned int rsvd3[54];
26 unsigned int mux_sel[6];
27 unsigned int rsvd4[250];
28 unsigned int div[4];
29};
30
31/* CMU TOP0 block device structure */
32struct exynos7420_clk_cmu_top0 {
33 unsigned int rsvd0[128];
34 unsigned int mux_sel[7];
35 unsigned int rsvd1[261];
36 unsigned int div_peric[5];
37};
38
39/**
40 * struct exynos7420_clk_topc_priv - private data for CMU topc clock driver.
41 *
42 * @topc: base address of the memory mapped CMU TOPC controller.
43 * @fin_freq: frequency of the Oscillator clock.
44 * @sclk_bus0_pll_a: frequency of sclk_bus0_pll_a clock.
45 * @sclk_bus1_pll_a: frequency of sclk_bus1_pll_a clock.
46 */
47struct exynos7420_clk_topc_priv {
48 struct exynos7420_clk_cmu_topc *topc;
49 unsigned long fin_freq;
50 unsigned long sclk_bus0_pll_a;
51 unsigned long sclk_bus1_pll_a;
52};
53
54/**
55 * struct exynos7420_clk_top0_priv - private data for CMU top0 clock driver.
56 *
57 * @top0: base address of the memory mapped CMU TOP0 controller.
58 * @mout_top0_bus0_pll_half: frequency of mout_top0_bus0_pll_half clock
59 * @sclk_uart2: frequency of sclk_uart2 clock.
60 */
61struct exynos7420_clk_top0_priv {
62 struct exynos7420_clk_cmu_top0 *top0;
63 unsigned long mout_top0_bus0_pll_half;
64 unsigned long sclk_uart2;
65};
66
135aa950 67static ulong exynos7420_topc_get_rate(struct clk *clk)
166097e8 68{
135aa950 69 struct exynos7420_clk_topc_priv *priv = dev_get_priv(clk->dev);
166097e8 70
135aa950 71 switch (clk->id) {
166097e8
TA
72 case DOUT_SCLK_BUS0_PLL:
73 case SCLK_BUS0_PLL_A:
74 case SCLK_BUS0_PLL_B:
75 return priv->sclk_bus0_pll_a;
76 case DOUT_SCLK_BUS1_PLL:
77 case SCLK_BUS1_PLL_A:
78 case SCLK_BUS1_PLL_B:
79 return priv->sclk_bus1_pll_a;
80 default:
81 return 0;
82 }
83}
84
85static struct clk_ops exynos7420_clk_topc_ops = {
135aa950 86 .get_rate = exynos7420_topc_get_rate,
166097e8
TA
87};
88
89static int exynos7420_clk_topc_probe(struct udevice *dev)
90{
91 struct exynos7420_clk_topc_priv *priv = dev_get_priv(dev);
92 struct exynos7420_clk_cmu_topc *topc;
135aa950 93 struct clk in_clk;
166097e8
TA
94 unsigned long rate;
95 fdt_addr_t base;
96 int ret;
97
2548493a 98 base = dev_read_addr(dev);
166097e8
TA
99 if (base == FDT_ADDR_T_NONE)
100 return -EINVAL;
101
102 topc = (struct exynos7420_clk_cmu_topc *)base;
103 priv->topc = topc;
104
135aa950 105 ret = clk_get_by_index(dev, 0, &in_clk);
166097e8 106 if (ret >= 0)
135aa950 107 priv->fin_freq = clk_get_rate(&in_clk);
166097e8
TA
108
109 rate = pll145x_get_rate(&topc->bus0_pll_con[0], priv->fin_freq);
110 if (readl(&topc->mux_sel[1]) & (1 << 16))
111 rate >>= 1;
112 rate /= DIVIDER(&topc->div[3], 0, 0xf);
113 priv->sclk_bus0_pll_a = rate;
114
115 rate = pll145x_get_rate(&topc->bus1_pll_con[0], priv->fin_freq) /
116 DIVIDER(&topc->div[3], 8, 0xf);
117 priv->sclk_bus1_pll_a = rate;
118
119 return 0;
120}
121
135aa950 122static ulong exynos7420_top0_get_rate(struct clk *clk)
166097e8 123{
135aa950 124 struct exynos7420_clk_top0_priv *priv = dev_get_priv(clk->dev);
166097e8
TA
125 struct exynos7420_clk_cmu_top0 *top0 = priv->top0;
126
135aa950 127 switch (clk->id) {
166097e8
TA
128 case CLK_SCLK_UART2:
129 return priv->mout_top0_bus0_pll_half /
130 DIVIDER(&top0->div_peric[3], 8, 0xf);
131 default:
132 return 0;
133 }
134}
135
136static struct clk_ops exynos7420_clk_top0_ops = {
135aa950 137 .get_rate = exynos7420_top0_get_rate,
166097e8
TA
138};
139
140static int exynos7420_clk_top0_probe(struct udevice *dev)
141{
142 struct exynos7420_clk_top0_priv *priv;
143 struct exynos7420_clk_cmu_top0 *top0;
135aa950 144 struct clk in_clk;
166097e8
TA
145 fdt_addr_t base;
146 int ret;
147
148 priv = dev_get_priv(dev);
149 if (!priv)
150 return -EINVAL;
151
2548493a 152 base = dev_read_addr(dev);
166097e8
TA
153 if (base == FDT_ADDR_T_NONE)
154 return -EINVAL;
155
156 top0 = (struct exynos7420_clk_cmu_top0 *)base;
157 priv->top0 = top0;
158
135aa950 159 ret = clk_get_by_index(dev, 1, &in_clk);
166097e8
TA
160 if (ret >= 0) {
161 priv->mout_top0_bus0_pll_half =
135aa950 162 clk_get_rate(&in_clk);
166097e8
TA
163 if (readl(&top0->mux_sel[1]) & (1 << 16))
164 priv->mout_top0_bus0_pll_half >>= 1;
165 }
166
167 return 0;
168}
169
135aa950 170static ulong exynos7420_peric1_get_rate(struct clk *clk)
166097e8 171{
135aa950 172 struct clk in_clk;
166097e8
TA
173 unsigned int ret;
174 unsigned long freq = 0;
175
135aa950 176 switch (clk->id) {
166097e8 177 case SCLK_UART2:
135aa950 178 ret = clk_get_by_index(clk->dev, 3, &in_clk);
166097e8
TA
179 if (ret < 0)
180 return ret;
135aa950 181 freq = clk_get_rate(&in_clk);
166097e8
TA
182 break;
183 }
184
185 return freq;
186}
187
188static struct clk_ops exynos7420_clk_peric1_ops = {
135aa950 189 .get_rate = exynos7420_peric1_get_rate,
166097e8
TA
190};
191
192static const struct udevice_id exynos7420_clk_topc_compat[] = {
193 { .compatible = "samsung,exynos7-clock-topc" },
194 { }
195};
196
197U_BOOT_DRIVER(exynos7420_clk_topc) = {
198 .name = "exynos7420-clock-topc",
199 .id = UCLASS_CLK,
200 .of_match = exynos7420_clk_topc_compat,
201 .probe = exynos7420_clk_topc_probe,
41575d8e 202 .priv_auto = sizeof(struct exynos7420_clk_topc_priv),
166097e8 203 .ops = &exynos7420_clk_topc_ops,
166097e8
TA
204};
205
206static const struct udevice_id exynos7420_clk_top0_compat[] = {
207 { .compatible = "samsung,exynos7-clock-top0" },
208 { }
209};
210
211U_BOOT_DRIVER(exynos7420_clk_top0) = {
212 .name = "exynos7420-clock-top0",
213 .id = UCLASS_CLK,
214 .of_match = exynos7420_clk_top0_compat,
215 .probe = exynos7420_clk_top0_probe,
41575d8e 216 .priv_auto = sizeof(struct exynos7420_clk_top0_priv),
166097e8 217 .ops = &exynos7420_clk_top0_ops,
166097e8
TA
218};
219
220static const struct udevice_id exynos7420_clk_peric1_compat[] = {
221 { .compatible = "samsung,exynos7-clock-peric1" },
222 { }
223};
224
225U_BOOT_DRIVER(exynos7420_clk_peric1) = {
226 .name = "exynos7420-clock-peric1",
227 .id = UCLASS_CLK,
228 .of_match = exynos7420_clk_peric1_compat,
229 .ops = &exynos7420_clk_peric1_ops,
166097e8 230};
This page took 0.192316 seconds and 4 git commands to generate.