blob: 1d5cbb589adeca76066f5645c6d5dab72c8bcc57 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Simon Glass8cc4d822015-07-06 12:54:24 -06002/*
3 * (C) Copyright 2015 Google, Inc
Simon Glass8cc4d822015-07-06 12:54:24 -06004 */
5
6#include <common.h>
Stephen Warrena9622432016-06-17 09:44:00 -06007#include <clk-uclass.h>
Simon Glass8cc4d822015-07-06 12:54:24 -06008#include <dm.h>
9#include <errno.h>
Stephen Warrena9622432016-06-17 09:44:00 -060010#include <asm/clk.h>
Simon Glass8cc4d822015-07-06 12:54:24 -060011
12struct sandbox_clk_priv {
Stephen Warrena9622432016-06-17 09:44:00 -060013 ulong rate[SANDBOX_CLK_ID_COUNT];
14 bool enabled[SANDBOX_CLK_ID_COUNT];
Simon Glass8cc4d822015-07-06 12:54:24 -060015};
16
Stephen Warrena9622432016-06-17 09:44:00 -060017static ulong sandbox_clk_get_rate(struct clk *clk)
Simon Glass8cc4d822015-07-06 12:54:24 -060018{
Stephen Warrena9622432016-06-17 09:44:00 -060019 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
20
Stephen Warrendaec47b2016-06-21 13:32:07 -060021 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Stephen Warrena9622432016-06-17 09:44:00 -060022 return -EINVAL;
Simon Glass8cc4d822015-07-06 12:54:24 -060023
Stephen Warrena9622432016-06-17 09:44:00 -060024 return priv->rate[clk->id];
Simon Glass8cc4d822015-07-06 12:54:24 -060025}
26
Stephen Warrena9622432016-06-17 09:44:00 -060027static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
Simon Glass8cc4d822015-07-06 12:54:24 -060028{
Stephen Warrena9622432016-06-17 09:44:00 -060029 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
30 ulong old_rate;
31
Stephen Warrendaec47b2016-06-21 13:32:07 -060032 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Stephen Warrena9622432016-06-17 09:44:00 -060033 return -EINVAL;
Simon Glass8cc4d822015-07-06 12:54:24 -060034
35 if (!rate)
36 return -EINVAL;
Simon Glass8cc4d822015-07-06 12:54:24 -060037
Stephen Warrena9622432016-06-17 09:44:00 -060038 old_rate = priv->rate[clk->id];
39 priv->rate[clk->id] = rate;
Simon Glass8cc4d822015-07-06 12:54:24 -060040
Stephen Warrena9622432016-06-17 09:44:00 -060041 return old_rate;
Simon Glass8cc4d822015-07-06 12:54:24 -060042}
43
Stephen Warrena9622432016-06-17 09:44:00 -060044static int sandbox_clk_enable(struct clk *clk)
Simon Glass8cc4d822015-07-06 12:54:24 -060045{
Stephen Warrena9622432016-06-17 09:44:00 -060046 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
Simon Glass8cc4d822015-07-06 12:54:24 -060047
Stephen Warrendaec47b2016-06-21 13:32:07 -060048 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Simon Glass8cc4d822015-07-06 12:54:24 -060049 return -EINVAL;
Simon Glass8cc4d822015-07-06 12:54:24 -060050
Stephen Warrena9622432016-06-17 09:44:00 -060051 priv->enabled[clk->id] = true;
52
53 return 0;
Simon Glass8cc4d822015-07-06 12:54:24 -060054}
55
Stephen Warrena9622432016-06-17 09:44:00 -060056static int sandbox_clk_disable(struct clk *clk)
Simon Glass8cc4d822015-07-06 12:54:24 -060057{
Stephen Warrena9622432016-06-17 09:44:00 -060058 struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
59
Stephen Warrendaec47b2016-06-21 13:32:07 -060060 if (clk->id >= SANDBOX_CLK_ID_COUNT)
Stephen Warrena9622432016-06-17 09:44:00 -060061 return -EINVAL;
Simon Glass8cc4d822015-07-06 12:54:24 -060062
Stephen Warrena9622432016-06-17 09:44:00 -060063 priv->enabled[clk->id] = false;
Simon Glass8cc4d822015-07-06 12:54:24 -060064
65 return 0;
66}
67
68static struct clk_ops sandbox_clk_ops = {
69 .get_rate = sandbox_clk_get_rate,
70 .set_rate = sandbox_clk_set_rate,
Stephen Warrena9622432016-06-17 09:44:00 -060071 .enable = sandbox_clk_enable,
72 .disable = sandbox_clk_disable,
Simon Glass8cc4d822015-07-06 12:54:24 -060073};
74
75static const struct udevice_id sandbox_clk_ids[] = {
76 { .compatible = "sandbox,clk" },
77 { }
78};
79
80U_BOOT_DRIVER(clk_sandbox) = {
81 .name = "clk_sandbox",
82 .id = UCLASS_CLK,
83 .of_match = sandbox_clk_ids,
84 .ops = &sandbox_clk_ops,
85 .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv),
Simon Glass8cc4d822015-07-06 12:54:24 -060086};
Stephen Warrena9622432016-06-17 09:44:00 -060087
88ulong sandbox_clk_query_rate(struct udevice *dev, int id)
89{
90 struct sandbox_clk_priv *priv = dev_get_priv(dev);
91
92 if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
93 return -EINVAL;
94
95 return priv->rate[id];
96}
97
98int sandbox_clk_query_enable(struct udevice *dev, int id)
99{
100 struct sandbox_clk_priv *priv = dev_get_priv(dev);
101
102 if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
103 return -EINVAL;
104
105 return priv->enabled[id];
106}