c8af7e3191825dfba89eb9bd544a2ce10d20d1c3
[openwrt/staging/ansuel.git] /
1 From 50859bea6a3334834b8250e7e5406507f0d0918a Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Wed, 31 Aug 2022 19:05:06 +0800
4 Subject: [PATCH 23/32] clk: mediatek: add support to configure clock driver
5 parent
6
7 This patch adds support for a clock node to configure its parent clock
8 where possible.
9
10 Reviewed-by: Simon Glass <sjg@chromium.org>
11 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
12 ---
13 drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++--------------
14 drivers/clk/mediatek/clk-mtk.h | 2 +
15 2 files changed, 48 insertions(+), 33 deletions(-)
16
17 --- a/drivers/clk/mediatek/clk-mtk.c
18 +++ b/drivers/clk/mediatek/clk-mtk.c
19 @@ -42,20 +42,14 @@
20 * the accurate frequency.
21 */
22 static ulong mtk_clk_find_parent_rate(struct clk *clk, int id,
23 - const struct driver *drv)
24 + struct udevice *pdev)
25 {
26 struct clk parent = { .id = id, };
27
28 - if (drv) {
29 - struct udevice *dev;
30 -
31 - if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev))
32 - return -ENODEV;
33 -
34 - parent.dev = dev;
35 - } else {
36 + if (pdev)
37 + parent.dev = pdev;
38 + else
39 parent.dev = clk->dev;
40 - }
41
42 return clk_get_rate(&parent);
43 }
44 @@ -296,7 +290,7 @@ static ulong mtk_topckgen_get_factor_rat
45 switch (fdiv->flags & CLK_PARENT_MASK) {
46 case CLK_PARENT_APMIXED:
47 rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
48 - DM_DRIVER_GET(mtk_clk_apmixedsys));
49 + priv->parent);
50 break;
51 case CLK_PARENT_TOPCKGEN:
52 rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
53 @@ -321,9 +315,18 @@ static ulong mtk_topckgen_get_mux_rate(s
54
55 if (mux->parent[index] > 0 ||
56 (mux->parent[index] == CLK_XTAL &&
57 - priv->tree->flags & CLK_BYPASS_XTAL))
58 - return mtk_clk_find_parent_rate(clk, mux->parent[index],
59 - NULL);
60 + priv->tree->flags & CLK_BYPASS_XTAL)) {
61 + switch (mux->flags & CLK_PARENT_MASK) {
62 + case CLK_PARENT_APMIXED:
63 + return mtk_clk_find_parent_rate(clk, mux->parent[index],
64 + priv->parent);
65 + break;
66 + default:
67 + return mtk_clk_find_parent_rate(clk, mux->parent[index],
68 + NULL);
69 + break;
70 + }
71 + }
72
73 return priv->tree->xtal_rate;
74 }
75 @@ -342,7 +345,7 @@ static ulong mtk_topckgen_get_rate(struc
76 priv->tree->muxes_offs);
77 }
78
79 -static int mtk_topckgen_enable(struct clk *clk)
80 +static int mtk_clk_mux_enable(struct clk *clk)
81 {
82 struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
83 const struct mtk_composite *mux;
84 @@ -375,7 +378,7 @@ static int mtk_topckgen_enable(struct cl
85 return 0;
86 }
87
88 -static int mtk_topckgen_disable(struct clk *clk)
89 +static int mtk_clk_mux_disable(struct clk *clk)
90 {
91 struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
92 const struct mtk_composite *mux;
93 @@ -401,7 +404,7 @@ static int mtk_topckgen_disable(struct c
94 return 0;
95 }
96
97 -static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent)
98 +static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent)
99 {
100 struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
101
102 @@ -473,19 +476,7 @@ static ulong mtk_clk_gate_get_rate(struc
103 struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
104 const struct mtk_gate *gate = &priv->gates[clk->id];
105
106 - switch (gate->flags & CLK_PARENT_MASK) {
107 - case CLK_PARENT_APMIXED:
108 - return mtk_clk_find_parent_rate(clk, gate->parent,
109 - DM_DRIVER_GET(mtk_clk_apmixedsys));
110 - break;
111 - case CLK_PARENT_TOPCKGEN:
112 - return mtk_clk_find_parent_rate(clk, gate->parent,
113 - DM_DRIVER_GET(mtk_clk_topckgen));
114 - break;
115 -
116 - default:
117 - return priv->tree->xtal_rate;
118 - }
119 + return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent);
120 }
121
122 const struct clk_ops mtk_clk_apmixedsys_ops = {
123 @@ -496,10 +487,10 @@ const struct clk_ops mtk_clk_apmixedsys_
124 };
125
126 const struct clk_ops mtk_clk_topckgen_ops = {
127 - .enable = mtk_topckgen_enable,
128 - .disable = mtk_topckgen_disable,
129 + .enable = mtk_clk_mux_enable,
130 + .disable = mtk_clk_mux_disable,
131 .get_rate = mtk_topckgen_get_rate,
132 - .set_parent = mtk_topckgen_set_parent,
133 + .set_parent = mtk_common_clk_set_parent,
134 };
135
136 const struct clk_ops mtk_clk_gate_ops = {
137 @@ -512,11 +503,22 @@ int mtk_common_clk_init(struct udevice *
138 const struct mtk_clk_tree *tree)
139 {
140 struct mtk_clk_priv *priv = dev_get_priv(dev);
141 + struct udevice *parent;
142 + int ret;
143
144 priv->base = dev_read_addr_ptr(dev);
145 if (!priv->base)
146 return -ENOENT;
147
148 + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
149 + if (ret || !parent) {
150 + ret = uclass_get_device_by_driver(UCLASS_CLK,
151 + DM_DRIVER_GET(mtk_clk_apmixedsys), &parent);
152 + if (ret || !parent)
153 + return -ENOENT;
154 + }
155 +
156 + priv->parent = parent;
157 priv->tree = tree;
158
159 return 0;
160 @@ -527,11 +529,22 @@ int mtk_common_clk_gate_init(struct udev
161 const struct mtk_gate *gates)
162 {
163 struct mtk_cg_priv *priv = dev_get_priv(dev);
164 + struct udevice *parent;
165 + int ret;
166
167 priv->base = dev_read_addr_ptr(dev);
168 if (!priv->base)
169 return -ENOENT;
170
171 + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent);
172 + if (ret || !parent) {
173 + ret = uclass_get_device_by_driver(UCLASS_CLK,
174 + DM_DRIVER_GET(mtk_clk_topckgen), &parent);
175 + if (ret || !parent)
176 + return -ENOENT;
177 + }
178 +
179 + priv->parent = parent;
180 priv->tree = tree;
181 priv->gates = gates;
182
183 --- a/drivers/clk/mediatek/clk-mtk.h
184 +++ b/drivers/clk/mediatek/clk-mtk.h
185 @@ -206,11 +206,13 @@ struct mtk_clk_tree {
186 };
187
188 struct mtk_clk_priv {
189 + struct udevice *parent;
190 void __iomem *base;
191 const struct mtk_clk_tree *tree;
192 };
193
194 struct mtk_cg_priv {
195 + struct udevice *parent;
196 void __iomem *base;
197 const struct mtk_clk_tree *tree;
198 const struct mtk_gate *gates;