[Freedreno] [PATCH 1/7] drm/msm/dpu: merge dpu_encoder_init() and dpu_encoder_setup()

Dmitry Baryshkov dmitry.baryshkov at linaro.org
Mon May 1 21:27:18 UTC 2023


On 02/05/2023 00:22, Abhinav Kumar wrote:
> 
> 
> On 5/1/2023 1:45 PM, Dmitry Baryshkov wrote:
>> On 01/05/2023 22:58, Abhinav Kumar wrote:
>>>
>>>
>>> On 4/30/2023 4:57 PM, Dmitry Baryshkov wrote:
>>>> There is no reason to split the dpu_encoder interface into separate
>>>> _init() and _setup() phases. Merge them into a single function.
>>>>
>>>
>>> I think the reason for having this split was to pass a valid encoder 
>>> to the interface_modeset_init() and then do the rest of encoder 
>>> initialization after modeset_init().
>>>
>>> Looking at the current code, one issue i am seeing is that you will 
>>> now initialize the dpu_encoder's msm_display_info along with 
>>> dpu_encoder_init().
>>>
>>> Most of it is fine but in the case of bonded_dsi(), I see an issue.
>>>
>>> The info.num_of_h_tiles++ happens after the modeset_init() of the 
>>> second dsi but now it has been moved earlier.
>>>
>>> If for some reason, msm_dsi_modeset_init() fails for the second DSI, 
>>> num_of_h_tiles will still be 2 now.
>>
>> If msm_dsi_modeset_init() fails, the function will err out and fail 
>> dpu_kms initialization. So it's not important, what is the value of 
>> num_h_tiles in this case.
>>
> 
> But I still feel the msm_display_info should be saved in the dpu encoder 
> after the modeset_init() and not before. That way if some display 
> interface specific init is done in the modeset_init(), we save the info 
> after that.

Up to now we have been using 'poll' model, e.g. we specifically asked 
for the DSC info from the DSI host rather than making msm_dsi set it. So 
far I don't see a good reason why this should be changed.

