Skip to contentSkip to conversation

Cleanup excessive DSI host controller version checks

PATCH Superseded Sibi S 4 participants 12 messages Mar 12, 2018 – Mar 13, 2018 5 messages not in the archive

Subsystems (3)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Sibi S

author
#0 lore raw

cover Cleanup excessive DSI host controller version checks

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(-)
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#1 lore raw

PATCH 1/5 drm/msm/dsi: add dsi host helper functions support

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

---
 drivers/gpu/drm/msm/dsi/dsi.h     |  1 +
 drivers/gpu/drm/msm/dsi/dsi_cfg.h | 12 ++++++++++++
 2 files changed, 13 insertions(+)
drivers/gpu/drm/msm/dsi/dsi.h +1 -0
index 70d9a9a..80be83e 100644
@@ -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,
drivers/gpu/drm/msm/dsi/dsi_cfg.h +12 -0
index 9cfdcf1..a795a06 100644
@@ -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);
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
author
#2 lore raw

PATCH 2/5 drm/msm/dsi: add implementation for helper functions

In reply to Sibi S

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

---
 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(-)
drivers/gpu/drm/msm/dsi/dsi.h +15 -0
index 80be83e..dfa049d 100644
@@ -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;
drivers/gpu/drm/msm/dsi/dsi_cfg.c +35 -9

55 lines not on this page · raw message

drivers/gpu/drm/msm/dsi/dsi_host.c +248 -2

298 lines not on this page · raw message

Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

A message that is not in the archive (sent off-list or not yet received): 1520860994-23334-3-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org

#4 lore raw

Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions

Quoted 9 lines · Sibi S

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

---
 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>

Quoted 25 lines

static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host) {

drivers/gpu/drm/msm/dsi/dsi_host.c +18 -0
 	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);

drivers/gpu/drm/msm/dsi/dsi_host.c static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) · line 1191

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +10 -0
+	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.

Quoted 6 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +6 -0
+	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)

drivers/gpu/drm/msm/dsi/dsi_host.c static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) · line 1208

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +10 -0
+{
+	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.

Review static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) · line 1208

Quoted 1 line
(quoted diff) +1 -0
+		return ret;

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

Quoted 37 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +23 -0
+	}
+
+	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)

drivers/gpu/drm/msm/dsi/dsi_host.c static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) · line 1407

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +10 -0
+{
+	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.

drivers/gpu/drm/msm/dsi/dsi_host.c static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) · line 1409

Quoted 2 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +2 -0
+	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

Review static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) · line 1410

Quoted 1 line
(quoted diff) +1 -0
+	return ret;

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

Jordan

Signature · 6 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

A message that is not in the archive (sent off-list or not yet received): 20180312151352.GA28808-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org

#6 lore raw

Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions

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

Quoted 41 lines · Jordan Crouse
Quoted 9 lines · Sibi S

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

---
  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>

Quoted 29 lines
  static int dsi_calc_clk_rate(struct msm_dsi_host *msm_host)
  {
  	struct drm_display_mode *mode = msm_host->mode;
drivers/gpu/drm/msm/dsi/dsi_host.c +22 -0
@@ -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;
Quoted 9 lines

drivers/gpu/drm/msm/dsi/dsi_host.c static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) · line 1191

Quoted 6 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +6 -0
+	}
+
+	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.

Quoted 21 lines
Quoted 6 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +6 -0
+	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)

drivers/gpu/drm/msm/dsi/dsi_host.c static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) · line 1208

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +10 -0
+{
+	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.

Quoted 4 lines

Review static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) · line 1208

Quoted 1 line
(quoted diff) +1 -0
+		return ret;

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

yep makes sense, will replace it.

Quoted 56 lines
Quoted 37 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +23 -0
+	}
+
+	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)

drivers/gpu/drm/msm/dsi/dsi_host.c static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) · line 1407

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +10 -0
+{
+	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.

drivers/gpu/drm/msm/dsi/dsi_host.c static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) · line 1409

Quoted 2 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +2 -0
+	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);

Quoted 7 lines

Easy, safe effective

Review static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) · line 1410

Quoted 1 line
(quoted diff) +1 -0
+	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.

Quoted 2 lines

Jordan

Signature · 7 lines
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc, is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#7 lore raw

Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions

In reply to a message not in the archive
Quoted 55 lines · Sibi S

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

---
  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(-)
drivers/gpu/drm/msm/dsi/dsi.h +15 -0
index 80be83e..dfa049d 100644
@@ -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;
drivers/gpu/drm/msm/dsi/dsi_cfg.c +11 -0
index 0327bb5..dc51aaa 100644
@@ -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,
+};
+

drivers/gpu/drm/msm/dsi/dsi_cfg.c line 159

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_cfg.c +10 -0
+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

Quoted 332 lines
drivers/gpu/drm/msm/dsi/dsi_cfg.c +14 -9
  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)
drivers/gpu/drm/msm/dsi/dsi_host.c +241 -2
index 7a03a94..f7a066d 100644
@@ -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)
+{

drivers/gpu/drm/msm/dsi/dsi_host.c static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg) · line 1424

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +7 -0
+	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
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

A message that is not in the archive (sent off-list or not yet received): 1091cdf6-7322-17ad-f156-c65cfe7df87a-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org

