Skip to content

Commit bbe7cbd

Browse files
saschahauerchanwoochoi
authored andcommitted
PM / devfreq: rockchip-dfi: account for multiple DDRMON_CTRL registers
The currently supported RK3399 has a set of registers per channel, but it has only a single DDRMON_CTRL register. With upcoming RK3588 this will be different, the RK3588 has a DDRMON_CTRL register per channel. Instead of expecting a single DDRMON_CTRL register, loop over the channels and write the channel specific DDRMON_CTRL register. Break out early out of the loop when there is only a single DDRMON_CTRL register like on the RK3399. Link: https://lore.kernel.org/all/[email protected]/ Reviewed-by: Jonathan Cameron <[email protected]> Reviewed-by: Sebastian Reichel <[email protected]> Signed-off-by: Sascha Hauer <[email protected]> Signed-off-by: Chanwoo Choi <[email protected]>
1 parent d1d0b3f commit bbe7cbd

File tree

1 file changed

+49
-24
lines changed

1 file changed

+49
-24
lines changed

drivers/devfreq/event/rockchip-dfi.c

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,13 @@ struct rockchip_dfi {
114114
int burst_len;
115115
int buswidth[DMC_MAX_CHANNELS];
116116
int ddrmon_stride;
117+
bool ddrmon_ctrl_single;
117118
};
118119

119120
static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
120121
{
121122
void __iomem *dfi_regs = dfi->regs;
122-
int ret = 0;
123+
int i, ret = 0;
123124

124125
mutex_lock(&dfi->mutex);
125126

@@ -133,29 +134,41 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
133134
goto out;
134135
}
135136

136-
/* clear DDRMON_CTRL setting */
137-
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN | DDRMON_CTRL_SOFTWARE_EN |
138-
DDRMON_CTRL_HARDWARE_EN), dfi_regs + DDRMON_CTRL);
137+
for (i = 0; i < dfi->max_channels; i++) {
138+
u32 ctrl = 0;
139139

140-
/* set ddr type to dfi */
141-
switch (dfi->ddr_type) {
142-
case ROCKCHIP_DDRTYPE_LPDDR2:
143-
case ROCKCHIP_DDRTYPE_LPDDR3:
144-
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_LPDDR23, DDRMON_CTRL_DDR_TYPE_MASK),
145-
dfi_regs + DDRMON_CTRL);
146-
break;
147-
case ROCKCHIP_DDRTYPE_LPDDR4:
148-
case ROCKCHIP_DDRTYPE_LPDDR4X:
149-
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_LPDDR4, DDRMON_CTRL_DDR_TYPE_MASK),
150-
dfi_regs + DDRMON_CTRL);
151-
break;
152-
default:
153-
break;
154-
}
140+
if (!(dfi->channel_mask & BIT(i)))
141+
continue;
155142

156-
/* enable count, use software mode */
157-
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, DDRMON_CTRL_SOFTWARE_EN),
158-
dfi_regs + DDRMON_CTRL);
143+
/* clear DDRMON_CTRL setting */
144+
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN |
145+
DDRMON_CTRL_SOFTWARE_EN | DDRMON_CTRL_HARDWARE_EN),
146+
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
147+
148+
/* set ddr type to dfi */
149+
switch (dfi->ddr_type) {
150+
case ROCKCHIP_DDRTYPE_LPDDR2:
151+
case ROCKCHIP_DDRTYPE_LPDDR3:
152+
ctrl = DDRMON_CTRL_LPDDR23;
153+
break;
154+
case ROCKCHIP_DDRTYPE_LPDDR4:
155+
case ROCKCHIP_DDRTYPE_LPDDR4X:
156+
ctrl = DDRMON_CTRL_LPDDR4;
157+
break;
158+
default:
159+
break;
160+
}
161+
162+
writel_relaxed(HIWORD_UPDATE(ctrl, DDRMON_CTRL_DDR_TYPE_MASK),
163+
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
164+
165+
/* enable count, use software mode */
166+
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, DDRMON_CTRL_SOFTWARE_EN),
167+
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
168+
169+
if (dfi->ddrmon_ctrl_single)
170+
break;
171+
}
159172
out:
160173
mutex_unlock(&dfi->mutex);
161174

@@ -165,6 +178,7 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
165178
static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
166179
{
167180
void __iomem *dfi_regs = dfi->regs;
181+
int i;
168182

169183
mutex_lock(&dfi->mutex);
170184

@@ -175,8 +189,17 @@ static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
175189
if (dfi->usecount > 0)
176190
goto out;
177191

178-
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN),
179-
dfi_regs + DDRMON_CTRL);
192+
for (i = 0; i < dfi->max_channels; i++) {
193+
if (!(dfi->channel_mask & BIT(i)))
194+
continue;
195+
196+
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN),
197+
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
198+
199+
if (dfi->ddrmon_ctrl_single)
200+
break;
201+
}
202+
180203
clk_disable_unprepare(dfi->clk);
181204
out:
182205
mutex_unlock(&dfi->mutex);
@@ -666,6 +689,7 @@ static int rk3399_dfi_init(struct rockchip_dfi *dfi)
666689
dfi->buswidth[1] = FIELD_GET(RK3399_PMUGRF_OS_REG2_BW_CH1, val) == 0 ? 4 : 2;
667690

668691
dfi->ddrmon_stride = 0x14;
692+
dfi->ddrmon_ctrl_single = true;
669693

670694
return 0;
671695
};
@@ -694,6 +718,7 @@ static int rk3568_dfi_init(struct rockchip_dfi *dfi)
694718
dfi->buswidth[0] = FIELD_GET(RK3568_PMUGRF_OS_REG2_BW_CH0, reg2) == 0 ? 4 : 2;
695719

696720
dfi->ddrmon_stride = 0x0; /* not relevant, we only have a single channel on this SoC */
721+
dfi->ddrmon_ctrl_single = true;
697722

698723
return 0;
699724
};

0 commit comments

Comments
 (0)