int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int ret = 0;
	unsigned long flag;

	if (ctrl_pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);

		return 0;
	}

	pr_debug("%s: Checking BTA status\n", __func__);

	mdss_dsi_clk_ctrl(ctrl_pdata, 1);
	spin_lock_irqsave(&ctrl_pdata->mdp_lock, flag);
	INIT_COMPLETION(ctrl_pdata->bta_comp);
	mdss_dsi_enable_irq(ctrl_pdata, DSI_BTA_TERM);
	spin_unlock_irqrestore(&ctrl_pdata->mdp_lock, flag);
	MIPI_OUTP(ctrl_pdata->ctrl_base + 0x098, 0x01); 
	wmb();

	ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
						DSI_BTA_EVENT_TIMEOUT);
	if (ret <= 0) {
		mdss_dsi_disable_irq(ctrl_pdata, DSI_BTA_TERM);
		pr_err("%s: DSI BTA error: %i\n", __func__, ret);
	}

	mdss_dsi_clk_ctrl(ctrl_pdata, 0);
	pr_debug("%s: BTA done with ret: %d\n", __func__, ret);

	return ret;
}
示例#2
0
static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state)
{
	int ret = 0;
	struct mipi_panel_info *mipi;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;

	pr_info("%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);
	mipi = &pdata->panel_info.mipi;

	pr_info("%s+: ctrl=%p ndx=%d power_state=%d\n",
		__func__, ctrl_pdata, ctrl_pdata->ndx, power_state);

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);

	if (power_state == MDSS_PANEL_POWER_DOZE) {
		pr_err("%s: low power state requested\n", __func__);
		if (ctrl_pdata->low_power_config)
			ret = ctrl_pdata->low_power_config(pdata, true);
		goto error;
	}

	if (pdata->panel_info.type == MIPI_VIDEO_PANEL &&
			ctrl_pdata->off_cmds.link_state == DSI_LP_MODE) {
		mdss_dsi_sw_reset(ctrl_pdata, false);
		mdss_dsi_host_init(pdata);
	}

	mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);

#if 0 /*It is not needed on oled cmd mode panel, The on seq has tear off cmd */
	if ((pdata->panel_info.type == MIPI_CMD_PANEL) &&
		mipi->vsync_enable && mipi->hw_vsync_mode)
		mdss_dsi_set_tear_off(ctrl_pdata);
#endif

	pr_info("%s : ctrl_state(%d)\n",__func__, ctrl_pdata->ctrl_state);

	if (ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT) {
		ret = ctrl_pdata->off(pdata);
		if (ret) {
			pr_err("%s: Panel OFF failed\n", __func__);
			goto error;
		}
		ctrl_pdata->ctrl_state &= ~CTRL_STATE_PANEL_INIT;
	}

error:
	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
	pr_info("%s-:End\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) {
		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;
}
示例#4
0
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;
}
示例#6
0
static int mdss_dsi_blank(struct mdss_panel_data *pdata)
{
	int ret = 0;
	struct mipi_panel_info *mipi;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;

	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);
	mipi = &pdata->panel_info.mipi;

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);

	if (pdata->panel_info.type == MIPI_VIDEO_PANEL &&
			ctrl_pdata->off_cmds.link_state == DSI_LP_MODE) {
		mdss_dsi_sw_reset(pdata);
		mdss_dsi_host_init(pdata);
	}

	mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);

	if (pdata->panel_info.dynamic_switch_pending) {
		pr_info("%s: switching to %s mode\n", __func__,
			(pdata->panel_info.mipi.mode ? "video" : "command"));
		if (pdata->panel_info.type == MIPI_CMD_PANEL) {
			ctrl_pdata->switch_mode(pdata, DSI_VIDEO_MODE);
		} else if (pdata->panel_info.type == MIPI_VIDEO_PANEL) {
			ctrl_pdata->switch_mode(pdata, DSI_CMD_MODE);
			mdss_dsi_set_tear_off(ctrl_pdata);
		}
	}

	if ((pdata->panel_info.type == MIPI_CMD_PANEL) &&
		mipi->vsync_enable && mipi->hw_vsync_mode)
		mdss_dsi_set_tear_off(ctrl_pdata);

	if (ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT) {
		if (!pdata->panel_info.dynamic_switch_pending) {
			ret = ctrl_pdata->off(pdata);
			if (ret) {
				pr_err("%s: Panel OFF failed\n", __func__);
				goto error;
			}
		}
		ctrl_pdata->ctrl_state &= ~CTRL_STATE_PANEL_INIT;
	}

