static bool mdss_dsi_is_ulps_req_valid(struct mdss_dsi_ctrl_pdata *ctrl, int enable) { struct mdss_panel_data *pdata = &ctrl->panel_data; struct mdss_panel_info *pinfo = &pdata->panel_info; pr_debug("%s: checking ulps req validity for ctrl%d\n", __func__, ctrl->ndx); if (!mdss_dsi_ulps_feature_enabled(pdata)) { pr_debug("%s: ULPS feature is not enabled\n", __func__); return false; } /* * No need to enter ULPS when transitioning from splash screen to * boot animation since it is expected that the clocks would be turned * right back on. */ if (enable && pinfo->cont_splash_enabled) { pr_debug("%s: skip ULPS config with splash screen enabled\n", __func__); return false; } /* * No need to enable ULPS if panel is not yet initialized. * However, this should be allowed in following usecases: * 1. If ULPS during suspend feature is enabled, where we * configure the lanes in ULPS after turning off the panel. * 2. When coming out of idle PC with clamps enabled, where we * transition the controller HW state back to ULPS prior to * disabling ULPS. */ if (enable && !ctrl->mmss_clamp && !(ctrl->ctrl_state & CTRL_STATE_PANEL_INIT)) { pr_debug("%s: panel not yet initialized\n", __func__); return false; } return true; }
/** * mdss_dsi_ulps_config() - Program DSI lanes to enter/exit ULPS mode * @ctrl: pointer to DSI controller structure * @enable: 1 to enter ULPS, 0 to exit ULPS * * This function executes the necessary programming sequence to enter/exit * DSI Ultra-Low Power State (ULPS). This function assumes that the link and * bus clocks are already on. */ static int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl, int enable) { int ret = 0; struct mdss_panel_data *pdata = NULL; struct mdss_panel_info *pinfo; struct mipi_panel_info *mipi; u32 lane_status = 0; u32 active_lanes = 0; if (!ctrl) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } pdata = &ctrl->panel_data; if (!pdata) { pr_err("%s: Invalid panel data\n", __func__); return -EINVAL; } pinfo = &pdata->panel_info; mipi = &pinfo->mipi; if (!mdss_dsi_ulps_feature_enabled(pdata) && !pinfo->ulps_suspend_enabled) { pr_debug("%s: ULPS feature not supported. enable=%d\n", __func__, enable); return -ENOTSUPP; } /* * No need to enter ULPS when transitioning from splash screen to * boot animation since it is expected that the clocks would be turned * right back on. */ if (pinfo->cont_splash_enabled) { pr_debug("%s: skip ULPS config with splash screen enabled\n", __func__); return 0; } /* clock lane will always be programmed for ulps */ active_lanes = BIT(4); /* * make a note of all active data lanes for which ulps entry/exit * is needed */ if (mipi->data_lane0) active_lanes |= BIT(0); if (mipi->data_lane1) active_lanes |= BIT(1); if (mipi->data_lane2) active_lanes |= BIT(2); if (mipi->data_lane3) active_lanes |= BIT(3); pr_debug("%s: configuring ulps (%s) for ctrl%d, active lanes=0x%08x\n", __func__, (enable ? "on" : "off"), ctrl->ndx, active_lanes); if (enable && !ctrl->ulps) { /* * ULPS Entry Request. * Wait for a short duration to ensure that the lanes * enter ULP state. */ MIPI_OUTP(ctrl->ctrl_base + 0x0AC, active_lanes); usleep(100); /* Check to make sure that all active data lanes are in ULPS */ lane_status = MIPI_INP(ctrl->ctrl_base + 0xA8); if (lane_status & (active_lanes << 8)) { pr_err("%s: ULPS entry req failed for ctrl%d. Lane status=0x%08x\n", __func__, ctrl->ndx, lane_status); ret = -EINVAL; goto error; } ctrl->ulps = true; } else if (!enable && ctrl->ulps) { /* * Clear out any phy errors prior to exiting ULPS * This fixes certain instances where phy does not exit * ULPS cleanly. */ mdss_dsi_dln0_phy_err(ctrl); /* * ULPS Exit Request * Hardware requirement is to wait for at least 1ms */ MIPI_OUTP(ctrl->ctrl_base + 0x0AC, active_lanes << 8); usleep(1000); /* * Sometimes when exiting ULPS, it is possible that some DSI * lanes are not in the stop state which could lead to DSI * commands not going through. To avoid this, force the lanes * to be in stop state. */ MIPI_OUTP(ctrl->ctrl_base + 0x0AC, active_lanes << 16); MIPI_OUTP(ctrl->ctrl_base + 0x0AC, 0x0); /* * Wait for a short duration before enabling * data transmission */ usleep(100); lane_status = MIPI_INP(ctrl->ctrl_base + 0xA8); ctrl->ulps = false; } else { pr_debug("%s: No change requested: %s -> %s\n", __func__, ctrl->ulps ? "enabled" : "disabled", enable ? "enabled" : "disabled"); } pr_debug("%s: DSI lane status = 0x%08x. Ulps %s\n", __func__, lane_status, enable ? "enabled" : "disabled"); error: return ret; }
static int mdss_dsi_clk_ctrl_sub(struct mdss_dsi_ctrl_pdata *ctrl, u8 clk_type, int enable) { int rc = 0; struct mdss_panel_data *pdata; if (!ctrl) { pr_err("%s: Invalid arg\n", __func__); return -EINVAL; } pdata = &ctrl->panel_data; pr_debug("%s: ndx=%d clk_type=%08x enable=%d\n", __func__, ctrl->ndx, clk_type, enable); if (enable) { if (clk_type & DSI_BUS_CLKS) { rc = mdss_dsi_core_power_ctrl(ctrl, enable); if (rc) { pr_err("%s: Failed to enable core power. rc=%d\n", __func__, rc); goto error; } } if (clk_type & DSI_LINK_CLKS) { rc = mdss_dsi_link_clk_start(ctrl); if (rc) { pr_err("%s: Failed to start link clocks. rc=%d\n", __func__, rc); goto error_link_clk_start; } /* Disable ULPS, if enabled */ if (ctrl->ulps) { rc = mdss_dsi_ulps_config(ctrl, 0); if (rc) { pr_err("%s: Failed to exit ulps. rc=%d\n", __func__, rc); goto error_ulps_exit; } } } } else { if (clk_type & DSI_LINK_CLKS) { /* * If ULPS feature is enabled, enter ULPS first. * If ULPS during suspend is not enabled, no need * to enable ULPS when turning off the clocks * while blanking the panel. */ if (((mdss_dsi_ulps_feature_enabled(pdata)) && (pdata->panel_info.blank_state != MDSS_PANEL_BLANK_BLANK)) || (pdata->panel_info.ulps_suspend_enabled)) mdss_dsi_ulps_config(ctrl, 1); mdss_dsi_link_clk_stop(ctrl); } if (clk_type & DSI_BUS_CLKS) { rc = mdss_dsi_core_power_ctrl(ctrl, enable); if (rc) { pr_err("%s: Failed to disable core power. rc=%d\n", __func__, rc); } } } return rc; error_ulps_exit: mdss_dsi_link_clk_stop(ctrl); error_link_clk_start: if ((clk_type & DSI_BUS_CLKS) && (mdss_dsi_core_power_ctrl(ctrl, !enable))) pr_warn("%s: Failed to disable core power. rc=%d\n", __func__, rc); error: return rc; }
static int mdss_dsi_clk_ctrl_sub(struct mdss_dsi_ctrl_pdata *ctrl, u8 clk_type, int enable) { int rc = 0; struct mdss_panel_data *pdata; if (!ctrl) { pr_err("%s: Invalid arg\n", __func__); return -EINVAL; } pdata = &ctrl->panel_data; pr_debug("%s: ndx=%d clk_type=%08x enable=%d\n", __func__, ctrl->ndx, clk_type, enable); if (enable) { if (clk_type & DSI_BUS_CLKS) { /* enable mdss gdsc */ pr_debug("%s: Enable MDP FS\n", __func__); rc = msm_dss_enable_vreg( ctrl->power_data[DSI_CORE_PM].vreg_config, ctrl->power_data[DSI_CORE_PM].num_vreg, 1); if (rc) { pr_err("%s: failed to enable vregs for %s\n", __func__, __mdss_dsi_pm_name(DSI_CORE_PM)); goto error; } rc = mdss_dsi_bus_clk_start(ctrl); if (rc) { pr_err("Failed to start bus clocks. rc=%d\n", rc); goto error_vreg; } } if (clk_type & DSI_LINK_CLKS) { rc = mdss_dsi_link_clk_start(ctrl); if (rc) { pr_err("Failed to start link clocks. rc=%d\n", rc); goto error_link_clk_start; } /* Disable ULPS, if enabled */ if (ctrl->ulps) { rc = mdss_dsi_ulps_config(ctrl, 0); if (rc) { pr_err("Failed to exit ulps. rc=%d\n", rc); goto error_ulps_exit; } } } } else { if (clk_type & DSI_LINK_CLKS) { /* * If ULPS feature is enabled, enter ULPS first. * No need to enable ULPS when turning off clocks * while blanking the panel. */ if ((mdss_dsi_ulps_feature_enabled(pdata)) && (pdata->panel_info.panel_power_on)) mdss_dsi_ulps_config(ctrl, 1); mdss_dsi_link_clk_stop(ctrl); } if (clk_type & DSI_BUS_CLKS) { mdss_dsi_bus_clk_stop(ctrl); /* disable mdss gdsc */ pr_debug("%s: Disable MDP FS\n", __func__); rc = msm_dss_enable_vreg( ctrl->power_data[DSI_CORE_PM].vreg_config, ctrl->power_data[DSI_CORE_PM].num_vreg, 0); if (rc) { pr_warn("%s: failed to disable vregs for %s\n", __func__, __mdss_dsi_pm_name(DSI_CORE_PM)); rc = 0; } } } return rc; error_ulps_exit: mdss_dsi_link_clk_stop(ctrl); error_link_clk_start: if (clk_type & DSI_BUS_CLKS) mdss_dsi_bus_clk_stop(ctrl); error_vreg: if ((clk_type & DSI_BUS_CLKS) && (msm_dss_enable_vreg(ctrl->power_data[DSI_CORE_PM].vreg_config, ctrl->power_data[DSI_CORE_PM].num_vreg, 0))) { pr_warn("%s: failed to disable vregs for %s\n", __func__, __mdss_dsi_pm_name(DSI_CORE_PM)); } error: return rc; }
int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata, int enable) { int ret = 0; struct mdss_panel_data *pdata = NULL; struct mdss_panel_info *pinfo; struct mipi_panel_info *mipi; u32 lane_status = 0, regval; u32 active_lanes = 0, clamp_reg; if (!ctrl_pdata) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } if (&ctrl_pdata->mmss_misc_io == NULL) { pr_err("%s: mmss_misc_io is NULL. ULPS not valid\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 = &pinfo->mipi; if (!mdss_dsi_ulps_feature_enabled(pdata)) { pr_debug("%s: ULPS feature not supported. enable=%d\n", __func__, enable); return -ENOTSUPP; } /* * No need to enter ULPS when transitioning from splash screen to * boot animation since it is expected that the clocks would be turned * right back on. */ if (pinfo->cont_splash_enabled) { pr_debug("%s: skip ULPS config with splash screen enabled\n", __func__); return 0; } /* clock lane will always be programmed for ulps and will be clamped */ active_lanes = BIT(4); clamp_reg = BIT(8) | BIT(9); /* * make a note of all active data lanes for which ulps entry/exit * as well as DSI clamps are needed */ if (mipi->data_lane0) { active_lanes |= BIT(0); clamp_reg |= (BIT(0) | BIT(1)); } if (mipi->data_lane1) { active_lanes |= BIT(1); clamp_reg |= (BIT(2) | BIT(3)); } if (mipi->data_lane2) { active_lanes |= BIT(2); clamp_reg |= (BIT(4) | BIT(5)); } if (mipi->data_lane3) { active_lanes |= BIT(3); clamp_reg |= (BIT(6) | BIT(7)); } pr_debug("%s: configuring ulps (%s) for ctrl%d, active lanes=0x%08x\n", __func__, (enable ? "on" : "off"), ctrl_pdata->ndx, active_lanes); if (enable && !ctrl_pdata->ulps) { /* * ULPS Entry Request. * Wait for a short duration to ensure that the lanes * enter ULP state. */ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, active_lanes); usleep(100); /* Check to make sure that all active data lanes are in ULPS */ lane_status = MIPI_INP(ctrl_pdata->ctrl_base + 0xA8); if (lane_status & (active_lanes << 8)) { pr_err("%s: ULPS entry req failed for ctrl%d. Lane status=0x%08x\n", __func__, ctrl_pdata->ndx, lane_status); ret = -EINVAL; goto error; } /* Enable MMSS DSI Clamps */ if (ctrl_pdata->ndx == DSI_CTRL_0) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | clamp_reg); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | (clamp_reg | BIT(15))); } else if (ctrl_pdata->ndx == DSI_CTRL_1) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | (clamp_reg << 16)); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | ((clamp_reg << 16) | BIT(31))); } wmb(); /* * This register write ensures that DSI PHY will not be * reset when mdss ahb clock reset is asserted while coming * out of power collapse */ MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x108, 0x1); ctrl_pdata->ulps = true; } else if (ctrl_pdata->ulps) { 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, active_lanes); usleep(100); /* Disable MMSS DSI Clamps */ if (ctrl_pdata->ndx == DSI_CTRL_0) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval & ~(clamp_reg | BIT(15))); } else if (ctrl_pdata->ndx == DSI_CTRL_1) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval & ~((clamp_reg << 16) | BIT(31))); } /* * ULPS Exit Request * Hardware requirement is to wait for at least 1ms */ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, active_lanes << 8); 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); ctrl_pdata->ulps = false; } pr_debug("%s: DSI lane status = 0x%08x. Ulps %s\n", __func__, lane_status, enable ? "enabled" : "disabled"); error: return ret; }
int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl_pdata, int enable) { int ret = 0; struct mdss_panel_data *pdata = NULL; struct mdss_panel_info *pinfo; struct mipi_panel_info *mipi; u32 lane_status = 0, regval; u32 active_lanes = 0, clamp_reg; if (!ctrl_pdata) { pr_err("%s: invalid input\n", __func__); return -EINVAL; } if (&ctrl_pdata->mmss_misc_io == NULL) { pr_err("%s: mmss_misc_io is NULL. ULPS not valid\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 = &pinfo->mipi; if (!mdss_dsi_ulps_feature_enabled(pdata)) { pr_debug("%s: ULPS feature not supported. enable=%d\n", __func__, enable); return -ENOTSUPP; } if (pinfo->cont_splash_enabled) { pr_debug("%s: skip ULPS config with splash screen enabled\n", __func__); return 0; } active_lanes = BIT(4); clamp_reg = BIT(8) | BIT(9); if (mipi->data_lane0) { active_lanes |= BIT(0); clamp_reg |= (BIT(0) | BIT(1)); } if (mipi->data_lane1) { active_lanes |= BIT(1); clamp_reg |= (BIT(2) | BIT(3)); } if (mipi->data_lane2) { active_lanes |= BIT(2); clamp_reg |= (BIT(4) | BIT(5)); } if (mipi->data_lane3) { active_lanes |= BIT(3); clamp_reg |= (BIT(6) | BIT(7)); } pr_debug("%s: configuring ulps (%s) for ctrl%d, active lanes=0x%08x\n", __func__, (enable ? "on" : "off"), ctrl_pdata->ndx, active_lanes); if (enable && !ctrl_pdata->ulps) { MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, active_lanes); usleep(100); lane_status = MIPI_INP(ctrl_pdata->ctrl_base + 0xA8); if (lane_status & (active_lanes << 8)) { pr_err("%s: ULPS entry req failed for ctrl%d. Lane status=0x%08x\n", __func__, ctrl_pdata->ndx, lane_status); ret = -EINVAL; goto error; } if (ctrl_pdata->ndx == DSI_CTRL_0) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | clamp_reg); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | (clamp_reg | BIT(15))); } else if (ctrl_pdata->ndx == DSI_CTRL_1) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | (clamp_reg << 16)); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval | ((clamp_reg << 16) | BIT(31))); } wmb(); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x108, 0x1); ctrl_pdata->ulps = true; } else if (ctrl_pdata->ulps) { 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); MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, active_lanes); usleep(100); if (ctrl_pdata->ndx == DSI_CTRL_0) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval & ~(clamp_reg | BIT(15))); } else if (ctrl_pdata->ndx == DSI_CTRL_1) { regval = MIPI_INP(ctrl_pdata->mmss_misc_io.base + 0x14); MIPI_OUTP(ctrl_pdata->mmss_misc_io.base + 0x14, regval & ~((clamp_reg << 16) | BIT(31))); } MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, active_lanes << 8); usleep(1000); MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0AC, 0x0); usleep(100); lane_status = MIPI_INP(ctrl_pdata->ctrl_base + 0xA8); 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_clk_ctrl_sub(struct mdss_dsi_ctrl_pdata *ctrl, u8 clk_type, int enable) { int rc = 0; struct mdss_panel_data *pdata; if (!ctrl) { pr_err("%s: Invalid arg\n", __func__); return -EINVAL; } pdata = &ctrl->panel_data; pr_debug("%s: ndx=%d clk_type=%08x enable=%d\n", __func__, ctrl->ndx, clk_type, enable); if (enable) { if (clk_type & DSI_BUS_CLKS) { /* enable mdss gdsc */ pr_debug("%s: Enable MDP FS\n", __func__); rc = msm_dss_enable_vreg( ctrl->power_data[DSI_CORE_PM].vreg_config, ctrl->power_data[DSI_CORE_PM].num_vreg, 1); if (rc) { pr_err("%s: failed to enable vregs for %s\n", __func__, __mdss_dsi_pm_name(DSI_CORE_PM)); goto error; } rc = mdss_dsi_bus_clk_start(ctrl); if (rc) { pr_err("Failed to start bus clocks. rc=%d\n", rc); goto error_vreg; } } if (clk_type & DSI_LINK_CLKS) { if (ctrl->mmss_clamp) { mdss_dsi_phy_init(pdata); mdss_dsi_ctrl_setup(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. */ mdss_dsi_ulps_config(ctrl, 1); mdss_dsi_clamp_ctrl(ctrl, 0); } rc = mdss_dsi_link_clk_start(ctrl); if (rc) { pr_err("Failed to start link clocks. rc=%d\n", rc); goto error_link_clk_start; } /* Disable ULPS, if enabled */ if (ctrl->ulps) { rc = mdss_dsi_ulps_config(ctrl, 0); if (rc) { pr_err("Failed to exit ulps. rc=%d\n", rc); goto error_ulps_exit; } } } } else { if (clk_type & DSI_LINK_CLKS) { /* * If ULPS feature is enabled, enter ULPS first. * No need to enable ULPS when turning off clocks * while blanking the panel. */ if (((mdss_dsi_ulps_feature_enabled(pdata)) && (pdata->panel_info.panel_power_on)) || (pdata->panel_info.ulps_suspend_enabled && !pdata->panel_info.panel_power_on)) { mdss_dsi_ulps_config(ctrl, 1); mdss_dsi_link_clk_stop(ctrl); mdss_dsi_clamp_ctrl(ctrl, 1); } else { mdss_dsi_link_clk_stop(ctrl); } } if (clk_type & DSI_BUS_CLKS) { mdss_dsi_bus_clk_stop(ctrl); /* disable mdss gdsc */ pr_debug("%s: Disable MDP FS\n", __func__); rc = msm_dss_enable_vreg( ctrl->power_data[DSI_CORE_PM].vreg_config, ctrl->power_data[DSI_CORE_PM].num_vreg, 0); if (rc) { pr_warn("%s: failed to disable vregs for %s\n", __func__, __mdss_dsi_pm_name(DSI_CORE_PM)); rc = 0; } } } return rc; error_ulps_exit: mdss_dsi_link_clk_stop(ctrl); error_link_clk_start: if (clk_type & DSI_BUS_CLKS) mdss_dsi_bus_clk_stop(ctrl); error_vreg: if ((clk_type & DSI_BUS_CLKS) && (msm_dss_enable_vreg(ctrl->power_data[DSI_CORE_PM].vreg_config, ctrl->power_data[DSI_CORE_PM].num_vreg, 0))) { pr_warn("%s: failed to disable vregs for %s\n", __func__, __mdss_dsi_pm_name(DSI_CORE_PM)); } error: return rc; }