All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Cleanup excessive DSI host controller version checks
@ 2018-03-12 13:23 Sibi S
  2018-03-12 13:23 ` [PATCH 1/5] drm/msm/dsi: add dsi host helper functions support Sibi S
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Sibi S @ 2018-03-12 13:23 UTC (permalink / raw)
  To: architt, robdclark; +Cc: linux-arm-msm, freedreno, Sibi S, dri-devel

This patch series aims to create and bind dsi host controller helper
functions to functionalities that vary across DSI v2, DSI 6G 1.x and
DSI 6G v2.0+ controllers. These functionalities are currently under
excessive version checks which is now replaced with the corresponding
helper function.

This patch series includes Archit's patch (4/5) which implements
command broadcast support for DSI 6G v2.0+ controller on SDM845.

The helper functions can later be moved to separate files for each
DSI controller on the event of addition of more functionality that
vary across the DSI controllers.

Archit Taneja (1):
  drm/msm/dsi: implement 6G v2.0+ DSI command broadcast

Sibi S (4):
  drm/msm/dsi: add dsi host helper functions support
  drm/msm/dsi: add implementation for helper functions
  drm/msm/dsi: replace version checks with helper functions
  drm/msm/dsi: replace version checks for commmand broadcast

 drivers/gpu/drm/msm/dsi/dsi.h         |  21 ++
 drivers/gpu/drm/msm/dsi/dsi_cfg.c     |  62 ++++-
 drivers/gpu/drm/msm/dsi/dsi_cfg.h     |  14 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c    | 428 +++++++++++++++++++++-------------
 drivers/gpu/drm/msm/dsi/dsi_manager.c |  66 ++++++
 5 files changed, 422 insertions(+), 169 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/5] drm/msm/dsi: add dsi host helper functions support
  2018-03-12 13:23 [PATCH 0/5] Cleanup excessive DSI host controller version checks Sibi S
@ 2018-03-12 13:23 ` Sibi S
  2018-03-12 13:23 ` [PATCH 2/5] drm/msm/dsi: add implementation for helper functions Sibi S
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Sibi S @ 2018-03-12 13:23 UTC (permalink / raw)
  To: architt, robdclark; +Cc: linux-arm-msm, freedreno, Sibi S, dri-devel

Add dsi host helper functions support for DSI v2 and DSI 6G 1.x
controllers that are under version checks

Signed-off-by: Sibi S <sibis@codeaurora.org>
---
 drivers/gpu/drm/msm/dsi/dsi.h     |  1 +
 drivers/gpu/drm/msm/dsi/dsi_cfg.h | 12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 70d9a9a..80be83e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -149,6 +149,7 @@ static inline int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
 #endif
 
 /* dsi host */
+struct msm_dsi_host;
 int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
 					const struct mipi_dsi_msg *msg);
 void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index 9cfdcf1..a795a06 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -40,10 +40,22 @@ struct msm_dsi_config {
 	const int num_dsi;
 };
 
+struct msm_dsi_host_cfg_ops {
+	int (*link_clk_enable)(struct msm_dsi_host *msm_host);
+	void (*link_clk_disable)(struct msm_dsi_host *msm_host);
+	int (*clk_init_ver)(struct msm_dsi_host *msm_host);
+	int (*tx_buf_alloc)(struct msm_dsi_host *msm_host, int size);
+	void* (*tx_buf_get)(struct msm_dsi_host *msm_host);
+	void (*tx_buf_put)(struct msm_dsi_host *msm_host);
+	int (*dma_base_get)(struct msm_dsi_host *msm_host, uint64_t *iova);
+	int (*calc_clk_rate)(struct msm_dsi_host *msm_host);
+};
+
 struct msm_dsi_cfg_handler {
 	u32 major;
 	u32 minor;
 	const struct msm_dsi_config *cfg;
+	const struct msm_dsi_host_cfg_ops *ops;
 };
 
 const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/5] drm/msm/dsi: add implementation for helper functions
  2018-03-12 13:23 [PATCH 0/5] Cleanup excessive DSI host controller version checks Sibi S
  2018-03-12 13:23 ` [PATCH 1/5] drm/msm/dsi: add dsi host helper functions support Sibi S
