void force_power_on_dpi_panel(struct drm_psb_private *dev_priv) { struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0]; struct mdfld_dsi_dpi_output *dpi_output = dev_priv->dpi_output; struct panel_funcs *p_funcs; if (!dsi_config) { DRM_INFO("%s: dsi_config NULL\n", __func__); return; } p_funcs = dpi_output->p_funcs; if (!p_funcs) { DRM_ERROR("%s: invalid panel function table\n", __func__); return; } mutex_lock(&dsi_config->context_lock); acquire_ospm_lock(); ospm_resume_display(gpDrmDevice->pdev); release_ospm_lock(); if (__dpi_panel_power_on(dsi_config, p_funcs)) { DRM_INFO("%s: on failed\n", __func__); mutex_unlock(&dsi_config->context_lock); return; } mutex_unlock(&dsi_config->context_lock); }
/** * Setup Display Controller to turn on/off a video mode panel. * Most of the video mode MIPI panel should follow the power on/off * sequence in this function. * NOTE: do NOT modify this function for new panel Enabling. Register * new panel function callbacks to make this function available for a * new video mode panel */ static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_connector *dsi_connector; struct mdfld_dsi_dpi_output *dpi_output; struct mdfld_dsi_config *dsi_config; struct panel_funcs *p_funcs; int pipe; struct drm_device *dev; struct drm_psb_private *dev_priv; if (!encoder) { DRM_ERROR("Invalid encoder\n"); return -EINVAL; } dsi_encoder = MDFLD_DSI_ENCODER(encoder); dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); p_funcs = dpi_output->p_funcs; pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder); if (!dsi_connector) { DRM_ERROR("dsi_connector is NULL\n"); return -EINVAL; } dev = dsi_config->dev; dev_priv = dev->dev_private; if (dsi_connector->status != connector_status_connected) return 0; mutex_lock(&dsi_config->context_lock); if (dpi_output->first_boot && dsi_config->dsi_hw_context.panel_on) { printk(KERN_ALERT "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 (__dpi_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; break; case false: if (__dpi_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; 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; }
/** * Setup Display Controller to turn on/off a video mode panel. * Most of the video mode MIPI panel should follow the power on/off * sequence in this function. * NOTE: do NOT modify this function for new panel Enabling. Register * new panel function callbacks to make this function available for a * new video mode panel */ static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_connector *dsi_connector; struct mdfld_dsi_dpi_output *dpi_output; struct mdfld_dsi_config *dsi_config; struct panel_funcs *p_funcs; int pipe; struct drm_device *dev; struct drm_psb_private *dev_priv; if (!encoder) { DRM_ERROR("Invalid encoder\n"); return -EINVAL; } dsi_encoder = MDFLD_DSI_ENCODER(encoder); dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); p_funcs = dpi_output->p_funcs; pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder); if (!dsi_connector) { DRM_ERROR("dsi_connector is NULL\n"); return -EINVAL; } dev = dsi_config->dev; dev_priv = dev->dev_private; if (dsi_connector->status != connector_status_connected) return 0; mutex_lock(&dsi_config->context_lock); if (dpi_output->first_boot && on) { if (dsi_config->dsi_hw_context.panel_on) { if (IS_ANN(dev)) ann_dc_setup(dsi_config); psb_enable_vblank(dev, dsi_config->pipe); /* don't need ISLAND c for non dual-dsi panel */ if (!is_dual_dsi(dev)) power_island_put(OSPM_DISPLAY_C); DRM_INFO("skip panle power setting for first boot! " "panel is already powered on\n"); goto fun_exit; } if (android_hdmi_is_connected(dev)) otm_hdmi_power_islands_off(); /* power down islands turned on by firmware */ power_island_put(OSPM_DISPLAY_A | OSPM_DISPLAY_C | OSPM_DISPLAY_MIO); } switch (on) { case true: /* panel is already on */ if (dsi_config->dsi_hw_context.panel_on) goto fun_exit; if (__dpi_panel_power_on(dsi_config, p_funcs, dpi_output->first_boot)) { DRM_ERROR("Faild to turn on panel\n"); goto set_power_err; } dsi_config->dsi_hw_context.panel_on = 1; /* for every dpi panel power on, clear the dpi underrun count */ dev_priv->pipea_dpi_underrun_count = 0; dev_priv->pipec_dpi_underrun_count = 0; break; case false: if (!dsi_config->dsi_hw_context.panel_on && !dpi_output->first_boot) goto fun_exit; if (__dpi_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; 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; }
void mdfld_reset_same_dpi_panel(struct drm_psb_private *dev_priv) { struct mdfld_dsi_config *dsi_config = dev_priv->dsi_configs[0]; struct mdfld_dsi_dpi_output *dpi_output = dev_priv->dpi_output; struct panel_funcs *p_funcs; struct drm_device *dev; if (!dsi_config || !dpi_output) { if (!dsi_config) DRM_INFO("%s: dsi_config NULL\n", __func__); else if (!dpi_output) DRM_INFO("%s: dpi_output NULL\n", __func__); return; } dev = dsi_config->dev; /*disable ESD when HDMI connected*/ if (hdmi_state) { DRM_INFO("%s: hdmi_state %d\n", __func__, hdmi_state); return; } DRM_INFO("[DISPLAY] %s: Enter\n", __func__); mutex_lock(&dsi_config->context_lock); if (dsi_config->dsi_hw_context.panel_on == 0) { DRM_INFO("[DISPLAY] %s: panel_on=%d, skip reset.\n", __func__, dsi_config->dsi_hw_context.panel_on); mutex_unlock(&dsi_config->context_lock); return; } PSB_DEBUG_ENTRY("\n"); p_funcs = dpi_output->p_funcs; if (!p_funcs) { DRM_ERROR("%s: invalid panel function table\n", __func__); mutex_unlock(&dsi_config->context_lock); return; } if (dev_priv->pvr_screen_event_handler) dev_priv->pvr_screen_event_handler(dev, 0); if (__dpi_panel_power_off(dsi_config, p_funcs)) { DRM_INFO("%s: off failed\n", __func__); /*mutex_unlock(&dsi_config->context_lock); return;*/ } acquire_ospm_lock(); /* ospm_power_island_down(OSPM_DISPLAY_ISLAND);*/ ospm_suspend_display(gpDrmDevice); /* ospm_power_island_up(OSPM_DISPLAY_ISLAND);*/ ospm_resume_display(gpDrmDevice->pdev); release_ospm_lock(); if (__dpi_panel_power_on(dsi_config, p_funcs)) { DRM_INFO("%s: on failed\n", __func__); /*psb_enable_vblank(dev, 0); mutex_unlock(&dsi_config->context_lock); return;*/ } if (dev_priv->pvr_screen_event_handler) dev_priv->pvr_screen_event_handler(dev, 1); mutex_unlock(&dsi_config->context_lock); /*leve1_cnt = 0; vsync_timeout_cnt = 0;*/ DRM_INFO("%s: End panel reset\n", __func__); }
/** * Setup Display Controller to turn on/off a video mode panel. * Most of the video mode MIPI panel should follow the power on/off * sequence in this function. * NOTE: do NOT modify this function for new panel Enabling. Register * new panel function callbacks to make this function available for a * new video mode panel */ static int __mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on) { struct mdfld_dsi_encoder *dsi_encoder; struct mdfld_dsi_connector *dsi_connector; struct mdfld_dsi_dpi_output *dpi_output; struct mdfld_dsi_config *dsi_config; struct panel_funcs *p_funcs; int pipe; struct drm_device *dev; struct drm_psb_private *dev_priv; static int last_ospm_suspend = -1; if (!encoder) { DRM_ERROR("Invalid encoder\n"); return -EINVAL; } PSB_DEBUG_ENTRY("%s, last_ospm_suspend = %s\n", (on ? "on" : "off"), (last_ospm_suspend ? "true" : "false")); dsi_encoder = MDFLD_DSI_ENCODER(encoder); dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); p_funcs = dpi_output->p_funcs; pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); dsi_connector = mdfld_dsi_encoder_get_connector(dsi_encoder); if (!dsi_connector) { DRM_ERROR("Invalid connector\n"); return -EINVAL; } dev = dsi_config->dev; dev_priv = dev->dev_private; if (dsi_connector->status != connector_status_connected) return 0; mutex_lock(&dsi_config->context_lock); if (last_ospm_suspend == -1) last_ospm_suspend = false; if (dpi_output->first_boot && dsi_config->dsi_hw_context.panel_on) { if (Check_fw_initilized_reusable(dsi_config, p_funcs)) { DRM_INFO("skip panle power setting for first boot!" " panel is already powered on\n"); goto fun_exit; } else dsi_config->dsi_hw_context.panel_on = 0; } /* ASUS_BSP: Louis +++*/ else if (dpi_output->first_boot && !dsi_config->dsi_hw_context.panel_on) { DRM_INFO("No display in ifwi, initialize panel in kernel\n"); psbfb_memclear(); } /* ASUS_BSP: Louis ---*/ /** * if ospm has turned panel off, but dpms tries to turn panel on, skip */ if (dev_priv->dpms_on_off && on && last_ospm_suspend) goto fun_exit; switch (on) { case true: /* panel is already on */ if (dsi_config->dsi_hw_context.panel_on) goto fun_exit; /* For DPMS case, just turn on/off panel */ if (dev_priv->dpms_on_off) { if (mdfld_dsi_dpi_panel_turn_on(dsi_config, p_funcs)) { DRM_ERROR("Faild to turn on panel\n"); goto set_power_err; } } else { if (__dpi_panel_power_on(dsi_config, p_funcs)) { DRM_ERROR("Faild to turn on panel\n"); goto set_power_err; } } /** * If power on, turn off color mode by default, * let panel in full color mode */ mdfld_dsi_dpi_set_color_mode(dsi_config, false); dsi_config->dsi_hw_context.panel_on = 1; last_ospm_suspend = false; break; case false: if (dev_priv->dpms_on_off && dsi_config->dsi_hw_context.panel_on) { if (mdfld_dsi_dpi_panel_shut_down(dsi_config, p_funcs)) DRM_ERROR("Faild to shutdown panel\n"); last_ospm_suspend = false; } else if (!dev_priv->dpms_on_off && !last_ospm_suspend) { if (__dpi_panel_power_off(dsi_config, p_funcs)) { DRM_ERROR("Faild to turn off panel\n"); goto set_power_err; } /* ospm suspend called? */ last_ospm_suspend = true; } dsi_config->dsi_hw_context.panel_on = 0; SetDisplayFrameUpdate(5); /* ASUS_BSP: Louis ++ */ break; default: break; } fun_exit: mutex_unlock(&dsi_config->context_lock); /*To optimize dpms with context lock, move panel sleep out of mutex*/ if (dev_priv->dpms_on_off) msleep(100); PSB_DEBUG_ENTRY("successfully\n"); return 0; set_power_err: mutex_unlock(&dsi_config->context_lock); PSB_DEBUG_ENTRY("unsuccessfully!!!!\n"); return -EAGAIN; }