Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edb7dd15 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mdss: Add support for dynamic mode switch on mdp3"

parents e388465c c67d4f42
Loading
Loading
Loading
Loading
+32 −22
Original line number Diff line number Diff line
@@ -578,15 +578,20 @@ void msm_dsi_op_mode_config(int mode, struct mdss_panel_data *pdata)
	pr_debug("msm_dsi_op_mode_config\n");

	dsi_ctrl = MIPI_INP(ctrl_base + DSI_CTRL);
	/*If Video enabled, Keep Video and Cmd mode ON */


	dsi_ctrl &= ~0x06;

	if (mode == DSI_VIDEO_MODE)
		dsi_ctrl |= 0x02;
	if (dsi_ctrl & DSI_VIDEO_MODE_EN)
		dsi_ctrl &= ~(DSI_CMD_MODE_EN|DSI_EN);
	else
		dsi_ctrl |= 0x04;
		dsi_ctrl &= ~(DSI_CMD_MODE_EN|DSI_VIDEO_MODE_EN|DSI_EN);

	if (mode == DSI_VIDEO_MODE) {
		dsi_ctrl |= (DSI_VIDEO_MODE_EN|DSI_EN);
	} else {
		dsi_ctrl |= (DSI_CMD_MODE_EN|DSI_EN);
		/* For Video mode panel, keep Video and Cmd mode ON */
		if (pdata->panel_info.type == MIPI_VIDEO_PANEL)
			dsi_ctrl |= DSI_VIDEO_MODE_EN;
	}

	pr_debug("%s: dsi_ctrl=%x\n", __func__, dsi_ctrl);

@@ -1070,6 +1075,8 @@ static int msm_dsi_on(struct mdss_panel_data *pdata)

	mutex_lock(&ctrl_pdata->mutex);


	if (!pdata->panel_info.dynamic_switch_pending) {
		for (i = 0; !ret && (i < DSI_MAX_PM); i++) {
			ret = msm_dss_enable_vreg(
				ctrl_pdata->power_data[i].vreg_config,
@@ -1080,6 +1087,7 @@ static int msm_dsi_on(struct mdss_panel_data *pdata)
				goto error_vreg;
			}
		}
	}

	msm_dsi_ahb_ctrl(1);
	msm_dsi_phy_sw_reset(dsi_host_private->dsi_base);
@@ -1204,6 +1212,7 @@ static int msm_dsi_off(struct mdss_panel_data *pdata)
	msm_dsi_phy_off(dsi_host_private->dsi_base);
	msm_dsi_ahb_ctrl(0);

	if (!pdata->panel_info.dynamic_switch_pending) {
		for (i = DSI_MAX_PM - 1; i >= 0; i--) {
			ret = msm_dss_enable_vreg(
				ctrl_pdata->power_data[i].vreg_config,
@@ -1212,6 +1221,7 @@ static int msm_dsi_off(struct mdss_panel_data *pdata)
				pr_err("%s: failed to disable vregs for %s\n",
					__func__, __mdss_dsi_pm_name(i));
		}
	}
	dsi_host_private->clk_count = 0;
	dsi_host_private->dsi_on = 0;

+4 −0
Original line number Diff line number Diff line
@@ -171,4 +171,8 @@
#define DSI_DSIPHY_BIST_CTRL4			0x049C
#define DSI_DSIPHY_BIST_CTRL5			0x04A0

#define DSI_EN			BIT(0)
#define DSI_VIDEO_MODE_EN	BIT(1)
#define DSI_CMD_MODE_EN		BIT(2)

#endif /* DSI_HOST_V2_H */
+58 −6
Original line number Diff line number Diff line
@@ -52,6 +52,37 @@ static int dsi_on(struct mdss_panel_data *pdata)
	return rc;
}

static int dsi_update_pconfig(struct mdss_panel_data *pdata,
				int mode)
{
	int ret = 0;
	struct mdss_panel_info *pinfo = &pdata->panel_info;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	if (!pdata)
		return -ENODEV;
	ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
				panel_data);

	if (mode == DSI_CMD_MODE) {
		pinfo->mipi.mode = DSI_CMD_MODE;
		pinfo->type = MIPI_CMD_PANEL;
		pinfo->mipi.vsync_enable = 1;
		pinfo->mipi.hw_vsync_mode = 1;
	} else {
		pinfo->mipi.mode = DSI_VIDEO_MODE;
		pinfo->type = MIPI_VIDEO_PANEL;
		pinfo->mipi.vsync_enable = 0;
		pinfo->mipi.hw_vsync_mode = 0;
	}

	ctrl_pdata->panel_mode = pinfo->mipi.mode;
	mdss_panel_get_dst_fmt(pinfo->bpp, pinfo->mipi.mode,
			pinfo->mipi.pixel_packing, &(pinfo->mipi.dst_format));
	pinfo->cont_splash_enabled = 0;

	return ret;
}

