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

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

Merge "mdss: mdp3: request and release clocks for every mdp operation"

parents bbc29e1c 297e0cf4
Loading
Loading
Loading
Loading
+91 −17
Original line number Diff line number Diff line
@@ -184,11 +184,11 @@ static irqreturn_t mdp3_irq_handler(int irq, void *ptr)
	u32 mdp_interrupt = 0;

	spin_lock(&mdata->irq_lock);
	if (!mdata->irq_mask) {
	if (!mdata->irq_mask)
		pr_err("spurious interrupt\n");
		spin_unlock(&mdata->irq_lock);
		return IRQ_HANDLED;
	}

	clk_enable(mdp3_res->clocks[MDP3_CLK_AHB]);
	clk_enable(mdp3_res->clocks[MDP3_CLK_CORE]);

	mdp_interrupt = MDP3_REG_READ(MDP3_REG_INTR_STATUS);
	MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, mdp_interrupt);
@@ -202,6 +202,10 @@ static irqreturn_t mdp3_irq_handler(int irq, void *ptr)
		mdp_interrupt = mdp_interrupt >> 1;
		i++;
	}

	clk_disable(mdp3_res->clocks[MDP3_CLK_AHB]);
	clk_disable(mdp3_res->clocks[MDP3_CLK_CORE]);

	spin_unlock(&mdata->irq_lock);

	return IRQ_HANDLED;
@@ -281,8 +285,6 @@ void mdp3_irq_deregister(void)
	spin_lock_irqsave(&mdp3_res->irq_lock, flag);
	memset(mdp3_res->irq_ref_count, 0, sizeof(u32) * MDP3_MAX_INTR);
	mdp3_res->irq_mask = 0;
	MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, 0);
	MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, 0xfffffff);
	disable_irq_nosync(mdp3_res->irq);
	spin_unlock_irqrestore(&mdp3_res->irq_lock, flag);
}
@@ -415,10 +417,10 @@ static int mdp3_clk_update(u32 clk_idx, u32 enable)
	count = mdp3_res->clock_ref_count[clk_idx];
	if (count == 1 && enable) {
		pr_debug("clk=%d en=%d\n", clk_idx, enable);
		ret = clk_prepare_enable(clk);
		ret = clk_enable(clk);
	} else if (count == 0) {
		pr_debug("clk=%d disable\n", clk_idx);
		clk_disable_unprepare(clk);
		clk_disable(clk);
		ret = 0;
	} else if (count < 0) {
		pr_err("clk=%d count=%d\n", clk_idx, count);
@@ -554,7 +556,7 @@ static void mdp3_clk_remove(void)
		clk_put(mdp3_res->clocks[MDP3_CLK_DSI]);
}

int mdp3_clk_enable(int enable)
int mdp3_clk_enable(int enable, int dsi_clk)
{
	int rc;

@@ -564,11 +566,62 @@ int mdp3_clk_enable(int enable)
	rc = mdp3_clk_update(MDP3_CLK_AHB, enable);
	rc |= mdp3_clk_update(MDP3_CLK_CORE, enable);
	rc |= mdp3_clk_update(MDP3_CLK_VSYNC, enable);
	if (dsi_clk)
		rc |= mdp3_clk_update(MDP3_CLK_DSI, enable);
	mutex_unlock(&mdp3_res->res_mutex);
	return rc;
}

int mdp3_clk_prepare(void)
{
	int rc = 0;

	mutex_lock(&mdp3_res->res_mutex);
	mdp3_res->clk_prepare_count++;
	if (mdp3_res->clk_prepare_count == 1) {
		rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_AHB]);
		if (rc < 0)
			goto error0;
		rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_CORE]);
		if (rc < 0)
			goto error1;
		rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_VSYNC]);
		if (rc < 0)
			goto error2;
		rc = clk_prepare(mdp3_res->clocks[MDP3_CLK_DSI]);
		if (rc < 0)
			goto error3;
	}
	mutex_unlock(&mdp3_res->res_mutex);
	return rc;

error3:
	clk_unprepare(mdp3_res->clocks[MDP3_CLK_VSYNC]);
error2:
	clk_unprepare(mdp3_res->clocks[MDP3_CLK_CORE]);
error1:
	clk_unprepare(mdp3_res->clocks[MDP3_CLK_AHB]);
error0:
	mdp3_res->clk_prepare_count--;
	mutex_unlock(&mdp3_res->res_mutex);
	return rc;
}

void mdp3_clk_unprepare(void)
{
	mutex_lock(&mdp3_res->res_mutex);
	mdp3_res->clk_prepare_count--;
	if (mdp3_res->clk_prepare_count == 0) {
		clk_unprepare(mdp3_res->clocks[MDP3_CLK_AHB]);
		clk_unprepare(mdp3_res->clocks[MDP3_CLK_CORE]);
		clk_unprepare(mdp3_res->clocks[MDP3_CLK_VSYNC]);
		clk_unprepare(mdp3_res->clocks[MDP3_CLK_DSI]);
	} else if (mdp3_res->clk_prepare_count < 0) {
		pr_err("mdp3 clk unprepare mismatch\n");
	}
	mutex_unlock(&mdp3_res->res_mutex);
}

