3434
3535/* DDRMON_CTRL */
3636#define DDRMON_CTRL 0x04
37+ #define DDRMON_CTRL_LPDDR5 BIT(6)
3738#define DDRMON_CTRL_DDR4 BIT(5)
3839#define DDRMON_CTRL_LPDDR4 BIT(4)
3940#define DDRMON_CTRL_HARDWARE_EN BIT(3)
4041#define DDRMON_CTRL_LPDDR23 BIT(2)
4142#define DDRMON_CTRL_SOFTWARE_EN BIT(1)
4243#define DDRMON_CTRL_TIMER_CNT_EN BIT(0)
43- #define DDRMON_CTRL_DDR_TYPE_MASK (DDRMON_CTRL_DDR4 | \
44+ #define DDRMON_CTRL_DDR_TYPE_MASK (DDRMON_CTRL_LPDDR5 | \
45+ DDRMON_CTRL_DDR4 | \
4446 DDRMON_CTRL_LPDDR4 | \
4547 DDRMON_CTRL_LPDDR23)
48+ #define DDRMON_CTRL_LP5_BANK_MODE_MASK GENMASK(8, 7)
4649
4750#define DDRMON_CH0_WR_NUM 0x20
4851#define DDRMON_CH0_RD_NUM 0x24
@@ -116,12 +119,60 @@ struct rockchip_dfi {
116119 int buswidth [DMC_MAX_CHANNELS ];
117120 int ddrmon_stride ;
118121 bool ddrmon_ctrl_single ;
122+ u32 lp5_bank_mode ;
123+ bool lp5_ckr ; /* true if in 4:1 command-to-data clock ratio mode */
124+ unsigned int count_multiplier ; /* number of data clocks per count */
119125};
120126
127+ static int rockchip_dfi_ddrtype_to_ctrl (struct rockchip_dfi * dfi , u32 * ctrl ,
128+ u32 * mask )
129+ {
130+ u32 ddrmon_ver ;
131+
132+ * mask = DDRMON_CTRL_DDR_TYPE_MASK ;
133+
134+ switch (dfi -> ddr_type ) {
135+ case ROCKCHIP_DDRTYPE_LPDDR2 :
136+ case ROCKCHIP_DDRTYPE_LPDDR3 :
137+ * ctrl = DDRMON_CTRL_LPDDR23 ;
138+ break ;
139+ case ROCKCHIP_DDRTYPE_LPDDR4 :
140+ case ROCKCHIP_DDRTYPE_LPDDR4X :
141+ * ctrl = DDRMON_CTRL_LPDDR4 ;
142+ break ;
143+ case ROCKCHIP_DDRTYPE_LPDDR5 :
144+ ddrmon_ver = readl_relaxed (dfi -> regs );
145+ if (ddrmon_ver < 0x40 ) {
146+ * ctrl = DDRMON_CTRL_LPDDR5 | dfi -> lp5_bank_mode ;
147+ * mask |= DDRMON_CTRL_LP5_BANK_MODE_MASK ;
148+ break ;
149+ }
150+
151+ /*
152+ * As it is unknown whether the unpleasant special case
153+ * behaviour used by the vendor kernel is needed for any
154+ * shipping hardware, ask users to report if they have
155+ * some of that hardware.
156+ */
157+ dev_err (& dfi -> edev -> dev ,
158+ "unsupported DDRMON version 0x%04X, please let linux-rockchip know!\n" ,
159+ ddrmon_ver );
160+ return - EOPNOTSUPP ;
161+ default :
162+ dev_err (& dfi -> edev -> dev , "unsupported memory type 0x%X\n" ,
163+ dfi -> ddr_type );
164+ return - EOPNOTSUPP ;
165+ }
166+
167+ return 0 ;
168+ }
169+
121170static int rockchip_dfi_enable (struct rockchip_dfi * dfi )
122171{
123172 void __iomem * dfi_regs = dfi -> regs ;
124173 int i , ret = 0 ;
174+ u32 ctrl ;
175+ u32 ctrl_mask ;
125176
126177 mutex_lock (& dfi -> mutex );
127178
@@ -135,8 +186,11 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
135186 goto out ;
136187 }
137188
189+ ret = rockchip_dfi_ddrtype_to_ctrl (dfi , & ctrl , & ctrl_mask );
190+ if (ret )
191+ goto out ;
192+
138193 for (i = 0 ; i < dfi -> max_channels ; i ++ ) {
139- u32 ctrl = 0 ;
140194
141195 if (!(dfi -> channel_mask & BIT (i )))
142196 continue ;
@@ -146,21 +200,7 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
146200 DDRMON_CTRL_SOFTWARE_EN | DDRMON_CTRL_HARDWARE_EN ),
147201 dfi_regs + i * dfi -> ddrmon_stride + DDRMON_CTRL );
148202
149- /* set ddr type to dfi */
150- switch (dfi -> ddr_type ) {
151- case ROCKCHIP_DDRTYPE_LPDDR2 :
152- case ROCKCHIP_DDRTYPE_LPDDR3 :
153- ctrl = DDRMON_CTRL_LPDDR23 ;
154- break ;
155- case ROCKCHIP_DDRTYPE_LPDDR4 :
156- case ROCKCHIP_DDRTYPE_LPDDR4X :
157- ctrl = DDRMON_CTRL_LPDDR4 ;
158- break ;
159- default :
160- break ;
161- }
162-
163- writel_relaxed (HIWORD_UPDATE (ctrl , DDRMON_CTRL_DDR_TYPE_MASK ),
203+ writel_relaxed (HIWORD_UPDATE (ctrl , ctrl_mask ),
164204 dfi_regs + i * dfi -> ddrmon_stride + DDRMON_CTRL );
165205
166206 /* enable count, use software mode */
@@ -435,7 +475,7 @@ static u64 rockchip_ddr_perf_event_get_count(struct perf_event *event)
435475
436476 switch (event -> attr .config ) {
437477 case PERF_EVENT_CYCLES :
438- count = total .c [0 ].clock_cycles ;
478+ count = total .c [0 ].clock_cycles * dfi -> count_multiplier ;
439479 break ;
440480 case PERF_EVENT_READ_BYTES :
441481 for (i = 0 ; i < dfi -> max_channels ; i ++ )
@@ -651,10 +691,14 @@ static int rockchip_ddr_perf_init(struct rockchip_dfi *dfi)
651691 break ;
652692 case ROCKCHIP_DDRTYPE_LPDDR4 :
653693 case ROCKCHIP_DDRTYPE_LPDDR4X :
694+ case ROCKCHIP_DDRTYPE_LPDDR5 :
654695 dfi -> burst_len = 16 ;
655696 break ;
656697 }
657698
699+ if (!dfi -> count_multiplier )
700+ dfi -> count_multiplier = 1 ;
701+
658702 ret = perf_pmu_register (pmu , "rockchip_ddr" , -1 );
659703 if (ret )
660704 return ret ;
@@ -726,7 +770,7 @@ static int rk3568_dfi_init(struct rockchip_dfi *dfi)
726770static int rk3588_dfi_init (struct rockchip_dfi * dfi )
727771{
728772 struct regmap * regmap_pmu = dfi -> regmap_pmu ;
729- u32 reg2 , reg3 , reg4 ;
773+ u32 reg2 , reg3 , reg4 , reg6 ;
730774
731775 regmap_read (regmap_pmu , RK3588_PMUGRF_OS_REG2 , & reg2 );
732776 regmap_read (regmap_pmu , RK3588_PMUGRF_OS_REG3 , & reg3 );
@@ -751,6 +795,15 @@ static int rk3588_dfi_init(struct rockchip_dfi *dfi)
751795 dfi -> max_channels = 4 ;
752796
753797 dfi -> ddrmon_stride = 0x4000 ;
798+ dfi -> count_multiplier = 2 ;
799+
800+ if (dfi -> ddr_type == ROCKCHIP_DDRTYPE_LPDDR5 ) {
801+ regmap_read (regmap_pmu , RK3588_PMUGRF_OS_REG6 , & reg6 );
802+ dfi -> lp5_bank_mode = FIELD_GET (RK3588_PMUGRF_OS_REG6_LP5_BANK_MODE , reg6 ) << 7 ;
803+ dfi -> lp5_ckr = FIELD_GET (RK3588_PMUGRF_OS_REG6_LP5_CKR , reg6 );
804+ if (dfi -> lp5_ckr )
805+ dfi -> count_multiplier *= 2 ;
806+ }
754807
755808 return 0 ;
756809};
0 commit comments