@ 2018-03-12 13:23 ` Sibi S
       [not found]   ` <1520860994-23334-3-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-03-12 13:23 ` [PATCH 3/5] drm/msm/dsi: replace version checks with " Sibi S
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Sibi S @ 2018-03-12 13:23 UTC (permalink / raw)
  To: architt, robdclark; +Cc: linux-arm-msm, freedreno, Sibi S, dri-devel

Add dsi host helper function implementation for DSI v2
and DSI 6G 1.x controllers

Signed-off-by: Sibi S <sibis@codeaurora.org>
---
 drivers/gpu/drm/msm/dsi/dsi.h      |  15 +++
 drivers/gpu/drm/msm/dsi/dsi_cfg.c  |  44 +++++--
 drivers/gpu/drm/msm/dsi/dsi_host.c | 250 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 298 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 80be83e..dfa049d 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -183,6 +183,21 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
 int msm_dsi_host_init(struct msm_dsi *msm_dsi);
 int msm_dsi_runtime_suspend(struct device *dev);
 int msm_dsi_runtime_resume(struct device *dev);
+int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
+int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
+void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
+void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
+int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
+int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
+void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
+void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host);
+void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host);
+int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova);
+int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
+int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
+int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host);
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host);
 
 /* dsi phy */
 struct msm_dsi_phy;
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 0327bb5..dc51aaa 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -136,20 +136,46 @@
 	.num_dsi = 2,
 };
 
+const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
+	.link_clk_enable = dsi_link_clk_enable_v2,
+	.link_clk_disable = dsi_link_clk_disable_v2,
+	.clk_init_ver = dsi_clk_init_v2,
+	.tx_buf_alloc = dsi_tx_buf_alloc_v2,
+	.tx_buf_get = dsi_tx_buf_get_v2,
+	.tx_buf_put = NULL,
+	.dma_base_get = dsi_dma_base_get_v2,
+	.calc_clk_rate = dsi_calc_clk_rate_v2,
+};
+
+const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
+	.link_clk_enable = dsi_link_clk_enable_6g,
+	.link_clk_disable = dsi_link_clk_disable_6g,
+	.clk_init_ver = NULL,
+	.tx_buf_alloc = dsi_tx_buf_alloc_6g,
+	.tx_buf_get = dsi_tx_buf_get_6g,
+	.tx_buf_put = dsi_tx_buf_put_6g,
+	.dma_base_get = dsi_dma_base_get_6g,
+	.calc_clk_rate = dsi_calc_clk_rate_6g,
+};
 static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
-	{MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064, &apq8064_dsi_cfg},
+	{MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064,
+		&apq8064_dsi_cfg, &msm_dsi_v2_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0,
-						&msm8974_apq8084_dsi_cfg},
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1,
-						&msm8974_apq8084_dsi_cfg},
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1_1,
-						&msm8974_apq8084_dsi_cfg},
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_2,
-						&msm8974_apq8084_dsi_cfg},
-	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3, &msm8994_dsi_cfg},
-	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1, &msm8916_dsi_cfg},
-	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1, &msm8996_dsi_cfg},
-	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1, &sdm845_dsi_cfg},
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3,
+		&msm8994_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1,
+		&msm8916_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
+		&msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
+		&sdm845_dsi_cfg, &msm_dsi_6g_host_ops},
 };
 
 const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7a03a94..f7a066d 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -331,6 +331,54 @@ static int dsi_regulator_init(struct msm_dsi_host *msm_host)
 	return 0;
 }
 
+int dsi_clk_init_v2(struct msm_dsi_host *msm_host)
+{
+	struct platform_device *pdev = msm_host->pdev;
+	int ret = 0;
+
+	msm_host->src_clk = msm_clk_get(pdev, "src");
+
+	if (IS_ERR(msm_host->src_clk)) {
+		ret = PTR_ERR(msm_host->src_clk);
+		pr_err("%s: can't find src clock. ret=%d\n",
+			__func__, ret);
+		msm_host->src_clk = NULL;
+		return ret;
+	}
+
+	msm_host->esc_clk_src = clk_get_parent(msm_host->esc_clk);
+	if (!msm_host->esc_clk_src) {
+		ret = -ENODEV;
+		pr_err("%s: can't get esc clock parent. ret=%d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	msm_host->dsi_clk_src = clk_get_parent(msm_host->src_clk);
+	if (!msm_host->dsi_clk_src) {
+		ret = -ENODEV;
+		pr_err("%s: can't get src clock parent. ret=%d\n",
+			__func__, ret);
+	}
+
+	return ret;
+}
+
+int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host)
+{
+	struct platform_device *pdev = msm_host->pdev;
+	int ret = 0;
+
+	msm_host->byte_intf_clk = msm_clk_get(pdev, "byte_intf");
+	if (IS_ERR(msm_host->byte_intf_clk)) {
+		ret = PTR_ERR(msm_host->byte_intf_clk);
+		pr_err("%s: can't find byte_intf clock. ret=%d\n",
+			__func__, ret);
+	}
+
+	return ret;
+}
+
 static int dsi_clk_init(struct msm_dsi_host *msm_host)
 {
 	struct platform_device *pdev = msm_host->pdev;
@@ -497,7 +545,7 @@ int msm_dsi_runtime_resume(struct device *dev)
 	return dsi_bus_clk_enable(msm_host);
 }
 
-static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
+int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
 {
 	int ret;
 
@@ -565,7 +613,7 @@ static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
 	return ret;
 }
 
-static int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
+int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
 {
 	int ret;
 
@@ -643,6 +691,23 @@ static int dsi_link_clk_enable(struct msm_dsi_host *msm_host)
 		return dsi_link_clk_enable_v2(msm_host);
 }
 
+void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
+{
+	clk_disable_unprepare(msm_host->esc_clk);
+	clk_disable_unprepare(msm_host->pixel_clk);
+	if (msm_host->byte_intf_clk)
+		clk_disable_unprepare(msm_host->byte_intf_clk);
+	clk_disable_unprepare(msm_host->byte_clk);
+}
+
+void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
+{
+	clk_disable_unprepare(msm_host->pixel_clk);
+	clk_disable_unprepare(msm_host->src_clk);
+	clk_disable_unprepare(msm_host->esc_clk);
+	clk_disable_unprepare(msm_host->byte_clk);
+}
+
 static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
 {
 	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
@@ -661,6 +726,94 @@ static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
 	}
 }
 
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
+{
+	struct drm_display_mode *mode = msm_host->mode;
+	u8 lanes = msm_host->lanes;
+	u32 bpp = dsi_get_bpp(msm_host->format);
+	u32 pclk_rate;
+
+	if (!mode) {
+		pr_err("%s: mode not set\n", __func__);
+		return -EINVAL;
+	}
+
+	pclk_rate = mode->clock * 1000;
+	if (lanes > 0) {
+		msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
+	} else {
+		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
+		msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
+	}
+
+	DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
+
+	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
+
+	return 0;
+}
+
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
+{
+	struct drm_display_mode *mode = msm_host->mode;
+	u8 lanes = msm_host->lanes;
+	u32 bpp = dsi_get_bpp(msm_host->format);
+	u32 pclk_rate;
+	unsigned int esc_mhz, esc_div;
+	unsigned long byte_mhz;
+
+	if (!mode) {
+		pr_err("%s: mode not set\n", __func__);
+		return -EINVAL;
+	}
+
+	pclk_rate = mode->clock * 1000;
+	if (lanes > 0) {
+		msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
+	} else {
+		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
+		msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
+	}
+
+	DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
+
+	msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
+
+	/*
+	 * esc clock is byte clock followed by a 4 bit divider,
+	 * we need to find an escape clock frequency within the
+	 * mipi DSI spec range within the maximum divider limit
+	 * We iterate here between an escape clock frequencey
+	 * between 20 Mhz to 5 Mhz and pick up the first one
+	 * that can be supported by our divider
+	 */
+
+	byte_mhz = msm_host->byte_clk_rate / 1000000;
+
+	for (esc_mhz = 20; esc_mhz >= 5; esc_mhz--) {
+		esc_div = DIV_ROUND_UP(byte_mhz, esc_mhz);
+
+		/*
+		 * TODO: Ideally, we shouldn't know what sort of divider
+		 * is available in mmss_cc, we're just assuming that
+		 * it'll always be a 4 bit divider. Need to come up with
+		 * a better way here.
+		 */
+		if (esc_div >= 1 && esc_div <= 16)
+			break;
+	}
+
+	if (esc_mhz < 5)
+		return -EINVAL;
+
+	msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
+
+	DBG("esc=%d, src=%d", msm_host->esc_clk_rate,
+		msm_host->src_clk_rate);
+
+	return 0;
+}
+
 static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
 {
 	struct drm_display_mode *mode = msm_host->mode;
@@ -1008,6 +1161,59 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
 	}
 }
 
+int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
+{
+	struct drm_device *dev = msm_host->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	int ret;
+	uint64_t iova;
+
+	msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
+	if (IS_ERR(msm_host->tx_gem_obj)) {
+		ret = PTR_ERR(msm_host->tx_gem_obj);
+		pr_err("%s: failed to allocate gem, %d\n",
+			__func__, ret);
+		msm_host->tx_gem_obj = NULL;
+		return ret;
+	}
+
+	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
+			priv->kms->aspace, &iova);
+	mutex_unlock(&dev->struct_mutex);
+	if (ret) {
+		pr_err("%s: failed to get iova, %d\n", __func__, ret);
+		return ret;
+	}
+
+	if (iova & 0x07) {
+		pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
+		return -EINVAL;
+	}
+
+	msm_host->tx_size = msm_host->tx_gem_obj->size;
+
+	return 0;
+}
+
+int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
+{
+	struct drm_device *dev = msm_host->dev;
+	int ret;
+
+	msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
+					&msm_host->tx_buf_paddr, GFP_KERNEL);
+	if (!msm_host->tx_buf) {
+		ret = -ENOMEM;
+		pr_err("%s: failed to allocate tx buf, %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	msm_host->tx_size = size;
+
+	return 0;
+}
+
 /* dsi_cmd */
 static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
 {
@@ -1072,6 +1278,21 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
 			msm_host->tx_buf_paddr);
 }
 
+void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host)
+{
+	return msm_gem_get_vaddr(msm_host->tx_gem_obj);
+}
+
+void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host)
+{
+	return msm_host->tx_buf;
+}
+
+void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host)
+{
+	msm_gem_put_vaddr(msm_host->tx_gem_obj);
+}
+
 /*
  * prepare cmd buffer to be txed
  */
@@ -1173,6 +1394,31 @@ static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg)
 	return msg->rx_len;
 }
 
+int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *dma_base)
+{
+	struct drm_device *dev = msm_host->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	uint64_t **iova;
+	int ret;
+
+	if (!dma_base)
+		return -EINVAL;
+
+	iova = &dma_base;
+	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
+				priv->kms->aspace, *iova);
+	return ret;
+}
+
+int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *dma_base)
+{
+	if (!dma_base)
+		return -EINVAL;
+
+	*dma_base = msm_host->tx_buf_paddr;
+	return 0;
+}
+
 static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
 {
 	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/5] drm/msm/dsi: replace version checks with helper functions
  2018-03-12 13:23 [PATCH 0/5] Cleanup excessive DSI host controller version checks Sibi S
  2018-03-12 13:23 ` [PATCH 1/5] drm/msm/dsi: add dsi host helper functions support Sibi S
  2018-03-12 13:23 ` [PATCH 2/5] drm/msm/dsi: add implementation for helper functions Sibi S
@ 2018-03-12 13:23 ` Sibi S
       [not found]   ` <1520860994-23334-4-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-03-12 13:23 ` [PATCH 4/5] drm/msm/dsi: implement 6G v2.0+ DSI command broadcast Sibi S
  2018-03-12 13:23 ` [PATCH 5/5] drm/msm/dsi: replace version checks for commmand broadcast Sibi S
  4 siblings, 1 reply; 12+ messages in thread
From: Sibi S @ 2018-03-12 13:23 UTC (permalink / raw)
  To: architt, robdclark; +Cc: linux-arm-msm, freedreno, Sibi S, dri-devel

Replace version checks with the helper functions bound to
cfg_handler for DSI v2 and DSI 6G 1.x controllers

Signed-off-by: Sibi S <sibis@codeaurora.org>
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 242 +++++--------------------------------
 1 file changed, 29 insertions(+), 213 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index f7a066d..b755b69 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -426,19 +426,6 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host)
 		goto exit;
 	}
 
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G &&
-	    cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V2_2_1) {
-		msm_host->byte_intf_clk = msm_clk_get(pdev, "byte_intf");
-		if (IS_ERR(msm_host->byte_intf_clk)) {
-			ret = PTR_ERR(msm_host->byte_intf_clk);
-			pr_err("%s: can't find byte_intf clock. ret=%d\n",
-			        __func__, ret);
-			goto exit;
-		}
-	} else {
-		msm_host->byte_intf_clk = NULL;
-	}
-
 	msm_host->byte_clk_src = clk_get_parent(msm_host->byte_clk);
 	if (!msm_host->byte_clk_src) {
 		ret = -ENODEV;
@@ -453,31 +440,8 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host)
 		goto exit;
 	}
 
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_V2) {
-		msm_host->src_clk = msm_clk_get(pdev, "src");
-		if (IS_ERR(msm_host->src_clk)) {
-			ret = PTR_ERR(msm_host->src_clk);
-			pr_err("%s: can't find src clock. ret=%d\n",
-				__func__, ret);
-			msm_host->src_clk = NULL;
-			goto exit;
-		}
-
-		msm_host->esc_clk_src = clk_get_parent(msm_host->esc_clk);
-		if (!msm_host->esc_clk_src) {
-			ret = -ENODEV;
-			pr_err("%s: can't get esc clock parent. ret=%d\n",
-				__func__, ret);
-			goto exit;
-		}
-
-		msm_host->dsi_clk_src = clk_get_parent(msm_host->src_clk);
-		if (!msm_host->dsi_clk_src) {
-			ret = -ENODEV;
-			pr_err("%s: can't get src clock parent. ret=%d\n",
-				__func__, ret);
-		}
-	}
+	if (cfg_hnd->ops->clk_init_ver)
+		ret = cfg_hnd->ops->clk_init_ver(msm_host);
 exit:
 	return ret;
 }
@@ -681,16 +645,6 @@ int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
 	return ret;
 }
 
-static int dsi_link_clk_enable(struct msm_dsi_host *msm_host)
-{
-	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G)
-		return dsi_link_clk_enable_6g(msm_host);
-	else
-		return dsi_link_clk_enable_v2(msm_host);
-}
-
 void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
 {
 	clk_disable_unprepare(msm_host->esc_clk);
@@ -708,24 +662,6 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
 	clk_disable_unprepare(msm_host->byte_clk);
 }
 
-static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
-{
-	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
-		clk_disable_unprepare(msm_host->esc_clk);
-		clk_disable_unprepare(msm_host->pixel_clk);
-		if (msm_host->byte_intf_clk)
-			clk_disable_unprepare(msm_host->byte_intf_clk);
-		clk_disable_unprepare(msm_host->byte_clk);
-	} else {
-		clk_disable_unprepare(msm_host->pixel_clk);
-		clk_disable_unprepare(msm_host->src_clk);
-		clk_disable_unprepare(msm_host->esc_clk);
-		clk_disable_unprepare(msm_host->byte_clk);
-	}
-}
-
 int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
 {
 	struct drm_display_mode *mode = msm_host->mode;
@@ -814,73 +750,6 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
 	return 0;
 }
 
-static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
-{
-	struct drm_display_mode *mode = msm_host->mode;
-	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-	u8 lanes = msm_host->lanes;
-	u32 bpp = dsi_get_bpp(msm_host->format);
-	u32 pclk_rate;
-
-	if (!mode) {
-		pr_err("%s: mode not set\n", __func__);
-		return -EINVAL;
-	}
-
-	pclk_rate = mode->clock * 1000;
-	if (lanes > 0) {
-		msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
-	} else {
-		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
-		msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
-	}
-
-	DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
-
-	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
-
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_V2) {
-		unsigned int esc_mhz, esc_div;
-		unsigned long byte_mhz;
-
-		msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
-
-		/*
-		 * esc clock is byte clock followed by a 4 bit divider,
-		 * we need to find an escape clock frequency within the
-		 * mipi DSI spec range within the maximum divider limit
-		 * We iterate here between an escape clock frequencey
-		 * between 20 Mhz to 5 Mhz and pick up the first one
-		 * that can be supported by our divider
-		 */
-
-		byte_mhz = msm_host->byte_clk_rate / 1000000;
-
-		for (esc_mhz = 20; esc_mhz >= 5; esc_mhz--) {
-			esc_div = DIV_ROUND_UP(byte_mhz, esc_mhz);
-
-			/*
-			 * TODO: Ideally, we shouldn't know what sort of divider
-			 * is available in mmss_cc, we're just assuming that
-			 * it'll always be a 4 bit divider. Need to come up with
-			 * a better way here.
-			 */
-			if (esc_div >= 1 && esc_div <= 16)
-				break;
-		}
-
-		if (esc_mhz < 5)
-			return -EINVAL;
-
-		msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
-
-		DBG("esc=%d, src=%d", msm_host->esc_clk_rate,
-			msm_host->src_clk_rate);
-	}
-
-	return 0;
-}
-
 static void dsi_intr_ctrl(struct msm_dsi_host *msm_host, u32 mask, int enable)
 {
 	u32 intr;
@@ -1214,55 +1083,6 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
 	return 0;
 }
 
-/* dsi_cmd */
-static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
-{
-	struct drm_device *dev = msm_host->dev;
-	struct msm_drm_private *priv = dev->dev_private;
-	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-	int ret;
-	uint64_t iova;
-
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
-		msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
-		if (IS_ERR(msm_host->tx_gem_obj)) {
-			ret = PTR_ERR(msm_host->tx_gem_obj);
-			pr_err("%s: failed to allocate gem, %d\n",
-				__func__, ret);
-			msm_host->tx_gem_obj = NULL;
-			return ret;
-		}
-
-		ret = msm_gem_get_iova(msm_host->tx_gem_obj,
-				priv->kms->aspace, &iova);
-		mutex_unlock(&dev->struct_mutex);
-		if (ret) {
-			pr_err("%s: failed to get iova, %d\n", __func__, ret);
-			return ret;
-		}
-
-		if (iova & 0x07) {
-			pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
-			return -EINVAL;
-		}
-
-		msm_host->tx_size = msm_host->tx_gem_obj->size;
-	} else {
-		msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
-					&msm_host->tx_buf_paddr, GFP_KERNEL);
-		if (!msm_host->tx_buf) {
-			ret = -ENOMEM;
-			pr_err("%s: failed to allocate tx buf, %d\n",
-				__func__, ret);
-			return ret;
-		}
-
-		msm_host->tx_size = size;
-	}
-
-	return 0;
-}
-
 static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
 {
 	struct drm_device *dev = msm_host->dev;
@@ -1317,15 +1137,11 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host,
 		return -EINVAL;
 	}
 
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
-		data = msm_gem_get_vaddr(msm_host->tx_gem_obj);
-		if (IS_ERR(data)) {
-			ret = PTR_ERR(data);
-			pr_err("%s: get vaddr failed, %d\n", __func__, ret);
-			return ret;
-		}
-	} else {
-		data = msm_host->tx_buf;
+	data = cfg_hnd->ops->tx_buf_get(msm_host);
+	if (IS_ERR(data)) {
+		ret = PTR_ERR(data);
+		pr_err("%s: get vaddr failed, %d\n", __func__, ret);
+		return ret;
 	}
 
 	/* MSM specific command format in memory */
@@ -1346,8 +1162,8 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host,
 	if (packet.size < len)
 		memset(data + packet.size, 0xff, len - packet.size);
 
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G)
-		msm_gem_put_vaddr(msm_host->tx_gem_obj);
+	if (cfg_hnd->ops->tx_buf_put)
+		cfg_hnd->ops->tx_buf_put(msm_host);
 
 	return len;
 }
@@ -1422,21 +1238,14 @@ int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *dma_base)
 static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
 {
 	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-	struct drm_device *dev = msm_host->dev;
-	struct msm_drm_private *priv = dev->dev_private;
 	int ret;
 	uint64_t dma_base;
 	bool triggered;
 
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
-		ret = msm_gem_get_iova(msm_host->tx_gem_obj,
-				priv->kms->aspace, &dma_base);
-		if (ret) {
-			pr_err("%s: failed to get iova: %d\n", __func__, ret);
-			return ret;
-		}
-	} else {
-		dma_base = msm_host->tx_buf_paddr;
+	ret = cfg_hnd->ops->dma_base_get(msm_host, &dma_base);
+	if (ret) {
+		pr_err("%s: failed to get iova: %d\n", __func__, ret);
+		return ret;
 	}
 
 	reinit_completion(&msm_host->dma_comp);
@@ -2074,6 +1883,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
 					struct drm_device *dev)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 	struct platform_device *pdev = msm_host->pdev;
 	int ret;
 
@@ -2094,7 +1904,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
 	}
 
 	msm_host->dev = dev;
-	ret = dsi_tx_buf_alloc(msm_host, SZ_4K);
+	ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
 	if (ret) {
 		pr_err("%s: alloc tx gem obj failed, %d\n", __func__, ret);
 		return ret;
@@ -2152,6 +1962,7 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
 				const struct mipi_dsi_msg *msg)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 
 	/* TODO: make sure dsi_cmd_mdp is idle.
 	 * Since DSI6G v1.2.0, we can set DSI_TRIG_CTRL.BLOCK_DMA_WITHIN_FRAME
@@ -2164,7 +1975,7 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
 	 * mdp clock need to be enabled to receive dsi interrupt
 	 */
 	pm_runtime_get_sync(&msm_host->pdev->dev);
-	dsi_link_clk_enable(msm_host);
+	cfg_hnd->ops->link_clk_enable(msm_host);
 
 	/* TODO: vote for bus bandwidth */
 
@@ -2185,6 +1996,7 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
 				const struct mipi_dsi_msg *msg)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 
 	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_DMA_DONE, 0);
 	dsi_write(msm_host, REG_DSI_CTRL, msm_host->dma_cmd_ctrl_restore);
@@ -2194,7 +2006,7 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
 
 	/* TODO: unvote for bus bandwidth */
 
-	dsi_link_clk_disable(msm_host);
+	cfg_hnd->ops->link_clk_disable(msm_host);
 	pm_runtime_put_autosuspend(&msm_host->pdev->dev);
 }
 
@@ -2358,7 +2170,6 @@ int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
 	struct msm_dsi_pll *src_pll)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
-	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 	struct clk *byte_clk_provider, *pixel_clk_provider;
 	int ret;
 
@@ -2384,14 +2195,16 @@ int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
 		goto exit;
 	}
 
-	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_V2) {
+	if (msm_host->dsi_clk_src) {
 		ret = clk_set_parent(msm_host->dsi_clk_src, pixel_clk_provider);
 		if (ret) {
 			pr_err("%s: can't set parent to dsi_clk_src. ret=%d\n",
 				__func__, ret);
 			goto exit;
 		}
+	}
 
+	if (msm_host->esc_clk_src) {
 		ret = clk_set_parent(msm_host->esc_clk_src, byte_clk_provider);
 		if (ret) {
 			pr_err("%s: can't set parent to esc_clk_src. ret=%d\n",
@@ -2421,9 +2234,10 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
 	struct msm_dsi_phy_clk_request *clk_req)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 	int ret;
 
-	ret = dsi_calc_clk_rate(msm_host);
+	ret = cfg_hnd->ops->calc_clk_rate(msm_host);
 	if (ret) {
 		pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
 		return;
@@ -2487,6 +2301,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
 			struct msm_dsi_phy_shared_timings *phy_shared_timings)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 	int ret = 0;
 
 	mutex_lock(&msm_host->dev_mutex);
@@ -2505,7 +2320,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
 	}
 
 	pm_runtime_get_sync(&msm_host->pdev->dev);
-	ret = dsi_link_clk_enable(msm_host);
+	ret = cfg_hnd->ops->link_clk_enable(msm_host);
 	if (ret) {
 		pr_err("%s: failed to enable link clocks. ret=%d\n",
 		       __func__, ret);
@@ -2532,7 +2347,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
 	return 0;
 
 fail_disable_clk:
-	dsi_link_clk_disable(msm_host);
+	cfg_hnd->ops->link_clk_disable(msm_host);
 	pm_runtime_put_autosuspend(&msm_host->pdev->dev);
 fail_disable_reg:
 	dsi_host_regulator_disable(msm_host);
@@ -2544,6 +2359,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
 int msm_dsi_host_power_off(struct mipi_dsi_host *host)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 
 	mutex_lock(&msm_host->dev_mutex);
 	if (!msm_host->power_on) {
@@ -2558,7 +2374,7 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
 
 	pinctrl_pm_select_sleep_state(&msm_host->pdev->dev);
 
-	dsi_link_clk_disable(msm_host);
+	cfg_hnd->ops->link_clk_disable(msm_host);
 	pm_runtime_put_autosuspend(&msm_host->pdev->dev);
 
 	dsi_host_regulator_disable(msm_host);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/5] drm/msm/dsi: implement 6G v2.0+ DSI command broadcast
  2018-03-12 13:23 [PATCH 0/5] Cleanup excessive DSI host controller version checks Sibi S
                   ` (2 preceding siblings ...)
  2018-03-12 13:23 ` [PATCH 3/5] drm/msm/dsi: replace version checks with " Sibi S
@ 2018-03-12 13:23 ` Sibi S
       [not found]   ` <1520860994-23334-5-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-03-12 13:23 ` [PATCH 5/5] drm/msm/dsi: replace version checks for commmand broadcast Sibi S
  4 siblings, 1 reply; 12+ messages in thread
