hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/clk/clk-fractional-divider.c
....@@ -1,9 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) 2014 Intel Corporation
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
74 *
85 * Adjustable fractional divider clock implementation.
96 * Output rate = (m / n) * parent_rate.
....@@ -11,10 +8,27 @@
118 */
129
1310 #include <linux/clk-provider.h>
11
+#include <linux/io.h>
1412 #include <linux/module.h>
1513 #include <linux/device.h>
1614 #include <linux/slab.h>
1715 #include <linux/rational.h>
16
+
17
+static inline u32 clk_fd_readl(struct clk_fractional_divider *fd)
18
+{
19
+ if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
20
+ return ioread32be(fd->reg);
21
+
22
+ return readl(fd->reg);
23
+}
24
+
25
+static inline void clk_fd_writel(struct clk_fractional_divider *fd, u32 val)
26
+{
27
+ if (fd->flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
28
+ iowrite32be(val, fd->reg);
29
+ else
30
+ writel(val, fd->reg);
31
+}
1832
1933 static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
2034 unsigned long parent_rate)
....@@ -30,7 +44,7 @@
3044 else
3145 __acquire(fd->lock);
3246
33
- val = clk_readl(fd->reg);
47
+ val = clk_fd_readl(fd);
3448
3549 if (fd->lock)
3650 spin_unlock_irqrestore(fd->lock, flags);
....@@ -39,6 +53,11 @@
3953
4054 m = (val & fd->mmask) >> fd->mshift;
4155 n = (val & fd->nmask) >> fd->nshift;
56
+
57
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
58
+ m++;
59
+ n++;
60
+ }
4261
4362 if (!n || !m)
4463 return parent_rate;
....@@ -77,16 +96,13 @@
7796 unsigned long m, n;
7897 u64 ret;
7998
80
- if (!rate)
99
+ if (!rate && rate >= *parent_rate)
81100 return *parent_rate;
82101
83
- if (fd->approximation) {
102
+ if (fd->approximation)
84103 fd->approximation(hw, rate, parent_rate, &m, &n);
85
- } else {
86
- if (rate >= *parent_rate)
87
- return *parent_rate;
104
+ else
88105 clk_fd_general_approximation(hw, rate, parent_rate, &m, &n);
89
- }
90106
91107 ret = (u64)*parent_rate * m;
92108 do_div(ret, n);
....@@ -106,6 +122,10 @@
106122 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
107123 &m, &n);
108124
125
+ if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
126
+ m--;
127
+ n--;
128
+ }
109129 /*
110130 * When compensation the fractional divider,
111131 * the [1:0] bits of the numerator register are omitted,
....@@ -138,10 +158,10 @@
138158 else
139159 __acquire(fd->lock);
140160
141
- val = clk_readl(fd->reg);
161
+ val = clk_fd_readl(fd);
142162 val &= ~(fd->mmask | fd->nmask);
143163 val |= (m << fd->mshift) | (n << fd->nshift);
144
- clk_writel(val, fd->reg);
164
+ clk_fd_writel(fd, val);
145165
146166 if (fd->lock)
147167 spin_unlock_irqrestore(fd->lock, flags);
....@@ -164,7 +184,7 @@
164184 u8 clk_divider_flags, spinlock_t *lock)
165185 {
166186 struct clk_fractional_divider *fd;
167
- struct clk_init_data init = {};
187
+ struct clk_init_data init;
168188 struct clk_hw *hw;
169189 int ret;
170190
....@@ -174,7 +194,7 @@
174194
175195 init.name = name;
176196 init.ops = &clk_fractional_divider_ops;
177
- init.flags = flags | CLK_IS_BASIC;
197
+ init.flags = flags;
178198 init.parent_names = parent_name ? &parent_name : NULL;
179199 init.num_parents = parent_name ? 1 : 0;
180200