xref: /OK3568_Linux_fs/kernel/drivers/devfreq/event/rockchip-dfi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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