drm/rockchip: vop2: Add submem power gate support

RK3588 VOP2 has power gates for VP0/1/2/3, DB0/1/2
and WB.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Change-Id: Ie3d67aa804282834949d6950470ba960ea51fcdb
This commit is contained in:
Andy Yan
2021-11-10 09:38:24 +08:00
committed by Tao Huang
parent 3df95bb0b9
commit 8854c8ef52
4 changed files with 123 additions and 4 deletions

View File

@@ -117,6 +117,20 @@ enum vop2_win_dly_mode {
#define VOP2_PD_DSC_8K BIT(5)
#define VOP2_PD_DSC_4K BIT(6)
/*
* vop2 submem power gate,
* should be all none zero, 0 will be
* treat as invalid;
*/
#define VOP2_MEM_PG_VP0 BIT(0)
#define VOP2_MEM_PG_VP1 BIT(1)
#define VOP2_MEM_PG_VP2 BIT(2)
#define VOP2_MEM_PG_VP3 BIT(3)
#define VOP2_MEM_PG_DB0 BIT(4)
#define VOP2_MEM_PG_DB1 BIT(5)
#define VOP2_MEM_PG_DB2 BIT(6)
#define VOP2_MEM_PG_WB BIT(7)
#define DSP_BG_SWAP 0x1
#define DSP_RB_SWAP 0x2
#define DSP_RG_SWAP 0x4
@@ -1027,6 +1041,7 @@ struct vop2_data {
uint8_t nr_gammas;
uint8_t nr_conns;
uint8_t nr_pds;
uint8_t nr_mem_pgs;
bool delayed_pd;
const struct vop_intr *axi_intr;
const struct vop2_ctrl *ctrl;
@@ -1039,6 +1054,7 @@ struct vop2_data {
const struct vop2_wb_data *wb;
const struct vop2_layer_data *layer;
const struct vop2_power_domain_data *pd;
const struct vop2_power_domain_data *mem_pg;
const struct vop_csc_table *csc_table;
const struct vop_hdr_table *hdr_table;
const struct vop_grf_ctrl *sys_grf;

View File

@@ -655,6 +655,7 @@ struct vop2 {
struct regmap *sys_grf;
struct regmap *vo0_grf;
struct regmap *vo1_grf;
struct regmap *pmu;
/* physical map length of vop2 register */
uint32_t len;
@@ -2946,7 +2947,7 @@ static void rk3588_vop2_regsbak(struct vop2 *vop2)
/*
* No need to backup DSC/GAMMA_LUT/BPP_LUT/MMU
*/
for (i = 0; i < (RK3588_DSC_8K_PPS0_3 >> 2); i++)
for (i = 0; i < (0x2000 >> 2); i++)
vop2->regsbak[i] = base[i];
for (i = 0; i < vop2_data->nr_dscs; i++) {
@@ -7071,7 +7072,7 @@ static irqreturn_t vop2_isr(int irq, void *data)
do { \
if (active_irqs & x##_INTR) {\
if (x##_INTR == POST_BUF_EMPTY_INTR) \
DRM_DEV_ERROR_RATELIMITED(vop2->dev, #x " irq err at vp%d\n", vp->id); \
printk(KERN_DEBUG #x " irq err at vp%d\n", vp->id); \
else \
DRM_DEV_ERROR_RATELIMITED(vop2->dev, #x " irq err\n"); \
active_irqs &= ~x##_INTR; \
@@ -7922,6 +7923,7 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
vop2->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf");
vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf");
vop2->pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu");
vop2->hclk = devm_clk_get(vop2->dev, "hclk_vop");
if (IS_ERR(vop2->hclk)) {

View File

@@ -1974,13 +1974,13 @@ static const struct vop2_power_domain_data rk3588_vop_pd_data[] = {
{
.id = VOP2_PD_CLUSTER2,
.parent_id = VOP2_PD_CLUSTER0,
.regs = &rk3588_cluster0_pd_regs,
.regs = &rk3588_cluster2_pd_regs,
},
{
.id = VOP2_PD_CLUSTER3,
.parent_id = VOP2_PD_CLUSTER0,
.regs = &rk3588_cluster1_pd_regs,
.regs = &rk3588_cluster3_pd_regs,
},
{
@@ -1999,6 +1999,98 @@ static const struct vop2_power_domain_data rk3588_vop_pd_data[] = {
},
};
const struct vop2_power_domain_regs rk3588_mem_pg_vp0_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON1, 0x1, 15),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 19),
};
const struct vop2_power_domain_regs rk3588_mem_pg_vp1_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON2, 0x1, 0),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 20),
};
const struct vop2_power_domain_regs rk3588_mem_pg_vp2_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON2, 0x1, 1),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 21),
};
const struct vop2_power_domain_regs rk3588_mem_pg_vp3_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON2, 0x1, 2),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 22),
};
const struct vop2_power_domain_regs rk3588_mem_pg_db0_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON2, 0x1, 3),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 23),
};
const struct vop2_power_domain_regs rk3588_mem_pg_db1_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON2, 0x1, 4),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 24),
};
const struct vop2_power_domain_regs rk3588_mem_pg_db2_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON2, 0x1, 5),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 25),
};
const struct vop2_power_domain_regs rk3588_mem_pg_wb_regs = {
.pd = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_CON2, 0x1, 6),
.status = VOP_REG(RK3588_PMU_SUBMEM_PWR_GATE_STATUS, 0x1, 26),
};
/*
* All power gates will power on when PD_VOP is turn on.
* Corresponding mem_pwr_ack_bypass bit should be enabled
* if power gate powe down before PD_VOP.
* power gates take effect immediately, this means there
* is no synchronization between vop frame scanout, so
* we can only enable a power gate before we enable
* a module, and turn off power gate after the module
* is actually disabled.
*/
static const struct vop2_power_domain_data rk3588_vop_mem_pg_data[] = {
{
.id = VOP2_MEM_PG_VP0,
.regs = &rk3588_mem_pg_vp0_regs,
},
{
.id = VOP2_MEM_PG_VP1,
.regs = &rk3588_mem_pg_vp1_regs,
},
{
.id = VOP2_MEM_PG_VP2,
.regs = &rk3588_mem_pg_vp2_regs,
},
{
.id = VOP2_MEM_PG_VP3,
.regs = &rk3588_mem_pg_vp3_regs,
},
{
.id = VOP2_MEM_PG_DB0,
.regs = &rk3588_mem_pg_db0_regs,
},
{
.id = VOP2_MEM_PG_DB1,
.regs = &rk3588_mem_pg_db1_regs,
},
{
.id = VOP2_MEM_PG_DB2,
.regs = &rk3588_mem_pg_db2_regs,
},
{
.id = VOP2_MEM_PG_WB,
.regs = &rk3588_mem_pg_wb_regs,
},
};
/*
* rk3588 vop with 4 cluster, 4 esmart win.
* Every cluster can work as 4K win or split into two win.
@@ -2511,6 +2603,8 @@ static const struct vop2_data rk3588_vop = {
.win_size = ARRAY_SIZE(rk3588_vop_win_data),
.pd = rk3588_vop_pd_data,
.nr_pds = ARRAY_SIZE(rk3588_vop_pd_data),
.mem_pg = rk3588_vop_mem_pg_data,
.nr_mem_pgs = ARRAY_SIZE(rk3588_vop_mem_pg_data),
};
static const struct of_device_id vop2_dt_match[] = {

View File

@@ -1613,4 +1613,11 @@
#define RK3588_GRF_VOP_CON2 0x08
#define RK3588_GRF_VO1_CON0 0x00
#define RK3588_PMU_PWR_GATE_CON1 0x150
#define RK3588_PMU_SUBMEM_PWR_GATE_CON1 0x1B4
#define RK3588_PMU_SUBMEM_PWR_GATE_CON2 0x1B8
#define RK3588_PMU_SUBMEM_PWR_GATE_STATUS 0x1BC
#define RK3588_PMU_BISR_STATUS5 0x294
#endif /* _ROCKCHIP_VOP_REG_H */