#9 lore raw

Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions

Hi Archit,
Thanks for the review.

Quoted 74 lines · Archit Taneja
Quoted 55 lines · Sibi S

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

---
  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(-)
drivers/gpu/drm/msm/dsi/dsi.h +15 -0
index 80be83e..dfa049d 100644
@@ -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;
drivers/gpu/drm/msm/dsi/dsi_cfg.c +11 -0
index 0327bb5..dc51aaa 100644
@@ -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,
+};
+

drivers/gpu/drm/msm/dsi/dsi_cfg.c line 158

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_cfg.c +10 -0
+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.

Quoted 5 lines

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.

Quoted 344 lines
Quoted 343 lines
drivers/gpu/drm/msm/dsi/dsi_cfg.c +14 -9
   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)

drivers/gpu/drm/msm/dsi/dsi_host.c +248 -2
index 7a03a94..f7a066d 100644
@@ -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;

Signature · 7 lines
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc, is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
author
#10 lore raw

PATCH 3/5 drm/msm/dsi: replace version checks with helper functions

In reply to Sibi S

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

---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 242 +++++--------------------------------
 1 file changed, 29 insertions(+), 213 deletions(-)
drivers/gpu/drm/msm/dsi/dsi_host.c +29 -213
index f7a066d..b755b69 100644
@@ -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);
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

A message that is not in the archive (sent off-list or not yet received): 1520860994-23334-4-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org

Reviewed-by
#12 lore raw

Re: [PATCH 3/5] drm/msm/dsi: replace version checks with helper functions

Quoted 3 lines · Sibi S

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:

Thanks,
Archit

Quoted 418 lines
---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 242 +++++--------------------------------
  1 file changed, 29 insertions(+), 213 deletions(-)
drivers/gpu/drm/msm/dsi/dsi_host.c +28 -212
index f7a066d..b755b69 100644
@@ -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) {

drivers/gpu/drm/msm/dsi/dsi_host.c int msm_dsi_host_power_off(struct mipi_dsi_host *host) · line 2380

Quoted 8 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +1 -1
@@ -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
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

author
#13 lore raw

PATCH 4/5 drm/msm/dsi: implement 6G v2.0+ DSI command broadcast

In reply to Sibi S

From: Archit Taneja <[email protected]>

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

---
 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(-)
drivers/gpu/drm/msm/dsi/dsi.h +5 -0
index dfa049d..22342c30 100644
@@ -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,
drivers/gpu/drm/msm/dsi/dsi_cfg.c +13 -1
index dc51aaa..dcdfb1b 100644
@@ -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)
drivers/gpu/drm/msm/dsi/dsi_host.c +59 -3

87 lines not on this page · raw message

drivers/gpu/drm/msm/dsi/dsi_manager.c +66 -0

78 lines not on this page · raw message

Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

A message that is not in the archive (sent off-list or not yet received): 1520860994-23334-5-git-send-email-sibis-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org

#15 lore raw

Re: [PATCH 4/5] drm/msm/dsi: implement 6G v2.0+ DSI command broadcast

Quoted 2 lines · Sibi S

From: Archit Taneja <[email protected]>

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

Quoted 146 lines

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

---
  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(-)
drivers/gpu/drm/msm/dsi/dsi.h +5 -0
index dfa049d..22342c30 100644
@@ -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,
drivers/gpu/drm/msm/dsi/dsi_cfg.c +13 -1
index dc51aaa..dcdfb1b 100644
@@ -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)
drivers/gpu/drm/msm/dsi/dsi_host.c +47 -3
index b755b69..bd61cad 100644
@@ -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);

drivers/gpu/drm/msm/dsi/dsi_host.c int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host, · line 2048

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +10 -0
+	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.

Quoted 51 lines
drivers/gpu/drm/msm/dsi/dsi_host.c +1 -0
+
  void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
  				const struct mipi_dsi_msg *msg)
  {
drivers/gpu/drm/msm/dsi/dsi_manager.c +39 -0
index 4cb1cb6..393e3ff 100644
@@ -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) :

drivers/gpu/drm/msm/dsi/dsi_manager.c int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) · line 863

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_manager.c +10 -0
+				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.

Quoted 11 lines
drivers/gpu/drm/msm/dsi/dsi_manager.c +4 -0
+
  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);

drivers/gpu/drm/msm/dsi/dsi_manager.c bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len) · line 894

Quoted 10 lines
drivers/gpu/drm/msm/dsi/dsi_manager.c +10 -0
+	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

drivers/gpu/drm/msm/dsi/dsi_manager.c bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len) · line 900

Quoted 7 lines
drivers/gpu/drm/msm/dsi/dsi_manager.c +3 -0
+	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
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

author
#16 lore raw

PATCH 5/5 drm/msm/dsi: replace version checks for commmand broadcast

In reply to Sibi S

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

---
 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(-)
drivers/gpu/drm/msm/dsi/dsi_cfg.c +6 -0
index dcdfb1b..6ec28d1 100644
@@ -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[] = {
drivers/gpu/drm/msm/dsi/dsi_cfg.h +2 -0
index a795a06..145251e 100644
@@ -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 {
drivers/gpu/drm/msm/dsi/dsi_host.c +3 -13
index bd61cad..240ecb8 100644
@@ -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);
 
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel