diff --git a/drivers/drm/meson_drv.c b/drivers/drm/meson_drv.c index 625afc5ad..1b0c056f8 100644 --- a/drivers/drm/meson_drv.c +++ b/drivers/drm/meson_drv.c @@ -693,6 +693,7 @@ static int am_meson_drm_pm_suspend(struct device *dev) DRM_INFO("%s: drm_atomic_helper_suspend fail\n", __func__); return PTR_ERR(priv->state); } + DRM_INFO("%s: done\n", __func__); return 0; } @@ -713,9 +714,16 @@ static int am_meson_drm_pm_resume(struct device *dev) return 0; } + /* + *for save power consumption, suspend will turn off vpu power, we need to + *do block register init again. + */ + vpu_pipeline_resume_init(priv->pipeline); + drm_atomic_helper_resume(drm, priv->state); am_meson_drm_fb_resume(drm); drm_kms_helper_poll_enable(drm); + DRM_INFO("%s: done\n", __func__); return 0; } diff --git a/drivers/drm/meson_vpu_pipeline.c b/drivers/drm/meson_vpu_pipeline.c index 06723178e..cdf9a21e0 100644 --- a/drivers/drm/meson_vpu_pipeline.c +++ b/drivers/drm/meson_vpu_pipeline.c @@ -381,6 +381,11 @@ static int populate_vpu_pipeline(struct device_node *vpu_block_node, return 0; } +void VPU_PIPELINE_RESET_INIT_DONE(struct meson_vpu_block *mvb) +{ + mvb->init_done = 0; +} + void VPU_PIPELINE_HW_INIT(struct meson_vpu_block *mvb) { if (mvb->ops->init) @@ -557,6 +562,44 @@ int vpu_pipeline_check(struct meson_vpu_pipeline *pipeline, return ret; } +void vpu_pipeline_resume_init(struct meson_vpu_pipeline *pipeline) +{ + int i; + + for (i = 0; i < MESON_MAX_OSDS; i++) { + if (pipeline->osds[i]) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->osds[i]->base); + } + + for (i = 0; i < pipeline->num_video; i++) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->video[i]->base); + + for (i = 0; i < pipeline->num_afbc_osds; i++) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->afbc_osds[i]->base); + + for (i = 0; i < MESON_MAX_SCALERS; i++) { + if (pipeline->scalers[i]) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->scalers[i]->base); + } + + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->osdblend->base); + + for (i = 0; i < MESON_MAX_HDRS; i++) + if (pipeline->hdrs[i]) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->hdrs[i]->base); + + for (i = 0; i < pipeline->num_postblend; i++) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->postblends[i]->base); + + if (pipeline->slice2ppc) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->slice2ppc->base); + + for (i = 0; i < pipeline->num_gfcd; i++) { + if (pipeline->gfcd[i]) + VPU_PIPELINE_RESET_INIT_DONE(&pipeline->gfcd[i]->base); + } +} + void vpu_pipeline_init(struct meson_vpu_pipeline *pipeline) { int i; diff --git a/drivers/drm/meson_vpu_pipeline.h b/drivers/drm/meson_vpu_pipeline.h index bcefa294a..34e7fe82c 100644 --- a/drivers/drm/meson_vpu_pipeline.h +++ b/drivers/drm/meson_vpu_pipeline.h @@ -132,6 +132,8 @@ struct meson_vpu_block_ops { struct meson_vpu_block_state *old_state); void (*dump_register)(struct drm_printer *p, struct meson_vpu_block *vblk); void (*init)(struct meson_vpu_block *vblk); + void (*init_register)(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state); void (*fini)(struct meson_vpu_block *vblk); }; @@ -749,6 +751,7 @@ int vpu_osd_pipeline_update(struct meson_vpu_sub_pipeline *pipeline, struct drm_atomic_state *old_state); void vpu_pipeline_init(struct meson_vpu_pipeline *pipeline); void vpu_pipeline_fini(struct meson_vpu_pipeline *pipeline); +void vpu_pipeline_resume_init(struct meson_vpu_pipeline *pipeline); int vpu_pipeline_read_scanout_pos(struct meson_vpu_pipeline *pipeline, int *vpos, int *hpos, int crtc_index); diff --git a/drivers/drm/vpu-hw/meson_vpu_osd_mif.c b/drivers/drm/vpu-hw/meson_vpu_osd_mif.c index 0f7dba25b..336311cbb 100644 --- a/drivers/drm/vpu-hw/meson_vpu_osd_mif.c +++ b/drivers/drm/vpu-hw/meson_vpu_osd_mif.c @@ -918,69 +918,6 @@ void osd_mali_unpack_enable(struct meson_vpu_block *vblk, reg_ops->rdma_write_reg_bits(reg->viu_osd_mali_unpack_ctrl, flag, 31, 1); } -void osd_ctrl_init(struct meson_vpu_block *vblk, struct rdma_reg_ops *reg_ops, - struct osd_mif_reg_s *reg) -{ - /*Need config follow crtc index.*/ - u8 holdline = VIU1_DEFAULT_HOLD_LINE; - u8 fifo_val = 0x20; - u32 osd_cfg_sync_en = 0; - - /* S7 and t5w are platforms with low-power consumption, so resuming will - * cause osd_cfg_sync_en bit of viu_osd_ctrl_stat to reset to be 1, not initial 0 - * anymore.Other previous platforms would not reset and always keep it to be initial 0. - * Currently, 0 is configured anyway to fix it. - * TODO: reset callback for each block is needed for more complicated reset cases. - */ - osd_cfg_sync_en = meson_drm_read_reg(reg->viu_osd_ctrl_stat) & 0x80000000; - osd_cfg_sync_en = osd_cfg_sync_en >> 31; - if (osd_cfg_sync_en == 1) { - reg_ops->rdma_write_reg_bits(reg->viu_osd_ctrl_stat, 0, 31, 1); - MESON_DRM_BLOCK("fixed reset of osd_cfg_sync_en in mif [%d].\n", vblk->index); - } - - if (vblk->init_done) - return; - - reg_ops->rdma_write_reg(reg->viu_osd_fifo_ctrl_stat, - (1 << 31) | /*BURSET_LEN_SEL[2]*/ - (0 << 30) | /*no swap*/ - (0 << 29) | /*div swap*/ - (2 << 24) | /*Fifo_lim 5bits*/ - (2 << 22) | /*Fifo_ctrl 2bits*/ - (fifo_val << 12) | /*FIFO_DEPATH_VAL 7bits*/ - (1 << 10) | /*BURSET_LEN_SEL[1:0]*/ - (holdline << 5) | /*hold fifo lines 5bits*/ - (0 << 4) | /*CLEAR_ERR*/ - (0 << 3) | /*fifo_sync_rst*/ - (0 << 1) | /*ENDIAN:no conversion*/ - (1 << 0)/*urgent enable*/); - reg_ops->rdma_write_reg(reg->viu_osd_ctrl_stat, - (0 << 31) | /*osd_cfg_sync_en*/ - (0 << 30) | /*Enable free_clk*/ - (0x100 << 12) | /*global alpha*/ - (0 << 11) | /*TEST_RD_EN*/ - (0 << 2) | /*osd_mem_mode 0:canvas_addr*/ - (0 << 1) | /*premult_en*/ - (0 << 0)/*OSD_BLK_ENABLE*/); - reg_ops->rdma_write_reg(reg->viu_osd_tcolor_ag3, 0); - -#ifndef CONFIG_AMLOGIC_ZAPPER_CUT - /*The fifo_crtl bits need to be configured with a maximum value of 0x2, otherwise it - *will affect bandwidth. The original values should to be obtained after mif init - */ - if (is_meson_t3x_cpu()) { - original_swap_t3x[vblk->index] = reg_ops->rdma_read_reg(reg->viu_osd_normal_swap); - original_osd1_fifo_ctrl_stat_t3x[vblk->index] = - reg_ops->rdma_read_reg(reg->viu_osd_fifo_ctrl_stat); - } -#endif - - MESON_DRM_BLOCK("init osd mif [%d].\n", vblk->index); - - vblk->init_done = 1; -} - static void osd_color_config(struct meson_vpu_block *vblk, struct rdma_reg_ops *reg_ops, struct osd_mif_reg_s *reg, @@ -1359,7 +1296,8 @@ static void osd_set_state(struct meson_vpu_block *vblk, if (old_state) old_mvos = to_osd_state(old_state); - osd_ctrl_init(vblk, reg_ops, reg); + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); if (priv->vpu_data && priv->vpu_data->has_gfcd) { process_unit = mvos->process_unit; @@ -1615,6 +1553,65 @@ void *osd_secure_op[VPP_TOP_MAX] = {meson_vpu_write_reg_bits, meson_vpu1_write_reg_bits, meson_vpu2_write_reg_bits}; #endif +static void osd_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) +{ + struct meson_vpu_osd *osd; + struct rdma_reg_ops *reg_ops; + struct osd_mif_reg_s *reg; + /*Need config follow crtc index.*/ + u8 holdline = VIU1_DEFAULT_HOLD_LINE; + u8 fifo_val = 0x20; + + if (vblk->init_done) + return; + + reg_ops = state->sub->reg_ops; + osd = to_osd_block(vblk); + reg = osd->reg; + if (!reg) { + MESON_DRM_BLOCK("set_state break for NULL OSD mixer reg.\n"); + return; + } + + reg_ops->rdma_write_reg(reg->viu_osd_fifo_ctrl_stat, + (1 << 31) | /*BURSET_LEN_SEL[2]*/ + (0 << 30) | /*no swap*/ + (0 << 29) | /*div swap*/ + (2 << 24) | /*Fifo_lim 5bits*/ + (2 << 22) | /*Fifo_ctrl 2bits*/ + (fifo_val << 12) | /*FIFO_DEPATH_VAL 7bits*/ + (1 << 10) | /*BURSET_LEN_SEL[1:0]*/ + (holdline << 5) | /*hold fifo lines 5bits*/ + (0 << 4) | /*CLEAR_ERR*/ + (0 << 3) | /*fifo_sync_rst*/ + (0 << 1) | /*ENDIAN:no conversion*/ + (1 << 0)/*urgent enable*/); + reg_ops->rdma_write_reg(reg->viu_osd_ctrl_stat, + (0 << 31) | /*osd_cfg_sync_en*/ + (0 << 30) | /*Enable free_clk*/ + (0x100 << 12) | /*global alpha*/ + (0 << 11) | /*TEST_RD_EN*/ + (0 << 2) | /*osd_mem_mode 0:canvas_addr*/ + (0 << 1) | /*premult_en*/ + (0 << 0)/*OSD_BLK_ENABLE*/); + reg_ops->rdma_write_reg(reg->viu_osd_tcolor_ag3, 0); + +#ifndef CONFIG_AMLOGIC_ZAPPER_CUT + /*The fifo_crtl bits need to be configured with a maximum value of 0x2, otherwise it + *will affect bandwidth. The original values should to be obtained after mif init + */ + if (is_meson_t3x_cpu()) { + original_swap_t3x[vblk->index] = reg_ops->rdma_read_reg(reg->viu_osd_normal_swap); + original_osd1_fifo_ctrl_stat_t3x[vblk->index] = + reg_ops->rdma_read_reg(reg->viu_osd_fifo_ctrl_stat); + } +#endif + + vblk->init_done = 1; + MESON_DRM_BLOCK("register_init vblk:%d.\n", vblk->index); +} + static void osd_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_pipeline *pipeline; @@ -1977,6 +1974,7 @@ struct meson_vpu_block_ops s1a_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = s1a_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -1987,6 +1985,7 @@ struct meson_vpu_block_ops osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -1999,6 +1998,7 @@ struct meson_vpu_block_ops g12b_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = g12b_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -2009,6 +2009,7 @@ struct meson_vpu_block_ops t7_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = t7_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -2019,6 +2020,7 @@ struct meson_vpu_block_ops s5_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = s5_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -2029,6 +2031,7 @@ struct meson_vpu_block_ops t3x_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = t3x_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -2039,6 +2042,7 @@ struct meson_vpu_block_ops txhd2_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = txhd2_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -2049,6 +2053,7 @@ struct meson_vpu_block_ops s7_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = s7_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -2059,6 +2064,7 @@ struct meson_vpu_block_ops s7d_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = s7d_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; @@ -2069,6 +2075,7 @@ struct meson_vpu_block_ops s6_osd_ops = { .disable = osd_hw_disable, .dump_register = osd_dump_register, .init = s6_osd_hw_init, + .init_register = osd_register_init, .fini = osd_hw_fini, }; #endif diff --git a/drivers/drm/vpu-hw/meson_vpu_osdblend.c b/drivers/drm/vpu-hw/meson_vpu_osdblend.c index eec8ff3e0..39693ecf8 100644 --- a/drivers/drm/vpu-hw/meson_vpu_osdblend.c +++ b/drivers/drm/vpu-hw/meson_vpu_osdblend.c @@ -856,6 +856,9 @@ static void osdblend_set_state(struct meson_vpu_block *vblk, return; } + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + if (pipeline_state->pipeline->osd_version <= OSD_V5) { mvobs->input_mask |= 5; for (i = 0; i < MAX_DIN_NUM; i++) { @@ -917,6 +920,9 @@ static void s5_osdblend_set_state(struct meson_vpu_block *vblk, return; } + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + mvsps = &mvps->sub_states[0]; for (i = 0; i < MAX_DIN_NUM; i++) { @@ -1106,6 +1112,9 @@ static void t3x_osdblend_set_state(struct meson_vpu_block *vblk, return; } + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + mvsps = &mvps->sub_states[state->sub->index]; for (i = 0; i < MAX_DIN_NUM; i++) { @@ -1298,6 +1307,9 @@ static void txhd2_osdblend_set_state(struct meson_vpu_block *vblk, struct meson_vpu_block_state *old_state) { struct rdma_reg_ops *reg_ops = state->sub->reg_ops; + + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); /*osd path dout alpha divider, default = 0*/ reg_ops->rdma_write_reg_bits(VIU_OSD_BLEND_CTRL, 0, 0, 1); reg_ops->rdma_write_reg_bits(VIU_OSD_BLEND_CTRL1, 0, 0, 1); @@ -1326,6 +1338,9 @@ static void s7d_osdblend_set_state(struct meson_vpu_block *vblk, return; } + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + if (pipeline_state->pipeline->osd_version <= OSD_V5) { mvobs->input_mask |= 5; for (i = 0; i < MAX_DIN_NUM; i++) { @@ -1478,13 +1493,15 @@ static void osdblend_dump_register(struct drm_printer *p, reg_addr, value); } -static void osdblend_hw_init(struct meson_vpu_block *vblk) +static void osdblend_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) { struct meson_vpu_osdblend *osdblend = to_osdblend_block(vblk); struct osd_dummy_data_s dummy_data = {0x80, 0x80, 0x80}; struct rdma_reg_ops *reg_ops = vblk->pipeline->subs[0].reg_ops; - osdblend->reg = &osdblend_reg; + if (vblk->init_done) + return; /*dummy data/alpha config*/ osd_blend_dummy_data_set(vblk, reg_ops, osdblend->reg, dummy_data); @@ -1493,6 +1510,16 @@ static void osdblend_hw_init(struct meson_vpu_block *vblk) /*reset blend ctrl hold line*/ reg_ops->rdma_write_reg_bits(osdblend->reg->viu_osd_blend_ctrl, 0, 29, 3); + vblk->init_done = 1; + MESON_DRM_BLOCK("%s register_init called.\n", osdblend->base.name); +} + +static void osdblend_hw_init(struct meson_vpu_block *vblk) +{ + struct meson_vpu_osdblend *osdblend = to_osdblend_block(vblk); + + osdblend->reg = &osdblend_reg; + MESON_DRM_BLOCK("%s hw_init called.\n", osdblend->base.name); } @@ -1502,13 +1529,15 @@ static void txhd2_osdblend_hw_init(struct meson_vpu_block *vblk) MESON_DRM_BLOCK("%s hw_init called.\n", vblk->name); } -static void s5_osdblend_hw_init(struct meson_vpu_block *vblk) +static void s5_osdblend_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) { struct meson_vpu_osdblend *osdblend = to_osdblend_block(vblk); struct osd_dummy_data_s dummy_data = {0x80, 0x80, 0x80}; struct rdma_reg_ops *reg_ops = vblk->pipeline->subs[0].reg_ops; - osdblend->reg = &osdblend_s5_reg; + if (vblk->init_done) + return; /*dummy data/alpha config*/ osd_blend_dummy_data_set(vblk, reg_ops, osdblend->reg, dummy_data); @@ -1517,19 +1546,28 @@ static void s5_osdblend_hw_init(struct meson_vpu_block *vblk) /*reset blend ctrl hold line*/ reg_ops->rdma_write_reg_bits(osdblend->reg->viu_osd_blend_ctrl, 4, 29, 3); + vblk->init_done = 1; + MESON_DRM_BLOCK("%s register_init called.\n", osdblend->base.name); +} + +static void s5_osdblend_hw_init(struct meson_vpu_block *vblk) +{ + struct meson_vpu_osdblend *osdblend = to_osdblend_block(vblk); + + osdblend->reg = &osdblend_s5_reg; + MESON_DRM_BLOCK("%s hw_init called.\n", osdblend->base.name); } -static void s7d_osdblend_hw_init(struct meson_vpu_block *vblk) +static void s7d_osdblend_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) { struct meson_vpu_osdblend *osdblend = to_osdblend_block(vblk); - struct meson_drm *priv = vblk->pipeline->priv; struct osd_dummy_data_s dummy_data = {0x80, 0x80, 0x80}; struct rdma_reg_ops *reg_ops = vblk->pipeline->subs[0].reg_ops; - osdblend->reg = &osdblend_reg; - osdblend->gfcd_global_alpha_policy = - !!(priv->of_conf.gfcd_mask & BIT(GFCD_GLOBAL_ALPHA)); + if (vblk->init_done) + return; /*dummy data/alpha config*/ osd_blend_dummy_data_set(vblk, reg_ops, osdblend->reg, dummy_data); @@ -1544,6 +1582,19 @@ static void s7d_osdblend_hw_init(struct meson_vpu_block *vblk) /*reset blend ctrl hold line*/ reg_ops->rdma_write_reg_bits(osdblend->reg->viu_osd_blend_ctrl, 0, 29, 3); + vblk->init_done = 1; + MESON_DRM_BLOCK("%s register_init called.\n", osdblend->base.name); +} + +static void s7d_osdblend_hw_init(struct meson_vpu_block *vblk) +{ + struct meson_vpu_osdblend *osdblend = to_osdblend_block(vblk); + struct meson_drm *priv = vblk->pipeline->priv; + + osdblend->reg = &osdblend_reg; + osdblend->gfcd_global_alpha_policy = + !!(priv->of_conf.gfcd_mask & BIT(GFCD_GLOBAL_ALPHA)); + MESON_DRM_BLOCK("%s hw_init called.\n", osdblend->base.name); } @@ -1556,6 +1607,7 @@ struct meson_vpu_block_ops osdblend_ops = { .disable = osdblend_hw_disable, .dump_register = osdblend_dump_register, .init = osdblend_hw_init, + .init_register = osdblend_register_init, }; #ifndef CONFIG_AMLOGIC_ZAPPER_CUT @@ -1575,6 +1627,7 @@ struct meson_vpu_block_ops s5_osdblend_ops = { .disable = osdblend_hw_disable, .dump_register = osdblend_dump_register, .init = s5_osdblend_hw_init, + .init_register = s5_osdblend_register_init, }; struct meson_vpu_block_ops t3x_osdblend_ops = { @@ -1584,6 +1637,7 @@ struct meson_vpu_block_ops t3x_osdblend_ops = { .disable = osdblend_hw_disable, .dump_register = osdblend_dump_register, .init = s5_osdblend_hw_init, + .init_register = s5_osdblend_register_init, }; struct meson_vpu_block_ops s7d_osdblend_ops = { @@ -1593,6 +1647,7 @@ struct meson_vpu_block_ops s7d_osdblend_ops = { .disable = osdblend_hw_disable, .dump_register = osdblend_dump_register, .init = s7d_osdblend_hw_init, + .init_register = s7d_osdblend_register_init, }; #endif diff --git a/drivers/drm/vpu-hw/meson_vpu_postblend.c b/drivers/drm/vpu-hw/meson_vpu_postblend.c index ee56d2aa4..8890ba14c 100644 --- a/drivers/drm/vpu-hw/meson_vpu_postblend.c +++ b/drivers/drm/vpu-hw/meson_vpu_postblend.c @@ -302,6 +302,9 @@ static void postblend_set_state(struct meson_vpu_block *vblk, crtc_index = vblk->index; amc = vblk->pipeline->priv->crtcs[crtc_index]; + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + MESON_DRM_BLOCK("%s set_state called.\n", postblend->base.name); mvps = priv_to_pipeline_state(pipeline->obj.state); @@ -365,6 +368,9 @@ static void txhd2_postblend_set_state(struct meson_vpu_block *vblk, crtc_index = vblk->index; amc = vblk->pipeline->priv->crtcs[crtc_index]; + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + MESON_DRM_BLOCK("%s set_state called.\n", postblend->base.name); mvps = priv_to_pipeline_state(pipeline->obj.state); for (i = 0; i < MESON_MAX_OSDS; i++) { @@ -451,11 +457,11 @@ static void t7_postblend_set_state(struct meson_vpu_block *vblk, struct meson_vpu_pipeline *pipeline = postblend->base.pipeline; struct postblend_reg_s *reg = postblend->reg; struct rdma_reg_ops *reg_ops = state->sub->reg_ops; - u32 *crtcmask_osd; - crtc_index = vblk->index; amc = vblk->pipeline->priv->crtcs[crtc_index]; - crtcmask_osd = amc->priv->of_conf.crtcmask_osd; + + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); MESON_DRM_BLOCK("%s set_state called.\n", postblend->base.name); mvps = priv_to_pipeline_state(pipeline->obj.state); @@ -468,14 +474,6 @@ static void t7_postblend_set_state(struct meson_vpu_block *vblk, secure_config(OSD_MODULE, mvps->sec_src, crtc_index); #endif - if (!vblk->init_done) { - if (!postblend->postblend_path_mask) - fix_vpu_clk2_default_regs(vblk, reg_ops, crtc_index, - crtcmask_osd); - - vblk->init_done = 1; - } - if (crtc_index == 0) { vpp_osd1_blend_scope_set(vblk, reg_ops, reg, scope); @@ -541,7 +539,6 @@ static void t7_postblend_set_state(struct meson_vpu_block *vblk, osd_vpp2_bld_ctrl = val | osd_vpp_bld_ctrl_update_mask; else MESON_DRM_BLOCK("invalid crtc index\n"); - drm_postblend_notify_amvideo(); if (bld_src2_sel == 2) { @@ -583,6 +580,9 @@ static void s5_postblend_set_state(struct meson_vpu_block *vblk, amc = vblk->pipeline->priv->crtcs[crtc_index]; meson_crtc_state = to_am_meson_crtc_state(amc->base.state); + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + MESON_DRM_BLOCK("%s set_state called.\n", postblend->base.name); mvps = priv_to_pipeline_state(pipeline->obj.state); mvsps = &mvps->sub_states[0]; @@ -644,6 +644,9 @@ static void t3x_postblend_set_state(struct meson_vpu_block *vblk, amc = vblk->pipeline->priv->crtcs[crtc_index]; meson_crtc_state = to_am_meson_crtc_state(amc->base.state); + if (vblk->ops->init_register) + vblk->ops->init_register(vblk, state); + MESON_DRM_BLOCK("%s set_state called.\n", postblend->base.name); mvps = priv_to_pipeline_state(pipeline->obj.state); mvsps = &mvps->sub_states[0]; @@ -652,14 +655,6 @@ static void t3x_postblend_set_state(struct meson_vpu_block *vblk, secure_config(OSD_MODULE, mvps->sec_src, crtc_index); #endif - if (!vblk->init_done) { - if (crtc_index == 1) - reg_ops->rdma_write_reg_bits(VPP_INTF_OSD3_CTRL, 0, 1, 1); - reg_ops->rdma_write_reg(VPP_MISC_T3X, 0); - - vblk->init_done = 1; - } - if (crtc_index == 0) { scope.h_start = 0; scope.v_start = 0; @@ -1225,17 +1220,30 @@ static void postblend_hw_init(struct meson_vpu_block *vblk) } #ifndef CONFIG_AMLOGIC_ZAPPER_CUT -static void txhd2_postblend_hw_init(struct meson_vpu_block *vblk) +static void txhd2_postblend_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) { struct meson_vpu_postblend *postblend = to_postblend_block(vblk); - postblend->reg = &postblend_reg; + if (vblk->init_done) + return; vpp_osd2_postblend_mux_set(vblk, vblk->pipeline->subs[0].reg_ops, postblend->reg, VPP_NULL); vpp_osd1_preblend_mux_set(vblk, vblk->pipeline->subs[0].reg_ops, postblend->reg, VPP_NULL); osd1_blend_premult_set(vblk, vblk->pipeline->subs[0].reg_ops, postblend->reg); + + vblk->init_done = 1; + MESON_DRM_BLOCK("%s register_init called.\n", postblend->base.name); +} + +static void txhd2_postblend_hw_init(struct meson_vpu_block *vblk) +{ + struct meson_vpu_postblend *postblend = to_postblend_block(vblk); + + postblend->reg = &postblend_reg; + MESON_DRM_BLOCK("%s hw_init called.\n", postblend->base.name); } @@ -1247,6 +1255,29 @@ static void s7_postblend_hw_init(struct meson_vpu_block *vblk) DRM_DEBUG("%s hw_init called.\n", postblend->base.name); } +static void t7_postblend_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) +{ + struct meson_vpu_postblend *postblend = to_postblend_block(vblk); + struct rdma_reg_ops *reg_ops = state->sub->reg_ops; + struct am_meson_crtc *amc; + int crtc_index = vblk->index; + u32 *crtcmask_osd; + + if (vblk->init_done) + return; + + amc = vblk->pipeline->priv->crtcs[crtc_index]; + crtcmask_osd = amc->priv->of_conf.crtcmask_osd; + + if (!postblend->postblend_path_mask) + fix_vpu_clk2_default_regs(vblk, reg_ops, crtc_index, + crtcmask_osd); + + vblk->init_done = 1; + MESON_DRM_BLOCK("%s register_init called.\n", postblend->base.name); +} + static void t7_postblend_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_postblend *postblend = to_postblend_block(vblk); @@ -1257,13 +1288,36 @@ static void t7_postblend_hw_init(struct meson_vpu_block *vblk) MESON_DRM_BLOCK("%s hw_init called.\n", postblend->base.name); } +static void t3_postblend_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) +{ + struct meson_vpu_postblend *postblend = to_postblend_block(vblk); + struct rdma_reg_ops *reg_ops = state->sub->reg_ops; + int crtc_index = vblk->index; + struct am_meson_crtc *amc; + u32 *crtcmask_osd = NULL; + + if (vblk->init_done) + return; + + amc = vblk->pipeline->priv->crtcs[crtc_index]; + crtcmask_osd = amc->priv->of_conf.crtcmask_osd; + + independ_path_default_regs(vblk, vblk->pipeline->subs[0].reg_ops); + if (!postblend->postblend_path_mask) + fix_vpu_clk2_default_regs(vblk, reg_ops, crtc_index, + crtcmask_osd); + + vblk->init_done = 1; + MESON_DRM_BLOCK("%s register_init called.\n", postblend->base.name); +} + static void t3_postblend_hw_init(struct meson_vpu_block *vblk) { struct meson_vpu_postblend *postblend = to_postblend_block(vblk); postblend->reg = &postblend_reg; - independ_path_default_regs(vblk, vblk->pipeline->subs[0].reg_ops); /*t3 t5w t5m paht crtl flag*/ postblend->postblend_path_mask = true; MESON_DRM_BLOCK("%s hw_init called.\n", postblend->base.name); @@ -1276,6 +1330,24 @@ static void s5_postblend_hw_init(struct meson_vpu_block *vblk) postblend->reg = &s5_postblend_reg; } +static void t3x_postblend_register_init(struct meson_vpu_block *vblk, + struct meson_vpu_block_state *state) +{ + struct meson_vpu_postblend *postblend = to_postblend_block(vblk); + struct rdma_reg_ops *reg_ops = state->sub->reg_ops; + int crtc_index = vblk->index; + + if (vblk->init_done) + return; + + if (crtc_index == 1) + reg_ops->rdma_write_reg_bits(VPP_INTF_OSD3_CTRL, 0, 1, 1); + reg_ops->rdma_write_reg(VPP_MISC_T3X, 0); + + vblk->init_done = 1; + MESON_DRM_BLOCK("%s register_init called.\n", postblend->base.name); +} + static void t3x_postblend_hw_init(struct meson_vpu_block *vblk) { int reg_h = 0, reg_v = 0; @@ -1336,6 +1408,7 @@ struct meson_vpu_block_ops t7_postblend_ops = { .disable = postblend_hw_disable, .dump_register = t7_postblend_dump_register, .init = t7_postblend_hw_init, + .init_register = t7_postblend_register_init, }; struct meson_vpu_block_ops t3_postblend_ops = { @@ -1345,6 +1418,7 @@ struct meson_vpu_block_ops t3_postblend_ops = { .disable = postblend_hw_disable, .dump_register = postblend_dump_register, .init = t3_postblend_hw_init, + .init_register = t3_postblend_register_init, }; struct meson_vpu_block_ops s5_postblend_ops = { @@ -1363,6 +1437,7 @@ struct meson_vpu_block_ops t3x_postblend_ops = { .disable = s5_postblend_hw_disable, .dump_register = postblend_dump_register, .init = t3x_postblend_hw_init, + .init_register = t3x_postblend_register_init, }; struct meson_vpu_block_ops txhd2_postblend_ops = { @@ -1372,6 +1447,7 @@ struct meson_vpu_block_ops txhd2_postblend_ops = { .disable = txhd2_postblend_hw_disable, .dump_register = postblend_dump_register, .init = txhd2_postblend_hw_init, + .init_register = txhd2_postblend_register_init, }; struct meson_vpu_block_ops s6_postblend_ops = {