static int mdp3_irq_setup(void)
{
	int ret;
@@ -1514,8 +1567,17 @@ int mdp3_iommu_is_attached(int client)
static int mdp3_init(struct msm_fb_data_type *mfd)
{
	int rc;

	rc = mdp3_ctrl_init(mfd);
	rc |= mdp3_ppp_res_init(mfd);
	if (rc) {
		pr_err("mdp3 ctl init fail\n");
		return rc;
	}

	rc = mdp3_ppp_res_init(mfd);
	if (rc)
		pr_err("mdp3 ppp res init fail\n");

	return rc;
}

@@ -1743,9 +1805,16 @@ static int mdp3_continuous_splash_on(struct mdss_panel_data *pdata)

	pr_debug("mdp3__continuous_splash_on\n");

	rc = mdp3_clk_enable(1);
	rc = mdp3_clk_prepare();
	if (rc) {
		pr_err("fail to prepare clk\n");
		return rc;
	}

	rc = mdp3_clk_enable(1, 1);
	if (rc) {
		pr_err("fail to enable clk\n");
		mdp3_clk_unprepare();
		return rc;
	}

@@ -1782,8 +1851,10 @@ static int mdp3_continuous_splash_on(struct mdss_panel_data *pdata)
	return 0;

splash_on_err:
	if (mdp3_clk_enable(0))
	if (mdp3_clk_enable(0, 1))
		pr_err("%s: Unable to disable mdp3 clocks\n", __func__);

	mdp3_clk_unprepare();
	return rc;
}

@@ -1816,10 +1887,13 @@ static int mdp3_debug_dump_stats(void *data, char *buf, int len)

static void mdp3_debug_enable_clock(int on)
{
	if (on)
		mdp3_clk_enable(1);
	else
		mdp3_clk_enable(0);
	if (on) {
		mdp3_clk_prepare();
		mdp3_clk_enable(1, 0);
	} else {
		mdp3_clk_enable(0, 0);
		mdp3_clk_unprepare();
	}
}

static int mdp3_debug_init(struct platform_device *pdev)
+5 −1
Original line number Diff line number Diff line
@@ -150,6 +150,8 @@ struct mdp3_hw_resource {
	u32 splash_mem_addr;
	u32 splash_mem_size;
	struct mdss_panel_cfg pan_cfg;

	int clk_prepare_count;
};

struct mdp3_img_data {
@@ -173,7 +175,9 @@ int mdp3_set_intr_callback(u32 type, struct mdp3_intr_cb *cb);
void mdp3_irq_register(void);
void mdp3_irq_deregister(void);
int mdp3_clk_set_rate(int clk_type, unsigned long clk_rate, int client);
int mdp3_clk_enable(int enable);
int mdp3_clk_enable(int enable, int dsi_clk);
int mdp3_clk_prepare(void);
void mdp3_clk_unprepare(void);
int mdp3_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota);
int mdp3_put_img(struct mdp3_img_data *data, int client);
int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data,
+35 −7
Original line number Diff line number Diff line
@@ -118,7 +118,9 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
	}

	mutex_lock(&mdp3_session->lock);
	mdp3_clk_enable(1, 0);
	mdp3_session->dma->vsync_enable(mdp3_session->dma, arg);
	mdp3_clk_enable(0, 0);
	if (enable && mdp3_session->status == 1 && !mdp3_session->intf->active)
		mod_timer(&mdp3_session->vsync_timer,
			jiffies + msecs_to_jiffies(mdp3_session->vsync_period));
@@ -236,12 +238,24 @@ static int mdp3_ctrl_res_req_clk(struct msm_fb_data_type *mfd, int status)
		mdp3_clk_set_rate(MDP3_CLK_VSYNC, MDP_VSYNC_CLK_RATE,
				MDP3_CLIENT_DMA_P);

		rc = mdp3_clk_enable(true);
		if (rc)
		rc = mdp3_clk_prepare();
		if (rc) {
			pr_err("mdp3 clk prepare fail\n");
			return rc;
		}

		rc = mdp3_clk_enable(1, 1);
		if (rc) {
			pr_err("mdp3 clk enable fail\n");
			mdp3_clk_unprepare();
			return rc;
		}
	} else {
		rc = mdp3_clk_enable(false);
		rc = mdp3_clk_enable(0, 1);
		if (rc)
			pr_err("mdp3 clk disable fail\n");
		else
			mdp3_clk_unprepare();
	}
	return rc;
}
@@ -514,19 +528,21 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd)
		goto off_error;
	}

	mdp3_clk_enable(1, 0);

	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");

	mdp3_clk_enable(0, 0);

	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");



	mdp3_irq_deregister();

	pr_debug("mdp3_ctrl_off stop clock\n");
