Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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