blob: cc084b0644cf95db529a130d5366ed86759585d5 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Simon Glass6a1c7ce2015-07-06 12:54:24 -06002/*
3 * (C) Copyright 2015 Google, Inc
Simon Glass6a1c7ce2015-07-06 12:54:24 -06004 */
5
6#include <common.h>
Stephen Warren135aa952016-06-17 09:44:00 -06007#include <clk-uclass.h>
Simon Glass6a1c7ce2015-07-06 12:54:24 -06008#include <dm.h>
9#include <errno.h>
Stephen Warren135aa952016-06-17 09:44:00 -060010#include <asm/clk.h>
Simon Glass6a1c7ce2015-07-06 12:54:24 -060011
12struct sandbox_clk_priv {
Jean-Jacques Hiblot9a52be12019-10-22 14:00:07 +020013 bool probed;
Stephen Warren135aa952016-06-17 09:44:00 -060014 ulong rate[SANDBOX_CLK_ID_COUNT];
15 bool enabled[SANDBOX_CLK_ID_COUNT];
Jean-Jacques Hiblotdd2e0ce2019-10-22 14:00:05 +020016 bool requested[SANDBOX_CLK_ID_COUNT];
Simon Glass6a1c7ce2015-07-06 12:54:24 -060017};
18
Stephen Warren135aa952016-06-17 09:44:00 -060019static ulong sandbox_clk_get_rate(struct clk *clk)
Simon Glass6a1c7ce2015-07-06 12:54:24 -060020{
Stephen Warren135aa952016-06-17 09:44:00 -060021 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
Simon Glass6a1c7ce2015-07-06 12:54:24 -060022
Jean-Jacques Hiblot9a52be12019-10-22 14:00:07 +020023 if (!priv->probed)
24 return -ENODEV;
25
Stephen Warrendf8b0a02016-06-21 13:32:07 -060026 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Stephen Warren135aa952016-06-17 09:44:00 -060027 return -EINVAL;
28
29 return priv->rate[clk->id];
Simon Glass6a1c7ce2015-07-06 12:54:24 -060030}
31
Stephen Warren135aa952016-06-17 09:44:00 -060032static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
Simon Glass6a1c7ce2015-07-06 12:54:24 -060033{
Stephen Warren135aa952016-06-17 09:44:00 -060034 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
35 ulong old_rate;
36
Jean-Jacques Hiblot9a52be12019-10-22 14:00:07 +020037 if (!priv->probed)
38 return -ENODEV;
39
Stephen Warrendf8b0a02016-06-21 13:32:07 -060040 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Stephen Warren135aa952016-06-17 09:44:00 -060041 return -EINVAL;
Simon Glass6a1c7ce2015-07-06 12:54:24 -060042
43 if (!rate)
44 return -EINVAL;
Simon Glass6a1c7ce2015-07-06 12:54:24 -060045
Stephen Warren135aa952016-06-17 09:44:00 -060046 old_rate = priv->rate[clk->id];
47 priv->rate[clk->id] = rate;
Simon Glass6a1c7ce2015-07-06 12:54:24 -060048
49 return old_rate;
50}
51
Stephen Warren135aa952016-06-17 09:44:00 -060052static int sandbox_clk_enable(struct clk *clk)
Simon Glass6a1c7ce2015-07-06 12:54:24 -060053{
Stephen Warren135aa952016-06-17 09:44:00 -060054 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
Simon Glass6a1c7ce2015-07-06 12:54:24 -060055
Jean-Jacques Hiblot9a52be12019-10-22 14:00:07 +020056 if (!priv->probed)
57 return -ENODEV;
58
Stephen Warrendf8b0a02016-06-21 13:32:07 -060059 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Stephen Warren135aa952016-06-17 09:44:00 -060060 return -EINVAL;
61
62 priv->enabled[clk->id] = true;
63
64 return 0;
65}
66
67static int sandbox_clk_disable(struct clk *clk)
68{
69 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
70
Jean-Jacques Hiblot9a52be12019-10-22 14:00:07 +020071 if (!priv->probed)
72 return -ENODEV;
73
Stephen Warrendf8b0a02016-06-21 13:32:07 -060074 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Stephen Warren135aa952016-06-17 09:44:00 -060075 return -EINVAL;
76
77 priv->enabled[clk->id] = false;
Simon Glass6a1c7ce2015-07-06 12:54:24 -060078
79 return 0;
80}
81
Jean-Jacques Hiblotdd2e0ce2019-10-22 14:00:05 +020082static int sandbox_clk_request(struct clk *clk)
83{
84 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
85
86 if (clk->id >= SANDBOX_CLK_ID_COUNT)
87 return -EINVAL;
88
89 priv->requested[clk->id] = true;
90 return 0;
91}
92
93static int sandbox_clk_free(struct clk *clk)
94{
95 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
96
97 if (clk->id >= SANDBOX_CLK_ID_COUNT)
98 return -EINVAL;
99
100 priv->requested[clk->id] = false;
101 return 0;
102}
103
Simon Glass6a1c7ce2015-07-06 12:54:24 -0600104static struct clk_ops sandbox_clk_ops = {
105 .get_rate = sandbox_clk_get_rate,
106 .set_rate = sandbox_clk_set_rate,
Stephen Warren135aa952016-06-17 09:44:00 -0600107 .enable = sandbox_clk_enable,
108 .disable = sandbox_clk_disable,
Jean-Jacques Hiblotdd2e0ce2019-10-22 14:00:05 +0200109 .request = sandbox_clk_request,
Simon Glassfb8c0d52020-02-03 07:35:54 -0700110 .rfree = sandbox_clk_free,
Simon Glass6a1c7ce2015-07-06 12:54:24 -0600111};
112
Jean-Jacques Hiblot9a52be12019-10-22 14:00:07 +0200113static int sandbox_clk_probe(struct udevice *dev)
114{
115 struct sandbox_clk_priv *priv = dev_get_priv(dev);
116
117 priv->probed = true;
118 return 0;
119}
120
Simon Glass6a1c7ce2015-07-06 12:54:24 -0600121static const struct udevice_id sandbox_clk_ids[] = {
122 { .compatible = "sandbox,clk" },
123 { }
124};
125
126U_BOOT_DRIVER(clk_sandbox) = {
127 .name = "clk_sandbox",
128 .id = UCLASS_CLK,
129 .of_match = sandbox_clk_ids,
130 .ops = &sandbox_clk_ops,
Jean-Jacques Hiblot9a52be12019-10-22 14:00:07 +0200131 .probe = sandbox_clk_probe,
Simon Glass6a1c7ce2015-07-06 12:54:24 -0600132 .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv),
Simon Glass6a1c7ce2015-07-06 12:54:24 -0600133};
Stephen Warren135aa952016-06-17 09:44:00 -0600134
135ulong sandbox_clk_query_rate(struct udevice *dev, int id)
136{
137 struct sandbox_clk_priv *priv = dev_get_priv(dev);
138
139 if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
140 return -EINVAL;
141
142 return priv->rate[id];
143}
144
145int sandbox_clk_query_enable(struct udevice *dev, int id)
146{
147 struct sandbox_clk_priv *priv = dev_get_priv(dev);
148
149 if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
150 return -EINVAL;
151
152 return priv->enabled[id];
153}
Jean-Jacques Hiblotdd2e0ce2019-10-22 14:00:05 +0200154
155int sandbox_clk_query_requested(struct udevice *dev, int id)
156{
157 struct sandbox_clk_priv *priv = dev_get_priv(dev);
158
159 if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
160 return -EINVAL;
161 return priv->requested[id];
162}