static int mdfld_dpu_enter_dsr(struct drm_device * dev) { struct drm_psb_private * dev_priv = dev->dev_private; struct mdfld_dbi_dpu_info * dpu_info = dev_priv->dbi_dpu_info; struct mdfld_dsi_dbi_output ** dbi_output; int i; PSB_DEBUG_ENTRY("\n"); dbi_output = dpu_info->dbi_outputs; for(i=0; i<dpu_info->dbi_output_num; i++) { /*if output is off or already in DSR state, don't enter again*/ if(dbi_output[i]->dbi_panel_on && !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) { mdfld_dsi_dbi_enter_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0); } } return 0; }
/* Periodically update dbi panel */ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe) { struct drm_psb_private *dev_priv = dev->dev_private; struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; struct mdfld_dsi_dbi_output **dbi_outputs; struct mdfld_dsi_dbi_output *dbi_output; int i; int can_enter_dsr = 0; u32 damage_mask; dbi_outputs = dsr_info->dbi_outputs; dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0]; if (!dbi_output) return; if (pipe == 0) damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0; else if (pipe == 2) damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2; else return; /* If FB is damaged and panel is on update on-panel FB */ if (damage_mask && dbi_output->dbi_panel_on) { dbi_output->dsr_fb_update_done = false; if (dbi_output->p_funcs->update_fb) dbi_output->p_funcs->update_fb(dbi_output, pipe); if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done) dev_priv->dsr_fb_update &= ~damage_mask; /*clean IN_DSR flag*/ dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; dbi_output->dsr_idle_count = 0; } else { dbi_output->dsr_idle_count++; } switch (dsr_info->dbi_output_num) { case 1: if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT) can_enter_dsr = 1; break; case 2: if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT) can_enter_dsr = 1; break; default: DRM_ERROR("Wrong DBI output number\n"); } /* Try to enter DSR */ if (can_enter_dsr) { for (i = 0; i < dsr_info->dbi_output_num; i++) { if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] && !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) { mdfld_dsi_dbi_enter_dsr(dbi_outputs[i], dbi_outputs[i]->channel_num ? 2 : 0); #if 0 enter_dsr = 1; pr_err("%s: enter_dsr = 1\n", __func__); #endif } } /*schedule rpm suspend after gfxrtdelay*/ #ifdef CONFIG_GFX_RTPM if (!dev_priv->rpm_enabled || !enter_dsr /* || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */ || pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay)) dev_warn(dev->dev, "Runtime PM schedule suspend failed, rpm %d\n", dev_priv->rpm_enabled); #endif } }