hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/cpufreq/ti-cpufreq.c
....@@ -1,17 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * TI CPUFreq/OPP hw-supported driver
34 *
45 * Copyright (C) 2016-2017 Texas Instruments, Inc.
56 * Dave Gerlach <d-gerlach@ti.com>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * version 2 as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
157 */
168
179 #include <linux/cpu.h>
....@@ -33,17 +25,26 @@
3325
3426 #define DRA7_EFUSE_HAS_OD_MPU_OPP 11
3527 #define DRA7_EFUSE_HAS_HIGH_MPU_OPP 15
28
+#define DRA76_EFUSE_HAS_PLUS_MPU_OPP 18
3629 #define DRA7_EFUSE_HAS_ALL_MPU_OPP 23
30
+#define DRA76_EFUSE_HAS_ALL_MPU_OPP 24
3731
3832 #define DRA7_EFUSE_NOM_MPU_OPP BIT(0)
3933 #define DRA7_EFUSE_OD_MPU_OPP BIT(1)
4034 #define DRA7_EFUSE_HIGH_MPU_OPP BIT(2)
35
+#define DRA76_EFUSE_PLUS_MPU_OPP BIT(3)
36
+
37
+#define OMAP3_CONTROL_DEVICE_STATUS 0x4800244C
38
+#define OMAP3_CONTROL_IDCODE 0x4830A204
39
+#define OMAP34xx_ProdID_SKUID 0x4830A20C
40
+#define OMAP3_SYSCON_BASE (0x48000000 + 0x2000 + 0x270)
4141
4242 #define VERSION_COUNT 2
4343
4444 struct ti_cpufreq_data;
4545
4646 struct ti_cpufreq_soc_data {
47
+ const char * const *reg_names;
4748 unsigned long (*efuse_xlate)(struct ti_cpufreq_data *opp_data,
4849 unsigned long efuse);
4950 unsigned long efuse_fallback;
....@@ -82,14 +83,26 @@
8283 */
8384
8485 switch (efuse) {
86
+ case DRA76_EFUSE_HAS_PLUS_MPU_OPP:
87
+ case DRA76_EFUSE_HAS_ALL_MPU_OPP:
88
+ calculated_efuse |= DRA76_EFUSE_PLUS_MPU_OPP;
89
+ fallthrough;
8590 case DRA7_EFUSE_HAS_ALL_MPU_OPP:
8691 case DRA7_EFUSE_HAS_HIGH_MPU_OPP:
8792 calculated_efuse |= DRA7_EFUSE_HIGH_MPU_OPP;
93
+ fallthrough;
8894 case DRA7_EFUSE_HAS_OD_MPU_OPP:
8995 calculated_efuse |= DRA7_EFUSE_OD_MPU_OPP;
9096 }
9197
9298 return calculated_efuse;
99
+}
100
+
101
+static unsigned long omap3_efuse_xlate(struct ti_cpufreq_data *opp_data,
102
+ unsigned long efuse)
103
+{
104
+ /* OPP enable bit ("Speed Binned") */
105
+ return BIT(efuse);
93106 }
94107
95108 static struct ti_cpufreq_soc_data am3x_soc_data = {
....@@ -119,6 +132,74 @@
119132 .multi_regulator = true,
120133 };
121134
135
+/*
136
+ * OMAP35x TRM (SPRUF98K):
137
+ * CONTROL_IDCODE (0x4830 A204) describes Silicon revisions.
138
+ * Control OMAP Status Register 15:0 (Address 0x4800 244C)
139
+ * to separate between omap3503, omap3515, omap3525, omap3530
140
+ * and feature presence.
141
+ * There are encodings for versions limited to 400/266MHz
142
+ * but we ignore.
143
+ * Not clear if this also holds for omap34xx.
144
+ * some eFuse values e.g. CONTROL_FUSE_OPP1_VDD1
145
+ * are stored in the SYSCON register range
146
+ * Register 0x4830A20C [ProdID.SKUID] [0:3]
147
+ * 0x0 for normal 600/430MHz device.
148
+ * 0x8 for 720/520MHz device.
149
+ * Not clear what omap34xx value is.
150
+ */
151
+
152
+static struct ti_cpufreq_soc_data omap34xx_soc_data = {
153
+ .efuse_xlate = omap3_efuse_xlate,
154
+ .efuse_offset = OMAP34xx_ProdID_SKUID - OMAP3_SYSCON_BASE,
155
+ .efuse_shift = 3,
156
+ .efuse_mask = BIT(3),
157
+ .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
158
+ .multi_regulator = false,
159
+};
160
+
161
+/*
162
+ * AM/DM37x TRM (SPRUGN4M)
163
+ * CONTROL_IDCODE (0x4830 A204) describes Silicon revisions.
164
+ * Control Device Status Register 15:0 (Address 0x4800 244C)
165
+ * to separate between am3703, am3715, dm3725, dm3730
166
+ * and feature presence.
167
+ * Speed Binned = Bit 9
168
+ * 0 800/600 MHz
169
+ * 1 1000/800 MHz
170
+ * some eFuse values e.g. CONTROL_FUSE_OPP 1G_VDD1
171
+ * are stored in the SYSCON register range.
172
+ * There is no 0x4830A20C [ProdID.SKUID] register (exists but
173
+ * seems to always read as 0).
174
+ */
175
+
176
+static const char * const omap3_reg_names[] = {"cpu0", "vbb"};
177
+
178
+static struct ti_cpufreq_soc_data omap36xx_soc_data = {
179
+ .reg_names = omap3_reg_names,
180
+ .efuse_xlate = omap3_efuse_xlate,
181
+ .efuse_offset = OMAP3_CONTROL_DEVICE_STATUS - OMAP3_SYSCON_BASE,
182
+ .efuse_shift = 9,
183
+ .efuse_mask = BIT(9),
184
+ .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
185
+ .multi_regulator = true,
186
+};
187
+
188
+/*
189
+ * AM3517 is quite similar to AM/DM37x except that it has no
190
+ * high speed grade eFuse and no abb ldo
191
+ */
192
+
193
+static struct ti_cpufreq_soc_data am3517_soc_data = {
194
+ .efuse_xlate = omap3_efuse_xlate,
195
+ .efuse_offset = OMAP3_CONTROL_DEVICE_STATUS - OMAP3_SYSCON_BASE,
196
+ .efuse_shift = 0,
197
+ .efuse_mask = 0,
198
+ .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
199
+ .multi_regulator = false,
200
+};
201
+
202
+
122203 /**
123204 * ti_cpufreq_get_efuse() - Parse and return efuse value present on SoC
124205 * @opp_data: pointer to ti_cpufreq_data context
....@@ -135,7 +216,17 @@
135216
136217 ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
137218 &efuse);
138
- if (ret) {
219
+ if (ret == -EIO) {
220
+ /* not a syscon register! */
221
+ void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
222
+ opp_data->soc_data->efuse_offset, 4);
223
+
224
+ if (!regs)
225
+ return -ENOMEM;
226
+ efuse = readl(regs);
227
+ iounmap(regs);
228
+ }
229
+ else if (ret) {
139230 dev_err(dev,
140231 "Failed to read the efuse value from syscon: %d\n",
141232 ret);
....@@ -166,7 +257,17 @@
166257
167258 ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
168259 &revision);
169
- if (ret) {
260
+ if (ret == -EIO) {
261
+ /* not a syscon register! */
262
+ void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
263
+ opp_data->soc_data->rev_offset, 4);
264
+
265
+ if (!regs)
266
+ return -ENOMEM;
267
+ revision = readl(regs);
268
+ iounmap(regs);
269
+ }
270
+ else if (ret) {
170271 dev_err(dev,
171272 "Failed to read the revision number from syscon: %d\n",
172273 ret);
....@@ -196,8 +297,14 @@
196297
197298 static const struct of_device_id ti_cpufreq_of_match[] = {
198299 { .compatible = "ti,am33xx", .data = &am3x_soc_data, },
300
+ { .compatible = "ti,am3517", .data = &am3517_soc_data, },
199301 { .compatible = "ti,am43", .data = &am4x_soc_data, },
200302 { .compatible = "ti,dra7", .data = &dra7_soc_data },
303
+ { .compatible = "ti,omap34xx", .data = &omap34xx_soc_data, },
304
+ { .compatible = "ti,omap36xx", .data = &omap36xx_soc_data, },
305
+ /* legacy */
306
+ { .compatible = "ti,omap3430", .data = &omap34xx_soc_data, },
307
+ { .compatible = "ti,omap3630", .data = &omap36xx_soc_data, },
201308 {},
202309 };
203310
....@@ -219,7 +326,7 @@
219326 const struct of_device_id *match;
220327 struct opp_table *ti_opp_table;
221328 struct ti_cpufreq_data *opp_data;
222
- const char * const reg_names[] = {"vdd", "vbb"};
329
+ const char * const default_reg_names[] = {"vdd", "vbb"};
223330 int ret;
224331
225332 match = dev_get_platdata(&pdev->dev);
....@@ -275,9 +382,13 @@
275382 opp_data->opp_table = ti_opp_table;
276383
277384 if (opp_data->soc_data->multi_regulator) {
385
+ const char * const *reg_names = default_reg_names;
386
+
387
+ if (opp_data->soc_data->reg_names)
388
+ reg_names = opp_data->soc_data->reg_names;
278389 ti_opp_table = dev_pm_opp_set_regulators(opp_data->cpu_dev,
279390 reg_names,
280
- ARRAY_SIZE(reg_names));
391
+ ARRAY_SIZE(default_reg_names));
281392 if (IS_ERR(ti_opp_table)) {
282393 dev_pm_opp_put_supported_hw(opp_data->opp_table);
283394 ret = PTR_ERR(ti_opp_table);