From: Sibi S @ 2018-03-12 13:23 UTC (permalink / raw)
  To: architt, robdclark; +Cc: linux-arm-msm, freedreno, Sibi S, dri-devel

From: Archit Taneja <architt@codeaurora.org>

Add command broadcast support for DSI 6G v2.0+ controller
on SDM845

Signed-off-by: Sibi S <sibis@codeaurora.org>
---
 drivers/gpu/drm/msm/dsi/dsi.h         |  5 +++
 drivers/gpu/drm/msm/dsi/dsi_cfg.c     | 14 +++++++-
 drivers/gpu/drm/msm/dsi/dsi_host.c    | 62 ++++++++++++++++++++++++++++++--
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 66 +++++++++++++++++++++++++++++++++++
 4 files changed, 143 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index dfa049d..22342c30 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -96,7 +96,9 @@ struct msm_dsi {
 struct drm_connector *msm_dsi_manager_connector_init(u8 id);
 struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id);
 int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
+int msm_dsi_manager_cmd_xfer_6g_v2(int id, const struct mipi_dsi_msg *msg);
 bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
+bool msm_dsi_manager_cmd_xfer_trigger_6g_v2(int id, u32 dma_base, u32 len);
 void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags);
 int msm_dsi_manager_register(struct msm_dsi *msm_dsi);
 void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi);
@@ -152,6 +154,9 @@ static inline int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
 struct msm_dsi_host;
 int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
 					const struct mipi_dsi_msg *msg);
+int msm_dsi_host_xfer_prepare_6g_v2(struct mipi_dsi_host *host,
+					const struct mipi_dsi_msg *msg,
+					bool broadcast, bool master);
 void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
 					const struct mipi_dsi_msg *msg);
 int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index dc51aaa..dcdfb1b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -157,6 +157,18 @@
 	.dma_base_get = dsi_dma_base_get_6g,
 	.calc_clk_rate = dsi_calc_clk_rate_6g,
 };
+
+const static struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
+	.link_clk_enable = dsi_link_clk_enable_6g,
+	.link_clk_disable = dsi_link_clk_disable_6g,
+	.clk_init_ver = dsi_clk_init_6g_v2,
+	.tx_buf_alloc = dsi_tx_buf_alloc_6g,
+	.tx_buf_get = dsi_tx_buf_get_6g,
+	.tx_buf_put = dsi_tx_buf_put_6g,
+	.dma_base_get = dsi_dma_base_get_6g,
+	.calc_clk_rate = dsi_calc_clk_rate_6g,
+};
+
 static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
 	{MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064,
 		&apq8064_dsi_cfg, &msm_dsi_v2_host_ops},
@@ -175,7 +187,7 @@
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
 		&msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
-		&sdm845_dsi_cfg, &msm_dsi_6g_host_ops},
+		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
 };
 
 const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index b755b69..bd61cad 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1251,9 +1251,14 @@ static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
 	reinit_completion(&msm_host->dma_comp);
 
 	dsi_wait4video_eng_busy(msm_host);
+	if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
+			(cfg_hnd->minor < MSM_DSI_6G_VER_MINOR_V2_2_1))
+		triggered = msm_dsi_manager_cmd_xfer_trigger(msm_host->id,
+								dma_base, len);
+	else
+		triggered = msm_dsi_manager_cmd_xfer_trigger_6g_v2(
+						  msm_host->id, dma_base, len);
 
-	triggered = msm_dsi_manager_cmd_xfer_trigger(
-						msm_host->id, dma_base, len);
 	if (triggered) {
 		ret = wait_for_completion_timeout(&msm_host->dma_comp,
 					msecs_to_jiffies(200));
@@ -1602,13 +1607,21 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
 					const struct mipi_dsi_msg *msg)
 {
 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
 	int ret;
 
 	if (!msg || !msm_host->power_on)
 		return -EINVAL;
 
 	mutex_lock(&msm_host->cmd_mutex);
-	ret = msm_dsi_manager_cmd_xfer(msm_host->id, msg);
+
+	if (((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
+			(cfg_hnd->minor < MSM_DSI_6G_VER_MINOR_V2_2_1)) ||
+			(cfg_hnd->major == MSM_DSI_VER_MAJOR_V2))
+		ret = msm_dsi_manager_cmd_xfer(msm_host->id, msg);
+	else
+		ret = msm_dsi_manager_cmd_xfer_6g_v2(msm_host->id, msg);
+
 	mutex_unlock(&msm_host->cmd_mutex);
 
 	return ret;
@@ -1992,6 +2005,49 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
 	return 0;
 }
 
+static void dsi_host_prepare_broadcast_6g_v2(struct msm_dsi_host *msm_host,
+					     bool broadcast, bool master)
+{
+	u32 val = dsi_read(msm_host, REG_DSI_CMD_DMA_CTRL);
+
+	if (broadcast)
+		val |= BIT(31);
+	else
+		val &= ~BIT(31);
+
+	if (master)
+		val |= BIT(30);
+	else
+		val &= ~BIT(30);
+
+	dsi_write(msm_host, REG_DSI_CMD_DMA_CTRL, val);
+}
+
+int msm_dsi_host_xfer_prepare_6g_v2(struct mipi_dsi_host *host,
+				    const struct mipi_dsi_msg *msg,
+				    bool broadcast, bool master)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	/* TODO: vote for bus bandwidth */
+
+	if (!(msg->flags & MIPI_DSI_MSG_USE_LPM))
+		dsi_set_tx_power_mode(0, msm_host);
+
+	dsi_host_prepare_broadcast_6g_v2(msm_host, broadcast, master);
+
+	msm_host->dma_cmd_ctrl_restore = dsi_read(msm_host, REG_DSI_CTRL);
+	dsi_write(msm_host, REG_DSI_CTRL,
+		msm_host->dma_cmd_ctrl_restore |
+		DSI_CTRL_CMD_MODE_EN |
+		DSI_CTRL_ENABLE);
+
+	if ((broadcast && master) || !broadcast)
+		dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_DMA_DONE, 1);
+
+	return 0;
+}
+
 void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
 				const struct mipi_dsi_msg *msg)
 {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 4cb1cb6..393e3ff 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -812,6 +812,56 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)
 	return ret;
 }
 
+int msm_dsi_manager_cmd_xfer_6g_v2(int id, const struct mipi_dsi_msg *msg)
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	bool is_read = (msg->rx_buf && msg->rx_len);
+	bool need_sync = (IS_SYNC_NEEDED() && !is_read);
+	int ret;
+
+	if (!msg->tx_buf || !msg->tx_len)
+		return 0;
+
+	if (need_sync && (id == DSI_0))
+		return is_read ? msg->rx_len : msg->tx_len;
+
+	if (need_sync && msm_dsi0) {
+		ret = msm_dsi_host_xfer_prepare_6g_v2(msm_dsi0->host, msg,
+						      true, true);
+		if (ret) {
+			pr_err("%s: failed to prepare non-trigger host, %d\n",
+				__func__, ret);
+			return ret;
+		}
+	}
+
+	ret = msm_dsi_host_xfer_prepare_6g_v2(msm_dsi->host, msg,
+					      need_sync ? true : false,
+					      false);
+	if (ret) {
+		pr_err("%s: failed to prepare host, %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	if (need_sync && msm_dsi0) {
+		ret = is_read ? msm_dsi_host_cmd_rx(msm_dsi0->host, msg) :
+				msm_dsi_host_cmd_tx(msm_dsi0->host, msg);
+	} else {
+		ret = is_read ? msm_dsi_host_cmd_rx(msm_dsi->host, msg) :
+				msm_dsi_host_cmd_tx(msm_dsi->host, msg);
+	}
+
+	msm_dsi_host_xfer_restore(host, msg);
+
+	if (need_sync && msm_dsi0)
+		msm_dsi_host_xfer_restore(msm_dsi0->host, msg);
+
+	return ret;
+}
+
 bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
 {
 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
@@ -829,6 +879,22 @@ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
 	return true;
 }
 
+bool msm_dsi_manager_cmd_xfer_trigger_6g_v2(int id, u32 dma_base, u32 len)
+{
+	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
+	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
+
+	if (IS_SYNC_NEEDED() && (id == DSI_1))
+		return false;
+
+	msm_dsi_host_cmd_xfer_commit(msm_dsi1->host, dma_base, len);
+
+	if (IS_SYNC_NEEDED() && msm_dsi0)
+		msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len);
+
+	return true;
+}
+
 void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags)
 {
 	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/5] drm/msm/dsi: replace version checks for commmand broadcast
  2018-03-12 13:23 [PATCH 0/5] Cleanup excessive DSI host controller version checks Sibi S
                   ` (3 preceding siblings ...)
  2018-03-12 13:23 ` [PATCH 4/5] drm/msm/dsi: implement 6G v2.0+ DSI command broadcast Sibi S
