예제 #1
0
/*
 * 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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #6
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;
}