mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
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/20231018061714.3553817-19-s.hauer@pengutronix.de/ Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
This commit is contained in:
parent
d1d0b3fe95
commit
bbe7cbd074
@ -114,12 +114,13 @@ struct rockchip_dfi {
|
||||
int burst_len;
|
||||
int buswidth[DMC_MAX_CHANNELS];
|
||||
int ddrmon_stride;
|
||||
bool ddrmon_ctrl_single;
|
||||
};
|
||||
|
||||
static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
|
||||
{
|
||||
void __iomem *dfi_regs = dfi->regs;
|
||||
int ret = 0;
|
||||
int i, ret = 0;
|
||||
|
||||
mutex_lock(&dfi->mutex);
|
||||
|
||||
@ -133,29 +134,41 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* clear DDRMON_CTRL setting */
|
||||
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN | DDRMON_CTRL_SOFTWARE_EN |
|
||||
DDRMON_CTRL_HARDWARE_EN), dfi_regs + DDRMON_CTRL);
|
||||
for (i = 0; i < dfi->max_channels; i++) {
|
||||
u32 ctrl = 0;
|
||||
|
||||
/* set ddr type to dfi */
|
||||
switch (dfi->ddr_type) {
|
||||
case ROCKCHIP_DDRTYPE_LPDDR2:
|
||||
case ROCKCHIP_DDRTYPE_LPDDR3:
|
||||
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_LPDDR23, DDRMON_CTRL_DDR_TYPE_MASK),
|
||||
dfi_regs + DDRMON_CTRL);
|
||||
break;
|
||||
case ROCKCHIP_DDRTYPE_LPDDR4:
|
||||
case ROCKCHIP_DDRTYPE_LPDDR4X:
|
||||
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_LPDDR4, DDRMON_CTRL_DDR_TYPE_MASK),
|
||||
dfi_regs + DDRMON_CTRL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (!(dfi->channel_mask & BIT(i)))
|
||||
continue;
|
||||
|
||||
/* clear DDRMON_CTRL setting */
|
||||
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN |
|
||||
DDRMON_CTRL_SOFTWARE_EN | DDRMON_CTRL_HARDWARE_EN),
|
||||
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
|
||||
|
||||
/* set ddr type to dfi */
|
||||
switch (dfi->ddr_type) {
|
||||
case ROCKCHIP_DDRTYPE_LPDDR2:
|
||||
case ROCKCHIP_DDRTYPE_LPDDR3:
|
||||
ctrl = DDRMON_CTRL_LPDDR23;
|
||||
break;
|
||||
case ROCKCHIP_DDRTYPE_LPDDR4:
|
||||
case ROCKCHIP_DDRTYPE_LPDDR4X:
|
||||
ctrl = DDRMON_CTRL_LPDDR4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
writel_relaxed(HIWORD_UPDATE(ctrl, DDRMON_CTRL_DDR_TYPE_MASK),
|
||||
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
|
||||
|
||||
/* enable count, use software mode */
|
||||
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, DDRMON_CTRL_SOFTWARE_EN),
|
||||
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
|
||||
|
||||
if (dfi->ddrmon_ctrl_single)
|
||||
break;
|
||||
}
|
||||
|
||||
/* enable count, use software mode */
|
||||
writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, DDRMON_CTRL_SOFTWARE_EN),
|
||||
dfi_regs + DDRMON_CTRL);
|
||||
out:
|
||||
mutex_unlock(&dfi->mutex);
|
||||
|
||||
@ -165,6 +178,7 @@ out:
|
||||
static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
|
||||
{
|
||||
void __iomem *dfi_regs = dfi->regs;
|
||||
int i;
|
||||
|
||||
mutex_lock(&dfi->mutex);
|
||||
|
||||
@ -175,8 +189,17 @@ static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
|
||||
if (dfi->usecount > 0)
|
||||
goto out;
|
||||
|
||||
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN),
|
||||
dfi_regs + DDRMON_CTRL);
|
||||
for (i = 0; i < dfi->max_channels; i++) {
|
||||
if (!(dfi->channel_mask & BIT(i)))
|
||||
continue;
|
||||
|
||||
writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN),
|
||||
dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
|
||||
|
||||
if (dfi->ddrmon_ctrl_single)
|
||||
break;
|
||||
}
|
||||
|
||||
clk_disable_unprepare(dfi->clk);
|
||||
out:
|
||||
mutex_unlock(&dfi->mutex);
|
||||
@ -666,6 +689,7 @@ static int rk3399_dfi_init(struct rockchip_dfi *dfi)
|
||||
dfi->buswidth[1] = FIELD_GET(RK3399_PMUGRF_OS_REG2_BW_CH1, val) == 0 ? 4 : 2;
|
||||
|
||||
dfi->ddrmon_stride = 0x14;
|
||||
dfi->ddrmon_ctrl_single = true;
|
||||
|
||||
return 0;
|
||||
};
|
||||
@ -694,6 +718,7 @@ static int rk3568_dfi_init(struct rockchip_dfi *dfi)
|
||||
dfi->buswidth[0] = FIELD_GET(RK3568_PMUGRF_OS_REG2_BW_CH0, reg2) == 0 ? 4 : 2;
|
||||
|
||||
dfi->ddrmon_stride = 0x0; /* not relevant, we only have a single channel on this SoC */
|
||||
dfi->ddrmon_ctrl_single = true;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user