> 
>>>
>>> Even for multi-DP case, the idea originally was the encoder gets 
>>> setup for that display after the modeset_init() of that display.
>>>
>>> This might become more relevant for DSC perhaps. So lets say first 
>>> encoder needs DSC and second doesnt, we would know that only post 
>>> msm_dp_modeset_init().
>>>
>>> So I think if you move the memcpy(&dpu_enc->disp_info, disp_info, 
>>> sizeof(*disp_info)); line out to be done after modeset_init(), this 
>>> change would look okay.
>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>>>> ---
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 55 +++++--------
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 14 +---
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     | 87 
>>>> ++++++++-------------
>>>>   3 files changed, 56 insertions(+), 100 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>>> index b34416cbd0f5..32785cb1b079 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>>> @@ -2377,7 +2377,8 @@ static const struct drm_encoder_funcs 
>>>> dpu_encoder_funcs = {
>>>>           .early_unregister = dpu_encoder_early_unregister,
>>>>   };
>>>> -int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
>>>> +struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
>>>> +        int drm_enc_mode,
>>>>           struct msm_display_info *disp_info)
>>>>   {
>>>>       struct msm_drm_private *priv = dev->dev_private;
>>>> @@ -2386,7 +2387,23 @@ int dpu_encoder_setup(struct drm_device *dev, 
>>>> struct drm_encoder *enc,
>>>>       struct dpu_encoder_virt *dpu_enc = NULL;
>>>>       int ret = 0;
>>>> -    dpu_enc = to_dpu_encoder_virt(enc);
>>>> +    dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL);
>>>> +    if (!dpu_enc)
>>>> +        return ERR_PTR(-ENOMEM);
>>>> +
>>>> +    ret = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs,
>>>> +                   drm_enc_mode, NULL);
>>>> +    if (ret) {
>>>> +        devm_kfree(dev->dev, dpu_enc);
>>>> +        return ERR_PTR(ret);
>>>> +    }
>>>> +
>>>> +    drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs);
>>>> +
>>>> +    spin_lock_init(&dpu_enc->enc_spinlock);
>>>> +    dpu_enc->enabled = false;
>>>> +    mutex_init(&dpu_enc->enc_lock);
>>>> +    mutex_init(&dpu_enc->rc_lock);
>>>>       ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info);
>>>>       if (ret)
>>>> @@ -2415,44 +2432,14 @@ int dpu_encoder_setup(struct drm_device 
>>>> *dev, struct drm_encoder *enc,
>>>>       DPU_DEBUG_ENC(dpu_enc, "created\n");
>>>> -    return ret;
>>>> +    return &dpu_enc->base;
>>>>   fail:
>>>>       DPU_ERROR("failed to create encoder\n");
>>>>       if (drm_enc)
>>>>           dpu_encoder_destroy(drm_enc);
>>>> -    return ret;
>>>> -
>>>> -
>>>> -}
>>>> -
>>>> -struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
>>>> -        int drm_enc_mode)
>>>> -{
>>>> -    struct dpu_encoder_virt *dpu_enc = NULL;
>>>> -    int rc = 0;
>>>> -
>>>> -    dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL);
>>>> -    if (!dpu_enc)
>>>> -        return ERR_PTR(-ENOMEM);
>>>> -
>>>> -
>>>> -    rc = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs,
>>>> -                              drm_enc_mode, NULL);
>>>> -    if (rc) {
>>>> -        devm_kfree(dev->dev, dpu_enc);
>>>> -        return ERR_PTR(rc);
>>>> -    }
>>>> -
>>>> -    drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs);
>>>> -
>>>> -    spin_lock_init(&dpu_enc->enc_spinlock);
>>>> -    dpu_enc->enabled = false;
>>>> -    mutex_init(&dpu_enc->enc_lock);
>>>> -    mutex_init(&dpu_enc->rc_lock);
>>>> -
>>>> -    return &dpu_enc->base;
>>>> +    return ERR_PTR(ret);
>>>>   }
>>>>   int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
>>>> index 6d14f84dd43f..90e1925d7770 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
>>>> @@ -130,20 +130,12 @@ void dpu_encoder_virt_runtime_resume(struct 
>>>> drm_encoder *encoder);
>>>>   /**
>>>>    * dpu_encoder_init - initialize virtual encoder object
>>>>    * @dev:        Pointer to drm device structure
>>>> + * @drm_enc_mode: corresponding DRM_MODE_ENCODER_* constant
>>>>    * @disp_info:  Pointer to display information structure
>>>>    * Returns:     Pointer to newly created drm encoder
>>>>    */
>>>> -struct drm_encoder *dpu_encoder_init(
>>>> -        struct drm_device *dev,
>>>> -        int drm_enc_mode);
>>>> -
>>>> -/**
>>>> - * dpu_encoder_setup - setup dpu_encoder for the display probed
>>>> - * @dev:        Pointer to drm device structure
>>>> - * @enc:        Pointer to the drm_encoder
>>>> - * @disp_info:    Pointer to the display info
>>>> - */
>>>> -int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
>>>> +struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
>>>> +        int drm_enc_mode,
>>>>           struct msm_display_info *disp_info);
>>>>   /**
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>>>> index e1fd7b0f39cd..10bd0fd4ff48 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>>>> @@ -535,15 +535,23 @@ static int _dpu_kms_initialize_dsi(struct 
>>>> drm_device *dev,
>>>>               !msm_dsi_is_master_dsi(priv->dsi[i]))
>>>>               continue;
>>>> -        encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI);
>>>> +        memset(&info, 0, sizeof(info));
>>>> +        info.intf_type = INTF_DSI;
>>>> +
>>>> +        info.h_tile_instance[info.num_of_h_tiles++] = i;
>>>> +        if (msm_dsi_is_bonded_dsi(priv->dsi[i]))
>>>> +            info.h_tile_instance[info.num_of_h_tiles++] = other;
>>>> +
>>>> +        info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]);
>>>> +
>>>> +        info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]);
>>>> +
>>>> +        encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI, &info);
>>>>           if (IS_ERR(encoder)) {
>>>>               DPU_ERROR("encoder init failed for dsi display\n");
>>>>               return PTR_ERR(encoder);
>>>>           }
>>>> -        memset(&info, 0, sizeof(info));
>>>> -        info.intf_type = INTF_DSI;
>>>> -
>>>>           rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder);
>>>>           if (rc) {
>>>>               DPU_ERROR("modeset_init failed for dsi[%d], rc = %d\n",
>>>> @@ -551,11 +559,6 @@ static int _dpu_kms_initialize_dsi(struct 
>>>> drm_device *dev,
>>>>               break;
>>>>           }
>>>> -        info.h_tile_instance[info.num_of_h_tiles++] = i;
>>>> -        info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]);
>>>> -
>>>> -        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) {
>>>> @@ -563,14 +566,7 @@ static int _dpu_kms_initialize_dsi(struct 
>>>> drm_device *dev,
>>>>                       other, rc);
>>>>                   break;
>>>>               }
>>>> -
>>>> -            info.h_tile_instance[info.num_of_h_tiles++] = other;
>>>>           }
>>>> -
>>>> -        rc = dpu_encoder_setup(dev, encoder, &info);
>>>> -        if (rc)
>>>> -            DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n",
>>>> -                  encoder->base.id, rc);
>>>>       }
>>>>       return rc;
>>>> @@ -589,29 +585,23 @@ static int 
>>>> _dpu_kms_initialize_displayport(struct drm_device *dev,
>>>>           if (!priv->dp[i])
>>>>               continue;
>>>> -        encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
>>>> +        memset(&info, 0, sizeof(info));
>>>> +        info.num_of_h_tiles = 1;
>>>> +        info.h_tile_instance[0] = i;
>>>> +        info.intf_type = INTF_DP;
>>>> +
>>>> +        encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS, &info);
>>>>           if (IS_ERR(encoder)) {
>>>>               DPU_ERROR("encoder init failed for dsi display\n");
>>>>               return PTR_ERR(encoder);
>>>>           }
>>>> -        memset(&info, 0, sizeof(info));
>>>>           rc = msm_dp_modeset_init(priv->dp[i], dev, encoder);
>>>>           if (rc) {
>>>>               DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
>>>>               drm_encoder_cleanup(encoder);
>>>>               return rc;
>>>>           }
>>>> -
>>>> -        info.num_of_h_tiles = 1;
>>>> -        info.h_tile_instance[0] = i;
>>>> -        info.intf_type = INTF_DP;
>>>> -        rc = dpu_encoder_setup(dev, encoder, &info);
>>>> -        if (rc) {
>>>> -            DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n",
>>>> -                  encoder->base.id, rc);
>>>> -            return rc;
>>>> -        }
>>>>       }
>>>>       return 0;
>>>> @@ -629,13 +619,17 @@ static int _dpu_kms_initialize_hdmi(struct 
>>>> drm_device *dev,
>>>>       if (!priv->hdmi)
>>>>           return 0;
>>>> -    encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
>>>> +    memset(&info, 0, sizeof(info));
>>>> +    info.num_of_h_tiles = 1;
>>>> +    info.h_tile_instance[0] = i;
>>>> +    info.intf_type = INTF_HDMI;
>>>> +
>>>> +    encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS, &info);
>>>>       if (IS_ERR(encoder)) {
>>>>           DPU_ERROR("encoder init failed for HDMI display\n");
>>>>           return PTR_ERR(encoder);
>>>>       }
>>>> -    memset(&info, 0, sizeof(info));
>>>>       rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder);
>>>>       if (rc) {
>>>>           DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
>>>> @@ -643,16 +637,6 @@ static int _dpu_kms_initialize_hdmi(struct 
>>>> drm_device *dev,
>>>>           return rc;
>>>>       }
>>>> -    info.num_of_h_tiles = 1;
>>>> -    info.h_tile_instance[0] = i;
>>>> -    info.intf_type = INTF_HDMI;
>>>> -    rc = dpu_encoder_setup(dev, encoder, &info);
>>>> -    if (rc) {
>>>> -        DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n",
>>>> -              encoder->base.id, rc);
>>>> -        return rc;
>>>> -    }
>>>> -
>>>>       return 0;
>>>>   }
>>>> @@ -664,14 +648,19 @@ static int 
>>>> _dpu_kms_initialize_writeback(struct drm_device *dev,
>>>>       struct msm_display_info info;
>>>>       int rc;
>>>> -    encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_VIRTUAL);
>>>> +    memset(&info, 0, sizeof(info));
>>>> +
>>>> +    info.num_of_h_tiles = 1;
>>>> +    /* use only WB idx 2 instance for DPU */
>>>> +    info.h_tile_instance[0] = WB_2;
>>>> +    info.intf_type = INTF_WB;
>>>> +
>>>> +    encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_VIRTUAL, &info);
>>>>       if (IS_ERR(encoder)) {
>>>>           DPU_ERROR("encoder init failed for dsi display\n");
>>>>           return PTR_ERR(encoder);
>>>>       }
>>>> -    memset(&info, 0, sizeof(info));
>>>> -
>>>>       rc = dpu_writeback_init(dev, encoder, wb_formats,
>>>>               n_formats);
>>>>       if (rc) {
>>>> @@ -680,18 +669,6 @@ static int _dpu_kms_initialize_writeback(struct 
>>>> drm_device *dev,
>>>>           return rc;
>>>>       }
>>>> -    info.num_of_h_tiles = 1;
>>>> -    /* use only WB idx 2 instance for DPU */
>>>> -    info.h_tile_instance[0] = WB_2;
>>>> -    info.intf_type = INTF_WB;
>>>> -
>>>> -    rc = dpu_encoder_setup(dev, encoder, &info);
>>>> -    if (rc) {
>>>> -        DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n",
>>>> -                  encoder->base.id, rc);
>>>> -        return rc;
>>>> -    }
>>>> -
>>>>       return 0;
>>>>   }
>>

-- 
With best wishes
Dmitry



More information about the Freedreno mailing list