@ 2018-03-12 13:23 ` Sibi S
  4 siblings, 0 replies; 12+ messages in thread
From: Sibi S @ 2018-03-12 13:23 UTC (permalink / raw)
  To: architt, robdclark; +Cc: linux-arm-msm, freedreno, Sibi S, dri-devel

Replace version checks for commmand broadcast with the helper
functions bound to cfg_handler for DSI v6G 1.x and DSI 6G v2.0+
controllers

Signed-off-by: Sibi S <sibis@codeaurora.org>
---
 drivers/gpu/drm/msm/dsi/dsi_cfg.c  |  6 ++++++
 drivers/gpu/drm/msm/dsi/dsi_cfg.h  |  2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c | 16 +++-------------
 3 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index dcdfb1b..6ec28d1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -145,6 +145,8 @@
 	.tx_buf_put = NULL,
 	.dma_base_get = dsi_dma_base_get_v2,
 	.calc_clk_rate = dsi_calc_clk_rate_v2,
+	.xfer = msm_dsi_manager_cmd_xfer,
+	.xfer_trigger = msm_dsi_manager_cmd_xfer_trigger,
 };
 
 const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
@@ -156,6 +158,8 @@
 	.tx_buf_put = dsi_tx_buf_put_6g,
 	.dma_base_get = dsi_dma_base_get_6g,
 	.calc_clk_rate = dsi_calc_clk_rate_6g,
+	.xfer = msm_dsi_manager_cmd_xfer,
+	.xfer_trigger = msm_dsi_manager_cmd_xfer_trigger,
 };
 
 const static struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
@@ -167,6 +171,8 @@
 	.tx_buf_put = dsi_tx_buf_put_6g,
 	.dma_base_get = dsi_dma_base_get_6g,
 	.calc_clk_rate = dsi_calc_clk_rate_6g,
+	.xfer = msm_dsi_manager_cmd_xfer_6g_v2,
+	.xfer_trigger = msm_dsi_manager_cmd_xfer_trigger_6g_v2,
 };
 
 static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index a795a06..145251e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -49,6 +49,8 @@ struct msm_dsi_host_cfg_ops {
 	void (*tx_buf_put)(struct msm_dsi_host *msm_host);
 	int (*dma_base_get)(struct msm_dsi_host *msm_host, uint64_t *iova);
 	int (*calc_clk_rate)(struct msm_dsi_host *msm_host);
+	bool (*xfer_trigger)(int id, u32 dma_base, u32 len);
+	int (*xfer)(int id, const struct mipi_dsi_msg *msg);
 };
 
 struct msm_dsi_cfg_handler {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index bd61cad..240ecb8 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1251,13 +1251,8 @@ static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
 	reinit_completion(&msm_host->dma_comp);
 
 	dsi_wait4video_eng_busy(msm_host);
-	if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
-			(cfg_hnd->minor < MSM_DSI_6G_VER_MINOR_V2_2_1))
-		triggered = msm_dsi_manager_cmd_xfer_trigger(msm_host->id,
-								dma_base, len);
-	else
-		triggered = msm_dsi_manager_cmd_xfer_trigger_6g_v2(
-						  msm_host->id, dma_base, len);
+	triggered = cfg_hnd->ops->xfer_trigger(msm_host->id,
+							dma_base, len);
 
 	if (triggered) {
 		ret = wait_for_completion_timeout(&msm_host->dma_comp,
@@ -1615,12 +1610,7 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
 
 	mutex_lock(&msm_host->cmd_mutex);
 
-	if (((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
-			(cfg_hnd->minor < MSM_DSI_6G_VER_MINOR_V2_2_1)) ||
-			(cfg_hnd->major == MSM_DSI_VER_MAJOR_V2))
-		ret = msm_dsi_manager_cmd_xfer(msm_host->id, msg);
-	else
-		ret = msm_dsi_manager_cmd_xfer_6g_v2(msm_host->id, msg);
+	ret = cfg_hnd->ops->xfer(msm_host->id, msg);
 
 	mutex_unlock(&msm_host->cmd_mutex);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions
       [not found]   ` <1520860994-23334-3-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-03-12 15:13     ` Jordan Crouse
       [not found]       ` <20180312151352.GA28808-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
  2018-03-13  5:19     ` Archit Taneja
  1 sibling, 1 reply; 12+ messages in thread
From: Jordan Crouse @ 2018-03-12 15:13 UTC (permalink / raw)
  To: Sibi S
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	architt-sgV2jX0FEOL9JmXXK+q4OQ,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Mon, Mar 12, 2018 at 06:53:11PM +0530, Sibi S wrote:
> Add dsi host helper function implementation for DSI v2
> and DSI 6G 1.x controllers
> 
> Signed-off-by: Sibi S <sibis@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/dsi/dsi.h      |  15 +++
>  drivers/gpu/drm/msm/dsi/dsi_cfg.c  |  44 +++++--
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 250 ++++++++++++++++++++++++++++++++++++-
>  3 files changed, 298 insertions(+), 11 deletions(-)

<snip>
>  static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
>  {
>  	struct drm_display_mode *mode = msm_host->mode;
> @@ -1008,6 +1161,59 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
>  	}
>  }
>  
> +int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
> +{
> +	struct drm_device *dev = msm_host->dev;
> +	struct msm_drm_private *priv = dev->dev_private;
> +	int ret;
> +	uint64_t iova;
> +
> +	msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
> +	if (IS_ERR(msm_host->tx_gem_obj)) {
> +		ret = PTR_ERR(msm_host->tx_gem_obj);
> +		pr_err("%s: failed to allocate gem, %d\n",
> +			__func__, ret);
> +		msm_host->tx_gem_obj = NULL;
> +		return ret;
> +	}
> +
> +	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
> +			priv->kms->aspace, &iova);
> +	mutex_unlock(&dev->struct_mutex);
> +	if (ret) {
> +		pr_err("%s: failed to get iova, %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	if (iova & 0x07) {
> +		pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
> +		return -EINVAL;
> +	}

This is impossible - new allocations will always be page aligned.

> +	msm_host->tx_size = msm_host->tx_gem_obj->size;
> +
> +	return 0;
> +}
> +
> +int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
> +{
> +	struct drm_device *dev = msm_host->dev;
> +	int ret;
> +
> +	msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
> +					&msm_host->tx_buf_paddr, GFP_KERNEL);
> +	if (!msm_host->tx_buf) {
> +		ret = -ENOMEM;
> +		pr_err("%s: failed to allocate tx buf, %d\n",
> +			__func__, ret);

You don't need to print ret here, it isn't a mystery what it is.  In fact, you
probably don't need to print anything here at all because dma_alloc_coherent
should be pretty noisy when it fails.

> +		return ret;

This can just be return -ENOMEM and you can lose 'ret'.

> +	}
> +
> +	msm_host->tx_size = size;
> +
> +	return 0;
> +}
> +
>  /* dsi_cmd */
>  static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
>  {
> @@ -1072,6 +1278,21 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
>  			msm_host->tx_buf_paddr);
>  }
>  
> +void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host)
> +{
> +	return msm_gem_get_vaddr(msm_host->tx_gem_obj);
> +}
> +
> +void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host)
> +{
> +	return msm_host->tx_buf;
> +}
> +
> +void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host)
> +{
> +	msm_gem_put_vaddr(msm_host->tx_gem_obj);
> +}
> +
>  /*
>   * prepare cmd buffer to be txed
>   */
> @@ -1173,6 +1394,31 @@ static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg)
>  	return msg->rx_len;
>  }
>  
> +int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *dma_base)
> +{
> +	struct drm_device *dev = msm_host->dev;
> +	struct msm_drm_private *priv = dev->dev_private;
> +	uint64_t **iova;
> +	int ret;
> +
> +	if (!dma_base)
> +		return -EINVAL;
> +
> +	iova = &dma_base;

This is a convoluted way of passing in the pointer and I doubt even the compiler
can see through it.

> +	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
> +				priv->kms->aspace, *iova);

ret = msm_gem_get_iova(msm_host->tx_gem_obj, priv->kms->aspace, dma_base);

Easy, safe effective 

> +	return ret;

If you put a return on the front of the msm_gem_get_iova you can eliminate the
need for 'ret'.

Jordan
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions
       [not found]   ` <1520860994-23334-3-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-03-12 15:13     ` Jordan Crouse
@ 2018-03-13  5:19     ` Archit Taneja
       [not found]       ` <1091cdf6-7322-17ad-f156-c65cfe7df87a-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  1 sibling, 1 reply; 12+ messages in thread
From: Archit Taneja @ 2018-03-13  5:19 UTC (permalink / raw)
  To: Sibi S, robdclark-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On Monday 12 March 2018 06:53 PM, Sibi S wrote:
> Add dsi host helper function implementation for DSI v2
> and DSI 6G 1.x controllers
> 
> Signed-off-by: Sibi S <sibis@codeaurora.org>
> ---
>   drivers/gpu/drm/msm/dsi/dsi.h      |  15 +++
>   drivers/gpu/drm/msm/dsi/dsi_cfg.c  |  44 +++++--
>   drivers/gpu/drm/msm/dsi/dsi_host.c | 250 ++++++++++++++++++++++++++++++++++++-
>   3 files changed, 298 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
> index 80be83e..dfa049d 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
> @@ -183,6 +183,21 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
>   int msm_dsi_host_init(struct msm_dsi *msm_dsi);
>   int msm_dsi_runtime_suspend(struct device *dev);
>   int msm_dsi_runtime_resume(struct device *dev);
> +int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
> +int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
> +void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
> +void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
> +int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
> +int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
> +void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
> +void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host);
> +void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host);
> +int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova);
> +int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
> +int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
> +int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
> +int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host);
> +int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host);
>   
>   /* dsi phy */
>   struct msm_dsi_phy;
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> index 0327bb5..dc51aaa 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> @@ -136,20 +136,46 @@
>   	.num_dsi = 2,
>   };
>   
> +const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
> +	.link_clk_enable = dsi_link_clk_enable_v2,
> +	.link_clk_disable = dsi_link_clk_disable_v2,
> +	.clk_init_ver = dsi_clk_init_v2,
> +	.tx_buf_alloc = dsi_tx_buf_alloc_v2,
> +	.tx_buf_get = dsi_tx_buf_get_v2,
> +	.tx_buf_put = NULL,
> +	.dma_base_get = dsi_dma_base_get_v2,
> +	.calc_clk_rate = dsi_calc_clk_rate_v2,
> +};
> +
> +const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
> +	.link_clk_enable = dsi_link_clk_enable_6g,
> +	.link_clk_disable = dsi_link_clk_disable_6g,
> +	.clk_init_ver = NULL,
> +	.tx_buf_alloc = dsi_tx_buf_alloc_6g,
> +	.tx_buf_get = dsi_tx_buf_get_6g,
> +	.tx_buf_put = dsi_tx_buf_put_6g,
> +	.dma_base_get = dsi_dma_base_get_6g,
> +	.calc_clk_rate = dsi_calc_clk_rate_6g,
> +};

Could you introduce the host ops for SDM845 (i.e,
msm_dsi_6g_v2_host_ops) in this patch itself? It would be nice to
keep the DSI command broadcast code as a separate patch since it
probably needs to go through more iterations.

The ops approach looks good otherwise.

Thanks,
Archit

>   static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
> -	{MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064, &apq8064_dsi_cfg},
> +	{MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064,
> +		&apq8064_dsi_cfg, &msm_dsi_v2_host_ops},
>   	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0,
> -						&msm8974_apq8084_dsi_cfg},
> +		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
>   	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1,
> -						&msm8974_apq8084_dsi_cfg},
> +		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
>   	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1_1,
> -						&msm8974_apq8084_dsi_cfg},
> +		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
>   	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_2,
> -						&msm8974_apq8084_dsi_cfg},
> -	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3, &msm8994_dsi_cfg},
> -	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1, &msm8916_dsi_cfg},
> -	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1, &msm8996_dsi_cfg},
> -	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1, &sdm845_dsi_cfg},
> +		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
> +	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3,
> +		&msm8994_dsi_cfg, &msm_dsi_6g_host_ops},
> +	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1,
> +		&msm8916_dsi_cfg, &msm_dsi_6g_host_ops},
> +	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
> +		&msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
> +	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
> +		&sdm845_dsi_cfg, &msm_dsi_6g_host_ops},
>   };
>   
>   const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 7a03a94..f7a066d 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -331,6 +331,54 @@ static int dsi_regulator_init(struct msm_dsi_host *msm_host)
>   	return 0;
>   }
>   
> +int dsi_clk_init_v2(struct msm_dsi_host *msm_host)
> +{
> +	struct platform_device *pdev = msm_host->pdev;
> +	int ret = 0;
> +
> +	msm_host->src_clk = msm_clk_get(pdev, "src");
> +
> +	if (IS_ERR(msm_host->src_clk)) {
> +		ret = PTR_ERR(msm_host->src_clk);
> +		pr_err("%s: can't find src clock. ret=%d\n",
> +			__func__, ret);
> +		msm_host->src_clk = NULL;
> +		return ret;
> +	}
> +
> +	msm_host->esc_clk_src = clk_get_parent(msm_host->esc_clk);
> +	if (!msm_host->esc_clk_src) {
> +		ret = -ENODEV;
> +		pr_err("%s: can't get esc clock parent. ret=%d\n",
> +			__func__, ret);
> +		return ret;
> +	}
> +
> +	msm_host->dsi_clk_src = clk_get_parent(msm_host->src_clk);
> +	if (!msm_host->dsi_clk_src) {
> +		ret = -ENODEV;
> +		pr_err("%s: can't get src clock parent. ret=%d\n",
> +			__func__, ret);
> +	}
> +
> +	return ret;
> +}
> +
> +int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host)
> +{
> +	struct platform_device *pdev = msm_host->pdev;
> +	int ret = 0;
> +
> +	msm_host->byte_intf_clk = msm_clk_get(pdev, "byte_intf");
> +	if (IS_ERR(msm_host->byte_intf_clk)) {
> +		ret = PTR_ERR(msm_host->byte_intf_clk);
> +		pr_err("%s: can't find byte_intf clock. ret=%d\n",
> +			__func__, ret);
> +	}
> +
> +	return ret;
> +}
> +
>   static int dsi_clk_init(struct msm_dsi_host *msm_host)
>   {
>   	struct platform_device *pdev = msm_host->pdev;
> @@ -497,7 +545,7 @@ int msm_dsi_runtime_resume(struct device *dev)
>   	return dsi_bus_clk_enable(msm_host);
>   }
>   
> -static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
> +int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
>   {
>   	int ret;
>   
> @@ -565,7 +613,7 @@ static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
>   	return ret;
>   }
>   
> -static int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
> +int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
>   {
>   	int ret;
>   
> @@ -643,6 +691,23 @@ static int dsi_link_clk_enable(struct msm_dsi_host *msm_host)
>   		return dsi_link_clk_enable_v2(msm_host);
>   }
>   
> +void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
> +{
> +	clk_disable_unprepare(msm_host->esc_clk);
> +	clk_disable_unprepare(msm_host->pixel_clk);
> +	if (msm_host->byte_intf_clk)
> +		clk_disable_unprepare(msm_host->byte_intf_clk);
> +	clk_disable_unprepare(msm_host->byte_clk);
> +}
> +
> +void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
> +{
> +	clk_disable_unprepare(msm_host->pixel_clk);
> +	clk_disable_unprepare(msm_host->src_clk);
> +	clk_disable_unprepare(msm_host->esc_clk);
> +	clk_disable_unprepare(msm_host->byte_clk);
> +}
> +
>   static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
>   {
>   	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
> @@ -661,6 +726,94 @@ static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
>   	}
>   }
>   
> +int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
> +{
> +	struct drm_display_mode *mode = msm_host->mode;
> +	u8 lanes = msm_host->lanes;
> +	u32 bpp = dsi_get_bpp(msm_host->format);
> +	u32 pclk_rate;
> +
> +	if (!mode) {
> +		pr_err("%s: mode not set\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	pclk_rate = mode->clock * 1000;
> +	if (lanes > 0) {
> +		msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
> +	} else {
> +		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
> +		msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
> +	}
> +
> +	DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
> +
> +	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
> +
> +	return 0;
> +}
> +
> +int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
> +{
> +	struct drm_display_mode *mode = msm_host->mode;
> +	u8 lanes = msm_host->lanes;
> +	u32 bpp = dsi_get_bpp(msm_host->format);
> +	u32 pclk_rate;
> +	unsigned int esc_mhz, esc_div;
> +	unsigned long byte_mhz;
> +
> +	if (!mode) {
> +		pr_err("%s: mode not set\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	pclk_rate = mode->clock * 1000;
> +	if (lanes > 0) {
> +		msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
> +	} else {
> +		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
> +		msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
> +	}
> +
> +	DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
> +
> +	msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
> +
> +	/*
> +	 * esc clock is byte clock followed by a 4 bit divider,
> +	 * we need to find an escape clock frequency within the
> +	 * mipi DSI spec range within the maximum divider limit
> +	 * We iterate here between an escape clock frequencey
> +	 * between 20 Mhz to 5 Mhz and pick up the first one
> +	 * that can be supported by our divider
> +	 */
> +
> +	byte_mhz = msm_host->byte_clk_rate / 1000000;
> +
> +	for (esc_mhz = 20; esc_mhz >= 5; esc_mhz--) {
> +		esc_div = DIV_ROUND_UP(byte_mhz, esc_mhz);
> +
> +		/*
> +		 * TODO: Ideally, we shouldn't know what sort of divider
> +		 * is available in mmss_cc, we're just assuming that
> +		 * it'll always be a 4 bit divider. Need to come up with
> +		 * a better way here.
> +		 */
> +		if (esc_div >= 1 && esc_div <= 16)
> +			break;
> +	}
> +
> +	if (esc_mhz < 5)
> +		return -EINVAL;
> +
> +	msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
> +
> +	DBG("esc=%d, src=%d", msm_host->esc_clk_rate,
> +		msm_host->src_clk_rate);
> +
> +	return 0;
> +}
> +
>   static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
>   {
>   	struct drm_display_mode *mode = msm_host->mode;
> @@ -1008,6 +1161,59 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
>   	}
>   }
>   
> +int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
> +{
> +	struct drm_device *dev = msm_host->dev;
> +	struct msm_drm_private *priv = dev->dev_private;
> +	int ret;
> +	uint64_t iova;
> +
> +	msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
> +	if (IS_ERR(msm_host->tx_gem_obj)) {
> +		ret = PTR_ERR(msm_host->tx_gem_obj);
> +		pr_err("%s: failed to allocate gem, %d\n",
> +			__func__, ret);
> +		msm_host->tx_gem_obj = NULL;
> +		return ret;
> +	}
> +
> +	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
> +			priv->kms->aspace, &iova);
> +	mutex_unlock(&dev->struct_mutex);
> +	if (ret) {
> +		pr_err("%s: failed to get iova, %d\n", __func__, ret);
> +		return ret;
> +	}
> +
> +	if (iova & 0x07) {
> +		pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	msm_host->tx_size = msm_host->tx_gem_obj->size;
> +
> +	return 0;
> +}
> +
> +int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
> +{
> +	struct drm_device *dev = msm_host->dev;
> +	int ret;
> +
> +	msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
> +					&msm_host->tx_buf_paddr, GFP_KERNEL);
> +	if (!msm_host->tx_buf) {
> +		ret = -ENOMEM;
> +		pr_err("%s: failed to allocate tx buf, %d\n",
> +			__func__, ret);
> +		return ret;
> +	}
> +
> +	msm_host->tx_size = size;
> +
> +	return 0;
> +}
> +
>   /* dsi_cmd */
>   static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
>   {
> @@ -1072,6 +1278,21 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
>   			msm_host->tx_buf_paddr);
>   }
>   
> +void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host)
> +{
> +	return msm_gem_get_vaddr(msm_host->tx_gem_obj);
> +}
> +
> +void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host)
> +{
> +	return msm_host->tx_buf;
> +}
> +
> +void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host)
> +{
> +	msm_gem_put_vaddr(msm_host->tx_gem_obj);
> +}
> +
>   /*
>    * prepare cmd buffer to be txed
>    */
> @@ -1173,6 +1394,31 @@ static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg)
>   	return msg->rx_len;
>   }
>   
> +int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *dma_base)
> +{
> +	struct drm_device *dev = msm_host->dev;
> +	struct msm_drm_private *priv = dev->dev_private;
> +	uint64_t **iova;
> +	int ret;
> +
> +	if (!dma_base)
> +		return -EINVAL;
> +
> +	iova = &dma_base;
> +	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
> +				priv->kms->aspace, *iova);
> +	return ret;
> +}
> +
> +int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *dma_base)
> +{
> +	if (!dma_base)
> +		return -EINVAL;
> +
> +	*dma_base = msm_host->tx_buf_paddr;
> +	return 0;
> +}
> +
>   static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
>   {
>   	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
> 
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/5] drm/msm/dsi: replace version checks with helper functions
       [not found]   ` <1520860994-23334-4-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-03-13  5:20     ` Archit Taneja
  0 siblings, 0 replies; 12+ messages in thread
From: Archit Taneja @ 2018-03-13  5:20 UTC (permalink / raw)
  To: Sibi S, robdclark-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On Monday 12 March 2018 06:53 PM, Sibi S wrote:
> Replace version checks with the helper functions bound to
> cfg_handler for DSI v2 and DSI 6G 1.x controllers
> 

With the ops set up for DSI6G 2.x too:

Reviewed-by: Archit Taneja <architt@codeaurora.org>

Thanks,
Archit

> Signed-off-by: Sibi S <sibis@codeaurora.org>
> ---
>   drivers/gpu/drm/msm/dsi/dsi_host.c | 242 +++++--------------------------------
>   1 file changed, 29 insertions(+), 213 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index f7a066d..b755b69 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -426,19 +426,6 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host)
>   		goto exit;
>   	}
>   
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G &&
> -	    cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V2_2_1) {
> -		msm_host->byte_intf_clk = msm_clk_get(pdev, "byte_intf");
> -		if (IS_ERR(msm_host->byte_intf_clk)) {
> -			ret = PTR_ERR(msm_host->byte_intf_clk);
> -			pr_err("%s: can't find byte_intf clock. ret=%d\n",
> -			        __func__, ret);
> -			goto exit;
> -		}
> -	} else {
> -		msm_host->byte_intf_clk = NULL;
> -	}
> -
>   	msm_host->byte_clk_src = clk_get_parent(msm_host->byte_clk);
>   	if (!msm_host->byte_clk_src) {
>   		ret = -ENODEV;
> @@ -453,31 +440,8 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host)
>   		goto exit;
>   	}
>   
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_V2) {
> -		msm_host->src_clk = msm_clk_get(pdev, "src");
> -		if (IS_ERR(msm_host->src_clk)) {
> -			ret = PTR_ERR(msm_host->src_clk);
> -			pr_err("%s: can't find src clock. ret=%d\n",
> -				__func__, ret);
> -			msm_host->src_clk = NULL;
> -			goto exit;
> -		}
> -
> -		msm_host->esc_clk_src = clk_get_parent(msm_host->esc_clk);
> -		if (!msm_host->esc_clk_src) {
> -			ret = -ENODEV;
> -			pr_err("%s: can't get esc clock parent. ret=%d\n",
> -				__func__, ret);
> -			goto exit;
> -		}
> -
> -		msm_host->dsi_clk_src = clk_get_parent(msm_host->src_clk);
> -		if (!msm_host->dsi_clk_src) {
> -			ret = -ENODEV;
> -			pr_err("%s: can't get src clock parent. ret=%d\n",
> -				__func__, ret);
> -		}
> -	}
> +	if (cfg_hnd->ops->clk_init_ver)
> +		ret = cfg_hnd->ops->clk_init_ver(msm_host);
>   exit:
>   	return ret;
>   }
> @@ -681,16 +645,6 @@ int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
>   	return ret;
>   }
>   
> -static int dsi_link_clk_enable(struct msm_dsi_host *msm_host)
> -{
> -	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
> -
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G)
> -		return dsi_link_clk_enable_6g(msm_host);
> -	else
> -		return dsi_link_clk_enable_v2(msm_host);
> -}
> -
>   void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
>   {
>   	clk_disable_unprepare(msm_host->esc_clk);
> @@ -708,24 +662,6 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
>   	clk_disable_unprepare(msm_host->byte_clk);
>   }
>   
> -static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
> -{
> -	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
> -
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
> -		clk_disable_unprepare(msm_host->esc_clk);
> -		clk_disable_unprepare(msm_host->pixel_clk);
> -		if (msm_host->byte_intf_clk)
> -			clk_disable_unprepare(msm_host->byte_intf_clk);
> -		clk_disable_unprepare(msm_host->byte_clk);
> -	} else {
> -		clk_disable_unprepare(msm_host->pixel_clk);
> -		clk_disable_unprepare(msm_host->src_clk);
> -		clk_disable_unprepare(msm_host->esc_clk);
> -		clk_disable_unprepare(msm_host->byte_clk);
> -	}
> -}
> -
>   int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
>   {
>   	struct drm_display_mode *mode = msm_host->mode;
> @@ -814,73 +750,6 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
>   	return 0;
>   }
>   
> -static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
> -{
> -	struct drm_display_mode *mode = msm_host->mode;
> -	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
> -	u8 lanes = msm_host->lanes;
> -	u32 bpp = dsi_get_bpp(msm_host->format);
> -	u32 pclk_rate;
> -
> -	if (!mode) {
> -		pr_err("%s: mode not set\n", __func__);
> -		return -EINVAL;
> -	}
> -
> -	pclk_rate = mode->clock * 1000;
> -	if (lanes > 0) {
> -		msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
> -	} else {
> -		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
> -		msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
> -	}
> -
> -	DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
> -
> -	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
> -
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_V2) {
> -		unsigned int esc_mhz, esc_div;
> -		unsigned long byte_mhz;
> -
> -		msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
> -
> -		/*
> -		 * esc clock is byte clock followed by a 4 bit divider,
> -		 * we need to find an escape clock frequency within the
> -		 * mipi DSI spec range within the maximum divider limit
> -		 * We iterate here between an escape clock frequencey
> -		 * between 20 Mhz to 5 Mhz and pick up the first one
> -		 * that can be supported by our divider
> -		 */
> -
> -		byte_mhz = msm_host->byte_clk_rate / 1000000;
> -
> -		for (esc_mhz = 20; esc_mhz >= 5; esc_mhz--) {
> -			esc_div = DIV_ROUND_UP(byte_mhz, esc_mhz);
> -
> -			/*
> -			 * TODO: Ideally, we shouldn't know what sort of divider
> -			 * is available in mmss_cc, we're just assuming that
> -			 * it'll always be a 4 bit divider. Need to come up with
> -			 * a better way here.
> -			 */
> -			if (esc_div >= 1 && esc_div <= 16)
> -				break;
> -		}
> -
> -		if (esc_mhz < 5)
> -			return -EINVAL;
> -
> -		msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
> -
> -		DBG("esc=%d, src=%d", msm_host->esc_clk_rate,
> -			msm_host->src_clk_rate);
> -	}
> -
> -	return 0;
> -}
> -
>   static void dsi_intr_ctrl(struct msm_dsi_host *msm_host, u32 mask, int enable)
>   {
>   	u32 intr;
> @@ -1214,55 +1083,6 @@ int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
>   	return 0;
>   }
>   
> -/* dsi_cmd */
> -static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
> -{
> -	struct drm_device *dev = msm_host->dev;
> -	struct msm_drm_private *priv = dev->dev_private;
> -	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
> -	int ret;
> -	uint64_t iova;
> -
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
> -		msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
> -		if (IS_ERR(msm_host->tx_gem_obj)) {
> -			ret = PTR_ERR(msm_host->tx_gem_obj);
> -			pr_err("%s: failed to allocate gem, %d\n",
> -				__func__, ret);
> -			msm_host->tx_gem_obj = NULL;
> -			return ret;
> -		}
> -
> -		ret = msm_gem_get_iova(msm_host->tx_gem_obj,
> -				priv->kms->aspace, &iova);
> -		mutex_unlock(&dev->struct_mutex);
> -		if (ret) {
> -			pr_err("%s: failed to get iova, %d\n", __func__, ret);
> -			return ret;
> -		}
> -
> -		if (iova & 0x07) {
> -			pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
> -			return -EINVAL;
> -		}
> -
> -		msm_host->tx_size = msm_host->tx_gem_obj->size;
> -	} else {
> -		msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
> -					&msm_host->tx_buf_paddr, GFP_KERNEL);
> -		if (!msm_host->tx_buf) {
> -			ret = -ENOMEM;
> -			pr_err("%s: failed to allocate tx buf, %d\n",
> -				__func__, ret);
> -			return ret;
> -		}
> -
> -		msm_host->tx_size = size;
> -	}
> -
> -	return 0;
> -}
> -
>   static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
>   {
>   	struct drm_device *dev = msm_host->dev;
> @@ -1317,15 +1137,11 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host,
>   		return -EINVAL;
>   	}
>   
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
> -		data = msm_gem_get_vaddr(msm_host->tx_gem_obj);
> -		if (IS_ERR(data)) {
> -			ret = PTR_ERR(data);
> -			pr_err("%s: get vaddr failed, %d\n", __func__, ret);
> -			return ret;
> -		}
> -	} else {
> -		data = msm_host->tx_buf;
> +	data = cfg_hnd->ops->tx_buf_get(msm_host);
> +	if (IS_ERR(data)) {
> +		ret = PTR_ERR(data);
> +		pr_err("%s: get vaddr failed, %d\n", __func__, ret);
> +		return ret;
>   	}
>   
>   	/* MSM specific command format in memory */
> @@ -1346,8 +1162,8 @@ static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host,
>   	if (packet.size < len)
>   		memset(data + packet.size, 0xff, len - packet.size);
>   
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G)
> -		msm_gem_put_vaddr(msm_host->tx_gem_obj);
> +	if (cfg_hnd->ops->tx_buf_put)
> +		cfg_hnd->ops->tx_buf_put(msm_host);
>   
>   	return len;
>   }
> @@ -1422,21 +1238,14 @@ int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *dma_base)
>   static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
>   {
>   	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
> -	struct drm_device *dev = msm_host->dev;
> -	struct msm_drm_private *priv = dev->dev_private;
>   	int ret;
>   	uint64_t dma_base;
>   	bool triggered;
>   
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
> -		ret = msm_gem_get_iova(msm_host->tx_gem_obj,
> -				priv->kms->aspace, &dma_base);
> -		if (ret) {
> -			pr_err("%s: failed to get iova: %d\n", __func__, ret);
> -			return ret;
> -		}
> -	} else {
> -		dma_base = msm_host->tx_buf_paddr;
> +	ret = cfg_hnd->ops->dma_base_get(msm_host, &dma_base);
> +	if (ret) {
> +		pr_err("%s: failed to get iova: %d\n", __func__, ret);
> +		return ret;
>   	}
>   
>   	reinit_completion(&msm_host->dma_comp);
> @@ -2074,6 +1883,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
>   					struct drm_device *dev)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   	struct platform_device *pdev = msm_host->pdev;
>   	int ret;
>   
> @@ -2094,7 +1904,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
>   	}
>   
>   	msm_host->dev = dev;
> -	ret = dsi_tx_buf_alloc(msm_host, SZ_4K);
> +	ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
>   	if (ret) {
>   		pr_err("%s: alloc tx gem obj failed, %d\n", __func__, ret);
>   		return ret;
> @@ -2152,6 +1962,7 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
>   				const struct mipi_dsi_msg *msg)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   
>   	/* TODO: make sure dsi_cmd_mdp is idle.
>   	 * Since DSI6G v1.2.0, we can set DSI_TRIG_CTRL.BLOCK_DMA_WITHIN_FRAME
> @@ -2164,7 +1975,7 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
>   	 * mdp clock need to be enabled to receive dsi interrupt
>   	 */
>   	pm_runtime_get_sync(&msm_host->pdev->dev);
> -	dsi_link_clk_enable(msm_host);
> +	cfg_hnd->ops->link_clk_enable(msm_host);
>   
>   	/* TODO: vote for bus bandwidth */
>   
> @@ -2185,6 +1996,7 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
>   				const struct mipi_dsi_msg *msg)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   
>   	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_DMA_DONE, 0);
>   	dsi_write(msm_host, REG_DSI_CTRL, msm_host->dma_cmd_ctrl_restore);
> @@ -2194,7 +2006,7 @@ void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
>   
>   	/* TODO: unvote for bus bandwidth */
>   
> -	dsi_link_clk_disable(msm_host);
> +	cfg_hnd->ops->link_clk_disable(msm_host);
>   	pm_runtime_put_autosuspend(&msm_host->pdev->dev);
>   }
>   
> @@ -2358,7 +2170,6 @@ int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
>   	struct msm_dsi_pll *src_pll)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> -	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   	struct clk *byte_clk_provider, *pixel_clk_provider;
>   	int ret;
>   
> @@ -2384,14 +2195,16 @@ int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
>   		goto exit;
>   	}
>   
> -	if (cfg_hnd->major == MSM_DSI_VER_MAJOR_V2) {
> +	if (msm_host->dsi_clk_src) {
>   		ret = clk_set_parent(msm_host->dsi_clk_src, pixel_clk_provider);
>   		if (ret) {
>   			pr_err("%s: can't set parent to dsi_clk_src. ret=%d\n",
>   				__func__, ret);
>   			goto exit;
>   		}
> +	}
>   
> +	if (msm_host->esc_clk_src) {
>   		ret = clk_set_parent(msm_host->esc_clk_src, byte_clk_provider);
>   		if (ret) {
>   			pr_err("%s: can't set parent to esc_clk_src. ret=%d\n",
> @@ -2421,9 +2234,10 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
>   	struct msm_dsi_phy_clk_request *clk_req)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   	int ret;
>   
> -	ret = dsi_calc_clk_rate(msm_host);
> +	ret = cfg_hnd->ops->calc_clk_rate(msm_host);
>   	if (ret) {
>   		pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
>   		return;
> @@ -2487,6 +2301,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
>   			struct msm_dsi_phy_shared_timings *phy_shared_timings)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   	int ret = 0;
>   
>   	mutex_lock(&msm_host->dev_mutex);
> @@ -2505,7 +2320,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
>   	}
>   
>   	pm_runtime_get_sync(&msm_host->pdev->dev);
> -	ret = dsi_link_clk_enable(msm_host);
> +	ret = cfg_hnd->ops->link_clk_enable(msm_host);
>   	if (ret) {
>   		pr_err("%s: failed to enable link clocks. ret=%d\n",
>   		       __func__, ret);
> @@ -2532,7 +2347,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
>   	return 0;
>   
>   fail_disable_clk:
> -	dsi_link_clk_disable(msm_host);
> +	cfg_hnd->ops->link_clk_disable(msm_host);
>   	pm_runtime_put_autosuspend(&msm_host->pdev->dev);
>   fail_disable_reg:
>   	dsi_host_regulator_disable(msm_host);
> @@ -2544,6 +2359,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
>   int msm_dsi_host_power_off(struct mipi_dsi_host *host)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   
>   	mutex_lock(&msm_host->dev_mutex);
>   	if (!msm_host->power_on) {
> @@ -2558,7 +2374,7 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host)
>   
>   	pinctrl_pm_select_sleep_state(&msm_host->pdev->dev);
>   
> -	dsi_link_clk_disable(msm_host);
> +	cfg_hnd->ops->link_clk_disable(msm_host);
>   	pm_runtime_put_autosuspend(&msm_host->pdev->dev);
>   
>   	dsi_host_regulator_disable(msm_host);
> 
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/5] drm/msm/dsi: implement 6G v2.0+ DSI command broadcast
       [not found]   ` <1520860994-23334-5-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-03-13  5:30     ` Archit Taneja
  0 siblings, 0 replies; 12+ messages in thread
From: Archit Taneja @ 2018-03-13  5:30 UTC (permalink / raw)
  To: Sibi S, robdclark-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On Monday 12 March 2018 06:53 PM, Sibi S wrote:
> From: Archit Taneja <architt@codeaurora.org>
> 

I'm a bit uncertain about using this patch in its current state.
Some reasons below.

> Add command broadcast support for DSI 6G v2.0+ controller
> on SDM845
> 
> Signed-off-by: Sibi S <sibis@codeaurora.org>
> ---
>   drivers/gpu/drm/msm/dsi/dsi.h         |  5 +++
>   drivers/gpu/drm/msm/dsi/dsi_cfg.c     | 14 +++++++-
>   drivers/gpu/drm/msm/dsi/dsi_host.c    | 62 ++++++++++++++++++++++++++++++--
>   drivers/gpu/drm/msm/dsi/dsi_manager.c | 66 +++++++++++++++++++++++++++++++++++
>   4 files changed, 143 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
> index dfa049d..22342c30 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi.h
> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
> @@ -96,7 +96,9 @@ struct msm_dsi {
>   struct drm_connector *msm_dsi_manager_connector_init(u8 id);
>   struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id);
>   int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
> +int msm_dsi_manager_cmd_xfer_6g_v2(int id, const struct mipi_dsi_msg *msg);
>   bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
> +bool msm_dsi_manager_cmd_xfer_trigger_6g_v2(int id, u32 dma_base, u32 len);
>   void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags);
>   int msm_dsi_manager_register(struct msm_dsi *msm_dsi);
>   void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi);
> @@ -152,6 +154,9 @@ static inline int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
>   struct msm_dsi_host;
>   int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
>   					const struct mipi_dsi_msg *msg);
> +int msm_dsi_host_xfer_prepare_6g_v2(struct mipi_dsi_host *host,
> +					const struct mipi_dsi_msg *msg,
> +					bool broadcast, bool master);
>   void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
>   					const struct mipi_dsi_msg *msg);
>   int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> index dc51aaa..dcdfb1b 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
> @@ -157,6 +157,18 @@
>   	.dma_base_get = dsi_dma_base_get_6g,
>   	.calc_clk_rate = dsi_calc_clk_rate_6g,
>   };
> +
> +const static struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
> +	.link_clk_enable = dsi_link_clk_enable_6g,
> +	.link_clk_disable = dsi_link_clk_disable_6g,
> +	.clk_init_ver = dsi_clk_init_6g_v2,
> +	.tx_buf_alloc = dsi_tx_buf_alloc_6g,
> +	.tx_buf_get = dsi_tx_buf_get_6g,
> +	.tx_buf_put = dsi_tx_buf_put_6g,
> +	.dma_base_get = dsi_dma_base_get_6g,
> +	.calc_clk_rate = dsi_calc_clk_rate_6g,
> +};
> +
>   static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
>   	{MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064,
>   		&apq8064_dsi_cfg, &msm_dsi_v2_host_ops},
> @@ -175,7 +187,7 @@
>   	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
>   		&msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
>   	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
> -		&sdm845_dsi_cfg, &msm_dsi_6g_host_ops},
> +		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
>   };
>   
>   const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index b755b69..bd61cad 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -1251,9 +1251,14 @@ static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
>   	reinit_completion(&msm_host->dma_comp);
>   
>   	dsi_wait4video_eng_busy(msm_host);
> +	if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
> +			(cfg_hnd->minor < MSM_DSI_6G_VER_MINOR_V2_2_1))
> +		triggered = msm_dsi_manager_cmd_xfer_trigger(msm_host->id,
> +								dma_base, len);
> +	else
> +		triggered = msm_dsi_manager_cmd_xfer_trigger_6g_v2(
> +						  msm_host->id, dma_base, len);
>   
> -	triggered = msm_dsi_manager_cmd_xfer_trigger(
> -						msm_host->id, dma_base, len);
>   	if (triggered) {
>   		ret = wait_for_completion_timeout(&msm_host->dma_comp,
>   					msecs_to_jiffies(200));
> @@ -1602,13 +1607,21 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
>   					const struct mipi_dsi_msg *msg)
>   {
>   	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>   	int ret;
>   
>   	if (!msg || !msm_host->power_on)
>   		return -EINVAL;
>   
>   	mutex_lock(&msm_host->cmd_mutex);
> -	ret = msm_dsi_manager_cmd_xfer(msm_host->id, msg);
> +
> +	if (((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
> +			(cfg_hnd->minor < MSM_DSI_6G_VER_MINOR_V2_2_1)) ||
> +			(cfg_hnd->major == MSM_DSI_VER_MAJOR_V2))
> +		ret = msm_dsi_manager_cmd_xfer(msm_host->id, msg);
> +	else
> +		ret = msm_dsi_manager_cmd_xfer_6g_v2(msm_host->id, msg);
> +
>   	mutex_unlock(&msm_host->cmd_mutex);
>   
>   	return ret;
> @@ -1992,6 +2005,49 @@ int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
>   	return 0;
>   }
>   
> +static void dsi_host_prepare_broadcast_6g_v2(struct msm_dsi_host *msm_host,
> +					     bool broadcast, bool master)
> +{
> +	u32 val = dsi_read(msm_host, REG_DSI_CMD_DMA_CTRL);
> +
> +	if (broadcast)
> +		val |= BIT(31);
> +	else
> +		val &= ~BIT(31);
> +
> +	if (master)
> +		val |= BIT(30);
> +	else
> +		val &= ~BIT(30);
> +
> +	dsi_write(msm_host, REG_DSI_CMD_DMA_CTRL, val);
> + > +
> +int msm_dsi_host_xfer_prepare_6g_v2(struct mipi_dsi_host *host,
> +				    const struct mipi_dsi_msg *msg,
> +				    bool broadcast, bool master)
> +{
> +	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
> +
> +	/* TODO: vote for bus bandwidth */
> +
> +	if (!(msg->flags & MIPI_DSI_MSG_USE_LPM))
> +		dsi_set_tx_power_mode(0, msm_host);
> +
> +	dsi_host_prepare_broadcast_6g_v2(msm_host, broadcast, master);
> +
> +	msm_host->dma_cmd_ctrl_restore = dsi_read(msm_host, REG_DSI_CTRL);
> +	dsi_write(msm_host, REG_DSI_CTRL,
> +		msm_host->dma_cmd_ctrl_restore |
> +		DSI_CTRL_CMD_MODE_EN |
> +		DSI_CTRL_ENABLE);
> +
> +	if ((broadcast && master) || !broadcast)
> +		dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_DMA_DONE, 1);
> +
> +	return 0;
> +}

This part above (i.e, the prepare for 6G v2.0+) looks okay.

> +
>   void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
>   				const struct mipi_dsi_msg *msg)
>   {
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> index 4cb1cb6..393e3ff 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
> @@ -812,6 +812,56 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)
>   	return ret;
>   }
>   
> +int msm_dsi_manager_cmd_xfer_6g_v2(int id, const struct mipi_dsi_msg *msg)
> +{
> +	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> +	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
> +	struct mipi_dsi_host *host = msm_dsi->host;
> +	bool is_read = (msg->rx_buf && msg->rx_len);
> +	bool need_sync = (IS_SYNC_NEEDED() && !is_read);
> +	int ret;
> +
> +	if (!msg->tx_buf || !msg->tx_len)
> +		return 0;
> +
> +	if (need_sync && (id == DSI_0))
> +		return is_read ? msg->rx_len : msg->tx_len;
> +
> +	if (need_sync && msm_dsi0) {
> +		ret = msm_dsi_host_xfer_prepare_6g_v2(msm_dsi0->host, msg,
> +						      true, true);
> +		if (ret) {
> +			pr_err("%s: failed to prepare non-trigger host, %d\n",
> +				__func__, ret);
> +			return ret;
> +		}
> +	}
> +
> +	ret = msm_dsi_host_xfer_prepare_6g_v2(msm_dsi->host, msg,
> +					      need_sync ? true : false,
> +					      false);
> +	if (ret) {
> +		pr_err("%s: failed to prepare host, %d\n",
> +			__func__, ret);
> +		return ret;
> +	}
> +
> +	if (need_sync && msm_dsi0) {
> +		ret = is_read ? msm_dsi_host_cmd_rx(msm_dsi0->host, msg) :
> +				msm_dsi_host_cmd_tx(msm_dsi0->host, msg);
> +	} else {
> +		ret = is_read ? msm_dsi_host_cmd_rx(msm_dsi->host, msg) :
> +				msm_dsi_host_cmd_tx(msm_dsi->host, msg);
> +	}
> +
> +	msm_dsi_host_xfer_restore(host, msg);
> +
> +	if (need_sync && msm_dsi0)
> +		msm_dsi_host_xfer_restore(msm_dsi0->host, msg);
> +
> +	return ret;
> +}

I think the func above has problems, I'd mostly copied it from the
original msm_dsi_manager_cmd_xfer func. We don't know if the 'need_sync'
feature is something that's even needed for SDM845. Also, we have
assumed here msm_dsi0 will always be the clock master, we might have
to make it flexible to work with either DSI being the clock master.

> +
>   bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
>   {
>   	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> @@ -829,6 +879,22 @@ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
>   	return true;
>   }
>   
> +bool msm_dsi_manager_cmd_xfer_trigger_6g_v2(int id, u32 dma_base, u32 len)
> +{
> +	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
> +	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
> +
> +	if (IS_SYNC_NEEDED() && (id == DSI_1))
> +		return false;
> +
> +	msm_dsi_host_cmd_xfer_commit(msm_dsi1->host, dma_base, len);
> +
> +	if (IS_SYNC_NEEDED() && msm_dsi0)
> +		msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len);
> +

This again is something I'd hacked to get the display running, we can't
assume that msm_dsi0 is going to be the clock master.

Thanks,
Archit

> +	return true;
> +}
> +
>   void msm_dsi_manager_attach_dsi_device(int id, u32 device_flags)
>   {
>   	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
> 
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions
       [not found]       ` <20180312151352.GA28808-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
