Cleanup excessive DSI host controller version checks
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
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
@@ -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
@@ -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
PATCH 2/5 drm/msm/dsi: add implementation for helper functions
In reply to Sibi SAdd 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
@@ -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
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
Signed-off-by Sibi S <[email protected]>--- 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
-0struct 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
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
Signed-off-by Sibi S <[email protected]>--- 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_coherentshould 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
-ENOMEMand 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_iovayou 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
Re: [PATCH 2/5] drm/msm/dsi: add implementation for helper functions
In reply to a message not in the archiveQuoted 55 lines · Sibi S
Add dsi host helper function implementation for DSI v2 and DSI 6G 1.x controllers
Signed-off-by Sibi S <[email protected]>--- 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@@ -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@@ -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
-9static 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@@ -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
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
Signed-off-by Sibi S <[email protected]>---
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@@ -183,6 +183,21 @@ int msm_dsi_host_modeset_init(structmipi_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@@ -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
-9static 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@@ -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 structmsm_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
PATCH 3/5 drm/msm/dsi: replace version checks with helper functions
In reply to Sibi SReplace 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
@@ -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
Archit Taneja
Reviewed-byRe: [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_handlerfor DSI v2 and DSI 6G 1.x controllers
With the ops set up for DSI6G 2.x too:
Thanks,
Archit
Quoted 418 lines
Signed-off-by Sibi S <[email protected]>--- 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@@ -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
PATCH 4/5 drm/msm/dsi: implement 6G v2.0+ DSI command broadcast
In reply to Sibi SFrom: 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
@@ -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
@@ -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
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
Signed-off-by Sibi S <[email protected]>--- 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@@ -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@@ -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@@ -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@@ -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
PATCH 5/5 drm/msm/dsi: replace version checks for commmand broadcast
In reply to Sibi SReplace 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
@@ -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
@@ -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
@@ -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