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

Commit 2dd6ff60 authored by Padmanabhan Komanduru's avatar Padmanabhan Komanduru Committed by Gerrit - the friendly Code Review server
Browse files

drm: msm: dsi-staging: add support for additional display clocks



DSI controller v2.0 requires configuring an additional clock
called the byte interface clock which is needed to drive high
speed PPI signals. Also, there is an extra core clock called
MNOC AHB clock which is needed on msm8998. Add support for these
clocks.

CRs-Fixed: 2008002
Change-Id: Icc5526f3ee99ee796b040a7bfa5a5340a24488b1
Signed-off-by: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
Signed-off-by: default avatarShashank Babu Chinta Venkata <sbchin@codeaurora.org>
parent 56611efa
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ enum dsi_link_clk_type {
	DSI_LINK_ESC_CLK,
	DSI_LINK_BYTE_CLK,
	DSI_LINK_PIX_CLK,
	DSI_LINK_BYTE_INTF_CLK,
	DSI_LINK_CLK_MAX,
};

@@ -65,12 +66,14 @@ struct clk_ctrl_cb {
 * @iface_clk:           Handle to MDP interface clock.
 * @core_mmss_clk:       Handle to MMSS core clock.
 * @bus_clk:             Handle to bus clock.
 * @mnoc_clk:            Handle to MMSS NOC clock.
 */
struct dsi_core_clk_info {
	struct clk *mdp_core_clk;
	struct clk *iface_clk;
	struct clk *core_mmss_clk;
	struct clk *bus_clk;
	struct clk *mnoc_clk;
};

/**
@@ -78,11 +81,13 @@ struct dsi_core_clk_info {
 * @byte_clk:        Handle to DSI byte clock.
 * @pixel_clk:       Handle to DSI pixel clock.
 * @esc_clk:         Handle to DSI escape clock.
 * @byte_intf_clk:   Handle to DSI byte intf. clock.
 */
struct dsi_link_clk_info {
	struct clk *byte_clk;
	struct clk *pixel_clk;
	struct clk *esc_clk;
	struct clk *byte_intf_clk;
};

/**
+55 −1
Original line number Diff line number Diff line
@@ -167,10 +167,18 @@ int dsi_core_clk_start(struct dsi_core_clks *c_clks)
		goto error;
	}

	if (c_clks->clks.mnoc_clk) {
		rc = clk_prepare_enable(c_clks->clks.mnoc_clk);
		if (rc) {
			pr_err("failed to enable mnoc_clk, rc=%d\n", rc);
			goto error_disable_core_clk;
		}
	}

	rc = clk_prepare_enable(c_clks->clks.iface_clk);
	if (rc) {
		pr_err("failed to enable iface_clk, rc=%d\n", rc);
		goto error_disable_core_clk;
		goto error_disable_mnoc_clk;
	}

	rc = clk_prepare_enable(c_clks->clks.bus_clk);
@@ -199,6 +207,9 @@ int dsi_core_clk_start(struct dsi_core_clks *c_clks)
	clk_disable_unprepare(c_clks->clks.bus_clk);
error_disable_iface_clk:
	clk_disable_unprepare(c_clks->clks.iface_clk);
error_disable_mnoc_clk:
	if (c_clks->clks.mnoc_clk)
		clk_disable_unprepare(c_clks->clks.mnoc_clk);
error_disable_core_clk:
	clk_disable_unprepare(c_clks->clks.mdp_core_clk);
error:
@@ -212,6 +223,8 @@ int dsi_core_clk_stop(struct dsi_core_clks *c_clks)
	clk_disable_unprepare(c_clks->clks.core_mmss_clk);
	clk_disable_unprepare(c_clks->clks.bus_clk);
	clk_disable_unprepare(c_clks->clks.iface_clk);
	if (c_clks->clks.mnoc_clk)
		clk_disable_unprepare(c_clks->clks.mnoc_clk);
	clk_disable_unprepare(c_clks->clks.mdp_core_clk);

	return 0;
@@ -238,6 +251,21 @@ static int dsi_link_clk_set_rate(struct dsi_link_clks *l_clks)
		pr_err("clk_set_rate failed for pixel_clk rc = %d\n", rc);
		goto error;
	}

	/*
	 * If byte_intf_clk is present, set rate for that too.
	 * For DPHY: byte_intf_clk_rate = byte_clk_rate / 2
	 * todo: this needs to be revisited when support for CPHY is added
	 */
	if (l_clks->clks.byte_intf_clk) {
		rc = clk_set_rate(l_clks->clks.byte_intf_clk,
			(l_clks->freq.byte_clk_rate / 2));
		if (rc) {
			pr_err("set_rate failed for byte_intf_clk rc = %d\n",
				rc);
			goto error;
		}
	}
error:
	return rc;
}
@@ -264,8 +292,19 @@ static int dsi_link_clk_prepare(struct dsi_link_clks *l_clks)
		goto pixel_clk_err;
	}

	if (l_clks->clks.byte_intf_clk) {
		rc = clk_prepare(l_clks->clks.byte_intf_clk);
		if (rc) {
			pr_err("Failed to prepare dsi byte intf clk, rc=%d\n",
				rc);
			goto byte_intf_clk_err;
		}
	}

	return rc;

