blob: 660e231921498f0cd0e5abfa1e2916f2a9d5c671 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Wenyou Yang8c772bd2016-07-20 17:55:12 +08002/*
3 * Copyright (C) 2016 Atmel Corporation
4 * Wenyou.Yang <wenyou.yang@atmel.com>
Wenyou Yang8c772bd2016-07-20 17:55:12 +08005 */
6
Claudiu Beznea3f203a12020-09-07 17:46:39 +03007#include <asm/io.h>
Claudiu Beznea6fa98982020-09-07 17:46:51 +03008#include <clk-uclass.h>
Wenyou Yang8c772bd2016-07-20 17:55:12 +08009#include <common.h>
Claudiu Beznea8fdb4252020-09-07 17:46:38 +030010
Claudiu Beznea6fa98982020-09-07 17:46:51 +030011#include "pmc.h"
12
13static int at91_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
14{
15 if (args->args_count != 2) {
16 debug("AT91: clk: Invalid args_count: %d\n", args->args_count);
17 return -EINVAL;
18 }
19
20 clk->id = AT91_TO_CLK_ID(args->args[0], args->args[1]);
21
22 return 0;
23}
24
25static ulong at91_clk_get_rate(struct clk *clk)
26{
27 struct clk *c;
28 int ret;
29
30 ret = clk_get_by_id(clk->id, &c);
31 if (ret)
32 return ret;
33
34 return clk_get_rate(c);
35}
36
37static ulong at91_clk_set_rate(struct clk *clk, ulong rate)
38{
39 struct clk *c;
40 int ret;
41
42 ret = clk_get_by_id(clk->id, &c);
43 if (ret)
44 return ret;
45
46 return clk_set_rate(c, rate);
47}
48
49static int at91_clk_enable(struct clk *clk)
50{
51 struct clk *c;
52 int ret;
53
54 ret = clk_get_by_id(clk->id, &c);
55 if (ret)
56 return ret;
57
58 return clk_enable(c);
59}
60
61static int at91_clk_disable(struct clk *clk)
62{
63 struct clk *c;
64 int ret;
65
66 ret = clk_get_by_id(clk->id, &c);
67 if (ret)
68 return ret;
69
70 return clk_disable(c);
71}
72
73const struct clk_ops at91_clk_ops = {
74 .of_xlate = at91_clk_of_xlate,
75 .set_rate = at91_clk_set_rate,
76 .get_rate = at91_clk_get_rate,
77 .enable = at91_clk_enable,
78 .disable = at91_clk_disable,
79};
80
Claudiu Beznea8fdb4252020-09-07 17:46:38 +030081/**
82 * pmc_read() - read content at address base + off into val
83 *
84 * @base: base address
85 * @off: offset to read from
86 * @val: where the content of base + off is stored
87 *
88 * @return: void
89 */
90void pmc_read(void __iomem *base, unsigned int off, unsigned int *val)
91{
92 *val = readl(base + off);
93}
94
95/**
96 * pmc_write() - write content of val at address base + off
97 *
98 * @base: base address
99 * @off: offset to write to
100 * @val: content to be written at base + off
101 *
102 * @return: void
103 */
104void pmc_write(void __iomem *base, unsigned int off, unsigned int val)
105{
106 writel(val, base + off);
107}
108
109/**
110 * pmc_update_bits() - update a set of bits at address base + off
111 *
112 * @base: base address
113 * @off: offset to be updated
114 * @mask: mask of bits to be updated
115 * @bits: the new value to be updated
116 *
117 * @return: void
118 */
119void pmc_update_bits(void __iomem *base, unsigned int off,
120 unsigned int mask, unsigned int bits)
121{
122 unsigned int tmp;
123
124 tmp = readl(base + off);
125 tmp &= ~mask;
126 writel(tmp | (bits & mask), base + off);
127}
128
129/**
130 * at91_clk_mux_val_to_index() - get parent index in mux table
131 *
132 * @table: clock mux table
133 * @num_parents: clock number of parents
134 * @val: clock id who's mux index should be retrieved
135 *
136 * @return: clock index in mux table or a negative error number in case of
137 * failure
138 */
139int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val)
140{
141 int i;
142
143 if (!table || !num_parents)
144 return -EINVAL;
145
146 for (i = 0; i < num_parents; i++) {
147 if (table[i] == val)
148 return i;
149 }
150
151 return -EINVAL;
152}
153
154/**
155 * at91_clk_mux_index_to_val() - get parent ID corresponding to an entry in
156 * clock's mux table
157 *
158 * @table: clock's mux table
159 * @num_parents: clock's number of parents
160 * @index: index in mux table which clock's ID should be retrieved
161 *
162 * @return: clock ID or a negative error number in case of failure
163 */
164int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index)
165{
166 if (!table || !num_parents || index < 0 || index > num_parents)
167 return -EINVAL;
168
169 return table[index];
170}