Loading drivers/gpu/drm/msm/sde/sde_encoder.c +24 −2 Original line number Diff line number Diff line Loading @@ -2625,6 +2625,29 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc) pending_flush = 0x0; /* * Trigger LUT DMA flush, this might need a wait, so we need * to do this outside of the atomic context */ for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; bool wait_for_dma = false; if (!phys || phys->enable_state == SDE_ENC_DISABLED) continue; ctl = phys->hw_ctl; if (!ctl) continue; if (phys->ops.wait_dma_trigger) wait_for_dma = phys->ops.wait_dma_trigger(phys); if (phys->hw_ctl->ops.reg_dma_flush) phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl, wait_for_dma); } /* update pending counts and trigger kickoff ctl flush atomically */ spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags); Loading Loading @@ -2652,8 +2675,7 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc) phys->split_role == ENC_ROLE_SLAVE) && phys->split_role != ENC_ROLE_SKIP) set_bit(i, sde_enc->frame_busy_mask); if (phys->hw_ctl->ops.reg_dma_flush) phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl); if (!phys->ops.needs_single_flush || !phys->ops.needs_single_flush(phys)) _sde_encoder_trigger_flush(&sde_enc->base, phys, 0x0); Loading drivers/gpu/drm/msm/sde/sde_encoder_phys.h +3 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,8 @@ struct sde_encoder_virt_ops { * @is_autorefresh_enabled: provides the autorefresh current * enable/disable state. * @get_line_count: Obtain current vertical line count * @wait_dma_trigger: Returns true if lut dma has to trigger and wait * unitl transaction is complete. */ struct sde_encoder_phys_ops { Loading Loading @@ -176,6 +178,7 @@ struct sde_encoder_phys_ops { void (*restore)(struct sde_encoder_phys *phys); bool (*is_autorefresh_enabled)(struct sde_encoder_phys *phys); int (*get_line_count)(struct sde_encoder_phys *phys); bool (*wait_dma_trigger)(struct sde_encoder_phys *phys); }; /** Loading drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +32 −0 Original line number Diff line number Diff line Loading @@ -591,6 +591,37 @@ static int sde_encoder_phys_vid_control_vblank_irq( return ret; } static bool sde_encoder_phys_vid_wait_dma_trigger( struct sde_encoder_phys *phys_enc) { struct sde_encoder_phys_vid *vid_enc; struct sde_hw_intf *intf; struct sde_hw_ctl *ctl; struct intf_status status; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return false; } vid_enc = to_sde_encoder_phys_vid(phys_enc); intf = vid_enc->hw_intf; ctl = phys_enc->hw_ctl; if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { SDE_ERROR("invalid hw_intf %d hw_ctl %d\n", vid_enc->hw_intf != NULL, phys_enc->hw_ctl != NULL); return false; } if (!intf->ops.get_status) return false; intf->ops.get_status(intf, &status); /* if interface is not enabled, return true to wait for dma trigger */ return status.is_en ? false : true; } static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) { struct msm_drm_private *priv; Loading Loading @@ -945,6 +976,7 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops) ops->trigger_flush = sde_encoder_helper_trigger_flush; ops->hw_reset = sde_encoder_helper_hw_reset; ops->get_line_count = sde_encoder_phys_vid_get_line_count; ops->wait_dma_trigger = sde_encoder_phys_vid_wait_dma_trigger; } struct sde_encoder_phys *sde_encoder_phys_vid_init( Loading drivers/gpu/drm/msm/sde/sde_hw_ctl.c +3 −2 Original line number Diff line number Diff line Loading @@ -565,12 +565,13 @@ static void sde_hw_ctl_setup_sbuf_cfg(struct sde_hw_ctl *ctx, SDE_REG_WRITE(c, CTL_ROT_TOP, val); } static void sde_hw_reg_dma_flush(struct sde_hw_ctl *ctx) static void sde_hw_reg_dma_flush(struct sde_hw_ctl *ctx, bool blocking) { struct sde_hw_reg_dma_ops *ops = sde_reg_dma_get_ops(); if (ops && ops->last_command) ops->last_command(ctx, DMA_CTL_QUEUE0); ops->last_command(ctx, DMA_CTL_QUEUE0, (blocking ? REG_DMA_WAIT4_COMP : REG_DMA_NOWAIT)); } static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, Loading drivers/gpu/drm/msm/sde/sde_hw_ctl.h +2 −1 Original line number Diff line number Diff line Loading @@ -214,8 +214,9 @@ struct sde_hw_ctl_ops { /** * Flush the reg dma by sending last command. * @ctx : ctl path ctx pointer * @blocking : if set to true api will block until flush is done */ void (*reg_dma_flush)(struct sde_hw_ctl *ctx); void (*reg_dma_flush)(struct sde_hw_ctl *ctx, bool blocking); }; Loading Loading
drivers/gpu/drm/msm/sde/sde_encoder.c +24 −2 Original line number Diff line number Diff line Loading @@ -2625,6 +2625,29 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc) pending_flush = 0x0; /* * Trigger LUT DMA flush, this might need a wait, so we need * to do this outside of the atomic context */ for (i = 0; i < sde_enc->num_phys_encs; i++) { struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; bool wait_for_dma = false; if (!phys || phys->enable_state == SDE_ENC_DISABLED) continue; ctl = phys->hw_ctl; if (!ctl) continue; if (phys->ops.wait_dma_trigger) wait_for_dma = phys->ops.wait_dma_trigger(phys); if (phys->hw_ctl->ops.reg_dma_flush) phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl, wait_for_dma); } /* update pending counts and trigger kickoff ctl flush atomically */ spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags); Loading Loading @@ -2652,8 +2675,7 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc) phys->split_role == ENC_ROLE_SLAVE) && phys->split_role != ENC_ROLE_SKIP) set_bit(i, sde_enc->frame_busy_mask); if (phys->hw_ctl->ops.reg_dma_flush) phys->hw_ctl->ops.reg_dma_flush(phys->hw_ctl); if (!phys->ops.needs_single_flush || !phys->ops.needs_single_flush(phys)) _sde_encoder_trigger_flush(&sde_enc->base, phys, 0x0); Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys.h +3 −0 Original line number Diff line number Diff line Loading @@ -132,6 +132,8 @@ struct sde_encoder_virt_ops { * @is_autorefresh_enabled: provides the autorefresh current * enable/disable state. * @get_line_count: Obtain current vertical line count * @wait_dma_trigger: Returns true if lut dma has to trigger and wait * unitl transaction is complete. */ struct sde_encoder_phys_ops { Loading Loading @@ -176,6 +178,7 @@ struct sde_encoder_phys_ops { void (*restore)(struct sde_encoder_phys *phys); bool (*is_autorefresh_enabled)(struct sde_encoder_phys *phys); int (*get_line_count)(struct sde_encoder_phys *phys); bool (*wait_dma_trigger)(struct sde_encoder_phys *phys); }; /** Loading
drivers/gpu/drm/msm/sde/sde_encoder_phys_vid.c +32 −0 Original line number Diff line number Diff line Loading @@ -591,6 +591,37 @@ static int sde_encoder_phys_vid_control_vblank_irq( return ret; } static bool sde_encoder_phys_vid_wait_dma_trigger( struct sde_encoder_phys *phys_enc) { struct sde_encoder_phys_vid *vid_enc; struct sde_hw_intf *intf; struct sde_hw_ctl *ctl; struct intf_status status; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); return false; } vid_enc = to_sde_encoder_phys_vid(phys_enc); intf = vid_enc->hw_intf; ctl = phys_enc->hw_ctl; if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { SDE_ERROR("invalid hw_intf %d hw_ctl %d\n", vid_enc->hw_intf != NULL, phys_enc->hw_ctl != NULL); return false; } if (!intf->ops.get_status) return false; intf->ops.get_status(intf, &status); /* if interface is not enabled, return true to wait for dma trigger */ return status.is_en ? false : true; } static void sde_encoder_phys_vid_enable(struct sde_encoder_phys *phys_enc) { struct msm_drm_private *priv; Loading Loading @@ -945,6 +976,7 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops) ops->trigger_flush = sde_encoder_helper_trigger_flush; ops->hw_reset = sde_encoder_helper_hw_reset; ops->get_line_count = sde_encoder_phys_vid_get_line_count; ops->wait_dma_trigger = sde_encoder_phys_vid_wait_dma_trigger; } struct sde_encoder_phys *sde_encoder_phys_vid_init( Loading
drivers/gpu/drm/msm/sde/sde_hw_ctl.c +3 −2 Original line number Diff line number Diff line Loading @@ -565,12 +565,13 @@ static void sde_hw_ctl_setup_sbuf_cfg(struct sde_hw_ctl *ctx, SDE_REG_WRITE(c, CTL_ROT_TOP, val); } static void sde_hw_reg_dma_flush(struct sde_hw_ctl *ctx) static void sde_hw_reg_dma_flush(struct sde_hw_ctl *ctx, bool blocking) { struct sde_hw_reg_dma_ops *ops = sde_reg_dma_get_ops(); if (ops && ops->last_command) ops->last_command(ctx, DMA_CTL_QUEUE0); ops->last_command(ctx, DMA_CTL_QUEUE0, (blocking ? REG_DMA_WAIT4_COMP : REG_DMA_NOWAIT)); } static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops, Loading
drivers/gpu/drm/msm/sde/sde_hw_ctl.h +2 −1 Original line number Diff line number Diff line Loading @@ -214,8 +214,9 @@ struct sde_hw_ctl_ops { /** * Flush the reg dma by sending last command. * @ctx : ctl path ctx pointer * @blocking : if set to true api will block until flush is done */ void (*reg_dma_flush)(struct sde_hw_ctl *ctx); void (*reg_dma_flush)(struct sde_hw_ctl *ctx, bool blocking); }; Loading