static int oaktrail_set_brightness(struct backlight_device *bd) { struct drm_device *dev = bl_get_data(oaktrail_backlight_device); struct drm_psb_private *dev_priv = dev->dev_private; int level = bd->props.brightness; u32 blc_pwm_ctl; u32 max_pwm_blc; /* Percentage 1-100% being valid */ if (level < 1) level = 1; if (gma_power_begin(dev, 0)) { /* Calculate and set the brightness value */ max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; blc_pwm_ctl = level * max_pwm_blc / 100; /* Adjust the backlight level with the percent in * dev_priv->blc_adj1; */ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; blc_pwm_ctl = blc_pwm_ctl / 100; /* Adjust the backlight level with the percent in * dev_priv->blc_adj2; */ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; blc_pwm_ctl = blc_pwm_ctl / 100; /* force PWM bit on */ REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); gma_power_end(dev); }
static int oaktrail_set_brightness(struct backlight_device *bd) { struct drm_device *dev = bl_get_data(oaktrail_backlight_device); struct drm_psb_private *dev_priv = dev->dev_private; int level = bd->props.brightness; u32 blc_pwm_ctl; u32 max_pwm_blc; /* */ if (level < 1) level = 1; if (gma_power_begin(dev, 0)) { /* */ max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; blc_pwm_ctl = level * max_pwm_blc / 100; /* */ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; blc_pwm_ctl = blc_pwm_ctl / 100; /* */ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; blc_pwm_ctl = blc_pwm_ctl / 100; /* */ REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); gma_power_end(dev); }
/** * Sets the power state for the panel. */ static void mrst_lvds_set_power(struct drm_device *dev, struct psb_intel_output *output, bool on) { u32 pp_status; struct drm_psb_private *dev_priv = dev->dev_private; if (!gma_power_begin(dev, true)) return; if (on) { REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); do { pp_status = REG_READ(PP_STATUS); } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); dev_priv->is_lvds_on = true; if (dev_priv->ops->lvds_bl_power) dev_priv->ops->lvds_bl_power(dev, true); } else { if (dev_priv->ops->lvds_bl_power) dev_priv->ops->lvds_bl_power(dev, false); REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON); do { pp_status = REG_READ(PP_STATUS); } while (pp_status & PP_ON); dev_priv->is_lvds_on = false; pm_request_idle(&dev->pdev->dev); } gma_power_end(dev); }
static void mrst_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct psb_intel_mode_device *mode_dev = enc_to_psb_intel_output(encoder)->mode_dev; struct drm_device *dev = encoder->dev; struct drm_psb_private *dev_priv = dev->dev_private; u32 lvds_port; uint64_t v = DRM_MODE_SCALE_FULLSCREEN; if (!gma_power_begin(dev, true)) return; /* * The LVDS pin pair will already have been turned on in the * psb_intel_crtc_mode_set since it has a large impact on the DPLL * settings. */ lvds_port = (REG_READ(LVDS) & (~LVDS_PIPEB_SELECT)) | LVDS_PORT_EN | LVDS_BORDER_EN; /* If the firmware says dither on Moorestown, or the BIOS does on Oaktrail then enable dithering */ if (mode_dev->panel_wants_dither || dev_priv->lvds_dither) lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; REG_WRITE(LVDS, lvds_port); drm_connector_property_get_value( &enc_to_psb_intel_output(encoder)->base, dev->mode_config.scaling_mode_property, &v); if (v == DRM_MODE_SCALE_NO_SCALE) REG_WRITE(PFIT_CONTROL, 0); else if (v == DRM_MODE_SCALE_ASPECT) { if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) || (mode->hdisplay != adjusted_mode->crtc_hdisplay)) { if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) == (mode->hdisplay * adjusted_mode->crtc_vdisplay)) REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); else if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) > (mode->hdisplay * adjusted_mode->crtc_vdisplay)) REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | PFIT_SCALING_MODE_PILLARBOX); else REG_WRITE(PFIT_CONTROL, PFIT_ENABLE | PFIT_SCALING_MODE_LETTERBOX); } else REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); } else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/ REG_WRITE(PFIT_CONTROL, PFIT_ENABLE); gma_power_end(dev); }
/* * Update the DBI MIPI Panel Frame Buffer. */ static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output, int pipe) { struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); 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 dpll_reg = MRST_DPLL_A; u32 dspcntr_reg = DSPACNTR; u32 pipeconf_reg = PIPEACONF; u32 dsplinoff_reg = DSPALINOFF; u32 dspsurf_reg = DSPASURF; 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) || !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE)) return; if (pipe == 2) { dspcntr_reg = DSPCCNTR; pipeconf_reg = PIPECCONF; dsplinoff_reg = DSPCLINOFF; dspsurf_reg = DSPCSURF; reg_offset = MIPIC_REG_OFFSET; } if (!gma_power_begin(dev, true)) { dev_err(dev->dev, "hw begin failed\n"); return; } /* Check DBI FIFO status */ if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) || !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) || !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) goto update_fb_out0; /* Refresh plane changes */ REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg)); REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg)); REG_READ(dspsurf_reg); mdfld_dsi_send_dcs(sender, DCS_WRITE_MEM_START, NULL, 0, CMD_DATA_SRC_PIPE, MDFLD_DSI_SEND_PACKAGE); dbi_output->dsr_fb_update_done = true; update_fb_out0: gma_power_end(dev); }
void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); struct drm_device *dev = dsi_config->dev; struct drm_psb_private *dev_priv = dev->dev_private; u32 mipi_reg = MIPI; u32 pipeconf_reg = PIPEACONF; if(pipe) { mipi_reg = MIPI_C; pipeconf_reg = PIPECCONF; } /* Start up display island if it was shutdown */ if (!gma_power_begin(dev, true)) return; if(on) { if (mdfld_get_panel_type(dev, pipe) == TMD_VID){ mdfld_dsi_dpi_turn_on(dpi_output, pipe); } else { /* Enable mipi port */ REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31))); REG_READ(mipi_reg); mdfld_dsi_dpi_turn_on(dpi_output, pipe); mdfld_dsi_tpo_ic_init(dsi_config, pipe); } if(pipe == 2) { dev_priv->dpi_panel_on2 = true; } else { dev_priv->dpi_panel_on = true; } } else { if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { mdfld_dsi_dpi_shut_down(dpi_output, pipe); } else { mdfld_dsi_dpi_shut_down(dpi_output, pipe); /* Disable mipi port */ REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31))); REG_READ(mipi_reg); } if(pipe == 2) dev_priv->dpi_panel_on2 = false; else dev_priv->dpi_panel_on = false; } gma_power_end(dev); }
static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height) { struct drm_device *dev = crtc->dev; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; uint32_t control = CURACNTR; uint32_t base = CURABASE; uint32_t temp; size_t addr = 0; struct gtt_range *gt; struct drm_gem_object *obj; int ret; switch (pipe) { case 0: break; case 1: control = CURBCNTR; base = CURBBASE; break; case 2: control = CURCCNTR; base = CURCBASE; break; default: dev_err(dev->dev, "Illegal Pipe Number. \n"); return -EINVAL; } #if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */ if (pipe != 0) return 0; #endif /* if we want to turn of the cursor ignore width and height */ if (!handle) { dev_dbg(dev->dev, "cursor off\n"); /* turn off the cursor */ temp = 0; temp |= CURSOR_MODE_DISABLE; if (gma_power_begin(dev, true)) { REG_WRITE(control, temp); REG_WRITE(base, 0); gma_power_end(dev); } /* Unpin the old GEM object */ if (psb_intel_crtc->cursor_obj) { gt = container_of(psb_intel_crtc->cursor_obj, struct gtt_range, gem); psb_gtt_unpin(gt); drm_gem_object_unreference(psb_intel_crtc->cursor_obj); psb_intel_crtc->cursor_obj = NULL; }
/** * psbfb_copyarea_accel - copyarea acceleration for /dev/fb * @info: our framebuffer * @a: copyarea parameters from the framebuffer core * * Perform a 2D copy via the accelerator */ static void psbfb_copyarea_accel(struct fb_info *info, const struct fb_copyarea *a) { struct psb_fbdev *fbdev = info->par; struct psb_framebuffer *psbfb = &fbdev->pfb; struct drm_device *dev = psbfb->base.dev; struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; struct drm_psb_private *dev_priv = dev->dev_private; uint32_t offset; uint32_t stride; uint32_t src_format; uint32_t dst_format; if (!fb) return; offset = psbfb->gtt->offset; stride = fb->pitches[0]; switch (fb->depth) { case 8: src_format = PSB_2D_SRC_332RGB; dst_format = PSB_2D_DST_332RGB; break; case 15: src_format = PSB_2D_SRC_555RGB; dst_format = PSB_2D_DST_555RGB; break; case 16: src_format = PSB_2D_SRC_565RGB; dst_format = PSB_2D_DST_565RGB; break; case 24: case 32: /* this is wrong but since we don't do blending its okay */ src_format = PSB_2D_SRC_8888ARGB; dst_format = PSB_2D_DST_8888ARGB; break; default: /* software fallback */ cfb_copyarea(info, a); return; } if (!gma_power_begin(dev, false)) { cfb_copyarea(info, a); return; } psb_accel_2d_copy(dev_priv, offset, stride, src_format, offset, stride, dst_format, a->sx, a->sy, a->dx, a->dy, a->width, a->height); gma_power_end(dev); }
static u32 mrst_lvds_get_max_backlight(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; u32 ret; if (gma_power_begin(dev, false)) { ret = ((REG_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >> BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; gma_power_end(dev); } else
void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != mask) { u32 reg = psb_pipestat(pipe); dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ if (gma_power_begin(dev_priv->dev, false)) { u32 writeVal = PSB_RVDC32(reg); writeVal |= (mask | (mask >> 16)); PSB_WVDC32(writeVal, reg); (void) PSB_RVDC32(reg); gma_power_end(dev_priv->dev); }
static void mrst_lvds_prepare(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct psb_intel_output *output = enc_to_psb_intel_output(encoder); struct psb_intel_mode_device *mode_dev = output->mode_dev; if (!gma_power_begin(dev, true)) return; mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & BACKLIGHT_DUTY_CYCLE_MASK); mrst_lvds_set_power(dev, output, false); gma_power_end(dev); }
static void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on) { struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder); struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); struct drm_device *dev = dsi_config->dev; struct drm_psb_private *dev_priv = dev->dev_private; /*start up display island if it was shutdown*/ if (!gma_power_begin(dev, true)) return; if (on) { if (mdfld_get_panel_type(dev, pipe) == TMD_VID) mdfld_dsi_dpi_turn_on(dpi_output, pipe); else if (mdfld_get_panel_type(dev, pipe) == TC35876X) mdfld_dsi_configure_up(dsi_encoder, pipe); else { /*enable mipi port*/ REG_WRITE(MIPI_PORT_CONTROL(pipe), REG_READ(MIPI_PORT_CONTROL(pipe)) | BIT(31)); REG_READ(MIPI_PORT_CONTROL(pipe)); mdfld_dsi_dpi_turn_on(dpi_output, pipe); mdfld_dsi_tpo_ic_init(dsi_config, pipe); } dev_priv->dpi_panel_on[pipe] = true; } else { if (mdfld_get_panel_type(dev, pipe) == TMD_VID) mdfld_dsi_dpi_shut_down(dpi_output, pipe); else if (mdfld_get_panel_type(dev, pipe) == TC35876X) mdfld_dsi_configure_down(dsi_encoder, pipe); else { mdfld_dsi_dpi_shut_down(dpi_output, pipe); /*disable mipi port*/ REG_WRITE(MIPI_PORT_CONTROL(pipe), REG_READ(MIPI_PORT_CONTROL(pipe)) & ~BIT(31)); REG_READ(MIPI_PORT_CONTROL(pipe)); } dev_priv->dpi_panel_on[pipe] = false; } gma_power_end(dev); }
int mdfld_set_brightness(struct backlight_device *bd) { struct drm_device *dev = (struct drm_device *)bl_get_data(mdfld_backlight_device); struct drm_psb_private *dev_priv = dev->dev_private; int level = bd->props.brightness; DRM_DEBUG_DRIVER("backlight level set to %d\n", level); /* Perform value bounds checking */ if (level < BRIGHTNESS_MIN_LEVEL) level = BRIGHTNESS_MIN_LEVEL; if (gma_power_begin(dev, false)) { u32 adjusted_level = 0; /* * Adjust the backlight level with the percent in * dev_priv->blc_adj2 */ adjusted_level = level * dev_priv->blc_adj2; adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX; dev_priv->brightness_adjusted = adjusted_level; if (mdfld_get_panel_type(dev, 0) == TC35876X) { if (dev_priv->dpi_panel_on[0] || dev_priv->dpi_panel_on[2]) tc35876x_brightness_control(dev, dev_priv->brightness_adjusted); } else { if (dev_priv->dpi_panel_on[0]) mdfld_dsi_brightness_control(dev, 0, dev_priv->brightness_adjusted); } if (dev_priv->dpi_panel_on[2]) mdfld_dsi_brightness_control(dev, 2, dev_priv->brightness_adjusted); gma_power_end(dev); } /* cache the brightness for later use */ dev_priv->brightness = level; return 0; }
static int mfld_set_brightness(struct backlight_device *bd) { struct drm_device *dev = bl_get_data(mdfld_backlight_device); struct drm_psb_private *dev_priv = dev->dev_private; int level = bd->props.brightness; /* Percentage 1-100% being valid */ if (level < 1) level = 1; if (gma_power_begin(dev, 0)) { /* Calculate and set the brightness value */ u32 adjusted_level; /* Adjust the backlight level with the percent in * dev_priv->blc_adj2; */ adjusted_level = level * dev_priv->blc_adj2; adjusted_level = adjusted_level / 100; #if 0 #ifndef CONFIG_MDFLD_DSI_DPU if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) && (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){ mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0); dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level); } #endif mdfld_dsi_brightness_control(dev, 0, adjusted_level); if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2)) mdfld_dsi_brightness_control(dev, 2, adjusted_level); #endif gma_power_end(dev); } mdfld_brightness = level; return 0; }
static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { int ret = 0; struct drm_device *dev = encoder->dev; struct drm_psb_private *dev_priv = dev->dev_private; struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dsi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); struct mdfld_dsi_connector *dsi_connector = dsi_config->connector; int pipe = dsi_connector->pipe; u8 param = 0; /* Regs */ u32 mipi_reg = MIPI; u32 dspcntr_reg = DSPACNTR; u32 pipeconf_reg = PIPEACONF; u32 reg_offset = 0; /* Values */ u32 dspcntr_val = dev_priv->dspcntr; u32 pipeconf_val = dev_priv->pipeconf; u32 h_active_area = mode->hdisplay; u32 v_active_area = mode->vdisplay; u32 mipi_val; mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX | TE_TRIGGER_GPIO_PIN); dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val); dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI"); dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay); if (pipe == 2) { mipi_reg = MIPI_C; dspcntr_reg = DSPCCNTR; pipeconf_reg = PIPECCONF; reg_offset = MIPIC_REG_OFFSET; dspcntr_val = dev_priv->dspcntr2; pipeconf_val = dev_priv->pipeconf2; } else { mipi_val |= 0x2; /*two lanes for port A and C respectively*/ } if (!gma_power_begin(dev, true)) { dev_err(dev->dev, "hw begin failed\n"); return; } REG_WRITE(dspcntr_reg, dspcntr_val); REG_READ(dspcntr_reg); /* 20ms delay before sending exit_sleep_mode */ msleep(20); /* Send exit_sleep_mode DCS */ ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_EXIT_SLEEP_MODE, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM); if (ret) { dev_err(dev->dev, "sent exit_sleep_mode faild\n"); goto out_err; } /* Send set_tear_on DCS */ ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON, ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM); if (ret) { dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__); goto out_err; } /* Do some init stuff */ REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR); REG_READ(pipeconf_reg); /* TODO: this looks ugly, try to move it to CRTC mode setting*/ if (pipe == 2) dev_priv->pipeconf2 |= PIPEACONF_DSR; else dev_priv->pipeconf |= PIPEACONF_DSR; dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg)); ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0, h_active_area - 1, v_active_area - 1); if (ret) { dev_err(dev->dev, "update area failed\n"); goto out_err; } out_err: gma_power_end(dev); if (ret) dev_err(dev->dev, "mode set failed\n"); }
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; }
/* * Enter DSR */ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe) { u32 reg_val; struct drm_device *dev = dbi_output->dev; struct drm_psb_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = dbi_output->base.base.crtc; struct psb_intel_crtc *psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; u32 dpll_reg = MRST_DPLL_A; u32 pipeconf_reg = PIPEACONF; u32 dspcntr_reg = DSPACNTR; if (!dbi_output) return; /* FIXME check if can go */ dev_priv->is_in_idle = true; gdbi_output = dbi_output; 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; } if (!gma_power_begin(dev, true)) { dev_err(dev->dev, "hw begin failed\n"); return; } /* Disable te interrupts */ mdfld_disable_te(dev, pipe); /* Disable plane */ reg_val = REG_READ(dspcntr_reg); if (!(reg_val & DISPLAY_PLANE_ENABLE)) { REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE); REG_READ(dspcntr_reg); } /* Disable pipe */ reg_val = REG_READ(pipeconf_reg); if (!(reg_val & DISPLAY_PLANE_ENABLE)) { reg_val &= ~DISPLAY_PLANE_ENABLE; reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF); REG_WRITE(pipeconf_reg, reg_val); REG_READ(pipeconf_reg); mdfldWaitForPipeDisable(dev, pipe); } /* Disable DPLL */ reg_val = REG_READ(dpll_reg); if (!(reg_val & DPLL_VCO_ENABLE)) { reg_val &= ~DPLL_VCO_ENABLE; REG_WRITE(dpll_reg, reg_val); REG_READ(dpll_reg); udelay(500); } gma_power_end(dev); dbi_output->mode_flags |= MODE_SETTING_IN_DSR; if (pipe == 2) { enter_dsr = 1; /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */ } }
void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); struct drm_device *dev = dsi_config->dev; struct drm_psb_private *dev_priv = dev->dev_private; int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); u32 pipeconf_reg = PIPEACONF; u32 dspcntr_reg = DSPACNTR; u32 mipi_reg = MIPI; u32 reg_offset = 0; u32 pipeconf = dev_priv->pipeconf; u32 dspcntr = dev_priv->dspcntr; u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n", mode->hdisplay, mode->vdisplay, pipe); if(pipe) { pipeconf_reg = PIPECCONF; dspcntr_reg = DSPCCNTR; mipi_reg = MIPI_C; reg_offset = MIPIC_REG_OFFSET; } else { mipi |= 2; } if (!gma_power_begin(dev, true)) return; /* Set up mipi port FIXME: do at init time */ REG_WRITE(mipi_reg, mipi); REG_READ(mipi_reg); /* Set up DSI controller DPI interface */ mdfld_dsi_dpi_controller_init(dsi_config, pipe); if (mdfld_get_panel_type(dev, pipe) != TMD_VID) { /* Turn on DPI interface */ mdfld_dsi_dpi_turn_on(dpi_output, pipe); } /* Set up pipe */ REG_WRITE(pipeconf_reg, pipeconf); REG_READ(pipeconf_reg); /* Set up display plane */ REG_WRITE(dspcntr_reg, dspcntr); REG_READ(dspcntr_reg); msleep(20); /* FIXME: this should wait for vblank */ dev_dbg(dev->dev, "State %x, power %d\n", REG_READ(MIPIA_INTR_STAT_REG + reg_offset), dpi_output->panel_on); if (mdfld_get_panel_type(dev, pipe) != TMD_VID) { /* Init driver ic */ mdfld_dsi_tpo_ic_init(dsi_config, pipe); /* Init backlight */ mdfld_dsi_brightness_init(dsi_config, pipe); } gma_power_end(dev); }
void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct mdfld_dsi_encoder *dsi_encoder = mdfld_dsi_encoder(encoder); struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); struct drm_device *dev = dsi_config->dev; struct drm_psb_private *dev_priv = dev->dev_private; int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); u32 pipeconf_reg = PIPEACONF; u32 dspcntr_reg = DSPACNTR; u32 pipeconf; u32 dspcntr; u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; if (pipe == -1) return; pipeconf = dev_priv->pipeconf[pipe]; dspcntr = dev_priv->dspcntr[pipe]; if (pipe) { pipeconf_reg = PIPECCONF; dspcntr_reg = DSPCCNTR; } else { if (mdfld_get_panel_type(dev, pipe) == TC35876X) mipi &= (~0x03); /* Use all four lanes */ else mipi |= 2; } /*start up display island if it was shutdown*/ if (!gma_power_begin(dev, true)) return; if (mdfld_get_panel_type(dev, pipe) == TC35876X) { /* * The following logic is required to reset the bridge and * configure. This also starts the DSI clock at 200MHz. */ tc35876x_set_bridge_reset_state(dev, 0); /*Pull High Reset */ tc35876x_toshiba_bridge_panel_on(dev); udelay(100); /* Now start the DSI clock */ REG_WRITE(MRST_DPLL_A, 0x00); REG_WRITE(MRST_FPA0, 0xC1); REG_WRITE(MRST_DPLL_A, 0x00800000); udelay(500); REG_WRITE(MRST_DPLL_A, 0x80800000); if (REG_BIT_WAIT(pipeconf_reg, 1, 29)) dev_err(&dev->pdev->dev, "%s: DSI PLL lock timeout\n", __func__); REG_WRITE(MIPI_DPHY_PARAM_REG(pipe), 0x2A0c6008); mipi_set_properties(dsi_config, pipe); mdfld_mipi_config(dsi_config, pipe); mdfld_set_pipe_timing(dsi_config, pipe); REG_WRITE(DSPABASE, 0x00); REG_WRITE(DSPASIZE, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); REG_WRITE(DSPACNTR, 0x98000000); REG_WRITE(DSPASURF, 0x00); REG_WRITE(VGACNTRL, 0x80000000); REG_WRITE(DEVICE_READY_REG, 0x00000001); REG_WRITE(MIPI_PORT_CONTROL(pipe), 0x80810000); } else { /*set up mipi port FIXME: do at init time */ REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi); } REG_READ(MIPI_PORT_CONTROL(pipe)); if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { /* NOP */ } else if (mdfld_get_panel_type(dev, pipe) == TC35876X) { /* set up DSI controller DPI interface */ mdfld_dsi_dpi_controller_init(dsi_config, pipe); /* Configure MIPI Bridge and Panel */ tc35876x_configure_lvds_bridge(dev); dev_priv->dpi_panel_on[pipe] = true; } else { /*turn on DPI interface*/ mdfld_dsi_dpi_turn_on(dpi_output, pipe); } /*set up pipe*/ REG_WRITE(pipeconf_reg, pipeconf); REG_READ(pipeconf_reg); /*set up display plane*/ REG_WRITE(dspcntr_reg, dspcntr); REG_READ(dspcntr_reg); msleep(20); /* FIXME: this should wait for vblank */ if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { /* NOP */ } else if (mdfld_get_panel_type(dev, pipe) == TC35876X) { mdfld_dsi_dpi_turn_on(dpi_output, pipe); } else { /* init driver ic */ mdfld_dsi_tpo_ic_init(dsi_config, pipe); /*init backlight*/ mdfld_dsi_brightness_init(dsi_config, pipe); } gma_power_end(dev); }
static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on) { int ret = 0; struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_encoder_get_pkg_sender(dsi_encoder); struct drm_device *dev = encoder->dev; struct drm_psb_private *dev_priv = dev->dev_private; u32 reg_offset = 0; int pipe = (dbi_output->channel_num == 0) ? 0 : 2; u32 data = 0; dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n", pipe, on ? "On" : "Off", dbi_output->dbi_panel_on ? "True" : "False"); if (pipe == 2) { if (on) dev_priv->dual_mipi = true; else dev_priv->dual_mipi = false; reg_offset = MIPIC_REG_OFFSET; } else { if (!on) dev_priv->dual_mipi = false; } if (!gma_power_begin(dev, true)) { dev_err(dev->dev, "hw begin failed\n"); return; } if (on) { if (dbi_output->dbi_panel_on) goto out_err; ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON); if (ret) { dev_err(dev->dev, "power on error\n"); goto out_err; } dbi_output->dbi_panel_on = true; if (pipe == 2) dev_priv->dbi_panel_on2 = true; else dev_priv->dbi_panel_on = true; mdfld_enable_te(dev, pipe); } else { if (!dbi_output->dbi_panel_on && !dbi_output->first_boot) goto out_err; dbi_output->dbi_panel_on = false; dbi_output->first_boot = false; if (pipe == 2) dev_priv->dbi_panel_on2 = false; else dev_priv->dbi_panel_on = false; mdfld_disable_te(dev, pipe); ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF); if (ret) { dev_err(dev->dev, "power on error\n"); goto out_err; } } /* * FIXME: this is a WA for TPO panel crash on DPMS on & off around * 83 times. the root cause of this issue is that Booster in * drvIC crashed. Add this WA so that we can resume the driver IC * once we found that booster has a fault */ mdfld_dsi_get_power_mode(dsi_config, &data, MDFLD_DSI_HS_TRANSMISSION); if (on && data && !(data & (1 << 7))) { /* Soft reset */ mdfld_dsi_send_dcs(sender, DCS_SOFT_RESET, NULL, 0, CMD_DATA_SRC_PIPE, MDFLD_DSI_SEND_PACKAGE); /* Init drvIC */ if (dbi_output->p_funcs->drv_ic_init) dbi_output->p_funcs->drv_ic_init(dsi_config, pipe); } out_err: gma_power_end(dev); if (ret) dev_err(dev->dev, "failed\n"); }