]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - arch/mips/lantiq/clk.c
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500
[mirror_ubuntu-jammy-kernel.git] / arch / mips / lantiq / clk.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
171bb2f1 2/*
171bb2f1
JC
3 *
4 * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
97b92108 5 * Copyright (C) 2010 John Crispin <john@phrozen.org>
171bb2f1
JC
6 */
7#include <linux/io.h>
4af92e7a 8#include <linux/export.h>
171bb2f1
JC
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/types.h>
12#include <linux/clk.h>
287e3f3f 13#include <linux/clkdev.h>
171bb2f1
JC
14#include <linux/err.h>
15#include <linux/list.h>
16
17#include <asm/time.h>
18#include <asm/irq.h>
19#include <asm/div64.h>
20
21#include <lantiq_soc.h>
22
23#include "clk.h"
287e3f3f 24#include "prom.h"
171bb2f1 25
287e3f3f 26/* lantiq socs have 3 static clocks */
740c606e 27static struct clk cpu_clk_generic[4];
171bb2f1 28
740c606e
JC
29void clkdev_add_static(unsigned long cpu, unsigned long fpi,
30 unsigned long io, unsigned long ppe)
287e3f3f
JC
31{
32 cpu_clk_generic[0].rate = cpu;
33 cpu_clk_generic[1].rate = fpi;
34 cpu_clk_generic[2].rate = io;
740c606e 35 cpu_clk_generic[3].rate = ppe;
287e3f3f 36}
171bb2f1 37
287e3f3f
JC
38struct clk *clk_get_cpu(void)
39{
40 return &cpu_clk_generic[0];
41}
42
43struct clk *clk_get_fpi(void)
44{
45 return &cpu_clk_generic[1];
46}
47EXPORT_SYMBOL_GPL(clk_get_fpi);
48
49struct clk *clk_get_io(void)
171bb2f1 50{
287e3f3f 51 return &cpu_clk_generic[2];
171bb2f1
JC
52}
53
740c606e
JC
54struct clk *clk_get_ppe(void)
55{
56 return &cpu_clk_generic[3];
57}
58EXPORT_SYMBOL_GPL(clk_get_ppe);
59
171bb2f1
JC
60static inline int clk_good(struct clk *clk)
61{
62 return clk && !IS_ERR(clk);
63}
64
65unsigned long clk_get_rate(struct clk *clk)
66{
67 if (unlikely(!clk_good(clk)))
68 return 0;
69
70 if (clk->rate != 0)
71 return clk->rate;
72
73 if (clk->get_rate != NULL)
74 return clk->get_rate();
75
76 return 0;
77}
78EXPORT_SYMBOL(clk_get_rate);
79
287e3f3f 80int clk_set_rate(struct clk *clk, unsigned long rate)
171bb2f1 81{
287e3f3f
JC
82 if (unlikely(!clk_good(clk)))
83 return 0;
84 if (clk->rates && *clk->rates) {
85 unsigned long *r = clk->rates;
86
87 while (*r && (*r != rate))
88 r++;
89 if (!*r) {
90 pr_err("clk %s.%s: trying to set invalid rate %ld\n",
91 clk->cl.dev_id, clk->cl.con_id, rate);
92 return -1;
93 }
94 }
95 clk->rate = rate;
96 return 0;
171bb2f1 97}
287e3f3f 98EXPORT_SYMBOL(clk_set_rate);
171bb2f1 99
500fab97
HM
100long clk_round_rate(struct clk *clk, unsigned long rate)
101{
102 if (unlikely(!clk_good(clk)))
103 return 0;
104 if (clk->rates && *clk->rates) {
105 unsigned long *r = clk->rates;
106
107 while (*r && (*r != rate))
108 r++;
109 if (!*r) {
110 return clk->rate;
111 }
112 }
113 return rate;
114}
115EXPORT_SYMBOL(clk_round_rate);
116
744120aa
JC
117int clk_enable(struct clk *clk)
118{
287e3f3f
JC
119 if (unlikely(!clk_good(clk)))
120 return -1;
121
122 if (clk->enable)
123 return clk->enable(clk);
124
125 return -1;
744120aa
JC
126}
127EXPORT_SYMBOL(clk_enable);
128
129void clk_disable(struct clk *clk)
130{
287e3f3f
JC
131 if (unlikely(!clk_good(clk)))
132 return;
133
134 if (clk->disable)
135 clk->disable(clk);
744120aa
JC
136}
137EXPORT_SYMBOL(clk_disable);
138
287e3f3f
JC
139int clk_activate(struct clk *clk)
140{
141 if (unlikely(!clk_good(clk)))
142 return -1;
143
144 if (clk->activate)
145 return clk->activate(clk);
146
147 return -1;
148}
149EXPORT_SYMBOL(clk_activate);
150
151void clk_deactivate(struct clk *clk)
152{
153 if (unlikely(!clk_good(clk)))
154 return;
155
156 if (clk->deactivate)
157 clk->deactivate(clk);
158}
159EXPORT_SYMBOL(clk_deactivate);
160
161static inline u32 get_counter_resolution(void)
171bb2f1
JC
162{
163 u32 res;
164
165 __asm__ __volatile__(
70342287
RB
166 ".set push\n"
167 ".set mips32r2\n"
168 "rdhwr %0, $3\n"
171bb2f1
JC
169 ".set pop\n"
170 : "=&r" (res)
171 : /* no input */
172 : "memory");
173
174 return res;
175}
176
177void __init plat_time_init(void)
178{
179 struct clk *clk;
180
287e3f3f 181 ltq_soc_init();
171bb2f1 182
287e3f3f
JC
183 clk = clk_get_cpu();
184 mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution();
171bb2f1 185 write_c0_compare(read_c0_count());
287e3f3f 186 pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000);
171bb2f1
JC
187 clk_put(clk);
188}