Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +3 −1 Original line number Diff line number Diff line Loading @@ -254,7 +254,9 @@ static void sde_encoder_phys_cmd_autorefresh_done_irq(void *arg, int irq_idx) spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); SDE_EVT32_IRQ(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, new_cnt); phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->hw_intf->idx - INTF_0, new_cnt); /* Signal any waiting atomic commit thread */ wake_up_all(&cmd_enc->autorefresh.kickoff_wq); Loading drivers/gpu/drm/msm/sde/sde_rm.c +130 −28 Original line number Diff line number Diff line Loading @@ -1215,47 +1215,132 @@ static u32 _sde_rm_poll_intr_status_for_cont_splash(struct sde_hw_intr *intr, return -ETIMEDOUT; } static inline bool _sde_rm_autorefresh_validate(struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, bool hw_intf_te) { if ((hw_intf_te && !intf) || (!hw_intf_te && !pp)) { SDE_ERROR("autorefresh wrong params!\n"); return true; } if (hw_intf_te) { if (!intf->ops.get_autorefresh || !intf->ops.setup_autorefresh || !intf->ops.connect_external_te || !intf->ops.get_vsync_info) { SDE_ERROR("intf autorefresh apis not supported\n"); return true; } } else { if (!pp->ops.get_autorefresh || !pp->ops.setup_autorefresh || !pp->ops.connect_external_te || !pp->ops.get_vsync_info) { SDE_ERROR("pp autorefresh apis not supported\n"); return true; } } return false; } static inline void _sde_rm_autorefresh_get_cfg( struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, struct sde_hw_autorefresh *cfg, bool hw_intf_te) { if (hw_intf_te) intf->ops.get_autorefresh(intf, cfg); else pp->ops.get_autorefresh(pp, cfg); } static inline void _sde_rm_autorefresh_connect_external_te( struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, bool hw_intf_te, bool enable) { if (hw_intf_te) intf->ops.connect_external_te(intf, enable); else pp->ops.connect_external_te(pp, enable); } static inline void _sde_rm_autorefresh_setup(struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, struct sde_hw_autorefresh *cfg, bool hw_intf_te) { if (hw_intf_te) intf->ops.setup_autorefresh(intf, cfg); else pp->ops.setup_autorefresh(pp, cfg); } static inline void _sde_rm_autorefresh_get_vsync_info( struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, struct sde_hw_pp_vsync_info *info, bool hw_intf_te) { if (hw_intf_te) intf->ops.get_vsync_info(intf, info); else pp->ops.get_vsync_info(pp, info); } static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, struct sde_hw_intr *hw_intr) struct sde_hw_intf *intf, struct sde_hw_intr *hw_intr, bool hw_intf_te) { u32 const timeout_ms = 35; /* Max two vsyncs delay */ int rc = 0, i, loop = 3; struct sde_hw_pp_vsync_info info; int irq_idx_pp_done = -1, irq_idx_autorefresh = -1; struct sde_hw_autorefresh cfg = {0}; int dbg_idx; int te_irq_idx; if (!pp->ops.get_autorefresh || !pp->ops.setup_autorefresh || !pp->ops.connect_external_te || !pp->ops.get_vsync_info) { SDE_ERROR("autorefresh update api not supported\n"); if (_sde_rm_autorefresh_validate(pp, intf, hw_intf_te)) return 0; } dbg_idx = hw_intf_te ? intf->idx - INTF_0 : pp->idx - PINGPONG_0; te_irq_idx = hw_intf_te ? intf->idx : pp->idx; /* read default autorefresh configuration */ pp->ops.get_autorefresh(pp, &cfg); _sde_rm_autorefresh_get_cfg(pp, intf, &cfg, hw_intf_te); if (!cfg.enable) { SDE_DEBUG("autorefresh already disabled\n"); SDE_EVT32(pp->idx - PINGPONG_0, SDE_EVTLOG_FUNC_CASE1); SDE_DEBUG("autorefresh already disabled idx:%d\n", dbg_idx); SDE_EVT32(dbg_idx, SDE_EVTLOG_FUNC_CASE1); return 0; } /* disable external TE first */ pp->ops.connect_external_te(pp, false); _sde_rm_autorefresh_connect_external_te(pp, intf, hw_intf_te, false); /* get all IRQ indexes */ if (hw_intr->ops.irq_idx_lookup) { irq_idx_pp_done = hw_intr->ops.irq_idx_lookup( SDE_IRQ_TYPE_PING_PONG_COMP, pp->idx); SDE_IRQ_TYPE_PING_PONG_COMP, te_irq_idx); irq_idx_autorefresh = hw_intr->ops.irq_idx_lookup( SDE_IRQ_TYPE_PING_PONG_AUTO_REF, pp->idx); SDE_DEBUG("pp_done itr_idx = %d autorefresh irq_idx:%d\n", SDE_IRQ_TYPE_PING_PONG_AUTO_REF, te_irq_idx); SDE_DEBUG("pp_done irq_idx = %d autorefresh irq_idx:%d\n", irq_idx_pp_done, irq_idx_autorefresh); } /* disable autorefresh */ cfg.enable = false; pp->ops.setup_autorefresh(pp, &cfg); _sde_rm_autorefresh_setup(pp, intf, &cfg, hw_intf_te); SDE_EVT32(pp->idx - PINGPONG_0, irq_idx_pp_done, irq_idx_autorefresh); SDE_EVT32(dbg_idx, irq_idx_pp_done, irq_idx_autorefresh); _sde_rm_clear_irq_status(hw_intr, irq_idx_pp_done, irq_idx_autorefresh); /* Loading @@ -1267,9 +1352,9 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, for (i = 0; i < loop; i++) { info.wr_ptr_line_count = 0; info.rd_ptr_init_val = 0; pp->ops.get_vsync_info(pp, &info); _sde_rm_autorefresh_get_vsync_info(pp, intf, &info, hw_intf_te); SDE_EVT32(pp->idx - PINGPONG_0, info.wr_ptr_line_count, SDE_EVT32(dbg_idx, info.wr_ptr_line_count, info.rd_ptr_init_val, SDE_EVTLOG_FUNC_CASE1); /* wait for read ptr intr */ Loading @@ -1278,10 +1363,11 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, info.wr_ptr_line_count = 0; info.rd_ptr_init_val = 0; pp->ops.get_vsync_info(pp, &info); SDE_DEBUG("i=%d, line count=%d\n", i, info.wr_ptr_line_count); SDE_EVT32(pp->idx - PINGPONG_0, info.wr_ptr_line_count, _sde_rm_autorefresh_get_vsync_info(pp, intf, &info, hw_intf_te); SDE_DEBUG("i=%d, line count=%d\n", i, info.wr_ptr_line_count); SDE_EVT32(dbg_idx, info.wr_ptr_line_count, info.rd_ptr_init_val, SDE_EVTLOG_FUNC_CASE2); /* log line count and return */ Loading @@ -1295,7 +1381,7 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, usleep_range(3000, 4000); } pp->ops.connect_external_te(pp, true); _sde_rm_autorefresh_connect_external_te(pp, intf, hw_intf_te, true); return rc; } Loading @@ -1315,29 +1401,33 @@ static int _sde_rm_get_pp_dsc_for_cont_splash(struct sde_rm *rm, { int index = 0; int value, dsc_cnt = 0; struct sde_rm_hw_iter iter_pp; struct sde_rm_hw_iter iter_pp, intf_iter; bool hw_intf_te_supported; struct sde_hw_intr *hw_intr = NULL; if (!rm || !sde_kms || !dsc_ids) { SDE_ERROR("invalid input parameters\n"); return 0; } hw_intf_te_supported = sde_hw_intf_te_supported(sde_kms->catalog); hw_intr = sde_kms->hw_intr; if (!hw_intr) { SDE_ERROR("hw_intr handler not initialized\n"); return 0; } SDE_DEBUG("max_dsc_cnt = %d\n", max_dsc_cnt); sde_rm_init_hw_iter(&iter_pp, 0, SDE_HW_BLK_PINGPONG); while (_sde_rm_get_hw_locked(rm, &iter_pp)) { struct sde_hw_pingpong *pp = to_sde_hw_pingpong(iter_pp.blk->hw); struct sde_hw_intr *hw_intr = NULL; if (!pp->ops.get_dsc_status) { SDE_ERROR("get_dsc_status ops not initialized\n"); return 0; } hw_intr = sde_kms->hw_intr; if (!hw_intr) { SDE_ERROR("hw_intr handler not initialized\n"); return 0; } value = pp->ops.get_dsc_status(pp); SDE_DEBUG("DSC[%d]=0x%x, dsc_cnt = %d\n", index, value, dsc_cnt); Loading @@ -1347,7 +1437,19 @@ static int _sde_rm_get_pp_dsc_for_cont_splash(struct sde_rm *rm, } index++; _sde_rm_autorefresh_disable(pp, hw_intr); if (!hw_intf_te_supported) _sde_rm_autorefresh_disable(pp, NULL, hw_intr, hw_intf_te_supported); } sde_rm_init_hw_iter(&intf_iter, 0, SDE_HW_BLK_INTF); while (_sde_rm_get_hw_locked(rm, &intf_iter)) { struct sde_hw_intf *intf = to_sde_hw_intf(intf_iter.blk->hw); if (hw_intf_te_supported) _sde_rm_autorefresh_disable(NULL, intf, hw_intr, hw_intf_te_supported); } return dsc_cnt; Loading Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c +3 −1 Original line number Diff line number Diff line Loading @@ -254,7 +254,9 @@ static void sde_encoder_phys_cmd_autorefresh_done_irq(void *arg, int irq_idx) spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); SDE_EVT32_IRQ(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0, new_cnt); phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->hw_intf->idx - INTF_0, new_cnt); /* Signal any waiting atomic commit thread */ wake_up_all(&cmd_enc->autorefresh.kickoff_wq); Loading
drivers/gpu/drm/msm/sde/sde_rm.c +130 −28 Original line number Diff line number Diff line Loading @@ -1215,47 +1215,132 @@ static u32 _sde_rm_poll_intr_status_for_cont_splash(struct sde_hw_intr *intr, return -ETIMEDOUT; } static inline bool _sde_rm_autorefresh_validate(struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, bool hw_intf_te) { if ((hw_intf_te && !intf) || (!hw_intf_te && !pp)) { SDE_ERROR("autorefresh wrong params!\n"); return true; } if (hw_intf_te) { if (!intf->ops.get_autorefresh || !intf->ops.setup_autorefresh || !intf->ops.connect_external_te || !intf->ops.get_vsync_info) { SDE_ERROR("intf autorefresh apis not supported\n"); return true; } } else { if (!pp->ops.get_autorefresh || !pp->ops.setup_autorefresh || !pp->ops.connect_external_te || !pp->ops.get_vsync_info) { SDE_ERROR("pp autorefresh apis not supported\n"); return true; } } return false; } static inline void _sde_rm_autorefresh_get_cfg( struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, struct sde_hw_autorefresh *cfg, bool hw_intf_te) { if (hw_intf_te) intf->ops.get_autorefresh(intf, cfg); else pp->ops.get_autorefresh(pp, cfg); } static inline void _sde_rm_autorefresh_connect_external_te( struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, bool hw_intf_te, bool enable) { if (hw_intf_te) intf->ops.connect_external_te(intf, enable); else pp->ops.connect_external_te(pp, enable); } static inline void _sde_rm_autorefresh_setup(struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, struct sde_hw_autorefresh *cfg, bool hw_intf_te) { if (hw_intf_te) intf->ops.setup_autorefresh(intf, cfg); else pp->ops.setup_autorefresh(pp, cfg); } static inline void _sde_rm_autorefresh_get_vsync_info( struct sde_hw_pingpong *pp, struct sde_hw_intf *intf, struct sde_hw_pp_vsync_info *info, bool hw_intf_te) { if (hw_intf_te) intf->ops.get_vsync_info(intf, info); else pp->ops.get_vsync_info(pp, info); } static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, struct sde_hw_intr *hw_intr) struct sde_hw_intf *intf, struct sde_hw_intr *hw_intr, bool hw_intf_te) { u32 const timeout_ms = 35; /* Max two vsyncs delay */ int rc = 0, i, loop = 3; struct sde_hw_pp_vsync_info info; int irq_idx_pp_done = -1, irq_idx_autorefresh = -1; struct sde_hw_autorefresh cfg = {0}; int dbg_idx; int te_irq_idx; if (!pp->ops.get_autorefresh || !pp->ops.setup_autorefresh || !pp->ops.connect_external_te || !pp->ops.get_vsync_info) { SDE_ERROR("autorefresh update api not supported\n"); if (_sde_rm_autorefresh_validate(pp, intf, hw_intf_te)) return 0; } dbg_idx = hw_intf_te ? intf->idx - INTF_0 : pp->idx - PINGPONG_0; te_irq_idx = hw_intf_te ? intf->idx : pp->idx; /* read default autorefresh configuration */ pp->ops.get_autorefresh(pp, &cfg); _sde_rm_autorefresh_get_cfg(pp, intf, &cfg, hw_intf_te); if (!cfg.enable) { SDE_DEBUG("autorefresh already disabled\n"); SDE_EVT32(pp->idx - PINGPONG_0, SDE_EVTLOG_FUNC_CASE1); SDE_DEBUG("autorefresh already disabled idx:%d\n", dbg_idx); SDE_EVT32(dbg_idx, SDE_EVTLOG_FUNC_CASE1); return 0; } /* disable external TE first */ pp->ops.connect_external_te(pp, false); _sde_rm_autorefresh_connect_external_te(pp, intf, hw_intf_te, false); /* get all IRQ indexes */ if (hw_intr->ops.irq_idx_lookup) { irq_idx_pp_done = hw_intr->ops.irq_idx_lookup( SDE_IRQ_TYPE_PING_PONG_COMP, pp->idx); SDE_IRQ_TYPE_PING_PONG_COMP, te_irq_idx); irq_idx_autorefresh = hw_intr->ops.irq_idx_lookup( SDE_IRQ_TYPE_PING_PONG_AUTO_REF, pp->idx); SDE_DEBUG("pp_done itr_idx = %d autorefresh irq_idx:%d\n", SDE_IRQ_TYPE_PING_PONG_AUTO_REF, te_irq_idx); SDE_DEBUG("pp_done irq_idx = %d autorefresh irq_idx:%d\n", irq_idx_pp_done, irq_idx_autorefresh); } /* disable autorefresh */ cfg.enable = false; pp->ops.setup_autorefresh(pp, &cfg); _sde_rm_autorefresh_setup(pp, intf, &cfg, hw_intf_te); SDE_EVT32(pp->idx - PINGPONG_0, irq_idx_pp_done, irq_idx_autorefresh); SDE_EVT32(dbg_idx, irq_idx_pp_done, irq_idx_autorefresh); _sde_rm_clear_irq_status(hw_intr, irq_idx_pp_done, irq_idx_autorefresh); /* Loading @@ -1267,9 +1352,9 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, for (i = 0; i < loop; i++) { info.wr_ptr_line_count = 0; info.rd_ptr_init_val = 0; pp->ops.get_vsync_info(pp, &info); _sde_rm_autorefresh_get_vsync_info(pp, intf, &info, hw_intf_te); SDE_EVT32(pp->idx - PINGPONG_0, info.wr_ptr_line_count, SDE_EVT32(dbg_idx, info.wr_ptr_line_count, info.rd_ptr_init_val, SDE_EVTLOG_FUNC_CASE1); /* wait for read ptr intr */ Loading @@ -1278,10 +1363,11 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, info.wr_ptr_line_count = 0; info.rd_ptr_init_val = 0; pp->ops.get_vsync_info(pp, &info); SDE_DEBUG("i=%d, line count=%d\n", i, info.wr_ptr_line_count); SDE_EVT32(pp->idx - PINGPONG_0, info.wr_ptr_line_count, _sde_rm_autorefresh_get_vsync_info(pp, intf, &info, hw_intf_te); SDE_DEBUG("i=%d, line count=%d\n", i, info.wr_ptr_line_count); SDE_EVT32(dbg_idx, info.wr_ptr_line_count, info.rd_ptr_init_val, SDE_EVTLOG_FUNC_CASE2); /* log line count and return */ Loading @@ -1295,7 +1381,7 @@ static int _sde_rm_autorefresh_disable(struct sde_hw_pingpong *pp, usleep_range(3000, 4000); } pp->ops.connect_external_te(pp, true); _sde_rm_autorefresh_connect_external_te(pp, intf, hw_intf_te, true); return rc; } Loading @@ -1315,29 +1401,33 @@ static int _sde_rm_get_pp_dsc_for_cont_splash(struct sde_rm *rm, { int index = 0; int value, dsc_cnt = 0; struct sde_rm_hw_iter iter_pp; struct sde_rm_hw_iter iter_pp, intf_iter; bool hw_intf_te_supported; struct sde_hw_intr *hw_intr = NULL; if (!rm || !sde_kms || !dsc_ids) { SDE_ERROR("invalid input parameters\n"); return 0; } hw_intf_te_supported = sde_hw_intf_te_supported(sde_kms->catalog); hw_intr = sde_kms->hw_intr; if (!hw_intr) { SDE_ERROR("hw_intr handler not initialized\n"); return 0; } SDE_DEBUG("max_dsc_cnt = %d\n", max_dsc_cnt); sde_rm_init_hw_iter(&iter_pp, 0, SDE_HW_BLK_PINGPONG); while (_sde_rm_get_hw_locked(rm, &iter_pp)) { struct sde_hw_pingpong *pp = to_sde_hw_pingpong(iter_pp.blk->hw); struct sde_hw_intr *hw_intr = NULL; if (!pp->ops.get_dsc_status) { SDE_ERROR("get_dsc_status ops not initialized\n"); return 0; } hw_intr = sde_kms->hw_intr; if (!hw_intr) { SDE_ERROR("hw_intr handler not initialized\n"); return 0; } value = pp->ops.get_dsc_status(pp); SDE_DEBUG("DSC[%d]=0x%x, dsc_cnt = %d\n", index, value, dsc_cnt); Loading @@ -1347,7 +1437,19 @@ static int _sde_rm_get_pp_dsc_for_cont_splash(struct sde_rm *rm, } index++; _sde_rm_autorefresh_disable(pp, hw_intr); if (!hw_intf_te_supported) _sde_rm_autorefresh_disable(pp, NULL, hw_intr, hw_intf_te_supported); } sde_rm_init_hw_iter(&intf_iter, 0, SDE_HW_BLK_INTF); while (_sde_rm_get_hw_locked(rm, &intf_iter)) { struct sde_hw_intf *intf = to_sde_hw_intf(intf_iter.blk->hw); if (hw_intf_te_supported) _sde_rm_autorefresh_disable(NULL, intf, hw_intr, hw_intf_te_supported); } return dsc_cnt; Loading