error:
	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
	pr_debug("%s-:End\n", __func__);
	return ret;
}
int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
	struct dcs_cmd_req *req;
	int ret = -EINVAL;
	int rc = 0;
	mutex_lock(&ctrl->cmd_mutex);
	req = mdss_dsi_cmdlist_get(ctrl);

	/* make sure dsi_cmd_mdp is idle */
	mdss_dsi_cmd_mdp_busy(ctrl);

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);

	if (req == NULL)
		goto need_lock;

	/*
	 * mdss interrupt is generated in mdp core clock domain
	 * mdp clock need to be enabled to receive dsi interrupt
	 * also, axi bus bandwidth need since dsi controller will
	 * fetch dcs commands from axi bus
	 */
	mdss_bus_scale_set_quota(MDSS_HW_DSI0, SZ_1M, SZ_1M);
	mdss_bus_bandwidth_ctrl(1);
	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
	mdss_dsi_clk_ctrl(ctrl, 1);

	rc = mdss_iommu_ctrl(1);
	if (IS_ERR_VALUE(rc)) {
		pr_err("IOMMU attach failed\n");
		mutex_unlock(&ctrl->cmd_mutex);
		return rc;
	}

	if (req->flags & CMD_REQ_HS_MODE)
		mdss_dsi_set_tx_power_mode(0, &ctrl->panel_data);

	if (req->flags & CMD_REQ_RX)
		ret = mdss_dsi_cmdlist_rx(ctrl, req);
	else
		ret = mdss_dsi_cmdlist_tx(ctrl, req);

	if (req->flags & CMD_REQ_HS_MODE)
		mdss_dsi_set_tx_power_mode(1, &ctrl->panel_data);

	mdss_iommu_ctrl(0);
	mdss_dsi_clk_ctrl(ctrl, 0);
	mdss_bus_scale_set_quota(MDSS_HW_DSI0, 0, 0);
	mdss_bus_bandwidth_ctrl(0);
need_lock:

	if (from_mdp) /* from pipe_commit */
		mdss_dsi_cmd_mdp_start(ctrl);

	mutex_unlock(&ctrl->cmd_mutex);
	return ret;
}
int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
	struct dcs_cmd_req *req;
	int ret = -EINVAL;
	int rc = 0;
	mutex_lock(&ctrl->cmd_mutex);
	req = mdss_dsi_cmdlist_get(ctrl);

	MDSS_XLOG(ctrl->ndx, from_mdp, ctrl->mdp_busy, current->pid,
							XLOG_FUNC_ENTRY);

	/* make sure dsi_cmd_mdp is idle */
	mdss_dsi_cmd_mdp_busy(ctrl);

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);

	if (req == NULL)
		goto need_lock;

	MDSS_XLOG(ctrl->ndx, req->flags, req->cmds_cnt, from_mdp, current->pid);

	/*
	 * mdss interrupt is generated in mdp core clock domain
	 * mdp clock need to be enabled to receive dsi interrupt
	 * also, axi bus bandwidth need since dsi controller will
	 * fetch dcs commands from axi bus
	 */
	mdss_bus_bandwidth_ctrl(1);
	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
	mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 1);

	rc = mdss_iommu_ctrl(1);
	if (IS_ERR_VALUE(rc)) {
		pr_err("IOMMU attach failed\n");
		mutex_unlock(&ctrl->cmd_mutex);
		return rc;
	}
	if (req->flags & CMD_REQ_RX)
		ret = mdss_dsi_cmdlist_rx(ctrl, req);
	else
		ret = mdss_dsi_cmdlist_tx(ctrl, req);
	mdss_iommu_ctrl(0);
	mdss_dsi_clk_ctrl(ctrl, DSI_ALL_CLKS, 0);
	mdss_bus_bandwidth_ctrl(0);

