static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct drm_device *dev = dbi_output->dev; struct drm_psb_private *dev_priv = dev->dev_private; struct psb_drm_dpu_rect rect; mdfld_dsi_dbi_set_power(encoder, true); dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; rect.x = rect.y = 0; rect.width = 864; rect.height = 480; if (dbi_output->channel_num == 1) { dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; /*if dpu enabled report a fullscreen damage*/ mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); } else { dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); } dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; }
static struct panel_funcs *dsi_config_to_p_func( struct mdfld_dsi_config *dsi_config) { struct mdfld_dsi_encoder *encoder; struct mdfld_dsi_dpi_output *dpi_output; struct mdfld_dsi_dbi_output *dbi_output; struct panel_funcs *p_funcs = NULL; if (!dsi_config) return NULL; encoder = dsi_config->encoders[dsi_config->type]; if (!encoder) return NULL; if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) { dbi_output = MDFLD_DSI_DBI_OUTPUT(encoder); p_funcs = dbi_output ? dbi_output->p_funcs : NULL; } else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) { dpi_output = MDFLD_DSI_DPI_OUTPUT(encoder); p_funcs = dpi_output ? dpi_output->p_funcs : NULL; } return p_funcs; }
void mdfld_panel_generic_dsi_dbi_commit(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct drm_device *dev = dbi_output->dev; struct drm_psb_private *dev_priv = dev->dev_private; /*DSI DPU was still on debugging, will remove this option later*/ #ifdef CONFIG_MDFLD_DSI_DPU struct psb_drm_dpu_rect rect; #endif PSB_DEBUG_ENTRY("\n"); mdfld_panel_generic_dsi_dbi_set_power(encoder, true); gbdispstatus = true; dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; #ifdef CONFIG_MDFLD_DSI_DPU rect.x = rect.y = 0; rect.width = 864; rect.height = 480; #endif dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; }
static bool mdfld_generic_dsi_dbi_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct drm_display_mode *fixed_mode = dbi_output->panel_fixed_mode; PSB_DEBUG_ENTRY("\n"); if (fixed_mode) { adjusted_mode->hdisplay = fixed_mode->hdisplay; adjusted_mode->hsync_start = fixed_mode->hsync_start; adjusted_mode->hsync_end = fixed_mode->hsync_end; adjusted_mode->htotal = fixed_mode->htotal; adjusted_mode->vdisplay = fixed_mode->vdisplay; adjusted_mode->vsync_start = fixed_mode->vsync_start; adjusted_mode->vsync_end = fixed_mode->vsync_end; adjusted_mode->vtotal = fixed_mode->vtotal; adjusted_mode->clock = fixed_mode->clock; drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); } return true; }
static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER; dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE; mdfld_dsi_dbi_set_power(encoder, false); }
static void mdfld_generic_dsi_dbi_prepare(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); PSB_DEBUG_ENTRY("\n"); dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER; dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE; }
void mdfld_panel_generic_dsi_dbi_prepare(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); PSB_DEBUG_ENTRY("\n"); dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER; dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE; mdfld_panel_generic_dsi_dbi_set_power(encoder, false); gbdispstatus = false; }
int mdfld_panel_generic_dsi_dbi_power_on(struct drm_encoder *encoder) { 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 panel_funcs *p_funcs = dbi_output->p_funcs; struct mdfld_dsi_hw_registers *regs = NULL; struct mdfld_dsi_hw_context *ctx = NULL; struct drm_device *dev = encoder->dev; struct drm_psb_private *dev_priv = dev->dev_private; int err = 0; if (!dev_priv->dsi_init_done) return 0; if (!dsi_config) return -EINVAL; regs = &dsi_config->regs; ctx = &dsi_config->dsi_hw_context; if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) return -EAGAIN; /* * Different panel may have different ways to have * panel turned on. Support it! */ if (p_funcs && p_funcs->power_on) { p_funcs->dsi_controller_init(dsi_config, dsi_config->pipe, true); if (p_funcs->power_on(dsi_config)) { DRM_ERROR("Failed to power on panel\n"); err = -EAGAIN; goto power_on_err; } } power_on_err: ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return err; }
static void pyr_dsi_dbi_commit(struct drm_encoder * encoder) { struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct drm_device * dev = dbi_output->dev; struct drm_psb_private * dev_priv = dev->dev_private; /*DSI DPU was still on debugging, will remove this option later*/ #ifdef CONFIG_MDFLD_DSI_DPU struct psb_drm_dpu_rect rect; #endif PSB_DEBUG_ENTRY("\n"); pyr_dsi_dbi_set_power(encoder, true); dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; #ifdef CONFIG_MDFLD_DSI_DPU rect.x = rect.y = 0; rect.width = 864; rect.height = 480; #endif if(dbi_output->channel_num == 1) { dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; #ifdef CONFIG_MDFLD_DSI_DPU /*if dpu enabled report a fullscreen damage*/ mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); #endif } else { dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; #ifdef CONFIG_MDFLD_DSI_DPU mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); /*start dpu timer*/ if (dev_priv->platform_rev_id == MDFLD_PNW_A0) mdfld_dbi_dpu_timer_start(dev_priv->dbi_dpu_info); #else if (dev_priv->platform_rev_id == MDFLD_PNW_A0) mdfld_dbi_dsr_timer_start(dev_priv->dbi_dsr_info); #endif } dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; }
static void mdfld_generic_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_dbi_output *dbi_output; struct drm_device *dev; struct mdfld_dsi_config *dsi_config; struct drm_psb_private *dev_priv; dsi_encoder = MDFLD_DSI_ENCODER(encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); if (!dsi_config) { DRM_ERROR("dsi_config is NULL\n"); return; } dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); dev = dsi_config->dev; dev_priv = dev->dev_private; PSB_DEBUG_ENTRY("%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off")); mutex_lock(&dev_priv->dpms_mutex); DCLockMutex(); if (mode == DRM_MODE_DPMS_ON) { mdfld_generic_dsi_dbi_set_power(encoder, true); DCAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOn(dsi_config->pipe); } else { mdfld_generic_dsi_dbi_set_power(encoder, false); drm_handle_vblank(dev, dsi_config->pipe); /* Turn off TE interrupt. */ drm_vblank_off(dev, dsi_config->pipe); /* Make the pending flip request as completed. */ DCUnAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOff(dsi_config->pipe); } DCUnLockMutex(); mutex_unlock(&dev_priv->dpms_mutex); }
int mdfld_panel_generic_dsi_dbi_power_off(struct drm_encoder *encoder) { 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 panel_funcs *p_funcs = dbi_output->p_funcs; struct mdfld_dsi_hw_context *ctx; struct drm_device *dev = encoder->dev; struct drm_psb_private *dev_priv = dev->dev_private; int err = 0; if (!dev_priv->dsi_init_done) return 0; if (!dsi_config) return -EINVAL; ctx = &dsi_config->dsi_hw_context; if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) return -EAGAIN; ctx->lastbrightnesslevel = psb_brightness; /* * Different panel may have different ways to have * panel turned off. Support it! */ if (p_funcs && p_funcs->power_off) { if (p_funcs->power_off(dsi_config)) { DRM_ERROR("Failed to power off panel\n"); err = -EAGAIN; goto power_off_err; } } power_off_err: ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); return err; }
static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct drm_device *dev = dbi_output->dev; struct drm_psb_private *dev_priv = dev->dev_private; static bool bdispoff; dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off")); if (mode == DRM_MODE_DPMS_ON) { /* * FIXME: in case I am wrong! * we don't need to exit dsr here to wake up plane/pipe/pll * if everything goes right, hw_begin will resume them all * during set_power. */ if (bdispoff /* FIXME && gbgfxsuspended */) { mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D); bdispoff = false; dev_priv->dispstatus = true; } mdfld_dsi_dbi_set_power(encoder, true); /* FIXME if (gbgfxsuspended) gbgfxsuspended = false; */ } else { /* * I am not sure whether this is the perfect place to * turn rpm on since we still have a lot of CRTC turnning * on work to do. */ bdispoff = true; dev_priv->dispstatus = false; mdfld_dsi_dbi_set_power(encoder, false); } }
static void mdfld_generic_dsi_dbi_commit(struct drm_encoder *encoder) { struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output *dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct drm_device *dev = dbi_output->dev; struct drm_psb_private *dev_priv = dev->dev_private; PSB_DEBUG_ENTRY("\n"); mdfld_generic_dsi_dbi_set_power(encoder, true); dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; if (dbi_output->channel_num == 1) dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; else dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; dbi_output->first_boot = false; }
static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) { struct mdfld_dsi_encoder * dsi_encoder = MDFLD_DSI_ENCODER(encoder); struct mdfld_dsi_dbi_output * dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); struct drm_device * dev = dbi_output->dev; static bool bdispoff = false; PSB_DEBUG_ENTRY("%s \n", (mode == DRM_MODE_DPMS_ON ? "on":"off")); if (mode == DRM_MODE_DPMS_ON){ if(gbgfxsuspended && bdispoff){ bdispoff = false; gbdispstatus = true; gbgfxsuspended = false; mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_2D_3D, 0, 0); } pyr_dsi_dbi_set_power(encoder, true); } else { bdispoff = true; gbdispstatus = false; pyr_dsi_dbi_set_power(encoder, false); } }
int mdfld_panel_generic_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 panel_funcs *p_funcs = dbi_output->p_funcs; struct mdfld_dsi_connector *dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder); struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(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; PSB_DEBUG_ENTRY("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 (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("hw begin failed\n"); return -EAGAIN; } mutex_lock(&dsi_config->context_lock); if (on) { if (dbi_output->dbi_panel_on) goto out_err; ret = mdfld_panel_generic_dsi_dbi_power_on(encoder); if (ret) { DRM_ERROR("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; if (dev_priv->platform_rev_id != MDFLD_PNW_A0) mdfld_enable_te(dev, pipe); /* wake up error detector if ESD enabled */ if (p_funcs->esd_detection) mdfld_dsi_error_detector_wakeup(dsi_connector); else PSB_DEBUG_ENTRY("ESD detection disabled\n"); dsi_config->dsi_hw_context.panel_on = 1; } 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; if (dev_priv->platform_rev_id != MDFLD_PNW_A0) mdfld_disable_te(dev, pipe); ret = mdfld_panel_generic_dsi_dbi_power_off(encoder); if (ret) { DRM_ERROR("power on error\n"); goto out_err; } dsi_config->dsi_hw_context.panel_on = 0; } out_err: mutex_unlock(&dsi_config->context_lock); ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); if (ret) DRM_ERROR("failed\n"); else PSB_DEBUG_ENTRY("successfully\n"); return ret; }
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"); }
/* generic dbi function */ static int mdfld_generic_dsi_dbi_set_power(struct drm_encoder *encoder, bool on) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_dbi_output *dbi_output; struct mdfld_dsi_connector *dsi_connector; struct mdfld_dsi_config *dsi_config; struct panel_funcs *p_funcs; struct drm_device *dev; struct drm_psb_private *dev_priv; int pipe = 0; if (!encoder) { DRM_ERROR("Invalid encoder\n"); return -EINVAL; } PSB_DEBUG_ENTRY("%s\n", (on ? "on" : "off")); dsi_encoder = MDFLD_DSI_ENCODER(encoder); dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder); if (!dsi_connector) { DRM_ERROR("dsi_connector is NULL\n"); return -EINVAL; } p_funcs = dbi_output->p_funcs; dev = encoder->dev; dev_priv = dev->dev_private; pipe = dsi_config->pipe; mutex_lock(&dsi_config->context_lock); if (dsi_connector->status != connector_status_connected) goto set_power_err; if (dbi_output->first_boot && dsi_config->dsi_hw_context.panel_on) { if (on) { /* When using smooth transition, * wake up ESD detection thread. */ mdfld_dsi_error_detector_wakeup(dsi_connector); } DRM_INFO("skip panle power setting for first boot! " \ "panel is already powered on\n"); goto fun_exit; } switch (on) { case true: /* panel is already on */ if (dsi_config->dsi_hw_context.panel_on) goto fun_exit; if (__dbi_panel_power_on(dsi_config, p_funcs)) { DRM_ERROR("Faild to turn on panel\n"); goto set_power_err; } dsi_config->dsi_hw_context.panel_on = 1; dbi_output->dbi_panel_on = 1; mdfld_dsi_error_detector_wakeup(dsi_connector); break; case false: if (!dsi_config->dsi_hw_context.panel_on && !dbi_output->first_boot) goto fun_exit; if (__dbi_panel_power_off(dsi_config, p_funcs)) { DRM_ERROR("Faild to turn off panel\n"); goto set_power_err; } dsi_config->dsi_hw_context.panel_on = 0; dbi_output->dbi_panel_on = 0; break; default: break; } fun_exit: mutex_unlock(&dsi_config->context_lock); PSB_DEBUG_ENTRY("successfully\n"); return 0; set_power_err: mutex_unlock(&dsi_config->context_lock); PSB_DEBUG_ENTRY("unsuccessfully!\n"); return -EAGAIN; }
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_generic_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_dbi_output *dbi_output; struct drm_device *dev; struct mdfld_dsi_config *dsi_config; struct drm_psb_private *dev_priv; struct panel_funcs *p_funcs; dsi_encoder = MDFLD_DSI_ENCODER(encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); if (!dsi_config) { DRM_ERROR("dsi_config is NULL\n"); return; } dbi_output = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); dev = dsi_config->dev; dev_priv = dev->dev_private; PSB_DEBUG_ENTRY("%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : DRM_MODE_DPMS_STANDBY == mode ? "standby" : "off")); mutex_lock(&dev_priv->dpms_mutex); DCLockMutex(); p_funcs = dbi_output->p_funcs; if (mode == DRM_MODE_DPMS_ON) { mdfld_generic_dsi_dbi_set_power(encoder, true); DCAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOn(dsi_config->pipe); #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE { struct mdfld_dsi_hw_context *ctx = &dsi_config->dsi_hw_context; struct backlight_device bd; bd.props.brightness = ctx->lastbrightnesslevel; psb_set_brightness(&bd); } #endif } else if (mode == DRM_MODE_DPMS_STANDBY) { #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE struct mdfld_dsi_hw_context *ctx = &dsi_config->dsi_hw_context; struct backlight_device bd; ctx->lastbrightnesslevel = psb_get_brightness(&bd); bd.props.brightness = 0; psb_set_brightness(&bd); #endif /* Make the pending flip request as completed. */ DCUnAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOff(dsi_config->pipe); } else { mdfld_generic_dsi_dbi_set_power(encoder, false); drm_handle_vblank(dev, dsi_config->pipe); /* Turn off TE interrupt. */ drm_vblank_off(dev, dsi_config->pipe); /* Make the pending flip request as completed. */ DCUnAttachPipe(dsi_config->pipe); DC_MRFLD_onPowerOff(dsi_config->pipe); } DCUnLockMutex(); mutex_unlock(&dev_priv->dpms_mutex); }
static void pyr_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 = (struct drm_psb_private*)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 = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX); if (dev_priv->platform_rev_id != MDFLD_PNW_A0) mipi_val = (PASS_FROM_SPHY_TO_AFE | TE_TRIGGER_GPIO_PIN); PSB_DEBUG_ENTRY("mipi_val =0x%x\n", mipi_val); PSB_DEBUG_ENTRY("type %s\n", (pipe == 2) ? "MIPI2" : "MIPI"); PSB_DEBUG_ENTRY("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 (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("hw begin failed\n"); return; } /*set up pipe related registers*/ REG_WRITE(mipi_reg, mipi_val); REG_READ(mipi_reg); pyr_dsi_controller_dbi_init(dsi_config, pipe); msleep(20); 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, exit_sleep_mode, NULL, 0, CMD_DATA_SRC_SYSTEM_MEM); if(ret) { DRM_ERROR("sent exit_sleep_mode faild\n"); goto out_err; } if (dev_priv->platform_rev_id != MDFLD_PNW_A0) { /*send set_tear_on DCS*/ ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on, ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM); if(ret) { DRM_ERROR("%s - sent set_tear_on faild\n", __func__); goto out_err; } } /*do some init stuff*/ mdfld_dsi_brightness_init(dsi_config, pipe); mdfld_dsi_gen_fifo_ready (dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset), HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); 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; } PSB_DEBUG_ENTRY("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) { DRM_ERROR("update area failed\n"); goto out_err; } out_err: ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); if(ret) { DRM_ERROR("mode set failed\n"); } else { PSB_DEBUG_ENTRY("mode set done successfully\n"); } }
static void pyr_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 drm_device * dev = dbi_output->dev;*/ 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; PSB_DEBUG_ENTRY("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 (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, OSPM_UHB_FORCE_POWER_ON)) { DRM_ERROR("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) { DRM_ERROR("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; if (dev_priv->platform_rev_id != MDFLD_PNW_A0) mdfld_enable_te(dev, 0); } } 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; if (dev_priv->platform_rev_id != MDFLD_PNW_A0) mdfld_disable_te(dev, 2); } else { dev_priv->dbi_panel_on = false; if (dev_priv->platform_rev_id != MDFLD_PNW_A0) { mdfld_disable_te(dev, 0); if (dev_priv->dbi_panel_on2) mdfld_enable_te(dev, 2); } } ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF); if(ret) { DRM_ERROR("power on error\n"); goto out_err; } } out_err: ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); if(ret) DRM_ERROR("failed\n"); else PSB_DEBUG_ENTRY("successfully\n"); }