@ 2018-03-13  6:57         ` Sibi S
  0 siblings, 0 replies; 12+ messages in thread
From: Sibi S @ 2018-03-13  6:57 UTC (permalink / raw)
  To: architt-sgV2jX0FEOL9JmXXK+q4OQ, robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hi Jordan,
Thanks for the review. Will incorporate the suggested changes in v2.

On 03/12/2018 08:43 PM, Jordan Crouse wrote:
> On Mon, Mar 12, 2018 at 06:53:11PM +0530, Sibi S wrote:
>> Add dsi host helper function implementation for DSI v2
>> and DSI 6G 1.x controllers
>>
>> Signed-off-by: Sibi S <sibis@codeaurora.org>
>> ---
>>   drivers/gpu/drm/msm/dsi/dsi.h      |  15 +++
>>   drivers/gpu/drm/msm/dsi/dsi_cfg.c  |  44 +++++--
>>   drivers/gpu/drm/msm/dsi/dsi_host.c | 250 ++++++++++++++++++++++++++++++++++++-
>>   3 files changed, 298 insertions(+), 11 deletions(-)
> 
> <snip>
>>   static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
>>   {
>>   	struct drm_display_mode *mode = msm_host->mode;
>> @@ -1008,6 +1161,59 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
>>   	}
>>   }
>>   
>> +int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
>> +{
>> +	struct drm_device *dev = msm_host->dev;
>> +	struct msm_drm_private *priv = dev->dev_private;
>> +	int ret;
>> +	uint64_t iova;
>> +
>> +	msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
>> +	if (IS_ERR(msm_host->tx_gem_obj)) {
>> +		ret = PTR_ERR(msm_host->tx_gem_obj);
>> +		pr_err("%s: failed to allocate gem, %d\n",
>> +			__func__, ret);
>> +		msm_host->tx_gem_obj = NULL;
>> +		return ret;
>> +	}
>> +
>> +	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
>> +			priv->kms->aspace, &iova);
>> +	mutex_unlock(&dev->struct_mutex);
>> +	if (ret) {
>> +		pr_err("%s: failed to get iova, %d\n", __func__, ret);
>> +		return ret;
>> +	}
>> +
>> +	if (iova & 0x07) {
>> +		pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
>> +		return -EINVAL;
>> +	}
> 
> This is impossible - new allocations will always be page aligned.
> 

Its always good to review and remove older code paths :).
Sure will remove this check.

>> +	msm_host->tx_size = msm_host->tx_gem_obj->size;
>> +
>> +	return 0;
>> +}
>> +
>> +int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
>> +{
>> +	struct drm_device *dev = msm_host->dev;
>> +	int ret;
>> +
>> +	msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
>> +					&msm_host->tx_buf_paddr, GFP_KERNEL);
>> +	if (!msm_host->tx_buf) {
>> +		ret = -ENOMEM;
>> +		pr_err("%s: failed to allocate tx buf, %d\n",
>> +			__func__, ret);
> 
> You don't need to print ret here, it isn't a mystery what it is.  In fact, you
> probably don't need to print anything here at all because dma_alloc_coherent
> should be pretty noisy when it fails.
> 
>> +		return ret;
> 
> This can just be return -ENOMEM and you can lose 'ret'.
> 

yep makes sense, will replace it.

>> +	}
>> +
>> +	msm_host->tx_size = size;
>> +
>> +	return 0;
>> +}
>> +
>>   /* dsi_cmd */
>>   static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
>>   {
>> @@ -1072,6 +1278,21 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host)
>>   			msm_host->tx_buf_paddr);
>>   }
>>   
>> +void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host)
>> +{
>> +	return msm_gem_get_vaddr(msm_host->tx_gem_obj);
>> +}
>> +
>> +void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host)
>> +{
>> +	return msm_host->tx_buf;
>> +}
>> +
>> +void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host)
>> +{
>> +	msm_gem_put_vaddr(msm_host->tx_gem_obj);
>> +}
>> +
>>   /*
>>    * prepare cmd buffer to be txed
>>    */
>> @@ -1173,6 +1394,31 @@ static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg)
>>   	return msg->rx_len;
>>   }
>>   
>> +int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *dma_base)
>> +{
>> +	struct drm_device *dev = msm_host->dev;
>> +	struct msm_drm_private *priv = dev->dev_private;
>> +	uint64_t **iova;
>> +	int ret;
>> +
>> +	if (!dma_base)
>> +		return -EINVAL;
>> +
>> +	iova = &dma_base;
> 
> This is a convoluted way of passing in the pointer and I doubt even the compiler
> can see through it.
> 
>> +	ret = msm_gem_get_iova(msm_host->tx_gem_obj,
>> +				priv->kms->aspace, *iova);
> 
> ret = msm_gem_get_iova(msm_host->tx_gem_obj, priv->kms->aspace, dma_base);
> 
> Easy, safe effective
> 
>> +	return ret;
> 
> If you put a return on the front of the msm_gem_get_iova you can eliminate the
> need for 'ret'.
> 

ok will do just that.

> Jordan
> 

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc, is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions
       [not found]       ` <1091cdf6-7322-17ad-f156-c65cfe7df87a-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-03-13  7:01         ` Sibi S
  0 siblings, 0 replies; 12+ messages in thread
From: Sibi S @ 2018-03-13  7:01 UTC (permalink / raw)
  To: Archit Taneja, robdclark-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hi Archit,
Thanks for the review.

On 03/13/2018 10:49 AM, Archit Taneja wrote:
> 
> 
> On Monday 12 March 2018 06:53 PM, Sibi S wrote:
>> Add dsi host helper function implementation for DSI v2
>> and DSI 6G 1.x controllers
>>
>> Signed-off-by: Sibi S <sibis@codeaurora.org>
>> ---
>>   drivers/gpu/drm/msm/dsi/dsi.h      |  15 +++
>>   drivers/gpu/drm/msm/dsi/dsi_cfg.c  |  44 +++++--
>>   drivers/gpu/drm/msm/dsi/dsi_host.c | 250 
>> ++++++++++++++++++++++++++++++++++++-
>>   3 files changed, 298 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h 
>> b/drivers/gpu/drm/msm/dsi/dsi.h
>> index 80be83e..dfa049d 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi.h
>> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
>> @@ -183,6 +183,21 @@ int msm_dsi_host_modeset_init(struct 
>> mipi_dsi_host *host,
>>   int msm_dsi_host_init(struct msm_dsi *msm_dsi);
>>   int msm_dsi_runtime_suspend(struct device *dev);
>>   int msm_dsi_runtime_resume(struct device *dev);
>> +int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
>> +int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
>> +void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
>> +void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
>> +int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
>> +int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
>> +void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
>> +void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host);
>> +void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host);
>> +int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova);
>> +int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
>> +int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
>> +int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
>> +int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host);
>> +int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host);
>>   /* dsi phy */
>>   struct msm_dsi_phy;
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c 
>> b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
>> index 0327bb5..dc51aaa 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
>> +++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
>> @@ -136,20 +136,46 @@
>>       .num_dsi = 2,
>>   };
>> +const static struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
>> +    .link_clk_enable = dsi_link_clk_enable_v2,
>> +    .link_clk_disable = dsi_link_clk_disable_v2,
>> +    .clk_init_ver = dsi_clk_init_v2,
>> +    .tx_buf_alloc = dsi_tx_buf_alloc_v2,
>> +    .tx_buf_get = dsi_tx_buf_get_v2,
>> +    .tx_buf_put = NULL,
>> +    .dma_base_get = dsi_dma_base_get_v2,
>> +    .calc_clk_rate = dsi_calc_clk_rate_v2,
>> +};
>> +
>> +const static struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
>> +    .link_clk_enable = dsi_link_clk_enable_6g,
>> +    .link_clk_disable = dsi_link_clk_disable_6g,
>> +    .clk_init_ver = NULL,
>> +    .tx_buf_alloc = dsi_tx_buf_alloc_6g,
>> +    .tx_buf_get = dsi_tx_buf_get_6g,
>> +    .tx_buf_put = dsi_tx_buf_put_6g,
>> +    .dma_base_get = dsi_dma_base_get_6g,
>> +    .calc_clk_rate = dsi_calc_clk_rate_6g,
>> +};
> 
> Could you introduce the host ops for SDM845 (i.e,
> msm_dsi_6g_v2_host_ops) in this patch itself? It would be nice to
> keep the DSI command broadcast code as a separate patch since it
> probably needs to go through more iterations.
> 
> The ops approach looks good otherwise.
> 
> Thanks,
> Archit
> 

Sure I'll re-order them and probably should separately post
separate patch series for command broadcast on sdm845.

>>   static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
>> -    {MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064, &apq8064_dsi_cfg},
>> +    {MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064,
>> +        &apq8064_dsi_cfg, &msm_dsi_v2_host_ops},
>>       {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0,
>> -                        &msm8974_apq8084_dsi_cfg},
>> +        &msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
>>       {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1,
>> -                        &msm8974_apq8084_dsi_cfg},
>> +        &msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
>>       {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1_1,
>> -                        &msm8974_apq8084_dsi_cfg},
>> +        &msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
>>       {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_2,
>> -                        &msm8974_apq8084_dsi_cfg},
>> -    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3, &msm8994_dsi_cfg},
>> -    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1, 
>> &msm8916_dsi_cfg},
>> -    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1, 
>> &msm8996_dsi_cfg},
>> -    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1, 
>> &sdm845_dsi_cfg},
>> +        &msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
>> +    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3,
>> +        &msm8994_dsi_cfg, &msm_dsi_6g_host_ops},
>> +    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1,
>> +        &msm8916_dsi_cfg, &msm_dsi_6g_host_ops},
>> +    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
>> +        &msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
>> +    {MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
>> +        &sdm845_dsi_cfg, &msm_dsi_6g_host_ops},
>>   };
>>   const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
>> b/drivers/gpu/drm/msm/dsi/dsi_host.c
>> index 7a03a94..f7a066d 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
>> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
>> @@ -331,6 +331,54 @@ static int dsi_regulator_init(struct msm_dsi_host 
>> *msm_host)
>>       return 0;
>>   }
>> +int dsi_clk_init_v2(struct msm_dsi_host *msm_host)
>> +{
>> +    struct platform_device *pdev = msm_host->pdev;
>> +    int ret = 0;
>> +
>> +    msm_host->src_clk = msm_clk_get(pdev, "src");
>> +
>> +    if (IS_ERR(msm_host->src_clk)) {
>> +        ret = PTR_ERR(msm_host->src_clk);
>> +        pr_err("%s: can't find src clock. ret=%d\n",
>> +            __func__, ret);
>> +        msm_host->src_clk = NULL;
>> +        return ret;
>> +    }
>> +
>> +    msm_host->esc_clk_src = clk_get_parent(msm_host->esc_clk);
>> +    if (!msm_host->esc_clk_src) {
>> +        ret = -ENODEV;
>> +        pr_err("%s: can't get esc clock parent. ret=%d\n",
>> +            __func__, ret);
>> +        return ret;
>> +    }
>> +
>> +    msm_host->dsi_clk_src = clk_get_parent(msm_host->src_clk);
>> +    if (!msm_host->dsi_clk_src) {
>> +        ret = -ENODEV;
>> +        pr_err("%s: can't get src clock parent. ret=%d\n",
>> +            __func__, ret);
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>> +int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host)
>> +{
>> +    struct platform_device *pdev = msm_host->pdev;
>> +    int ret = 0;
>> +
>> +    msm_host->byte_intf_clk = msm_clk_get(pdev, "byte_intf");
>> +    if (IS_ERR(msm_host->byte_intf_clk)) {
>> +        ret = PTR_ERR(msm_host->byte_intf_clk);
>> +        pr_err("%s: can't find byte_intf clock. ret=%d\n",
>> +            __func__, ret);
>> +    }
>> +
>> +    return ret;
>> +}
>> +
>>   static int dsi_clk_init(struct msm_dsi_host *msm_host)
>>   {
>>       struct platform_device *pdev = msm_host->pdev;
>> @@ -497,7 +545,7 @@ int msm_dsi_runtime_resume(struct device *dev)
>>       return dsi_bus_clk_enable(msm_host);
>>   }
>> -static int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
>> +int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
>>   {
>>       int ret;
>> @@ -565,7 +613,7 @@ static int dsi_link_clk_enable_6g(struct 
>> msm_dsi_host *msm_host)
>>       return ret;
>>   }
>> -static int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
>> +int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
>>   {
>>       int ret;
>> @@ -643,6 +691,23 @@ static int dsi_link_clk_enable(struct 
>> msm_dsi_host *msm_host)
>>           return dsi_link_clk_enable_v2(msm_host);
>>   }
>> +void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
>> +{
>> +    clk_disable_unprepare(msm_host->esc_clk);
>> +    clk_disable_unprepare(msm_host->pixel_clk);
>> +    if (msm_host->byte_intf_clk)
>> +        clk_disable_unprepare(msm_host->byte_intf_clk);
>> +    clk_disable_unprepare(msm_host->byte_clk);
>> +}
>> +
>> +void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
>> +{
>> +    clk_disable_unprepare(msm_host->pixel_clk);
>> +    clk_disable_unprepare(msm_host->src_clk);
>> +    clk_disable_unprepare(msm_host->esc_clk);
>> +    clk_disable_unprepare(msm_host->byte_clk);
>> +}
>> +
>>   static void dsi_link_clk_disable(struct msm_dsi_host *msm_host)
>>   {
>>       const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>> @@ -661,6 +726,94 @@ static void dsi_link_clk_disable(struct 
>> msm_dsi_host *msm_host)
>>       }
>>   }
>> +int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host)
>> +{
>> +    struct drm_display_mode *mode = msm_host->mode;
>> +    u8 lanes = msm_host->lanes;
>> +    u32 bpp = dsi_get_bpp(msm_host->format);
>> +    u32 pclk_rate;
>> +
>> +    if (!mode) {
>> +        pr_err("%s: mode not set\n", __func__);
>> +        return -EINVAL;
>> +    }
>> +
>> +    pclk_rate = mode->clock * 1000;
>> +    if (lanes > 0) {
>> +        msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
>> +    } else {
>> +        pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
>> +        msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
>> +    }
>> +
>> +    DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
>> +
>> +    msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
>> +
>> +    return 0;
>> +}
>> +
>> +int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host)
>> +{
>> +    struct drm_display_mode *mode = msm_host->mode;
>> +    u8 lanes = msm_host->lanes;
>> +    u32 bpp = dsi_get_bpp(msm_host->format);
>> +    u32 pclk_rate;
>> +    unsigned int esc_mhz, esc_div;
>> +    unsigned long byte_mhz;
>> +
>> +    if (!mode) {
>> +        pr_err("%s: mode not set\n", __func__);
>> +        return -EINVAL;
>> +    }
>> +
>> +    pclk_rate = mode->clock * 1000;
>> +    if (lanes > 0) {
>> +        msm_host->byte_clk_rate = (pclk_rate * bpp) / (8 * lanes);
>> +    } else {
>> +        pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
>> +        msm_host->byte_clk_rate = (pclk_rate * bpp) / 8;
>> +    }
>> +
>> +    DBG("pclk=%d, bclk=%d", pclk_rate, msm_host->byte_clk_rate);
>> +
>> +    msm_host->src_clk_rate = (pclk_rate * bpp) / 8;
>> +
>> +    /*
>> +     * esc clock is byte clock followed by a 4 bit divider,
>> +     * we need to find an escape clock frequency within the
>> +     * mipi DSI spec range within the maximum divider limit
>> +     * We iterate here between an escape clock frequencey
>> +     * between 20 Mhz to 5 Mhz and pick up the first one
>> +     * that can be supported by our divider
>> +     */
>> +
>> +    byte_mhz = msm_host->byte_clk_rate / 1000000;
>> +
>> +    for (esc_mhz = 20; esc_mhz >= 5; esc_mhz--) {
>> +        esc_div = DIV_ROUND_UP(byte_mhz, esc_mhz);
>> +
>> +        /*
>> +         * TODO: Ideally, we shouldn't know what sort of divider
>> +         * is available in mmss_cc, we're just assuming that
>> +         * it'll always be a 4 bit divider. Need to come up with
>> +         * a better way here.
>> +         */
>> +        if (esc_div >= 1 && esc_div <= 16)
>> +            break;
>> +    }
>> +
>> +    if (esc_mhz < 5)
>> +        return -EINVAL;
>> +
>> +    msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
>> +
>> +    DBG("esc=%d, src=%d", msm_host->esc_clk_rate,
>> +        msm_host->src_clk_rate);
>> +
>> +    return 0;
>> +}
>> +
>>   static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
>>   {
>>       struct drm_display_mode *mode = msm_host->mode;
>> @@ -1008,6 +1161,59 @@ static void dsi_wait4video_eng_busy(struct 
>> msm_dsi_host *msm_host)
>>       }
>>   }
>> +int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
>> +{
>> +    struct drm_device *dev = msm_host->dev;
>> +    struct msm_drm_private *priv = dev->dev_private;
>> +    int ret;
>> +    uint64_t iova;
>> +
>> +    msm_host->tx_gem_obj = msm_gem_new(dev, size, MSM_BO_UNCACHED);
>> +    if (IS_ERR(msm_host->tx_gem_obj)) {
>> +        ret = PTR_ERR(msm_host->tx_gem_obj);
>> +        pr_err("%s: failed to allocate gem, %d\n",
>> +            __func__, ret);
>> +        msm_host->tx_gem_obj = NULL;
>> +        return ret;
>> +    }
>> +
>> +    ret = msm_gem_get_iova(msm_host->tx_gem_obj,
>> +            priv->kms->aspace, &iova);
>> +    mutex_unlock(&dev->struct_mutex);
>> +    if (ret) {
>> +        pr_err("%s: failed to get iova, %d\n", __func__, ret);
>> +        return ret;
>> +    }
>> +
>> +    if (iova & 0x07) {
>> +        pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
>> +        return -EINVAL;
>> +    }
>> +
>> +    msm_host->tx_size = msm_host->tx_gem_obj->size;
>> +
>> +    return 0;
>> +}
>> +
>> +int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
>> +{
>> +    struct drm_device *dev = msm_host->dev;
>> +    int ret;
>> +
>> +    msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
>> +                    &msm_host->tx_buf_paddr, GFP_KERNEL);
>> +    if (!msm_host->tx_buf) {
>> +        ret = -ENOMEM;
>> +        pr_err("%s: failed to allocate tx buf, %d\n",
>> +            __func__, ret);
>> +        return ret;
>> +    }
>> +
>> +    msm_host->tx_size = size;
>> +
>> +    return 0;
>> +}
>> +
>>   /* dsi_cmd */
>>   static int dsi_tx_buf_alloc(struct msm_dsi_host *msm_host, int size)
>>   {
>> @@ -1072,6 +1278,21 @@ static void dsi_tx_buf_free(struct msm_dsi_host 
>> *msm_host)
>>               msm_host->tx_buf_paddr);
>>   }
>> +void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host)
>> +{
>> +    return msm_gem_get_vaddr(msm_host->tx_gem_obj);
>> +}
>> +
>> +void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host)
>> +{
>> +    return msm_host->tx_buf;
>> +}
>> +
>> +void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host)
>> +{
>> +    msm_gem_put_vaddr(msm_host->tx_gem_obj);
>> +}
>> +
>>   /*
>>    * prepare cmd buffer to be txed
>>    */
>> @@ -1173,6 +1394,31 @@ static int dsi_long_read_resp(u8 *buf, const 
>> struct mipi_dsi_msg *msg)
>>       return msg->rx_len;
>>   }
>> +int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t 
>> *dma_base)
>> +{
>> +    struct drm_device *dev = msm_host->dev;
>> +    struct msm_drm_private *priv = dev->dev_private;
>> +    uint64_t **iova;
>> +    int ret;
>> +
>> +    if (!dma_base)
>> +        return -EINVAL;
>> +
>> +    iova = &dma_base;
>> +    ret = msm_gem_get_iova(msm_host->tx_gem_obj,
>> +                priv->kms->aspace, *iova);
>> +    return ret;
>> +}
>> +
>> +int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t 
>> *dma_base)
>> +{
>> +    if (!dma_base)
>> +        return -EINVAL;
>> +
>> +    *dma_base = msm_host->tx_buf_paddr;
>> +    return 0;
>> +}
>> +
>>   static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
>>   {
>>       const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
>>
> 

-- 
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc, is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2018-03-13  7:01 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-12 13:23 [PATCH 0/5] Cleanup excessive DSI host controller version checks Sibi S
2018-03-12 13:23 ` [PATCH 1/5] drm/msm/dsi: add dsi host helper functions support Sibi S
2018-03-12 13:23 ` [PATCH 2/5] drm/msm/dsi: add implementation for helper functions Sibi S
     [not found]   ` <1520860994-23334-3-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-12 15:13     ` Jordan Crouse
     [not found]       ` <20180312151352.GA28808-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2018-03-13  6:57         ` Sibi S
2018-03-13  5:19     ` Archit Taneja
     [not found]       ` <1091cdf6-7322-17ad-f156-c65cfe7df87a-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-13  7:01         ` Sibi S
2018-03-12 13:23 ` [PATCH 3/5] drm/msm/dsi: replace version checks with " Sibi S
     [not found]   ` <1520860994-23334-4-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-13  5:20     ` Archit Taneja
2018-03-12 13:23 ` [PATCH 4/5] drm/msm/dsi: implement 6G v2.0+ DSI command broadcast Sibi S
     [not found]   ` <1520860994-23334-5-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-03-13  5:30     ` Archit Taneja
2018-03-12 13:23 ` [PATCH 5/5] drm/msm/dsi: replace version checks for commmand broadcast Sibi S

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.