need_lock:

	if (from_mdp) /* from pipe_commit */
		mdss_dsi_cmd_mdp_start(ctrl);

	MDSS_XLOG(ctrl->ndx, from_mdp, ctrl->mdp_busy, current->pid,
							XLOG_FUNC_EXIT);
	mutex_unlock(&ctrl->cmd_mutex);
	return ret;
}
示例#9
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;
}
示例#10
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 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;
}
int mdss_get_tx_power_mode(struct mdss_panel_data *pdata)
{
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	u32 data;

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);

	mdss_dsi_clk_ctrl(ctrl_pdata, 1);
	data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x3c);
	mdss_dsi_clk_ctrl(ctrl_pdata, 0);
	return !!(data & BIT(26));
}
int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
	struct dcs_cmd_req *req;
	int ret = -EINVAL;
	int rc = 0;
	mutex_lock(&ctrl->cmd_mutex);
	req = mdss_dsi_cmdlist_get(ctrl);

	
	mdss_dsi_cmd_mdp_busy(ctrl);

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);

	if (req == NULL)
		goto need_lock;

	mdss_bus_scale_set_quota(MDSS_HW_DSI0, SZ_1M, SZ_1M);
	mdss_bus_bandwidth_ctrl(1);
	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
	mdss_dsi_clk_ctrl(ctrl, 1);

	rc = mdss_iommu_ctrl(1);
	if (IS_ERR_VALUE(rc)) {
		pr_err("IOMMU attach failed\n");
		mutex_unlock(&ctrl->cmd_mutex);
		return rc;
	}

	if (req->flags & CMD_REQ_HS_MODE)
		mdss_dsi_set_tx_power_mode(0, &ctrl->panel_data);

	if (req->flags & CMD_REQ_RX)
		ret = mdss_dsi_cmdlist_rx(ctrl, req);
	else
		ret = mdss_dsi_cmdlist_tx(ctrl, req);

	if (req->flags & CMD_REQ_HS_MODE)
		mdss_dsi_set_tx_power_mode(1, &ctrl->panel_data);

	mdss_iommu_ctrl(0);
	mdss_dsi_clk_ctrl(ctrl, 0);
	mdss_bus_scale_set_quota(MDSS_HW_DSI0, 0, 0);
	mdss_bus_bandwidth_ctrl(0);
need_lock:

	if (from_mdp) 
		mdss_dsi_cmd_mdp_start(ctrl);

	mutex_unlock(&ctrl->cmd_mutex);
	return ret;
}
示例#13
0
static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
{
	int ret = 0;
	struct mipi_panel_info *mipi;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = 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);
	mipi  = &pdata->panel_info.mipi;

	pr_err("%s+: ctrl=%p ndx=%d cur_blank_state=%d\n", __func__,
		ctrl_pdata, ctrl_pdata->ndx, pdata->panel_info.blank_state);

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);

	if (pdata->panel_info.blank_state == MDSS_PANEL_BLANK_LOW_POWER) {
		pr_debug("%s: dsi_unblank with panel always on\n", __func__);
		if (ctrl_pdata->low_power_config)
			ret = ctrl_pdata->low_power_config(pdata, false);
		goto error;
	}

	pr_info("ctrl_state = (%d)\n",ctrl_pdata->ctrl_state);

	if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) {
		ret = ctrl_pdata->on(pdata);
		if (ret) {
			pr_err("%s: unable to initialize the panel\n",
							__func__);
				goto error;
		}
		ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT;
	}
#if 0 /*It is not needed on oled cmd mode panel, The on seq has tear on cmd */
	if ((pdata->panel_info.type == MIPI_CMD_PANEL) &&
		mipi->vsync_enable && mipi->hw_vsync_mode)
		mdss_dsi_set_tear_on(ctrl_pdata);