@@ -843,9 +859,11 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,

	data = mdp3_bufq_pop(&mdp3_session->bufq_in);
	if (data) {
		mdp3_clk_enable(1, 0);
		mdp3_session->dma->update(mdp3_session->dma,
			(void *)(int)data->addr,
			mdp3_session->intf);
		mdp3_clk_enable(0, 0);
		mdp3_bufq_push(&mdp3_session->bufq_out, data);
	}

@@ -911,6 +929,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
		goto pan_error;
	}

	mdp3_clk_enable(1, 0);
	if (mfd->fbi->screen_base) {
		mdp3_session->dma->update(mdp3_session->dma,
				(void *)(int)(mfd->iova + offset),
@@ -919,6 +938,7 @@ static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
		pr_debug("mdp3_ctrl_pan_display no memory, stop interface");
		mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
	}
	mdp3_clk_enable(0, 0);

	if (mdp3_session->first_commit) {
		/*wait for one frame time to ensure frame is sent to panel*/
@@ -1033,10 +1053,11 @@ static int mdp3_histogram_start(struct mdp3_session_data *session,

	if (session->histo_status) {
		pr_err("mdp3_histogram_start already started\n");
		ret = -EBUSY;
		goto histogram_start_err;
		mutex_unlock(&session->histo_lock);
		return -EBUSY;
	}

	mdp3_clk_enable(1, 0);
	ret = session->dma->histo_op(session->dma, MDP3_DMA_HISTO_OP_RESET);
	if (ret) {
		pr_err("mdp3_histogram_start reset error\n");
@@ -1062,6 +1083,8 @@ static int mdp3_histogram_start(struct mdp3_session_data *session,
	session->histo_status = 1;

histogram_start_err:
	if (ret)
		mdp3_clk_enable(0, 0);
	mutex_unlock(&session->histo_lock);
	return ret;
}
@@ -1085,6 +1108,7 @@ static int mdp3_histogram_stop(struct mdp3_session_data *session,
	}

	ret = session->dma->histo_op(session->dma, MDP3_DMA_HISTO_OP_CANCEL);
	mdp3_clk_enable(0, 0);
	if (ret)
		pr_err("mdp3_histogram_stop error\n");

@@ -1198,7 +1222,9 @@ static int mdp3_csc_config(struct mdp3_session_data *session,
	ccs.post_lv = data->csc_data.csc_post_lv;

	mutex_lock(&session->lock);
	mdp3_clk_enable(1, 0);
	ret = session->dma->config_ccs(session->dma, &config, &ccs);
	mdp3_clk_enable(0, 0);
	mutex_unlock(&session->lock);
	return ret;
}
@@ -1340,8 +1366,10 @@ static int mdp3_ctrl_lut_update(struct msm_fb_data_type *mfd,
		return -EPERM;
	}

	mdp3_clk_enable(1, 0);
	rc = mdp3_session->dma->config_lut(mdp3_session->dma, &lut_config,
					&lut);
	mdp3_clk_enable(0, 0);
	if (rc)
		pr_err("mdp3_ctrl_lut_update failed\n");

+3 −0
Original line number Diff line number Diff line
@@ -828,6 +828,9 @@ static int mdp3_dma_stop(struct mdp3_dma *dma, struct mdp3_intf *intf)
					MDP3_DMA_CALLBACK_TYPE_DMA_DONE);
	mdp3_irq_disable(MDP3_INTR_LCDC_UNDERFLOW);

	MDP3_REG_WRITE(MDP3_REG_INTR_ENABLE, 0);
	MDP3_REG_WRITE(MDP3_REG_INTR_CLEAR, 0xfffffff);

	init_completion(&dma->dma_comp);
	dma->vsync_client.handler = NULL;
	return ret;
+2 −2
Original line number Diff line number Diff line
@@ -370,14 +370,14 @@ int mdp3_ppp_turnon(struct msm_fb_data_type *mfd, int on_off)
		ib = (ab * 3) / 2;
	}
	mdp3_clk_set_rate(MDP3_CLK_CORE, rate, MDP3_CLIENT_PPP);
	rc = mdp3_clk_enable(on_off);
	rc = mdp3_clk_enable(on_off, 0);
	if (rc < 0) {
		pr_err("%s: mdp3_clk_enable failed\n", __func__);
		return rc;
	}
	rc = mdp3_bus_scale_set_quota(MDP3_CLIENT_PPP, ab, ib);
	if (rc < 0) {
		mdp3_clk_enable(!on_off);
		mdp3_clk_enable(!on_off, 0);
		pr_err("%s: scale_set_quota failed\n", __func__);
		return rc;
	}