/* * acquire ctrl->mutex first */ void mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) { mutex_lock(&ctrl->mutex); if (enable) { if (ctrl->clk_cnt == 0) { mdss_dsi_enable_bus_clocks(ctrl); mdss_dsi_prepare_clocks(ctrl); mdss_dsi_clk_enable(ctrl); } ctrl->clk_cnt++; } else { if (ctrl->clk_cnt) { ctrl->clk_cnt--; if (ctrl->clk_cnt == 0) { mdss_dsi_clk_disable(ctrl); mdss_dsi_unprepare_clocks(ctrl); mdss_dsi_disable_bus_clocks(ctrl); } } } pr_debug("%s: ctrl ndx=%d enabled=%d clk_cnt=%d\n", __func__, ctrl->ndx, enable, ctrl->clk_cnt); mutex_unlock(&ctrl->mutex); }
int mdss_dsi_clk_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) { int rc = 0; mutex_lock(&ctrl->mutex); if (enable) { if (ctrl->clk_cnt == 0) { rc = mdss_dsi_enable_bus_clocks(ctrl); if (rc) { pr_err("%s: failed to enable bus clks. rc=%d\n", __func__, rc); goto error; } rc = mdss_dsi_clk_set_rate(ctrl); if (rc) { pr_err("%s: failed to set clk rates. rc=%d\n", __func__, rc); mdss_dsi_disable_bus_clocks(ctrl); goto error; } rc = mdss_dsi_clk_prepare(ctrl); if (rc) { pr_err("%s: failed to prepare clks. rc=%d\n", __func__, rc); mdss_dsi_disable_bus_clocks(ctrl); goto error; } rc = mdss_dsi_clk_enable(ctrl); if (rc) { pr_err("%s: failed to enable clks. rc=%d\n", __func__, rc); mdss_dsi_clk_unprepare(ctrl); mdss_dsi_disable_bus_clocks(ctrl); goto error; } } ctrl->clk_cnt++; } else { if (ctrl->clk_cnt) { ctrl->clk_cnt--; if (ctrl->clk_cnt == 0) { mdss_dsi_clk_disable(ctrl); mdss_dsi_clk_unprepare(ctrl); mdss_dsi_disable_bus_clocks(ctrl); } } } pr_debug("%s: ctrl ndx=%d enabled=%d clk_cnt=%d\n", __func__, ctrl->ndx, enable, ctrl->clk_cnt); error: mutex_unlock(&ctrl->mutex); return rc; }
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_enable_clks(struct mdss_dsi_ctrl_pdata *ctrl) { int rc = 0; rc = mdss_dsi_enable_bus_clocks(ctrl); if (rc) { pr_err("%s: failed to enable bus clks. rc=%d\n", __func__, rc); goto error; } rc = mdss_dsi_clk_set_rate(ctrl); if (rc) { pr_err("%s: failed to set clk rates. rc=%d\n", __func__, rc); mdss_dsi_disable_bus_clocks(ctrl); goto error; } rc = mdss_dsi_clk_prepare(ctrl); if (rc) { pr_err("%s: failed to prepare clks. rc=%d\n", __func__, rc); mdss_dsi_disable_bus_clocks(ctrl); goto error; } rc = mdss_dsi_clk_enable(ctrl); if (rc) { pr_err("%s: failed to enable clks. rc=%d\n", __func__, rc); mdss_dsi_clk_unprepare(ctrl); mdss_dsi_disable_bus_clocks(ctrl); goto error; } error: return rc; }
int mdss_dsi_on(struct mdss_panel_data *pdata) { int ret = 0; u32 clk_rate; struct mdss_panel_info *pinfo; struct mipi_panel_info *mipi; u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height; u32 ystride, bpp, data, dst_bpp; u32 dummy_xres, dummy_yres; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; u32 hsync_period, vsync_period; 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 on.\n", __func__, __LINE__); return 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); pinfo = &pdata->panel_info; ret = mdss_dsi_panel_power_on(pdata, 1); if (ret) { pr_err("%s: Panel power on failed\n", __func__); return ret; } pdata->panel_info.panel_power_on = 1; 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; } mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base)); mdss_dsi_phy_init(pdata); mdss_dsi_disable_bus_clocks(ctrl_pdata); mdss_dsi_clk_ctrl(ctrl_pdata, 1); clk_rate = pdata->panel_info.clk_rate; clk_rate = min(clk_rate, pdata->panel_info.clk_max); dst_bpp = pdata->panel_info.fbc.enabled ? (pdata->panel_info.fbc.target_bpp) : (pinfo->bpp); hbp = mult_frac(pdata->panel_info.lcdc.h_back_porch, dst_bpp, pdata->panel_info.bpp); hfp = mult_frac(pdata->panel_info.lcdc.h_front_porch, dst_bpp, pdata->panel_info.bpp); vbp = mult_frac(pdata->panel_info.lcdc.v_back_porch, dst_bpp, pdata->panel_info.bpp); vfp = mult_frac(pdata->panel_info.lcdc.v_front_porch, dst_bpp, pdata->panel_info.bpp); hspw = mult_frac(pdata->panel_info.lcdc.h_pulse_width, dst_bpp, pdata->panel_info.bpp); vspw = pdata->panel_info.lcdc.v_pulse_width; width = mult_frac(pdata->panel_info.xres, dst_bpp, pdata->panel_info.bpp); height = pdata->panel_info.yres; if (pdata->panel_info.type == MIPI_VIDEO_PANEL) { dummy_xres = pdata->panel_info.lcdc.xres_pad; dummy_yres = pdata->panel_info.lcdc.yres_pad; } vsync_period = vspw + vbp + height + dummy_yres + vfp; hsync_period = hspw + hbp + width + dummy_xres + hfp; mipi = &pdata->panel_info.mipi; if (pdata->panel_info.type == MIPI_VIDEO_PANEL) { MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x24, ((hspw + hbp + width + dummy_xres) << 16 | (hspw + hbp))); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x28, ((vspw + vbp + height + dummy_yres) << 16 | (vspw + vbp))); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x2C, ((vsync_period - 1) << 16) | (hsync_period - 1)); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x30, (hspw << 16)); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x34, 0); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x38, (vspw << 16)); } else { /* command mode */ if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888) bpp = 3; else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB666) bpp = 3; else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565) bpp = 2; else bpp = 3; /* Default format set to RGB888 */ ystride = width * bpp + 1; /* DSI_COMMAND_MODE_MDP_STREAM_CTRL */ data = (ystride << 16) | (mipi->vc << 8) | DTYPE_DCS_LWRITE; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x60, data); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x58, data); /* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */ data = height << 16 | width; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x64, data); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x5C, data); } mdss_dsi_sw_reset(pdata); mdss_dsi_host_init(mipi, pdata); if (mipi->force_clk_lane_hs) { u32 tmp; tmp = MIPI_INP((ctrl_pdata->ctrl_base) + 0xac); tmp |= (1<<28); MIPI_OUTP((ctrl_pdata->ctrl_base) + 0xac, tmp); wmb(); } if (pdata->panel_info.type == MIPI_CMD_PANEL) mdss_dsi_clk_ctrl(ctrl_pdata, 0); pr_debug("%s-:\n", __func__); return 0; }
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_enable_clks(struct mdss_dsi_ctrl_pdata *ctrl) { int rc = 0; #if defined(CONFIG_FB_MSM_MIPI_SAMSUNG_OCTA_CMD_WQXGA_S6TNMR7_PT_PANEL) rc = mdss_dsi_clk_set_rate(ctrl); if (rc) { pr_err("%s: failed to set clk rates. rc=%d\n", __func__, rc); goto error; } rc = mdss_dsi_clk_prepare(ctrl); if (rc) { pr_err("%s: failed to prepare clks. rc=%d\n", __func__, rc); goto error; } rc = mdss_dsi_clk_enable(ctrl); if (rc) { pr_err("%s: failed to enable clks. rc=%d\n", __func__, rc); mdss_dsi_clk_unprepare(ctrl); goto error; } #else rc = mdss_dsi_enable_bus_clocks(ctrl); if (rc) { pr_err("%s: failed to enable bus clks. rc=%d\n", __func__, rc); goto error; } rc = mdss_dsi_clk_set_rate(ctrl); if (rc) { pr_err("%s: failed to set clk rates. rc=%d\n", __func__, rc); mdss_dsi_disable_bus_clocks(ctrl); goto error; } rc = mdss_dsi_clk_prepare(ctrl); if (rc) { pr_err("%s: failed to prepare clks. rc=%d\n", __func__, rc); mdss_dsi_disable_bus_clocks(ctrl); goto error; } rc = mdss_dsi_clk_enable(ctrl); if (rc) { pr_err("%s: failed to enable clks. rc=%d\n", __func__, rc); mdss_dsi_clk_unprepare(ctrl); mdss_dsi_disable_bus_clocks(ctrl); goto error; } #endif error: return rc; }