#endif

error:
	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
	pr_err("%s-:\n", __func__);

	return ret;
}
void mdss_dsi_pll_relock(struct mdss_dsi_ctrl_pdata *ctrl)
{
	int i, cnt;

	cnt = ctrl->clk_cnt;

	
	for (i = 0; i < cnt; i++)
		mdss_dsi_clk_ctrl(ctrl, 0);

	
	for (i = 0; i < cnt; i++)
		mdss_dsi_clk_ctrl(ctrl, 1);
}
示例#15
0
void mdss_dsi_pll_relock(struct mdss_dsi_ctrl_pdata *ctrl)
{
	int i, cnt;

	cnt = ctrl->clk_cnt;

	/* disable dsi clk */
	for (i = 0; i < cnt; i++)
		mdss_dsi_clk_ctrl(ctrl, 0);

	/* enable dsi clk */
	for (i = 0; i < cnt; i++)
		mdss_dsi_clk_ctrl(ctrl, 1);
}
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int ret = 0;
	unsigned long flag;

	if (ctrl_pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);

		/*
		 * This should not return error otherwise
		 * BTA status thread will treat it as dead panel scenario
		 * and request for blank/unblank
		 */
		return 0;
	}

	pr_debug("%s: Checking BTA status\n", __func__);
#ifdef CONFIG_HUAWEI_KERNEL
	mutex_lock(&ctrl_pdata->cmd_mutex);
#endif
	mdss_dsi_clk_ctrl(ctrl_pdata, 1);
	spin_lock_irqsave(&ctrl_pdata->mdp_lock, flag);
	INIT_COMPLETION(ctrl_pdata->bta_comp);
	mdss_dsi_enable_irq(ctrl_pdata, DSI_BTA_TERM);
	spin_unlock_irqrestore(&ctrl_pdata->mdp_lock, flag);
	MIPI_OUTP(ctrl_pdata->ctrl_base + 0x098, 0x01); /* trigger  */
	wmb();

	ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
						DSI_BTA_EVENT_TIMEOUT);
	if (ret <= 0) {
		mdss_dsi_disable_irq(ctrl_pdata, DSI_BTA_TERM);
		pr_err("%s: DSI BTA error: %i\n", __func__, ret);
	}
	mdss_dsi_clk_ctrl(ctrl_pdata, 0);
#ifdef CONFIG_HUAWEI_KERNEL
	mutex_unlock(&ctrl_pdata->cmd_mutex);
#endif
	pr_debug("%s: BTA done with ret: %d\n", __func__, ret);
#ifdef CONFIG_HUAWEI_LCD
	if(ret > 0)
	{
		/*if panel check error and enable the esd check bit in dtsi,report the event to hal layer*/
		if(ctrl_pdata->esd_check_enable)
			ret = panel_check_live_status(ctrl_pdata);
	}
#endif
	return ret;
}
static int prepare_for_reg_access(struct msm_fb_data_type *mfd)
{
	struct mdss_panel_data *pdata;
	int ret = 0;
	struct mdss_mdp_ctl *ctl;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;

	ctl = mfd_to_ctl(mfd);
	if (!ctl)
		return -ENODEV;

	pdata = dev_get_platdata(&mfd->pdev->dev);
	if (!pdata) {
		pr_err("%s: no panel connected\n", __func__);
		return -ENODEV;
	}

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
	mdss_dsi_cmd_mdp_busy(ctrl_pdata);
	mdss_bus_bandwidth_ctrl(1);
	mdss_dsi_clk_ctrl(ctrl_pdata, 1);

	mdss_dsi_op_mode_config(DSI_CMD_MODE, pdata);

	return ret;
}
示例#18
0
static int mdss_dsi_unblank(struct mdss_panel_data *pdata)
{
	int ret = 0;
	struct mipi_panel_info *mipi;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;

	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);
	mipi  = &pdata->panel_info.mipi;

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);

	if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) {
		if (!pdata->panel_info.dynamic_switch_pending) {
			ret = ctrl_pdata->on(pdata);
			if (ret) {
				pr_err("%s: unable to initialize the panel\n",
							__func__);
				goto error;
			}
		}
		ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT;
	}