static int dsi_panel_handler(struct mdss_panel_data *pdata, int enable)
{
	int rc = 0;
@@ -64,18 +95,36 @@ static int dsi_panel_handler(struct mdss_panel_data *pdata, int enable)
				panel_data);

	if (enable && pdata->panel_info.panel_power_on == 0) {
		if (!pdata->panel_info.dynamic_switch_pending) {
			mdss_dsi_panel_reset(pdata, 1);
		pdata->panel_info.panel_power_on = 1;
			rc = ctrl_pdata->on(pdata);
			if (rc)
			pr_err("dsi_panel_handler panel on failed %d\n", rc);
				pr_err("dsi_panel_handler panel on failed %d\n",
									rc);
		}
		pdata->panel_info.panel_power_on = 1;
		if (pdata->panel_info.type == MIPI_CMD_PANEL)
			mdss_dsi_set_tear_on(ctrl_pdata);
	} else if (!enable && pdata->panel_info.panel_power_on == 1) {
		msm_dsi_sw_reset();
		if (dsi_intf.op_mode_config)
			dsi_intf.op_mode_config(DSI_CMD_MODE, pdata);
		rc = ctrl_pdata->off(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);
			}
		}
		pdata->panel_info.panel_power_on = 0;
		if (!pdata->panel_info.dynamic_switch_pending) {
			rc = ctrl_pdata->off(pdata);
			mdss_dsi_panel_reset(pdata, 0);
		}
	}
	return rc;
}

@@ -136,6 +185,9 @@ static int dsi_event_handler(struct mdss_panel_data *pdata,
	case MDSS_EVENT_PANEL_CLK_CTRL:
		rc = dsi_clk_ctrl(pdata, (int)arg);
		break;
	case MDSS_EVENT_DSI_DYNAMIC_SWITCH:
		rc = dsi_update_pconfig(pdata, (int)(unsigned long) arg);
		break;
	default:
		pr_debug("%s: unhandled event=%d\n", __func__, event);
		break;
+1 −0
Original line number Diff line number Diff line
@@ -52,4 +52,5 @@ struct mdss_panel_cfg *mdp3_panel_intf_type(int intf_val);

int mdp3_panel_get_boot_cfg(void);

void msm_dsi_sw_reset(void);
#endif /* DSI_V2_H */
+49 −5
Original line number Diff line number Diff line
@@ -672,16 +672,17 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd)

	mdp3_histogram_stop(mdp3_session, MDP_BLOCK_DMA_P);

	rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
	if (rc)
		pr_debug("fail to stop the MDP3 dma\n");


	if (panel->event_handler)
		rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
	if (rc)
		pr_err("fail to turn off the panel\n");

	rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
	if (rc)
		pr_debug("fail to stop the MDP3 dma\n");
	/* Wait for TG to turn off */
	msleep(20);

	mdp3_irq_deregister();

	pr_debug("mdp3_ctrl_off stop clock\n");
@@ -1813,6 +1814,48 @@ int mdp3_wait_for_dma_done(struct mdp3_session_data *session)
	return rc;
}

static int mdp3_update_panel_info(struct msm_fb_data_type *mfd, int mode)
{
	int ret = 0;
	struct mdp3_session_data *mdp3_session;
	struct mdss_panel_data *panel;
	u32 intf_type = 0;

	if (!mfd || !mfd->mdp.private1)
		return -EINVAL;

	mdp3_session = mfd->mdp.private1;
	panel = mdp3_session->panel;

	if (!panel->event_handler)
		return 0;
	ret = panel->event_handler(panel, MDSS_EVENT_DSI_DYNAMIC_SWITCH,
						(void *)(unsigned long)mode);
	if (ret)
		pr_err("Dynamic switch to %s mode failed!\n",
					mode ? "command" : "video");
	if (mode == 1)
		mfd->panel.type = MIPI_CMD_PANEL;
	else
		mfd->panel.type = MIPI_VIDEO_PANEL;

	if (mfd->panel.type != MIPI_VIDEO_PANEL)
		mdp3_session->wait_for_dma_done = mdp3_wait_for_dma_done;

	intf_type = mdp3_ctrl_get_intf_type(mfd);
	mdp3_session->intf->cfg.type = intf_type;
	mdp3_session->intf->available = 1;
	mdp3_session->intf->in_use = 1;
	mdp3_res->intf[intf_type].in_use = 1;

	mdp3_intf_init(mdp3_session->intf);

	mdp3_session->dma->output_config.out_sel = intf_type;
	mdp3_session->status = mdp3_session->intf->active;

	return 0;
}

int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
{
	struct device *dev = mfd->fbi->dev;
@@ -1835,6 +1878,7 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
	mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler;
	mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff;
	mdp3_interface->lut_update = mdp3_ctrl_lut_update;
	mdp3_interface->configure_panel = mdp3_update_panel_info;

	mdp3_session = kzalloc(sizeof(struct mdp3_session_data), GFP_KERNEL);
	if (!mdp3_session) {