Re: [REPOST PATCH v4 02/13] drm/msm/dsi: Pass DSC params to drm_panel

Abhinav Kumar
2022-03-03T19:08:13Z

On 2/21/2022 4:37 AM, Dmitry Baryshkov wrote:
> On 10/02/2022 13:34, Vinod Koul wrote:
>> When DSC is enabled, we need to pass the DSC parameters to panel driver
>> as well, so add a dsc parameter in panel and set it when DSC is enabled
>>
>> Also, fetch and pass DSC configuration for DSI panels to DPU encoder,
>> which will enable and configure DSC hardware blocks accordingly.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> Signed-off-by: Vinod Koul <vkoul@kernel.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  2 ++
>>   drivers/gpu/drm/msm/dsi/dsi.c           |  5 +++++
>>   drivers/gpu/drm/msm/dsi/dsi.h           |  1 +
>>   drivers/gpu/drm/msm/dsi/dsi_host.c      | 22 ++++++++++++++++++++++
>>   drivers/gpu/drm/msm/msm_drv.h           |  8 ++++++++
>>   include/drm/drm_panel.h                 |  7 +++++++
>>   6 files changed, 45 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> index 47fe11a84a77..ef6ddac22767 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> @@ -578,6 +578,8 @@ static int _dpu_kms_initialize_dsi(struct
>> drm_device *dev,
>>               MSM_DISPLAY_CAP_CMD_MODE :
>>               MSM_DISPLAY_CAP_VID_MODE;
>> +        info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]);
>> +
>>           if (msm_dsi_is_bonded_dsi(priv->dsi[i]) && priv->dsi[other]) {
>>               rc = msm_dsi_modeset_init(priv->dsi[other], dev, encoder);
>>               if (rc) {
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi.c
>> b/drivers/gpu/drm/msm/dsi/dsi.c
>> index 052548883d27..3aeac15e7421 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi.c
>> +++ b/drivers/gpu/drm/msm/dsi/dsi.c
>> @@ -20,6 +20,11 @@ bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
>>       return !(host_flags & MIPI_DSI_MODE_VIDEO);
>>   }
>> +struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi
>> *msm_dsi)
>> +{
>> +    return msm_dsi_host_get_dsc_config(msm_dsi->host);
>> +}
>> +
>>   static int dsi_get_phy(struct msm_dsi *msm_dsi)
>>   {
>>       struct platform_device *pdev = msm_dsi->pdev;
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h
>> b/drivers/gpu/drm/msm/dsi/dsi.h
>> index c8dedc95428c..16cd9b2fce86 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi.h
>> +++ b/drivers/gpu/drm/msm/dsi/dsi.h
>> @@ -152,6 +152,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host
>> *msm_host, bool is_bonded_dsi);
>>   int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool
>> is_bonded_dsi);
>>   void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct
>> mipi_dsi_host *host);
>>   void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
>> +struct msm_display_dsc_config *msm_dsi_host_get_dsc_config(struct
>> mipi_dsi_host *host);
>>   /* dsi phy */
>>   struct msm_dsi_phy;
>> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
>> b/drivers/gpu/drm/msm/dsi/dsi_host.c
>> index 27553194f9fa..7e9913eff724 100644
>> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
>> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
>> @@ -2059,9 +2059,24 @@ int msm_dsi_host_modeset_init(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;
>> +    struct drm_panel *panel;
>>       int ret;
>>       msm_host->dev = dev;
>> +    panel = msm_dsi_host_get_panel(&msm_host->base);
>> +
>> +    if (panel && panel->dsc) {
>> +        struct msm_display_dsc_config *dsc = msm_host->dsc;
>> +
>> +        if (!dsc) {
>> +            dsc = devm_kzalloc(&msm_host->pdev->dev, sizeof(*dsc),
>> GFP_KERNEL);
>> +            if (!dsc)
>> +                return -ENOMEM;
>> +            dsc->drm = panel->dsc;
>> +            msm_host->dsc = dsc;
>> +        }
>> +    }
>> +
>>       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);
>> @@ -2626,3 +2641,10 @@ void msm_dsi_host_test_pattern_en(struct
>> mipi_dsi_host *host)
>>           dsi_write(msm_host,
>> REG_DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER,
>>                   DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER_SW_TRIGGER);
>>   }
>> +
>> +struct msm_display_dsc_config *msm_dsi_host_get_dsc_config(struct
>> mipi_dsi_host *host)
>> +{
>> +    struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
>> +
>> +    return msm_host->dsc;
>> +}
>> diff --git a/drivers/gpu/drm/msm/msm_drv.h
>> b/drivers/gpu/drm/msm/msm_drv.h
>> index 384f9bad4760..e7a312edfe67 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.h
>> +++ b/drivers/gpu/drm/msm/msm_drv.h
>> @@ -119,6 +119,7 @@ struct msm_display_topology {
>>    *                      based on num_of_h_tiles
>>    * @is_te_using_watchdog_timer:  Boolean to indicate watchdog TE is
>>    *                 used instead of panel TE in cmd mode panels
>> + * @dsc:        DSC configuration data for DSC-enabled displays
>>    */
>>   struct msm_display_info {
>>       int intf_type;
>> @@ -126,6 +127,7 @@ struct msm_display_info {
>>       uint32_t num_of_h_tiles;
>>       uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
>>       bool is_te_using_watchdog_timer;
>> +    struct msm_display_dsc_config *dsc;
>>   };
>>   /* Commit/Event thread specific structure */
>> @@ -365,6 +367,7 @@ void msm_dsi_snapshot(struct msm_disp_state
>> *disp_state, struct msm_dsi *msm_dsi
>>   bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi);
>>   bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi);
>>   bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi);
>> +struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi
>> *msm_dsi);
>>   #else
>>   static inline void __init msm_dsi_register(void)
>>   {
>> @@ -393,6 +396,11 @@ static inline bool msm_dsi_is_master_dsi(struct
>> msm_dsi *msm_dsi)
>>   {
>>       return false;
>>   }
>> +
>> +static inline struct msm_display_dsc_config
>> *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
>> +{
>> +    return NULL;
>> +}
>>   #endif
>>   #ifdef CONFIG_DRM_MSM_DP
>> diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
>> index 4602f833eb51..eb8ae9bf32ed 100644
>> --- a/include/drm/drm_panel.h
>> +++ b/include/drm/drm_panel.h
>> @@ -171,6 +171,13 @@ struct drm_panel {
>>        * Panel entry in registry.
>>        */
>>       struct list_head list;
>> +
>> +    /**
>> +     * @dsc:
>> +     *
>> +     * Panel DSC pps payload to be sent
>> +     */
>> +    struct drm_dsc_config *dsc;
>
> This is not a blocker or a request for a change, just a kind of thought:
>
> I've been looking onto this change for a while from the following point
> of view. I'd like to switch DSI driver to use panel
> bridge/drm_bridge_connector(). This simplifies handling of DRM bridge
> chains.
>
> Also since DSC can be consumed not by the panel itself, but by the next
> bridge in chain (e.g. it's supported on the DSI input by the ANX7625
> bridge), using drm_panel doesn't look completely correct.
>
> So, I have been looking for a better way to pass DSC configuration.
>
> For DSI we can use struct mipi_dsi_device (together with the rest of
> data we are passing from DSI device driver to DSI host). This would
> allow both DSI panels and DSI bridges to pass the DSC config to the
> previous deivce in chain (DSI host).
>
> Any comments/thoughs?
>
> Note, for DP this problem doesn't exist. The DSC config is a part of
> DPDC, so it will be parsed by the msm/dp driver in a natural way.
>

Yes, i do agree that in case of bridges in between , drm_panel is not
necessarily the best place to do it and mipi_dsi_device is better.

However, I also think we can do this post the cleanup fo move to panel
bridge.

>
>>   };
>>   void drm_panel_init(struct drm_panel *panel, struct device *dev,
>
>