//+++
#ifdef CONFIG_ZTEMT_LCD_DISP_ENHANCE
	zte_disp_enhance();
#endif
//---
	if ((pdata->panel_info.type == MIPI_CMD_PANEL) &&
		mipi->vsync_enable && mipi->hw_vsync_mode)
		mdss_dsi_set_tear_on(ctrl_pdata);

error:
	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
	pr_debug("%s-:\n", __func__);

	return ret;
}
void mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
	struct dcs_cmd_req *req;
	u32 data;

	mutex_lock(&ctrl->cmd_mutex);
	req = mdss_dsi_cmdlist_get(ctrl);

	/* make sure dsi_cmd_mdp is idle */
	mdss_dsi_cmd_mdp_busy(ctrl);

	if (req == NULL)
		goto need_lock;

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
	mdss_dsi_clk_ctrl(ctrl, 1);

	data = MIPI_INP((ctrl->ctrl_base) + 0x0004);
	if (data & 0x02) {
		/* video mode, make sure video engine is busy
		 * so dcs command will be sent at start of BLLP
		 */
		mdss_dsi_wait4video_eng_busy(ctrl);
	} else {
		/* command mode */
		if (!from_mdp) { /* cmdlist_put */
			/* make sure dsi_cmd_mdp is idle */
			mdss_dsi_cmd_mdp_busy(ctrl);
		}
	}

	if (req->flags & CMD_REQ_RX)
		mdss_dsi_cmdlist_rx(ctrl, req);
	else
		mdss_dsi_cmdlist_tx(ctrl, req);

	mdss_dsi_clk_ctrl(ctrl, 0);

need_lock:

	if (from_mdp) /* from pipe_commit */
		mdss_dsi_cmd_mdp_start(ctrl);

	mutex_unlock(&ctrl->cmd_mutex);
}
void mdss_dsi_pll_relock(struct mdss_dsi_ctrl_pdata *ctrl)
{
	int i, cnt;

	/*
	 * todo: this code does not work very well with dual
	 * dsi use cases. Need to fix this eventually.
	 */
	cnt = ctrl->link_clk_cnt;

	/* disable dsi clk */
	for (i = 0; i < cnt; i++)
		mdss_dsi_clk_ctrl(ctrl, DSI_LINK_CLKS, 0);

	/* enable dsi clk */
	for (i = 0; i < cnt; i++)
		mdss_dsi_clk_ctrl(ctrl, DSI_LINK_CLKS, 1);
}
int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
{
	struct dcs_cmd_req *req;
	int ret = -EINVAL;

	mutex_lock(&ctrl->cmd_mutex);
	req = mdss_dsi_cmdlist_get(ctrl);

	/* make sure dsi_cmd_mdp is idle */
	mdss_dsi_cmd_mdp_busy(ctrl);

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);

	if (req == NULL)
		goto need_lock;

	/*
	 * mdss interrupt is generated in mdp core clock domain
	 * mdp clock need to be enabled to receive dsi interrupt
	 * also, axi bus bandwidth need since dsi controller will
	 * fetch dcs commands from axi bus
	 */
	mdss_bus_bandwidth_ctrl(1);

	pr_debug("%s:  from_mdp=%d pid=%d\n", __func__, from_mdp, current->pid);
	mdss_dsi_clk_ctrl(ctrl, 1);

	if (req->flags & CMD_REQ_RX) {
		mdss_dsi_cmdlist_rx(ctrl, req);
		ret = ctrl->rx_buf.len;
	} else
		ret = mdss_dsi_cmdlist_tx(ctrl, req);

	mdss_dsi_clk_ctrl(ctrl, 0);
	mdss_bus_bandwidth_ctrl(0);

