static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) { int rc = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; u32 dsi_ctrl; pr_debug("%s+:\n", __func__); if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); if (!ctrl_pdata->panel_data.panel_info.dynamic_fps) { pr_err("%s: Dynamic fps not enabled for this panel\n", __func__); return -EINVAL; } if (new_fps != ctrl_pdata->panel_data.panel_info.mipi.frame_rate) { rc = mdss_dsi_clk_div_config (&ctrl_pdata->panel_data.panel_info, new_fps); if (rc) { pr_err("%s: unable to initialize the clk dividers\n", __func__); return rc; } ctrl_pdata->pclk_rate = ctrl_pdata->panel_data.panel_info.mipi.dsi_pclk_rate; ctrl_pdata->byte_clk_rate = ctrl_pdata->panel_data.panel_info.clk_rate / 8; if (pdata->panel_info.dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) { dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004); ctrl_pdata->panel_data.panel_info.mipi.frame_rate = new_fps; dsi_ctrl &= ~0x2; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl); mdss_dsi_controller_cfg(true, pdata); mdss_dsi_clk_ctrl(ctrl_pdata, 0); mdss_dsi_clk_ctrl(ctrl_pdata, 1); dsi_ctrl |= 0x2; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl); } } else { pr_debug("%s: Panel is already at this FPS\n", __func__); } return rc; }
static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) { int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_panel_info *panel_info = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); panel_info = &ctrl_pdata->panel_data.panel_info; pr_info("%s+: ctrl=%p ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); if (power_state == panel_info->panel_power_state) { pr_err("%s: No change in power state %d -> %d\n", __func__, panel_info->panel_power_state, power_state); goto end; } if (power_state != MDSS_PANEL_POWER_OFF) { pr_err("%s: dsi_off with panel always on\n", __func__); goto panel_power_ctrl; } if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); /* disable DSI phy */ mdss_dsi_phy_disable(ctrl_pdata); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); panel_power_ctrl: ret = mdss_dsi_panel_power_ctrl(pdata, power_state); if (ret) { pr_err("%s: Panel power off failed\n", __func__); } else { if (panel_info->dynamic_fps && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE) && (panel_info->new_fps != panel_info->mipi.frame_rate)) panel_info->mipi.frame_rate = panel_info->new_fps; } panel_info->dsi_on_status = false; end: pr_info("%s-:\n", __func__); return ret; }
static int mdss_dsi_off(struct mdss_panel_data *pdata) { int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_panel_info *panel_info = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } if (!pdata->panel_info.panel_power_on) { pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); return 0; } pdata->panel_info.panel_power_on = 0; ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); mutex_lock(&ctrl_pdata->mutex); panel_info = &ctrl_pdata->panel_data.panel_info; pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); /* disable DSI phy */ mdss_dsi_phy_disable(ctrl_pdata); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); #ifndef CONFIG_FB_MSM_MDSS_SPECIFIC_PANEL ret = mdss_dsi_panel_power_on(pdata, 0); #else ret = ctrl_pdata->spec_pdata->panel_power_on(pdata, 0); #endif /* CONFIG_FB_MSM_MDSS_SPECIFIC_PANEL */ if (ret) { mutex_unlock(&ctrl_pdata->mutex); pr_err("%s: Panel power off failed\n", __func__); return ret; } if (panel_info->dynamic_fps && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE) && (panel_info->new_fps != panel_info->mipi.frame_rate)) panel_info->mipi.frame_rate = panel_info->new_fps; mutex_unlock(&ctrl_pdata->mutex); pr_debug("%s-:\n", __func__); return ret; }
static int mdss_dsi_off(struct mdss_panel_data *pdata) { int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_panel_info *panel_info = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } if (!pdata->panel_info.panel_power_on) { pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); return 0; } // keep reset before video off usleep(pdata->panel_info.mipi.sleep_lp00_delay); pdata->panel_info.panel_power_on = 0; ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); panel_info = &ctrl_pdata->panel_data.panel_info; pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); /* disable DSI phy */ mdss_dsi_phy_disable(ctrl_pdata); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); ret = mdss_dsi_panel_power_on(pdata, 0); if (ret) { pr_err("%s: Panel power off failed\n", __func__); return ret; } if (panel_info->dynamic_fps && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE) && (panel_info->new_fps != panel_info->mipi.frame_rate)) panel_info->mipi.frame_rate = panel_info->new_fps; pr_debug("%s-:\n", __func__); return ret; }
static int mdss_dsi_off(struct mdss_panel_data *pdata) { int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } if (!pdata->panel_info.panel_power_on) { pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); return -EPERM; } pdata->panel_info.panel_power_on = 0; ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, 1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); mdss_dsi_clk_ctrl(ctrl_pdata, 0); ret = mdss_dsi_enable_bus_clocks(ctrl_pdata); if (ret) { pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__, ret); mdss_dsi_panel_power_on(pdata, 0); return ret; } /* disable DSI phy */ mdss_dsi_phy_enable(ctrl_pdata, 0); mdss_dsi_disable_bus_clocks(ctrl_pdata); ret = mdss_dsi_panel_power_on(pdata, 0); if (ret) { pr_err("%s: Panel power off failed\n", __func__); return ret; } pr_debug("%s-:\n", __func__); return ret; }
static int mdss_dsi_off(struct mdss_panel_data *pdata) { int ret = 0; mdss_dsi_clk_disable(pdata); mdss_dsi_unprepare_clocks(); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); ret = mdss_dsi_panel_power_on(0); if (ret) { pr_err("%s: Panel power off failed\n", __func__); return ret; } pr_debug("%s-:\n", __func__); return ret; }
static int mdss_dsi_dfps_config(struct mdss_panel_data *pdata, int new_fps) { int rc = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; u32 dsi_ctrl; pr_debug("%s+:\n", __func__); if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); if (!ctrl_pdata->panel_data.panel_info.dynamic_fps) { pr_err("%s: Dynamic fps not enabled for this panel\n", __func__); return -EINVAL; } if (new_fps != ctrl_pdata->panel_data.panel_info.mipi.frame_rate) { if (pdata->panel_info.dfps_update == DFPS_IMMEDIATE_PORCH_UPDATE_MODE) { u32 hsync_period, vsync_period; u32 new_dsi_v_total, current_dsi_v_total; vsync_period = mdss_panel_get_vtotal(&pdata->panel_info); hsync_period = mdss_panel_get_htotal(&pdata->panel_info); current_dsi_v_total = MIPI_INP((ctrl_pdata->ctrl_base) + 0x2C); new_dsi_v_total = ((vsync_period - 1) << 16) | (hsync_period - 1); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, (current_dsi_v_total | 0x8000000)); if (new_dsi_v_total & 0x8000000) { MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, new_dsi_v_total); } else { MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, (new_dsi_v_total | 0x8000000)); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, (new_dsi_v_total & 0x7ffffff)); } pdata->panel_info.mipi.frame_rate = new_fps; } else { rc = mdss_dsi_clk_div_config (&ctrl_pdata->panel_data.panel_info, new_fps); if (rc) { pr_err("%s: unable to initialize the clk dividers\n", __func__); return rc; } ctrl_pdata->pclk_rate = pdata->panel_info.mipi.dsi_pclk_rate; ctrl_pdata->byte_clk_rate = pdata->panel_info.clk_rate / 8; if (pdata->panel_info.dfps_update == DFPS_IMMEDIATE_CLK_UPDATE_MODE) { dsi_ctrl = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0004); pdata->panel_info.mipi.frame_rate = new_fps; dsi_ctrl &= ~0x2; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl); mdss_dsi_controller_cfg(true, pdata); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); dsi_ctrl |= 0x2; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl); } } } else { pr_debug("%s: Panel is already at this FPS\n", __func__); } return rc; }
static int mdss_dsi_ulps_config_sub(struct mdss_dsi_ctrl_pdata *ctrl_pdata, int enable, int partial) { int ret = 0; struct mdss_panel_data *pdata = NULL; struct mipi_panel_info *pinfo = NULL; u32 lane_status = 0; u32 active_lanes = 0; if (!ctrl_pdata) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } pdata = &ctrl_pdata->panel_data; if (!pdata) { pr_err("%s: Invalid panel data\n", __func__); return -EINVAL; } pinfo = &pdata->panel_info.mipi; if (!partial && !__mdss_dsi_ulps_feature_enabled(pdata)) { pr_debug("%s: ULPS feature not supported. enable=%d\n", __func__, enable); return -ENOTSUPP; } if (enable && !ctrl_pdata->ulps) { /* No need to configure ULPS mode when entering suspend state */ if (!partial && !pdata->panel_info.panel_power_on) { pr_err("%s: panel off. returning\n", __func__); goto error; } if (!partial && __mdss_dsi_clk_enabled(ctrl_pdata, DSI_LINK_CLKS)) { pr_err("%s: cannot enter ulps mode if dsi clocks are on\n", __func__); ret = -EPERM; goto error; } ret = mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); if (ret) { pr_err("%s: Failed to enable clocks. rc=%d\n", __func__, ret); goto error; } /* * ULPS Entry Request. * Wait for a short duration to ensure that the lanes * enter ULP state. */ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x01F); usleep(100); /* Check to make sure that all active data lanes are in ULPS */ if (pinfo->data_lane3) active_lanes |= BIT(11); if (pinfo->data_lane2) active_lanes |= BIT(10); if (pinfo->data_lane1) active_lanes |= BIT(9); if (pinfo->data_lane0) active_lanes |= BIT(8); active_lanes |= BIT(12); /* clock lane */ lane_status = MIPI_INP(ctrl_pdata->ctrl_base + 0xA8); if (lane_status & active_lanes) { pr_err("%s: ULPS entry req failed. Lane status=0x%08x\n", __func__, lane_status); ret = -EINVAL; mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); goto error; } /* Enable MMSS DSI Clamps */ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x3FF); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x83FF); wmb(); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x108, 0x1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); ctrl_pdata->ulps = true; } else if (ctrl_pdata->ulps) { ret = mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 1); if (ret) { pr_err("%s: Failed to enable bus clocks. rc=%d\n", __func__, ret); goto error; } MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x108, 0x0); mdss_dsi_phy_init(pdata); __mdss_dsi_ctrl_setup(pdata); mdss_dsi_sw_reset(pdata); mdss_dsi_host_init(pdata); mdss_dsi_op_mode_config(pdata->panel_info.mipi.mode, pdata); /* * ULPS Entry Request. This is needed because, after power * collapse and reset, the DSI controller resets back to * idle state and not ULPS. * Wait for a short duration to ensure that the lanes * enter ULP state. */ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x01F); usleep(100); /* Disable MMSS DSI Clamps */ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x3FF); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, 0x0); ret = mdss_dsi_clk_ctrl(ctrl_pdata, DSI_LINK_CLKS, 1); if (ret) { pr_err("%s: Failed to enable link clocks. rc=%d\n", __func__, ret); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 0); goto error; } /* * ULPS Exit Request * Hardware requirement is to wait for at least 1ms */ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x1F00); usleep(1000); MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x0); /* * Wait for a short duration before enabling * data transmission */ usleep(100); lane_status = MIPI_INP(ctrl_pdata->ctrl_base + 0xA8); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_LINK_CLKS, 0); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 0); ctrl_pdata->ulps = false; } pr_debug("%s: DSI lane status = 0x%08x. Ulps %s\n", __func__, lane_status, enable ? "enabled" : "disabled"); error: return ret; }
static int mdss_dsi_off(struct mdss_panel_data *pdata) { int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_panel_info *panel_info = NULL; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } if (!pdata->panel_info.panel_power_on) { pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); return -EPERM; } pdata->panel_info.panel_power_on = 0; ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); panel_info = &ctrl_pdata->panel_data.panel_info; pr_info("%s+: ctrl=%p ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); if (ctrl_pdata->partial_mode_enabled && !pdata->panel_info.panel_dead) { mdss_dsi_ulps_config_sub(ctrl_pdata, 1, 1); mdata->ulps = true; } else { if (ctrl_pdata->partial_mode_enabled && pdata->panel_info.panel_dead) pr_warn("%s: Panel is dead, shut down DSI\n", __func__); if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); /* disable DSI phy */ mdss_dsi_phy_disable(ctrl_pdata); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); ret = mdss_dsi_panel_power_on(pdata, 0); if (ret) { pr_err("%s: Panel power off failed\n", __func__); return ret; } } if (panel_info->dynamic_fps && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE) && (panel_info->new_fps != panel_info->mipi.frame_rate)) panel_info->mipi.frame_rate = panel_info->new_fps; pr_info("%s-:\n", __func__); return ret; }
static int mdss_dsi_off(struct mdss_panel_data *pdata) { int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_panel_info *panel_info = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } if (!pdata->panel_info.panel_power_on) { pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); return -EPERM; } pdata->panel_info.panel_power_on = 0; ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); panel_info = &ctrl_pdata->panel_data.panel_info; pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, 1); /* disable DSI controller */ mdss_dsi_controller_cfg(0, pdata); mdss_dsi_clk_ctrl(ctrl_pdata, 0); ret = mdss_dsi_enable_bus_clocks(ctrl_pdata); if (ret) { pr_err("%s: failed to enable bus clocks. rc=%d\n", __func__, ret); mdss_dsi_panel_power_on(pdata, 0); return ret; } /* disable DSI phy */ mdss_dsi_phy_enable(ctrl_pdata->ctrl_base, 0); mdss_dsi_disable_bus_clocks(ctrl_pdata); ret = mdss_dsi_panel_power_on(pdata, 0); if (ret) { pr_err("%s: Panel power off failed\n", __func__); return ret; } if (panel_info->dynamic_fps && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE) && (panel_info->new_fps != panel_info->mipi.frame_rate)) panel_info->mipi.frame_rate = panel_info->new_fps; pr_debug("%s-:\n", __func__); return ret; }
static int mdss_dsi_off(struct mdss_panel_data *pdata) { int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_panel_info *panel_info = NULL; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; } if (!pdata->panel_info.panel_power_on) { pr_warn("%s:%d Panel already off.\n", __func__, __LINE__); return -EPERM; } pdata->panel_info.panel_power_on = 0; ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); panel_info = &ctrl_pdata->panel_data.panel_info; pr_info("%s+: ctrl=%p ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); #ifdef CONFIG_MACH_LGE mdss_dsi_panel_reset(pdata, 0); #endif if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, 1); /* */ mdss_dsi_controller_cfg(0, pdata); /* */ mdss_dsi_phy_disable(ctrl_pdata); mdss_dsi_clk_ctrl(ctrl_pdata, 0); #ifdef CONFIG_MACH_LGE mdelay(5); mdss_dsi_panel_io(pdata, 0); ret = msm_dss_enable_vreg(ctrl_pdata->power_data.vreg_config, ctrl_pdata->power_data.num_vreg, 0); if (ret) { pr_err("%s:Failed to enable vregs. rc=%d\n", __func__, ret); return ret; } #else ret = mdss_dsi_panel_power_on(pdata, 0); if (ret) { pr_err("%s: Panel power off failed\n", __func__); return ret; } #endif if (panel_info->dynamic_fps && (panel_info->dfps_update == DFPS_SUSPEND_RESUME_MODE) && (panel_info->new_fps != panel_info->mipi.frame_rate)) panel_info->mipi.frame_rate = panel_info->new_fps; pr_info("%s-:\n", __func__); return ret; }