]> git.ipfire.org Git - thirdparty/u-boot.git/blame - drivers/clk/at91/pmc.c
Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
[thirdparty/u-boot.git] / drivers / clk / at91 / pmc.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
9e5935c0
WY
2/*
3 * Copyright (C) 2016 Atmel Corporation
4 * Wenyou.Yang <wenyou.yang@atmel.com>
9e5935c0
WY
5 */
6
d678a59d 7#include <common.h>
653bcce4 8#include <asm/io.h>
7b7e2267 9#include <clk-uclass.h>
682e73d2 10#include <linux/clk-provider.h>
7b7e2267
CB
11#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
7b7e2267
CB
25const struct clk_ops at91_clk_ops = {
26 .of_xlate = at91_clk_of_xlate,
682e73d2
SA
27 .set_rate = ccf_clk_set_rate,
28 .get_rate = ccf_clk_get_rate,
29 .enable = ccf_clk_enable,
30 .disable = ccf_clk_disable,
7b7e2267
CB
31};
32
5d729f96
CB
33/**
34 * pmc_read() - read content at address base + off into val
35 *
36 * @base: base address
37 * @off: offset to read from
38 * @val: where the content of base + off is stored
39 *
40 * @return: void
41 */
42void pmc_read(void __iomem *base, unsigned int off, unsigned int *val)
43{
44 *val = readl(base + off);
45}
46
47/**
48 * pmc_write() - write content of val at address base + off
49 *
50 * @base: base address
51 * @off: offset to write to
52 * @val: content to be written at base + off
53 *
54 * @return: void
55 */
56void pmc_write(void __iomem *base, unsigned int off, unsigned int val)
57{
58 writel(val, base + off);
59}
60
61/**
62 * pmc_update_bits() - update a set of bits at address base + off
63 *
64 * @base: base address
65 * @off: offset to be updated
66 * @mask: mask of bits to be updated
67 * @bits: the new value to be updated
68 *
69 * @return: void
70 */
71void pmc_update_bits(void __iomem *base, unsigned int off,
72 unsigned int mask, unsigned int bits)
73{
74 unsigned int tmp;
75
76 tmp = readl(base + off);
77 tmp &= ~mask;
78 writel(tmp | (bits & mask), base + off);
79}
80
81/**
82 * at91_clk_mux_val_to_index() - get parent index in mux table
83 *
84 * @table: clock mux table
85 * @num_parents: clock number of parents
86 * @val: clock id who's mux index should be retrieved
87 *
88 * @return: clock index in mux table or a negative error number in case of
89 * failure
90 */
91int at91_clk_mux_val_to_index(const u32 *table, u32 num_parents, u32 val)
92{
93 int i;
94
95 if (!table || !num_parents)
96 return -EINVAL;
97
98 for (i = 0; i < num_parents; i++) {
99 if (table[i] == val)
100 return i;
101 }
102
103 return -EINVAL;
104}
105
106/**
107 * at91_clk_mux_index_to_val() - get parent ID corresponding to an entry in
108 * clock's mux table
109 *
110 * @table: clock's mux table
111 * @num_parents: clock's number of parents
112 * @index: index in mux table which clock's ID should be retrieved
113 *
114 * @return: clock ID or a negative error number in case of failure
115 */
116int at91_clk_mux_index_to_val(const u32 *table, u32 num_parents, u32 index)
117{
118 if (!table || !num_parents || index < 0 || index > num_parents)
119 return -EINVAL;
120
121 return table[index];
122}
248e4100
CB
123
124int at91_clk_setup(const struct pmc_clk_setup *setup, int size)
125{
126 struct clk *c, *parent;
127 int i, ret;
128
129 if (!size)
130 return 0;
131
132 if (!setup)
133 return -EINVAL;
134
135 for (i = 0; i < size; i++) {
136 ret = clk_get_by_id(setup[i].cid, &c);
137 if (ret)
138 return ret;
139
140 if (setup[i].pid) {
141 ret = clk_get_by_id(setup[i].pid, &parent);
142 if (ret)
143 return ret;
144
145 ret = clk_set_parent(c, parent);
146 if (ret)
147 return ret;
148
149 if (setup[i].prate) {
150 ret = clk_set_rate(parent, setup[i].prate);
151 if (ret < 0)
152 return ret;
153 }
154 }
155
156 if (setup[i].rate) {
157 ret = clk_set_rate(c, setup[i].rate);
158 if (ret < 0)
159 return ret;
160 }
161 }
162
163 return 0;
164}