1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
4 * Author: Lin Huang <hl@rock-chips.com>
5 */
6
7 #include <linux/clk.h>
8 #include <linux/devfreq-event.h>
9 #include <linux/kernel.h>
10 #include <linux/err.h>
11 #include <linux/init.h>
12 #include <linux/io.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/regmap.h>
17 #include <linux/slab.h>
18 #include <linux/list.h>
19 #include <linux/of.h>
20
21 #include <soc/rockchip/rk3399_grf.h>
22
23 #define PX30_PMUGRF_OS_REG2 0x208
24 #define PX30_PMUGRF_OS_REG3 0x20c
25
26 #define RK3588_PMUGRF_OS_REG(n) (0x200 + (n) * 4)
27
28 #define RK3128_GRF_SOC_CON0 0x140
29 #define RK3128_GRF_OS_REG1 0x1cc
30 #define RK3128_GRF_DFI_WRNUM 0x220
31 #define RK3128_GRF_DFI_RDNUM 0x224
32 #define RK3128_GRF_DFI_TIMERVAL 0x22c
33 #define RK3128_DDR_MONITOR_EN ((1 << (16 + 6)) + (1 << 6))
34 #define RK3128_DDR_MONITOR_DISB ((1 << (16 + 6)) + (0 << 6))
35
36 #define RK3288_PMU_SYS_REG2 0x9c
37 #define RK3288_GRF_SOC_CON4 0x254
38 #define RK3288_GRF_SOC_STATUS(n) (0x280 + (n) * 4)
39 #define RK3288_DFI_EN (0x30003 << 14)
40 #define RK3288_DFI_DIS (0x30000 << 14)
41 #define RK3288_LPDDR_SEL (0x10001 << 13)
42 #define RK3288_DDR3_SEL (0x10000 << 13)
43
44 #define RK3328_GRF_OS_REG2 0x5d0
45
46 #define RK3368_GRF_DDRC0_CON0 0x600
47 #define RK3368_GRF_SOC_STATUS5 0x494
48 #define RK3368_GRF_SOC_STATUS6 0x498
49 #define RK3368_GRF_SOC_STATUS8 0x4a0
50 #define RK3368_GRF_SOC_STATUS9 0x4a4
51 #define RK3368_GRF_SOC_STATUS10 0x4a8
52 #define RK3368_DFI_EN (0x30003 << 5)
53 #define RK3368_DFI_DIS (0x30000 << 5)
54
55 #define RK3528_PMUGRF_OFFSET 0x70000
56 #define RK3528_PMUGRF_OS_REG18 0x248
57 #define RK3528_PMUGRF_OS_REG19 0x24c
58
59 #define MAX_DMC_NUM_CH 4
60 #define READ_DRAMTYPE_INFO(n) (((n) >> 13) & 0x7)
61 #define READ_CH_INFO(n) (((n) >> 28) & 0x3)
62 #define READ_DRAMTYPE_INFO_V3(n, m) ((((n) >> 13) & 0x7) | ((((m) >> 12) & 0x3) << 3))
63 #define READ_SYSREG_VERSION(m) (((m) >> 28) & 0xf)
64 #define READ_LP5_BANK_MODE(m) (((m) >> 1) & 0x3)
65 #define READ_LP5_CKR(m) (((m) >> 0) & 0x1)
66 /* DDRMON_CTRL */
67 #define DDRMON_CTRL 0x04
68 #define CLR_DDRMON_CTRL (0xffff0000 << 0)
69 #define LPDDR5_BANK_MODE(m) ((0x30000 | ((m) & 0x3)) << 7)
70 #define LPDDR5_EN (0x10001 << 6)
71 #define DDR4_EN (0x10001 << 5)
72 #define LPDDR4_EN (0x10001 << 4)
73 #define HARDWARE_EN (0x10001 << 3)
74 #define LPDDR2_3_EN (0x10001 << 2)
75 #define SOFTWARE_EN (0x10001 << 1)
76 #define SOFTWARE_DIS (0x10000 << 1)
77 #define TIME_CNT_EN (0x10001 << 0)
78
79 #define DDRMON_CH0_COUNT_NUM 0x28
80 #define DDRMON_CH0_DFI_ACCESS_NUM 0x2c
81 #define DDRMON_CH1_COUNT_NUM 0x3c
82 #define DDRMON_CH1_DFI_ACCESS_NUM 0x40
83
84 /* pmu grf */
85 #define PMUGRF_OS_REG2 0x308
86
87 enum {
88 DDR4 = 0,
89 DDR3 = 3,
90 LPDDR2 = 5,
91 LPDDR3 = 6,
92 LPDDR4 = 7,
93 LPDDR4X = 8,
94 LPDDR5 = 9,
95 DDR5 = 10,
96 UNUSED = 0xFF
97 };
98
99 struct dmc_usage {
100 u64 access;
101 u64 total;
102 };
103
104 /*
105 * The dfi controller can monitor DDR load. It has an upper and lower threshold
106 * for the operating points. Whenever the usage leaves these bounds an event is
107 * generated to indicate the DDR frequency should be changed.
108 */
109 struct rockchip_dfi {
110 struct devfreq_event_dev *edev;
111 struct devfreq_event_desc *desc;
112 struct dmc_usage ch_usage[MAX_DMC_NUM_CH];
113 struct device *dev;
114 void __iomem *regs;
115 struct regmap *regmap_pmu;
116 struct regmap *regmap_grf;
117 struct regmap *regmap_pmugrf;
118 struct clk *clk;
119 u32 dram_type;
120 u32 mon_idx;
121 u32 count_rate;
122 u32 dram_dynamic_info_reg;
123 /* 0: BG mode, 1: 16 Bank mode, 2: 8 bank mode */
124 u32 lp5_bank_mode;
125 /* 0: clk:dqs = 1:2, 1: 1:4 */
126 u32 lp5_ckr;
127 /*
128 * available mask, 1: available, 0: not available
129 * each bit represent a channel
130 */
131 u32 ch_msk;
132 };
133
rk3128_dfi_start_hardware_counter(struct devfreq_event_dev * edev)134 static void rk3128_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
135 {
136 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
137
138 regmap_write(info->regmap_grf,
139 RK3128_GRF_SOC_CON0,
140 RK3128_DDR_MONITOR_EN);
141 }
142
rk3128_dfi_stop_hardware_counter(struct devfreq_event_dev * edev)143 static void rk3128_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
144 {
145 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
146
147 regmap_write(info->regmap_grf,
148 RK3128_GRF_SOC_CON0,
149 RK3128_DDR_MONITOR_DISB);
150 }
151
rk3128_dfi_disable(struct devfreq_event_dev * edev)152 static int rk3128_dfi_disable(struct devfreq_event_dev *edev)
153 {
154 rk3128_dfi_stop_hardware_counter(edev);
155
156 return 0;
157 }
158
rk3128_dfi_enable(struct devfreq_event_dev * edev)159 static int rk3128_dfi_enable(struct devfreq_event_dev *edev)
160 {
161 rk3128_dfi_start_hardware_counter(edev);
162
163 return 0;
164 }
165
rk3128_dfi_set_event(struct devfreq_event_dev * edev)166 static int rk3128_dfi_set_event(struct devfreq_event_dev *edev)
167 {
168 return 0;
169 }
170
rk3128_dfi_get_event(struct devfreq_event_dev * edev,struct devfreq_event_data * edata)171 static int rk3128_dfi_get_event(struct devfreq_event_dev *edev,
172 struct devfreq_event_data *edata)
173 {
174 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
175 unsigned long flags;
176 u32 dfi_wr, dfi_rd, dfi_timer;
177
178 local_irq_save(flags);
179
180 rk3128_dfi_stop_hardware_counter(edev);
181
182 regmap_read(info->regmap_grf, RK3128_GRF_DFI_WRNUM, &dfi_wr);
183 regmap_read(info->regmap_grf, RK3128_GRF_DFI_RDNUM, &dfi_rd);
184 regmap_read(info->regmap_grf, RK3128_GRF_DFI_TIMERVAL, &dfi_timer);
185
186 edata->load_count = (dfi_wr + dfi_rd) * 4;
187 edata->total_count = dfi_timer;
188
189 rk3128_dfi_start_hardware_counter(edev);
190
191 local_irq_restore(flags);
192
193 return 0;
194 }
195
196 static const struct devfreq_event_ops rk3128_dfi_ops = {
197 .disable = rk3128_dfi_disable,
198 .enable = rk3128_dfi_enable,
199 .get_event = rk3128_dfi_get_event,
200 .set_event = rk3128_dfi_set_event,
201 };
202
rk3288_dfi_start_hardware_counter(struct devfreq_event_dev * edev)203 static void rk3288_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
204 {
205 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
206
207 regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_EN);
208 }
209
rk3288_dfi_stop_hardware_counter(struct devfreq_event_dev * edev)210 static void rk3288_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
211 {
212 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
213
214 regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_DIS);
215 }
216
rk3288_dfi_disable(struct devfreq_event_dev * edev)217 static int rk3288_dfi_disable(struct devfreq_event_dev *edev)
218 {
219 rk3288_dfi_stop_hardware_counter(edev);
220
221 return 0;
222 }
223
rk3288_dfi_enable(struct devfreq_event_dev * edev)224 static int rk3288_dfi_enable(struct devfreq_event_dev *edev)
225 {
226 rk3288_dfi_start_hardware_counter(edev);
227
228 return 0;
229 }
230
rk3288_dfi_set_event(struct devfreq_event_dev * edev)231 static int rk3288_dfi_set_event(struct devfreq_event_dev *edev)
232 {
233 return 0;
234 }
235
rk3288_dfi_get_busier_ch(struct devfreq_event_dev * edev)236 static int rk3288_dfi_get_busier_ch(struct devfreq_event_dev *edev)
237 {
238 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
239 u32 tmp, max = 0;
240 u32 i, busier_ch = 0;
241 u32 rd_count, wr_count, total_count;
242
243 rk3288_dfi_stop_hardware_counter(edev);
244
245 /* Find out which channel is busier */
246 for (i = 0; i < MAX_DMC_NUM_CH; i++) {
247 if (!(info->ch_msk & BIT(i)))
248 continue;
249 regmap_read(info->regmap_grf,
250 RK3288_GRF_SOC_STATUS(11 + i * 4), &wr_count);
251 regmap_read(info->regmap_grf,
252 RK3288_GRF_SOC_STATUS(12 + i * 4), &rd_count);
253 regmap_read(info->regmap_grf,
254 RK3288_GRF_SOC_STATUS(14 + i * 4), &total_count);
255 info->ch_usage[i].access = (wr_count + rd_count) * 4;
256 info->ch_usage[i].total = total_count;
257 tmp = info->ch_usage[i].access;
258 if (tmp > max) {
259 busier_ch = i;
260 max = tmp;
261 }
262 }
263 rk3288_dfi_start_hardware_counter(edev);
264
265 return busier_ch;
266 }
267
rk3288_dfi_get_event(struct devfreq_event_dev * edev,struct devfreq_event_data * edata)268 static int rk3288_dfi_get_event(struct devfreq_event_dev *edev,
269 struct devfreq_event_data *edata)
270 {
271 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
272 int busier_ch;
273 unsigned long flags;
274
275 local_irq_save(flags);
276 busier_ch = rk3288_dfi_get_busier_ch(edev);
277 local_irq_restore(flags);
278
279 edata->load_count = info->ch_usage[busier_ch].access;
280 edata->total_count = info->ch_usage[busier_ch].total;
281
282 return 0;
283 }
284
285 static const struct devfreq_event_ops rk3288_dfi_ops = {
286 .disable = rk3288_dfi_disable,
287 .enable = rk3288_dfi_enable,
288 .get_event = rk3288_dfi_get_event,
289 .set_event = rk3288_dfi_set_event,
290 };
291
rk3368_dfi_start_hardware_counter(struct devfreq_event_dev * edev)292 static void rk3368_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
293 {
294 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
295
296 regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_EN);
297 }
298
rk3368_dfi_stop_hardware_counter(struct devfreq_event_dev * edev)299 static void rk3368_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
300 {
301 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
302
303 regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_DIS);
304 }
305
rk3368_dfi_disable(struct devfreq_event_dev * edev)306 static int rk3368_dfi_disable(struct devfreq_event_dev *edev)
307 {
308 rk3368_dfi_stop_hardware_counter(edev);
309
310 return 0;
311 }
312
rk3368_dfi_enable(struct devfreq_event_dev * edev)313 static int rk3368_dfi_enable(struct devfreq_event_dev *edev)
314 {
315 rk3368_dfi_start_hardware_counter(edev);
316
317 return 0;
318 }
319
rk3368_dfi_set_event(struct devfreq_event_dev * edev)320 static int rk3368_dfi_set_event(struct devfreq_event_dev *edev)
321 {
322 return 0;
323 }
324
rk3368_dfi_get_event(struct devfreq_event_dev * edev,struct devfreq_event_data * edata)325 static int rk3368_dfi_get_event(struct devfreq_event_dev *edev,
326 struct devfreq_event_data *edata)
327 {
328 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
329 unsigned long flags;
330 u32 dfi0_wr, dfi0_rd, dfi1_wr, dfi1_rd, dfi_timer;
331
332 local_irq_save(flags);
333
334 rk3368_dfi_stop_hardware_counter(edev);
335
336 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS5, &dfi0_wr);
337 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS6, &dfi0_rd);
338 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS9, &dfi1_wr);
339 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS10, &dfi1_rd);
340 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS8, &dfi_timer);
341
342 edata->load_count = (dfi0_wr + dfi0_rd + dfi1_wr + dfi1_rd) * 2;
343 edata->total_count = dfi_timer;
344
345 rk3368_dfi_start_hardware_counter(edev);
346
347 local_irq_restore(flags);
348
349 return 0;
350 }
351
352 static const struct devfreq_event_ops rk3368_dfi_ops = {
353 .disable = rk3368_dfi_disable,
354 .enable = rk3368_dfi_enable,
355 .get_event = rk3368_dfi_get_event,
356 .set_event = rk3368_dfi_set_event,
357 };
358
rockchip_dfi_start_hardware_counter(struct devfreq_event_dev * edev)359 static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
360 {
361 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
362 void __iomem *dfi_regs = info->regs;
363 u32 mon_idx = 0, val_6 = 0;
364 u32 i;
365
366 if (info->mon_idx)
367 mon_idx = info->mon_idx;
368
369 if (info->dram_dynamic_info_reg)
370 regmap_read(info->regmap_pmugrf, info->dram_dynamic_info_reg, &val_6);
371
372 if (info->dram_type == LPDDR5) {
373 info->lp5_bank_mode = READ_LP5_BANK_MODE(val_6);
374 info->lp5_ckr = READ_LP5_CKR(val_6);
375 }
376
377 for (i = 0; i < MAX_DMC_NUM_CH; i++) {
378 if (!(info->ch_msk & BIT(i)))
379 continue;
380 /* clear DDRMON_CTRL setting */
381 writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + i * mon_idx + DDRMON_CTRL);
382
383 /* set ddr type to dfi */
384 if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2)
385 writel_relaxed(LPDDR2_3_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
386 else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
387 writel_relaxed(LPDDR4_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
388 else if (info->dram_type == DDR4)
389 writel_relaxed(DDR4_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
390 else if (info->dram_type == LPDDR5)
391 writel_relaxed(LPDDR5_EN | LPDDR5_BANK_MODE(info->lp5_bank_mode),
392 dfi_regs + i * mon_idx + DDRMON_CTRL);
393
394 /* enable count, use software mode */
395 writel_relaxed(SOFTWARE_EN, dfi_regs + i * mon_idx + DDRMON_CTRL);
396 }
397 }
398
rockchip_dfi_stop_hardware_counter(struct devfreq_event_dev * edev)399 static void rockchip_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
400 {
401 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
402 void __iomem *dfi_regs = info->regs;
403 u32 mon_idx = 0, i;
404
405 if (info->mon_idx)
406 mon_idx = info->mon_idx;
407
408 for (i = 0; i < MAX_DMC_NUM_CH; i++) {
409 if (!(info->ch_msk & BIT(i)))
410 continue;
411 writel_relaxed(SOFTWARE_DIS, dfi_regs + i * mon_idx + DDRMON_CTRL);
412 }
413 }
414
rockchip_dfi_get_busier_ch(struct devfreq_event_dev * edev)415 static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
416 {
417 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
418 u32 tmp, max = 0;
419 u32 i, busier_ch = 0;
420 void __iomem *dfi_regs = info->regs;
421 u32 mon_idx = 0x20, count_rate = 1;
422
423 rockchip_dfi_stop_hardware_counter(edev);
424
425 if (info->mon_idx)
426 mon_idx = info->mon_idx;
427 if (info->count_rate)
428 count_rate = info->count_rate;
429
430 /* Find out which channel is busier */
431 for (i = 0; i < MAX_DMC_NUM_CH; i++) {
432 if (!(info->ch_msk & BIT(i)))
433 continue;
434
435 /* rk3588 counter is dfi clk rate */
436 info->ch_usage[i].total = readl_relaxed(dfi_regs +
437 DDRMON_CH0_COUNT_NUM + i * mon_idx) * count_rate;
438
439 /* LPDDR5 LPDDR4 and LPDDR4X BL = 16,other DDR type BL = 8 */
440 tmp = readl_relaxed(dfi_regs +
441 DDRMON_CH0_DFI_ACCESS_NUM + i * mon_idx);
442 if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X)
443 tmp *= 8;
444 else if (info->dram_type == LPDDR5)
445 tmp *= 16 / (4 << info->lp5_ckr);
446 else
447 tmp *= 4;
448 info->ch_usage[i].access = tmp;
449
450 if (tmp > max) {
451 busier_ch = i;
452 max = tmp;
453 }
454 }
455 rockchip_dfi_start_hardware_counter(edev);
456
457 return busier_ch;
458 }
459
rockchip_dfi_disable(struct devfreq_event_dev * edev)460 static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
461 {
462 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
463
464 rockchip_dfi_stop_hardware_counter(edev);
465 if (info->clk)
466 clk_disable_unprepare(info->clk);
467
468 return 0;
469 }
470
rockchip_dfi_enable(struct devfreq_event_dev * edev)471 static int rockchip_dfi_enable(struct devfreq_event_dev *edev)
472 {
473 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
474 int ret;
475
476 if (info->clk) {
477 ret = clk_prepare_enable(info->clk);
478 if (ret) {
479 dev_err(&edev->dev, "failed to enable dfi clk: %d\n",
480 ret);
481 return ret;
482 }
483 }
484
485 rockchip_dfi_start_hardware_counter(edev);
486 return 0;
487 }
488
rockchip_dfi_set_event(struct devfreq_event_dev * edev)489 static int rockchip_dfi_set_event(struct devfreq_event_dev *edev)
490 {
491 return 0;
492 }
493
rockchip_dfi_get_event(struct devfreq_event_dev * edev,struct devfreq_event_data * edata)494 static int rockchip_dfi_get_event(struct devfreq_event_dev *edev,
495 struct devfreq_event_data *edata)
496 {
497 struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
498 int busier_ch;
499 unsigned long flags;
500
501 local_irq_save(flags);
502 busier_ch = rockchip_dfi_get_busier_ch(edev);
503 local_irq_restore(flags);
504
505 edata->load_count = info->ch_usage[busier_ch].access;
506 edata->total_count = info->ch_usage[busier_ch].total;
507
508 return 0;
509 }
510
511 static const struct devfreq_event_ops rockchip_dfi_ops = {
512 .disable = rockchip_dfi_disable,
513 .enable = rockchip_dfi_enable,
514 .get_event = rockchip_dfi_get_event,
515 .set_event = rockchip_dfi_set_event,
516 };
517
rk3588_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)518 static __maybe_unused __init int rk3588_dfi_init(struct platform_device *pdev,
519 struct rockchip_dfi *data,
520 struct devfreq_event_desc *desc)
521 {
522 struct device_node *np = pdev->dev.of_node;
523 struct resource *res;
524 u32 val_2, val_3, val_4;
525
526 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
527 data->regs = devm_ioremap_resource(&pdev->dev, res);
528 if (IS_ERR(data->regs))
529 return PTR_ERR(data->regs);
530
531 data->regmap_pmugrf = syscon_regmap_lookup_by_phandle(np, "rockchip,pmu_grf");
532 if (IS_ERR(data->regmap_pmugrf))
533 return PTR_ERR(data->regmap_pmugrf);
534
535 regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(2), &val_2);
536 regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(3), &val_3);
537 regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(4), &val_4);
538 if (READ_SYSREG_VERSION(val_3) >= 0x3)
539 data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3);
540 else
541 data->dram_type = READ_DRAMTYPE_INFO(val_2);
542
543 data->mon_idx = 0x4000;
544 if (data->dram_type == LPDDR5)
545 data->count_rate = 1;
546 else
547 data->count_rate = 2;
548 data->dram_dynamic_info_reg = RK3588_PMUGRF_OS_REG(6);
549 data->ch_msk = READ_CH_INFO(val_2) | READ_CH_INFO(val_4) << 2;
550 data->clk = NULL;
551
552 desc->ops = &rockchip_dfi_ops;
553
554 return 0;
555 }
556
px30_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)557 static __maybe_unused __init int px30_dfi_init(struct platform_device *pdev,
558 struct rockchip_dfi *data,
559 struct devfreq_event_desc *desc)
560 {
561 struct device_node *np = pdev->dev.of_node, *node;
562 struct resource *res;
563 u32 val_2, val_3;
564
565 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
566 data->regs = devm_ioremap_resource(&pdev->dev, res);
567 if (IS_ERR(data->regs))
568 return PTR_ERR(data->regs);
569
570 node = of_parse_phandle(np, "rockchip,pmugrf", 0);
571 if (node) {
572 data->regmap_pmugrf = syscon_node_to_regmap(node);
573 if (IS_ERR(data->regmap_pmugrf))
574 return PTR_ERR(data->regmap_pmugrf);
575 }
576
577 regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG2, &val_2);
578 regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG3, &val_3);
579 if (READ_SYSREG_VERSION(val_3) >= 0x3)
580 data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3);
581 else
582 data->dram_type = READ_DRAMTYPE_INFO(val_2);
583 data->ch_msk = 1;
584 data->clk = NULL;
585
586 desc->ops = &rockchip_dfi_ops;
587
588 return 0;
589 }
590
rk3128_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)591 static __maybe_unused __init int rk3128_dfi_init(struct platform_device *pdev,
592 struct rockchip_dfi *data,
593 struct devfreq_event_desc *desc)
594 {
595 struct device_node *np = pdev->dev.of_node, *node;
596
597 node = of_parse_phandle(np, "rockchip,grf", 0);
598 if (node) {
599 data->regmap_grf = syscon_node_to_regmap(node);
600 if (IS_ERR(data->regmap_grf))
601 return PTR_ERR(data->regmap_grf);
602 }
603
604 desc->ops = &rk3128_dfi_ops;
605
606 return 0;
607 }
608
rk3288_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)609 static __maybe_unused __init int rk3288_dfi_init(struct platform_device *pdev,
610 struct rockchip_dfi *data,
611 struct devfreq_event_desc *desc)
612 {
613 struct device_node *np = pdev->dev.of_node, *node;
614 u32 val;
615
616 node = of_parse_phandle(np, "rockchip,pmu", 0);
617 if (node) {
618 data->regmap_pmu = syscon_node_to_regmap(node);
619 if (IS_ERR(data->regmap_pmu))
620 return PTR_ERR(data->regmap_pmu);
621 }
622
623 node = of_parse_phandle(np, "rockchip,grf", 0);
624 if (node) {
625 data->regmap_grf = syscon_node_to_regmap(node);
626 if (IS_ERR(data->regmap_grf))
627 return PTR_ERR(data->regmap_grf);
628 }
629
630 regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val);
631 data->dram_type = READ_DRAMTYPE_INFO(val);
632 data->ch_msk = READ_CH_INFO(val);
633
634 if (data->dram_type == DDR3)
635 regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
636 RK3288_DDR3_SEL);
637 else
638 regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4,
639 RK3288_LPDDR_SEL);
640
641 desc->ops = &rk3288_dfi_ops;
642
643 return 0;
644 }
645
rk3368_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)646 static __maybe_unused __init int rk3368_dfi_init(struct platform_device *pdev,
647 struct rockchip_dfi *data,
648 struct devfreq_event_desc *desc)
649 {
650 struct device *dev = &pdev->dev;
651
652 if (!dev->parent || !dev->parent->of_node)
653 return -EINVAL;
654
655 data->regmap_grf = syscon_node_to_regmap(dev->parent->of_node);
656 if (IS_ERR(data->regmap_grf))
657 return PTR_ERR(data->regmap_grf);
658
659 desc->ops = &rk3368_dfi_ops;
660
661 return 0;
662 }
663
rockchip_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)664 static __maybe_unused __init int rockchip_dfi_init(struct platform_device *pdev,
665 struct rockchip_dfi *data,
666 struct devfreq_event_desc *desc)
667 {
668 struct device *dev = &pdev->dev;
669 struct device_node *np = pdev->dev.of_node, *node;
670 u32 val;
671
672 data->regs = devm_platform_ioremap_resource(pdev, 0);
673 if (IS_ERR(data->regs))
674 return PTR_ERR(data->regs);
675
676 data->clk = devm_clk_get(dev, "pclk_ddr_mon");
677 if (IS_ERR(data->clk)) {
678 dev_err(dev, "Cannot get the clk dmc_clk\n");
679 return PTR_ERR(data->clk);
680 }
681
682 /* try to find the optional reference to the pmu syscon */
683 node = of_parse_phandle(np, "rockchip,pmu", 0);
684 if (node) {
685 data->regmap_pmu = syscon_node_to_regmap(node);
686 of_node_put(node);
687 if (IS_ERR(data->regmap_pmu))
688 return PTR_ERR(data->regmap_pmu);
689 }
690
691 regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val);
692 data->dram_type = READ_DRAMTYPE_INFO(val);
693 data->ch_msk = READ_CH_INFO(val);
694
695 desc->ops = &rockchip_dfi_ops;
696
697 return 0;
698 }
699
rk3328_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)700 static __maybe_unused __init int rk3328_dfi_init(struct platform_device *pdev,
701 struct rockchip_dfi *data,
702 struct devfreq_event_desc *desc)
703 {
704 struct device_node *np = pdev->dev.of_node, *node;
705 struct resource *res;
706 u32 val;
707
708 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
709 data->regs = devm_ioremap_resource(&pdev->dev, res);
710 if (IS_ERR(data->regs))
711 return PTR_ERR(data->regs);
712
713 node = of_parse_phandle(np, "rockchip,grf", 0);
714 if (node) {
715 data->regmap_grf = syscon_node_to_regmap(node);
716 if (IS_ERR(data->regmap_grf))
717 return PTR_ERR(data->regmap_grf);
718 }
719
720 regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val);
721 data->dram_type = READ_DRAMTYPE_INFO(val);
722 data->ch_msk = 1;
723 data->clk = NULL;
724
725 desc->ops = &rockchip_dfi_ops;
726
727 return 0;
728 }
729
rk3528_dfi_init(struct platform_device * pdev,struct rockchip_dfi * data,struct devfreq_event_desc * desc)730 static __maybe_unused __init int rk3528_dfi_init(struct platform_device *pdev,
731 struct rockchip_dfi *data,
732 struct devfreq_event_desc *desc)
733 {
734 struct device_node *np = pdev->dev.of_node, *node;
735 struct resource *res;
736 u32 val_18, val_19;
737
738 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
739 data->regs = devm_ioremap_resource(&pdev->dev, res);
740 if (IS_ERR(data->regs))
741 return PTR_ERR(data->regs);
742
743 node = of_parse_phandle(np, "rockchip,grf", 0);
744 if (node) {
745 data->regmap_grf = syscon_node_to_regmap(node);
746 if (IS_ERR(data->regmap_grf))
747 return PTR_ERR(data->regmap_grf);
748 }
749
750 regmap_read(data->regmap_grf, RK3528_PMUGRF_OFFSET + RK3528_PMUGRF_OS_REG18, &val_18);
751 regmap_read(data->regmap_grf, RK3528_PMUGRF_OFFSET + RK3528_PMUGRF_OS_REG19, &val_19);
752 if (READ_SYSREG_VERSION(val_19) >= 0x3)
753 data->dram_type = READ_DRAMTYPE_INFO_V3(val_18, val_19);
754 else
755 data->dram_type = READ_DRAMTYPE_INFO(val_18);
756 data->count_rate = 2;
757 data->ch_msk = 1;
758 data->clk = NULL;
759
760 desc->ops = &rockchip_dfi_ops;
761
762 return 0;
763 }
764
765 static const struct of_device_id rockchip_dfi_id_match[] = {
766 #ifdef CONFIG_CPU_PX30
767 { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init },
768 #endif
769 #ifdef CONFIG_CPU_RK1808
770 { .compatible = "rockchip,rk1808-dfi", .data = px30_dfi_init },
771 #endif
772 #ifdef CONFIG_CPU_RK312X
773 { .compatible = "rockchip,rk3128-dfi", .data = rk3128_dfi_init },
774 #endif
775 #ifdef CONFIG_CPU_RK3288
776 { .compatible = "rockchip,rk3288-dfi", .data = rk3288_dfi_init },
777 #endif
778 #ifdef CONFIG_CPU_RK3328
779 { .compatible = "rockchip,rk3328-dfi", .data = rk3328_dfi_init },
780 #endif
781 #ifdef CONFIG_CPU_RK3368
782 { .compatible = "rockchip,rk3368-dfi", .data = rk3368_dfi_init },
783 #endif
784 #ifdef CONFIG_CPU_RK3399
785 { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init },
786 #endif
787 #ifdef CONFIG_CPU_RK3528
788 { .compatible = "rockchip,rk3528-dfi", .data = rk3528_dfi_init },
789 #endif
790 #ifdef CONFIG_CPU_RK3562
791 { .compatible = "rockchip,rk3562-dfi", .data = px30_dfi_init },
792 #endif
793 #ifdef CONFIG_CPU_RK3568
794 { .compatible = "rockchip,rk3568-dfi", .data = px30_dfi_init },
795 #endif
796 #ifdef CONFIG_CPU_RK3588
797 { .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init },
798 #endif
799 #ifdef CONFIG_CPU_RV1126
800 { .compatible = "rockchip,rv1126-dfi", .data = px30_dfi_init },
801 #endif
802 { },
803 };
804
rockchip_dfi_probe(struct platform_device * pdev)805 static int rockchip_dfi_probe(struct platform_device *pdev)
806 {
807 struct device *dev = &pdev->dev;
808 struct rockchip_dfi *data;
809 struct devfreq_event_desc *desc;
810 struct device_node *np = pdev->dev.of_node;
811 const struct of_device_id *match;
812 int (*init)(struct platform_device *pdev, struct rockchip_dfi *data,
813 struct devfreq_event_desc *desc);
814
815 data = devm_kzalloc(dev, sizeof(struct rockchip_dfi), GFP_KERNEL);
816 if (!data)
817 return -ENOMEM;
818
819 desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
820 if (!desc)
821 return -ENOMEM;
822
823 match = of_match_node(rockchip_dfi_id_match, pdev->dev.of_node);
824 if (match) {
825 init = match->data;
826 if (init) {
827 if (init(pdev, data, desc))
828 return -EINVAL;
829 } else {
830 return 0;
831 }
832 } else {
833 return 0;
834 }
835
836 desc->driver_data = data;
837 desc->name = np->name;
838
839 data->edev = devm_devfreq_event_add_edev(dev, desc);
840 if (IS_ERR(data->edev)) {
841 dev_err(dev, "failed to add devfreq-event device\n");
842 return PTR_ERR(data->edev);
843 }
844 data->desc = desc;
845 data->dev = &pdev->dev;
846
847 platform_set_drvdata(pdev, data);
848
849 return 0;
850 }
851
852 static struct platform_driver rockchip_dfi_driver = {
853 .probe = rockchip_dfi_probe,
854 .driver = {
855 .name = "rockchip-dfi",
856 .of_match_table = rockchip_dfi_id_match,
857 },
858 };
859 module_platform_driver(rockchip_dfi_driver);
860
861 MODULE_LICENSE("GPL v2");
862 MODULE_AUTHOR("Lin Huang <hl@rock-chips.com>");
863 MODULE_DESCRIPTION("Rockchip DFI driver");
864