forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/clk/mvebu/ap806-system-controller.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Marvell Armada AP806 System Controller
34 *
....@@ -5,25 +6,22 @@
56 *
67 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
78 *
8
- * This file is licensed under the terms of the GNU General Public
9
- * License version 2. This program is licensed "as is" without any
10
- * warranty of any kind, whether express or implied.
119 */
1210
1311 #define pr_fmt(fmt) "ap806-system-controller: " fmt
1412
13
+#include "armada_ap_cp_helper.h"
1514 #include <linux/clk-provider.h>
1615 #include <linux/mfd/syscon.h>
1716 #include <linux/init.h>
1817 #include <linux/of.h>
19
-#include <linux/of_address.h>
2018 #include <linux/platform_device.h>
2119 #include <linux/regmap.h>
2220
2321 #define AP806_SAR_REG 0x400
2422 #define AP806_SAR_CLKFREQ_MODE_MASK 0x1f
2523
26
-#define AP806_CLK_NUM 5
24
+#define AP806_CLK_NUM 6
2725
2826 static struct clk *ap806_clks[AP806_CLK_NUM];
2927
....@@ -32,22 +30,106 @@
3230 .clk_num = AP806_CLK_NUM,
3331 };
3432
35
-static char *ap806_unique_name(struct device *dev, struct device_node *np,
36
- char *name)
33
+static int ap806_get_sar_clocks(unsigned int freq_mode,
34
+ unsigned int *cpuclk_freq,
35
+ unsigned int *dclk_freq)
3736 {
38
- const __be32 *reg;
39
- u64 addr;
37
+ switch (freq_mode) {
38
+ case 0x0:
39
+ *cpuclk_freq = 2000;
40
+ *dclk_freq = 600;
41
+ break;
42
+ case 0x1:
43
+ *cpuclk_freq = 2000;
44
+ *dclk_freq = 525;
45
+ break;
46
+ case 0x6:
47
+ *cpuclk_freq = 1800;
48
+ *dclk_freq = 600;
49
+ break;
50
+ case 0x7:
51
+ *cpuclk_freq = 1800;
52
+ *dclk_freq = 525;
53
+ break;
54
+ case 0x4:
55
+ *cpuclk_freq = 1600;
56
+ *dclk_freq = 400;
57
+ break;
58
+ case 0xB:
59
+ *cpuclk_freq = 1600;
60
+ *dclk_freq = 450;
61
+ break;
62
+ case 0xD:
63
+ *cpuclk_freq = 1600;
64
+ *dclk_freq = 525;
65
+ break;
66
+ case 0x1a:
67
+ *cpuclk_freq = 1400;
68
+ *dclk_freq = 400;
69
+ break;
70
+ case 0x14:
71
+ *cpuclk_freq = 1300;
72
+ *dclk_freq = 400;
73
+ break;
74
+ case 0x17:
75
+ *cpuclk_freq = 1300;
76
+ *dclk_freq = 325;
77
+ break;
78
+ case 0x19:
79
+ *cpuclk_freq = 1200;
80
+ *dclk_freq = 400;
81
+ break;
82
+ case 0x13:
83
+ *cpuclk_freq = 1000;
84
+ *dclk_freq = 325;
85
+ break;
86
+ case 0x1d:
87
+ *cpuclk_freq = 1000;
88
+ *dclk_freq = 400;
89
+ break;
90
+ case 0x1c:
91
+ *cpuclk_freq = 800;
92
+ *dclk_freq = 400;
93
+ break;
94
+ case 0x1b:
95
+ *cpuclk_freq = 600;
96
+ *dclk_freq = 400;
97
+ break;
98
+ default:
99
+ return -EINVAL;
100
+ }
40101
41
- reg = of_get_property(np, "reg", NULL);
42
- addr = of_translate_address(np, reg);
43
- return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
44
- (unsigned long long)addr, name);
102
+ return 0;
103
+}
104
+
105
+static int ap807_get_sar_clocks(unsigned int freq_mode,
106
+ unsigned int *cpuclk_freq,
107
+ unsigned int *dclk_freq)
108
+{
109
+ switch (freq_mode) {
110
+ case 0x0:
111
+ *cpuclk_freq = 2000;
112
+ *dclk_freq = 1200;
113
+ break;
114
+ case 0x6:
115
+ *cpuclk_freq = 2200;
116
+ *dclk_freq = 1200;
117
+ break;
118
+ case 0xD:
119
+ *cpuclk_freq = 1600;
120
+ *dclk_freq = 1200;
121
+ break;
122
+ default:
123
+ return -EINVAL;
124
+ }
125
+
126
+ return 0;
45127 }
46128
47129 static int ap806_syscon_common_probe(struct platform_device *pdev,
48130 struct device_node *syscon_node)
49131 {
50
- unsigned int freq_mode, cpuclk_freq;
132
+ unsigned int freq_mode, cpuclk_freq, dclk_freq;
51133 const char *name, *fixedclk_name;
52134 struct device *dev = &pdev->dev;
53135 struct device_node *np = dev->of_node;
....@@ -68,50 +150,29 @@
68150 }
69151
70152 freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK;
71
- switch (freq_mode) {
72
- case 0x0:
73
- case 0x1:
74
- cpuclk_freq = 2000;
75
- break;
76
- case 0x6:
77
- case 0x7:
78
- cpuclk_freq = 1800;
79
- break;
80
- case 0x4:
81
- case 0xB:
82
- case 0xD:
83
- cpuclk_freq = 1600;
84
- break;
85
- case 0x1a:
86
- cpuclk_freq = 1400;
87
- break;
88
- case 0x14:
89
- case 0x17:
90
- cpuclk_freq = 1300;
91
- break;
92
- case 0x19:
93
- cpuclk_freq = 1200;
94
- break;
95
- case 0x13:
96
- case 0x1d:
97
- cpuclk_freq = 1000;
98
- break;
99
- case 0x1c:
100
- cpuclk_freq = 800;
101
- break;
102
- case 0x1b:
103
- cpuclk_freq = 600;
104
- break;
105
- default:
106
- dev_err(dev, "invalid SAR value\n");
153
+
154
+ if (of_device_is_compatible(pdev->dev.of_node,
155
+ "marvell,ap806-clock")) {
156
+ ret = ap806_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq);
157
+ } else if (of_device_is_compatible(pdev->dev.of_node,
158
+ "marvell,ap807-clock")) {
159
+ ret = ap807_get_sar_clocks(freq_mode, &cpuclk_freq, &dclk_freq);
160
+ } else {
161
+ dev_err(dev, "compatible not supported\n");
107162 return -EINVAL;
163
+ }
164
+
165
+ if (ret) {
166
+ dev_err(dev, "invalid Sample at Reset value\n");
167
+ return ret;
108168 }
109169
110170 /* Convert to hertz */
111171 cpuclk_freq *= 1000 * 1000;
172
+ dclk_freq *= 1000 * 1000;
112173
113174 /* CPU clocks depend on the Sample At Reset configuration */
114
- name = ap806_unique_name(dev, syscon_node, "cpu-cluster-0");
175
+ name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-0");
115176 ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL,
116177 0, cpuclk_freq);
117178 if (IS_ERR(ap806_clks[0])) {
....@@ -119,7 +180,7 @@
119180 goto fail0;
120181 }
121182
122
- name = ap806_unique_name(dev, syscon_node, "cpu-cluster-1");
183
+ name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-1");
123184 ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0,
124185 cpuclk_freq);
125186 if (IS_ERR(ap806_clks[1])) {
....@@ -128,7 +189,7 @@
128189 }
129190
130191 /* Fixed clock is always 1200 Mhz */
131
- fixedclk_name = ap806_unique_name(dev, syscon_node, "fixed");
192
+ fixedclk_name = ap_cp_unique_name(dev, syscon_node, "fixed");
132193 ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL,
133194 0, 1200 * 1000 * 1000);
134195 if (IS_ERR(ap806_clks[2])) {
....@@ -137,7 +198,7 @@
137198 }
138199
139200 /* MSS Clock is fixed clock divided by 6 */
140
- name = ap806_unique_name(dev, syscon_node, "mss");
201
+ name = ap_cp_unique_name(dev, syscon_node, "mss");
141202 ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name,
142203 0, 1, 6);
143204 if (IS_ERR(ap806_clks[3])) {
....@@ -146,7 +207,7 @@
146207 }
147208
148209 /* SDIO(/eMMC) Clock is fixed clock divided by 3 */
149
- name = ap806_unique_name(dev, syscon_node, "sdio");
210
+ name = ap_cp_unique_name(dev, syscon_node, "sdio");
150211 ap806_clks[4] = clk_register_fixed_factor(NULL, name,
151212 fixedclk_name,
152213 0, 1, 3);
....@@ -155,7 +216,14 @@
155216 goto fail4;
156217 }
157218
158
- of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
219
+ /* AP-DCLK(HCLK) Clock is DDR clock divided by 2 */
220
+ name = ap_cp_unique_name(dev, syscon_node, "ap-dclk");
221
+ ap806_clks[5] = clk_register_fixed_rate(dev, name, NULL, 0, dclk_freq);
222
+ if (IS_ERR(ap806_clks[5])) {
223
+ ret = PTR_ERR(ap806_clks[5]);
224
+ goto fail5;
225
+ }
226
+
159227 ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
160228 if (ret)
161229 goto fail_clk_add;
....@@ -163,6 +231,8 @@
163231 return 0;
164232
165233 fail_clk_add:
234
+ clk_unregister_fixed_factor(ap806_clks[5]);
235
+fail5:
166236 clk_unregister_fixed_factor(ap806_clks[4]);
167237 fail4:
168238 clk_unregister_fixed_factor(ap806_clks[3]);
....@@ -209,6 +279,7 @@
209279
210280 static const struct of_device_id ap806_clock_of_match[] = {
211281 { .compatible = "marvell,ap806-clock", },
282
+ { .compatible = "marvell,ap807-clock", },
212283 { }
213284 };
214285