need_lock:

	if (from_mdp) /* from pipe_commit */
		mdss_dsi_cmd_mdp_start(ctrl);

	mutex_unlock(&ctrl->cmd_mutex);
	return ret;
}
void mdss_dsi_clk_req(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
{
	if (enable == 0) {
		
		mutex_lock(&ctrl->cmd_mutex);
		mdss_dsi_cmd_mdp_busy(ctrl);
		mutex_unlock(&ctrl->cmd_mutex);
	}

	mdss_dsi_clk_ctrl(ctrl, enable);
}
void mdss_dsi_clk_req(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
{
	MDSS_XLOG(ctrl->ndx, enable, ctrl->mdp_busy, current->pid);
	if (enable == 0) {
		/* need wait before disable */
		mutex_lock(&ctrl->cmd_mutex);
		mdss_dsi_cmd_mdp_busy(ctrl);
		mutex_unlock(&ctrl->cmd_mutex);
	}
	MDSS_XLOG(ctrl->ndx, enable, ctrl->mdp_busy, current->pid);
	mdss_dsi_clk_ctrl(ctrl, enable);
}
/**
 * mdss_dsi_reg_status_check() - Check dsi panel status through reg read
 * @ctrl_pdata: pointer to the dsi controller structure
 *
 * This function can be used to check the panel status through reading the
 * status register from the panel.
 *
 * Return: positive value if the panel is in good state, negative value or
 * zero otherwise.
 */
int mdss_dsi_reg_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int ret = 0;

	if (ctrl_pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);
		return 0;
	}

	pr_debug("%s: Checking Register status\n", __func__);

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);

	if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE)
		mdss_dsi_set_tx_power_mode(0, &ctrl_pdata->panel_data);

	ret = mdss_dsi_read_status(ctrl_pdata);

	if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE)
		mdss_dsi_set_tx_power_mode(1, &ctrl_pdata->panel_data);

	if (ret == 0) {
		if (ctrl_pdata->status_buf.data[0] !=
						ctrl_pdata->status_value) {
			pr_err("%s: Read back value from panel is incorrect\n",
								__func__);
			ret = -EINVAL;
		} else {
			ret = 1;
		}
	} else {
		pr_err("%s: Read status register returned error\n", __func__);
	}

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
	pr_debug("%s: Read register done with ret: %d\n", __func__, ret);

	return ret;
}
/**
 * mdss_dsi_bta_status_check() - Check dsi panel status through bta check
 * @ctrl_pdata: pointer to the dsi controller structure
 *
 * This function can be used to check status of the panel using bta check
 * for the panel.
 *
 * Return: positive value if the panel is in good state, negative value or
 * zero otherwise.
 */
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int ret = 0;
	unsigned long flag;

	if (ctrl_pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);

		/*
		 * This should not return error otherwise
		 * BTA status thread will treat it as dead panel scenario
		 * and request for blank/unblank
		 */
		return 0;
	}

	pr_debug("%s: Checking BTA status\n", __func__);

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
	spin_lock_irqsave(&ctrl_pdata->mdp_lock, flag);
	INIT_COMPLETION(ctrl_pdata->bta_comp);
	mdss_dsi_enable_irq(ctrl_pdata, DSI_BTA_TERM);
	spin_unlock_irqrestore(&ctrl_pdata->mdp_lock, flag);
	MIPI_OUTP(ctrl_pdata->ctrl_base + 0x098, 0x01); /* trigger  */
	wmb();

	ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
						DSI_BTA_EVENT_TIMEOUT);
	if (ret <= 0) {
		mdss_dsi_disable_irq(ctrl_pdata, DSI_BTA_TERM);
		pr_err("%s: DSI BTA error: %i\n", __func__, ret);
	}

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
	pr_debug("%s: BTA done with ret: %d\n", __func__, ret);

	return ret;
}
void mdss_set_tx_power_mode(int mode, struct mdss_panel_data *pdata)
{
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	u32 data;

	if (pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);
		return;
	}

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);

	mdss_dsi_clk_ctrl(ctrl_pdata, 1);
	data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x3c);

	if (mode == 0)
		data &= ~BIT(26);
	else
		data |= BIT(26);

	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x3c, data);
	mdss_dsi_clk_ctrl(ctrl_pdata, 0);
}
void mdss_dsi_clk_req(struct mdss_dsi_ctrl_pdata *ctrl, int enable)
{
#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
	xlog(__func__,ctrl->ndx, enable, ctrl->mdp_busy, 0x111, 0, current->pid);
#endif
	if (enable == 0) {
		/* need wait before disable */
		mutex_lock(&ctrl->cmd_mutex);
		mdss_dsi_cmd_mdp_busy(ctrl);
		mutex_unlock(&ctrl->cmd_mutex);
	}
#if defined (CONFIG_FB_MSM_MDSS_DSI_DBG)
	xlog(__func__,ctrl->ndx, enable, ctrl->mdp_busy, 0x222, 0, current->pid);
#endif

	mdss_dsi_clk_ctrl(ctrl, enable);
}
static int post_reg_access(struct msm_fb_data_type *mfd)
{
	struct mdss_panel_data *pdata;
	int ret = 0;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;

	pdata = dev_get_platdata(&mfd->pdev->dev);
	if (!pdata) {
		pr_err("%s: no panel connected\n", __func__);
		return -ENODEV;
	}

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);

	mdss_dsi_clk_ctrl(ctrl_pdata, 0);
	mdss_bus_bandwidth_ctrl(0);
	mdss_dsi_op_mode_config(pdata->panel_info.mipi.mode, pdata);
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);

	return ret;
}
示例#29
0
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;
}
示例#30
0
int mdss_dsi_on(struct mdss_panel_data *pdata)
{
	int ret = 0;
	struct mdss_panel_info *pinfo;
	struct mipi_panel_info *mipi;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = 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 on.\n", __func__, __LINE__);
		return 0;
	}

	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);

	pr_info("%s+: ctrl=%p ndx=%d\n",
				__func__, ctrl_pdata, ctrl_pdata->ndx);

	pinfo = &pdata->panel_info;
	mipi = &pdata->panel_info.mipi;

	if (ctrl_pdata->partial_mode_enabled
		&& !pdata->panel_info.panel_dead) {
		mdss_dsi_ulps_config_sub(ctrl_pdata, 0, 1);
		mdata->ulps = false;
		pdata->panel_info.panel_power_on = 1;
		mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);
	} else {
		if (ctrl_pdata->partial_mode_enabled
			&& pdata->panel_info.panel_dead)
			pr_warn("%s: Panel is dead, bring up DSI\n", __func__);

		ret = mdss_dsi_panel_power_on(pdata, 1);
		if (ret) {
			pr_err("%s:Panel power on failed. rc=%d\n", __func__, ret);
			return 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);
			ret = mdss_dsi_panel_power_on(pdata, 0);
			if (ret) {
				pr_err("%s: Panel reset failed. rc=%d\n",
					__func__, ret);
				return ret;
			}
			pdata->panel_info.panel_power_on = 0;
			return ret;
		}
		pdata->panel_info.panel_power_on = 1;

		mdss_dsi_phy_sw_reset((ctrl_pdata->ctrl_base));
		mdss_dsi_phy_init(pdata);
		mdss_dsi_clk_ctrl(ctrl_pdata, DSI_BUS_CLKS, 0);
		mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);

		__mdss_dsi_ctrl_setup(pdata);
		mdss_dsi_sw_reset(pdata);
		mdss_dsi_host_init(pdata);
	}

	/*
	 * Issue hardware reset line after enabling the DSI clocks and data
	 * data lanes for LP11 init
	 */
	if (mipi->lp11_init)
		mdss_dsi_panel_reset(pdata, 1);

	if (mipi->init_delay)
		usleep(mipi->init_delay);

	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, DSI_ALL_CLKS, 0);

	pr_info("%s-:\n", __func__);
	return 0;
}