byte_intf_clk_err:
	clk_unprepare(l_clks->clks.pixel_clk);
pixel_clk_err:
	clk_unprepare(l_clks->clks.byte_clk);
byte_clk_err:
@@ -276,6 +315,8 @@ static int dsi_link_clk_prepare(struct dsi_link_clks *l_clks)

static void dsi_link_clk_unprepare(struct dsi_link_clks *l_clks)
{
	if (l_clks->clks.byte_intf_clk)
		clk_unprepare(l_clks->clks.byte_intf_clk);
	clk_unprepare(l_clks->clks.pixel_clk);
	clk_unprepare(l_clks->clks.byte_clk);
	clk_unprepare(l_clks->clks.esc_clk);
@@ -303,8 +344,19 @@ static int dsi_link_clk_enable(struct dsi_link_clks *l_clks)
		goto pixel_clk_err;
	}

	if (l_clks->clks.byte_intf_clk) {
		rc = clk_enable(l_clks->clks.byte_intf_clk);
		if (rc) {
			pr_err("Failed to enable dsi byte intf clk, rc=%d\n",
				rc);
			goto byte_intf_clk_err;
		}
	}

	return rc;

byte_intf_clk_err:
	clk_disable(l_clks->clks.pixel_clk);
pixel_clk_err:
	clk_disable(l_clks->clks.byte_clk);
byte_clk_err:
@@ -315,6 +367,8 @@ static int dsi_link_clk_enable(struct dsi_link_clks *l_clks)

static void dsi_link_clk_disable(struct dsi_link_clks *l_clks)
{
	if (l_clks->clks.byte_intf_clk)
		clk_disable(l_clks->clks.byte_intf_clk);
	clk_disable(l_clks->clks.esc_clk);
	clk_disable(l_clks->clks.pixel_clk);
	clk_disable(l_clks->clks.byte_clk);
+16 −0
Original line number Diff line number Diff line
@@ -454,6 +454,8 @@ static int dsi_ctrl_clocks_deinit(struct dsi_ctrl *ctrl)
		devm_clk_put(&ctrl->pdev->dev, core->core_mmss_clk);
	if (core->bus_clk)
		devm_clk_put(&ctrl->pdev->dev, core->bus_clk);
	if (core->mnoc_clk)
		devm_clk_put(&ctrl->pdev->dev, core->mnoc_clk);

	memset(core, 0x0, sizeof(*core));

@@ -463,6 +465,8 @@ static int dsi_ctrl_clocks_deinit(struct dsi_ctrl *ctrl)
		devm_clk_put(&ctrl->pdev->dev, link->pixel_clk);
	if (link->esc_clk)
		devm_clk_put(&ctrl->pdev->dev, link->esc_clk);
	if (link->byte_intf_clk)
		devm_clk_put(&ctrl->pdev->dev, link->byte_intf_clk);

	memset(link, 0x0, sizeof(*link));

@@ -512,6 +516,12 @@ static int dsi_ctrl_clocks_init(struct platform_device *pdev,
		goto fail;
	}

	core->mnoc_clk = devm_clk_get(&pdev->dev, "mnoc_clk");
	if (IS_ERR(core->mnoc_clk)) {
		core->mnoc_clk = NULL;
		pr_debug("can't get mnoc clock, rc=%d\n", rc);
	}

	link->byte_clk = devm_clk_get(&pdev->dev, "byte_clk");
	if (IS_ERR(link->byte_clk)) {
		rc = PTR_ERR(link->byte_clk);
@@ -533,6 +543,12 @@ static int dsi_ctrl_clocks_init(struct platform_device *pdev,
		goto fail;
	}

	link->byte_intf_clk = devm_clk_get(&pdev->dev, "byte_intf_clk");
	if (IS_ERR(link->byte_intf_clk)) {
		link->byte_intf_clk = NULL;
		pr_debug("can't find byte intf clk, rc=%d\n", rc);
	}

	rcg->byte_clk = devm_clk_get(&pdev->dev, "byte_clk_rcg");
	if (IS_ERR(rcg->byte_clk)) {
		rc = PTR_ERR(rcg->byte_clk);