static int __mdfld_dbi_exit_dsr(struct mdfld_dsi_dbi_output * dbi_output, int pipe) { struct drm_device * dev = dbi_output->dev; struct drm_crtc * crtc = dbi_output->base.base.crtc; struct psb_intel_crtc * psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; u32 reg_val; u32 dpll_reg = PSB_DSI_PLL_CTRL; u32 pipeconf_reg = PSB_PIPECONF(PSB_PIPE_A); u32 dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_A); u32 dspbase_reg = PSB_DSPBASE(PSB_PIPE_A); u32 dspsurf_reg = PSB_DSPSURF(PSB_PIPE_A); PSB_DEBUG_ENTRY("\n"); if(!dbi_output) { return 0; } /*if mode setting on-going, back off*/ if((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) return -EAGAIN; if(pipe == 2) { dpll_reg = PSB_DSI_PLL_CTRL; pipeconf_reg = PSB_PIPECONF(PSB_PIPE_C); dspcntr_reg = PSB_DSPCNTR(PSB_PIPE_C); dspbase_reg = MDFLD_DSPCBASE; dspsurf_reg = PSB_DSPSURF(PSB_PIPE_C); } if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, true)) return -EAGAIN; /*enable DPLL*/ reg_val = REG_READ(dpll_reg); if(!(reg_val & DPLL_VCO_ENABLE)) { if(reg_val & MDFLD_PWR_GATE_EN) { reg_val &= ~MDFLD_PWR_GATE_EN; REG_WRITE(dpll_reg, reg_val); REG_READ(dpll_reg); udelay(500); } reg_val |= DPLL_VCO_ENABLE; REG_WRITE(dpll_reg, reg_val); REG_READ(dpll_reg); udelay(500); /*FIXME: add timeout*/ while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)); } /*enable pipe*/ reg_val = REG_READ(pipeconf_reg); if(!(reg_val & PIPEACONF_ENABLE)) { reg_val |= PIPEACONF_ENABLE; REG_WRITE(pipeconf_reg, reg_val); REG_READ(pipeconf_reg); udelay(500); mdfldWaitForPipeEnable(dev, pipe); } /*enable plane*/ reg_val = REG_READ(dspcntr_reg); if(!(reg_val & DISPLAY_PLANE_ENABLE)) { reg_val |= DISPLAY_PLANE_ENABLE; REG_WRITE(dspcntr_reg, reg_val); REG_READ(dspcntr_reg); udelay(500); } ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); /*clean IN_DSR flag*/ dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; return 0; }
static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe) { struct drm_device *dev = dbi_output->dev; struct drm_crtc *crtc = dbi_output->base.base.crtc; struct psb_intel_crtc *psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; u32 reg_val; u32 dpll_reg = MRST_DPLL_A; u32 pipeconf_reg = PIPEACONF; u32 dspcntr_reg = DSPACNTR; u32 reg_offset = 0; /*if mode setting on-going, back off*/ if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) return; if (pipe == 2) { dpll_reg = MRST_DPLL_A; pipeconf_reg = PIPECCONF; dspcntr_reg = DSPCCNTR; reg_offset = MIPIC_REG_OFFSET; } if (!gma_power_begin(dev, true)) { dev_err(dev->dev, "hw begin failed\n"); return; } /* Enable DPLL */ reg_val = REG_READ(dpll_reg); if (!(reg_val & DPLL_VCO_ENABLE)) { if (reg_val & MDFLD_PWR_GATE_EN) { reg_val &= ~MDFLD_PWR_GATE_EN; REG_WRITE(dpll_reg, reg_val); REG_READ(dpll_reg); udelay(500); } reg_val |= DPLL_VCO_ENABLE; REG_WRITE(dpll_reg, reg_val); REG_READ(dpll_reg); udelay(500); /* Add timeout */ while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) cpu_relax(); } /* Enable pipe */ reg_val = REG_READ(pipeconf_reg); if (!(reg_val & PIPEACONF_ENABLE)) { reg_val |= PIPEACONF_ENABLE; REG_WRITE(pipeconf_reg, reg_val); REG_READ(pipeconf_reg); udelay(500); mdfldWaitForPipeEnable(dev, pipe); } /* Enable plane */ reg_val = REG_READ(dspcntr_reg); if (!(reg_val & DISPLAY_PLANE_ENABLE)) { reg_val |= DISPLAY_PLANE_ENABLE; REG_WRITE(dspcntr_reg, reg_val); REG_READ(dspcntr_reg); udelay(500); } /* Enable TE interrupt on this pipe */ mdfld_enable_te(dev, pipe); gma_power_end(dev); /*clean IN_DSR flag*/ dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; }