[PATCH v5 3/6] drm/msm/dpu: get INTF blocks directly rather than through RM

Dmitry Baryshkov dmitry.baryshkov at linaro.org
Thu Feb 10 09:32:33 UTC 2022


On 10/02/2022 03:25, Abhinav Kumar wrote:
> 
> 
> On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:
>> INTF blocks are not really handled by resource manager, they are
>> assigned at dpu_encoder_setup_display using dpu_encoder_get_intf().
>> Then this allocation is passed to RM and then returned to then
>> dpu_encoder.
>> So allocate them outside of RM and use them directly.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
>> Reviewed-by: Stephen Boyd <swboyd at chromium.org>
> 
> I have some questions about this approach.
> 
> Agreed, that when there is one encoder tied to one interface, we dont 
> need to go through RM because RM just gives what the encoder asks. 
> Instead we can directly get the interface from encoder.
> 
> But what happens when multiple displays are requesting the same interface?
> 
> There are use-cases which we have handled especially in mid-tier chips 
> which do not have external display where between mode-switches
> OR between some user triggered events DSI0 was shared between two displays.
> 
> So  lets say display 1 (with encoder X) requests DSI0
> and display 2 (with encoder Y) also requests DSI0,

All the encoders are allocated in the loop over possible DSI/DP 
interfaces. Thus it's not possible to have two encoders being driven by 
the same DSI entity. Moreover, the MSM DSI manager would not be able to 
cope with such cases.

In my opinion, the proper way to handle such cases would be a bridge 
which would generate hotplug events and toggle display pipeline inbetween.

> with this change, the code will allow that as there is no interface to
> encoder mapping.
> 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   | 36 +---------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h   | 16 -----
>>   .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  5 --
>>   .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |  8 ---
>>   .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  |  8 ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h       |  1 -
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c        | 68 ++-----------------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h        |  8 +++
>>   8 files changed, 16 insertions(+), 134 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> index 1e648db439f9..11f7126728db 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> @@ -420,26 +420,6 @@ int dpu_encoder_get_linecount(struct drm_encoder 
>> *drm_enc)
>>       return linecount;
>>   }
>> -void dpu_encoder_get_hw_resources(struct drm_encoder *drm_enc,
>> -                  struct dpu_encoder_hw_resources *hw_res)
>> -{
>> -    struct dpu_encoder_virt *dpu_enc = NULL;
>> -    int i = 0;
>> -
>> -    dpu_enc = to_dpu_encoder_virt(drm_enc);
>> -    DPU_DEBUG_ENC(dpu_enc, "\n");
>> -
>> -    /* Query resources used by phys encs, expected to be without 
>> overlap */
>> -    memset(hw_res, 0, sizeof(*hw_res));
>> -
>> -    for (i = 0; i < dpu_enc->num_phys_encs; i++) {
>> -        struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
>> -
>> -        if (phys->ops.get_hw_resources)
>> -            phys->ops.get_hw_resources(phys, hw_res);
>> -    }
>> -}
>> -
>>   static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
>>   {
>>       struct dpu_encoder_virt *dpu_enc = NULL;
>> @@ -973,7 +953,7 @@ static void dpu_encoder_virt_mode_set(struct 
>> drm_encoder *drm_enc,
>>       struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
>>       struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
>>       int num_lm, num_ctl, num_pp;
>> -    int i, j;
>> +    int i;
>>       if (!drm_enc) {
>>           DPU_ERROR("invalid encoder\n");
>> @@ -1040,8 +1020,6 @@ static void dpu_encoder_virt_mode_set(struct 
>> drm_encoder *drm_enc,
>>       cstate->num_mixers = num_lm;
>>       for (i = 0; i < dpu_enc->num_phys_encs; i++) {
>> -        int num_blk;
>> -        struct dpu_hw_blk *hw_blk[MAX_CHANNELS_PER_ENC];
>>           struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
>>           if (!dpu_enc->hw_pp[i]) {
>> @@ -1059,16 +1037,8 @@ static void dpu_encoder_virt_mode_set(struct 
>> drm_encoder *drm_enc,
>>           phys->hw_pp = dpu_enc->hw_pp[i];
>>           phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
>> -        num_blk = dpu_rm_get_assigned_resources(&dpu_kms->rm,
>> -            global_state, drm_enc->base.id, DPU_HW_BLK_INTF,
>> -            hw_blk, ARRAY_SIZE(hw_blk));
>> -        for (j = 0; j < num_blk; j++) {
>> -            struct dpu_hw_intf *hw_intf;
>> -
>> -            hw_intf = to_dpu_hw_intf(hw_blk[i]);
>> -            if (hw_intf->idx == phys->intf_idx)
>> -                phys->hw_intf = hw_intf;
>> -        }
>> +        if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX)
>> +            phys->hw_intf = dpu_rm_get_intf(&dpu_kms->rm, 
>> phys->intf_idx);
>>           if (!phys->hw_intf) {
>>               DPU_ERROR_ENC(dpu_enc,
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
>> index e241914a9677..722dd7db6bdf 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
>> @@ -18,22 +18,6 @@
>>   #define IDLE_TIMEOUT    (66 - 16/2)
>> -/**
>> - * Encoder functions and data types
>> - * @intfs:    Interfaces this encoder is using, INTF_MODE_NONE if unused
>> - */
>> -struct dpu_encoder_hw_resources {
>> -    enum dpu_intf_mode intfs[INTF_MAX];
>> -};
>> -
>> -/**
>> - * dpu_encoder_get_hw_resources - Populate table of required hardware 
>> resources
>> - * @encoder:    encoder pointer
>> - * @hw_res:    resource table to populate with encoder required 
>> resources
>> - */
>> -void dpu_encoder_get_hw_resources(struct drm_encoder *encoder,
>> -                  struct dpu_encoder_hw_resources *hw_res);
>> -
>>   /**
>>    * dpu_encoder_assign_crtc - Link the encoder to the crtc it's 
>> assigned to
>>    * @encoder:    encoder pointer
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> index e7270eb6b84b..42febfce79c7 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>> @@ -91,9 +91,6 @@ struct dpu_encoder_virt_ops {
>>    * @disable:            DRM Call. Disable mode.
>>    * @atomic_check:        DRM Call. Atomic check new DRM state.
>>    * @destroy:            DRM Call. Destroy and release resources.
>> - * @get_hw_resources:        Populate the structure with the hardware
>> - *                resources that this phys_enc is using.
>> - *                Expect no overlap between phys_encs.
>>    * @control_vblank_irq        Register/Deregister for VBLANK IRQ
>>    * @wait_for_commit_done:    Wait for hardware to have flushed the
>>    *                current pending frames to hardware
>> @@ -129,8 +126,6 @@ struct dpu_encoder_phys_ops {
>>                   struct drm_crtc_state *crtc_state,
>>                   struct drm_connector_state *conn_state);
>>       void (*destroy)(struct dpu_encoder_phys *encoder);
>> -    void (*get_hw_resources)(struct dpu_encoder_phys *encoder,
>> -                 struct dpu_encoder_hw_resources *hw_res);
>>       int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool 
>> enable);
>>       int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
>>       int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>> index 34a6940d12c5..7d2beea9cc4e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>> @@ -534,13 +534,6 @@ static void dpu_encoder_phys_cmd_destroy(struct 
>> dpu_encoder_phys *phys_enc)
>>       kfree(cmd_enc);
>>   }
>> -static void dpu_encoder_phys_cmd_get_hw_resources(
>> -        struct dpu_encoder_phys *phys_enc,
>> -        struct dpu_encoder_hw_resources *hw_res)
>> -{
>> -    hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD;
>> -}
>> -
>>   static void dpu_encoder_phys_cmd_prepare_for_kickoff(
>>           struct dpu_encoder_phys *phys_enc)
>>   {
>> @@ -736,7 +729,6 @@ static void dpu_encoder_phys_cmd_init_ops(
>>       ops->enable = dpu_encoder_phys_cmd_enable;
>>       ops->disable = dpu_encoder_phys_cmd_disable;
>>       ops->destroy = dpu_encoder_phys_cmd_destroy;
>> -    ops->get_hw_resources = dpu_encoder_phys_cmd_get_hw_resources;
>>       ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
>>       ops->wait_for_commit_done = 
>> dpu_encoder_phys_cmd_wait_for_commit_done;
>>       ops->prepare_for_kickoff = 
>> dpu_encoder_phys_cmd_prepare_for_kickoff;
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
>> index ddd9d89cd456..db6a9b896e42 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
>> @@ -465,13 +465,6 @@ static void dpu_encoder_phys_vid_destroy(struct 
>> dpu_encoder_phys *phys_enc)
>>       kfree(phys_enc);
>>   }
>> -static void dpu_encoder_phys_vid_get_hw_resources(
>> -        struct dpu_encoder_phys *phys_enc,
>> -        struct dpu_encoder_hw_resources *hw_res)
>> -{
>> -    hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_VIDEO;
>> -}
>> -
>>   static int dpu_encoder_phys_vid_wait_for_vblank(
>>           struct dpu_encoder_phys *phys_enc)
>>   {
>> @@ -680,7 +673,6 @@ static void dpu_encoder_phys_vid_init_ops(struct 
>> dpu_encoder_phys_ops *ops)
>>       ops->enable = dpu_encoder_phys_vid_enable;
>>       ops->disable = dpu_encoder_phys_vid_disable;
>>       ops->destroy = dpu_encoder_phys_vid_destroy;
>> -    ops->get_hw_resources = dpu_encoder_phys_vid_get_hw_resources;
>>       ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq;
>>       ops->wait_for_commit_done = 
>> dpu_encoder_phys_vid_wait_for_commit_done;
>>       ops->wait_for_vblank = dpu_encoder_phys_vid_wait_for_vblank;
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
>> index 2d385b4b7f5e..3f518c809e33 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
>> @@ -144,7 +144,6 @@ struct dpu_global_state {
>>       uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0];
>>       uint32_t mixer_to_enc_id[LM_MAX - LM_0];
>>       uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
>> -    uint32_t intf_to_enc_id[INTF_MAX - INTF_0];
>>       uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
>>   };
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> index 63ed0d7df848..8df21a46308e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> @@ -28,7 +28,6 @@ static inline bool reserved_by_other(uint32_t 
>> *res_map, int idx,
>>    */
>>   struct dpu_rm_requirements {
>>       struct msm_display_topology topology;
>> -    struct dpu_encoder_hw_resources hw_res;
>>   };
>>   int dpu_rm_destroy(struct dpu_rm *rm)
>> @@ -448,54 +447,6 @@ static int _dpu_rm_reserve_ctls(
>>       return 0;
>>   }
>> -static int _dpu_rm_reserve_intf(
>> -        struct dpu_rm *rm,
>> -        struct dpu_global_state *global_state,
>> -        uint32_t enc_id,
>> -        uint32_t id)
>> -{
>> -    int idx = id - INTF_0;
>> -
>> -    if (idx < 0 || idx >= ARRAY_SIZE(rm->intf_blks)) {
>> -        DPU_ERROR("invalid intf id: %d", id);
>> -        return -EINVAL;
>> -    }
>> -
>> -    if (!rm->intf_blks[idx]) {
>> -        DPU_ERROR("couldn't find intf id %d\n", id);
>> -        return -EINVAL;
>> -    }
>> -
>> -    if (reserved_by_other(global_state->intf_to_enc_id, idx, enc_id)) {
>> -        DPU_ERROR("intf id %d already reserved\n", id);
>> -        return -ENAVAIL;
>> -    }
>> -
>> -    global_state->intf_to_enc_id[idx] = enc_id;
>> -    return 0;
>> -}
>> -
>> -static int _dpu_rm_reserve_intf_related_hw(
>> -        struct dpu_rm *rm,
>> -        struct dpu_global_state *global_state,
>> -        uint32_t enc_id,
>> -        struct dpu_encoder_hw_resources *hw_res)
>> -{
>> -    int i, ret = 0;
>> -    u32 id;
>> -
>> -    for (i = 0; i < ARRAY_SIZE(hw_res->intfs); i++) {
>> -        if (hw_res->intfs[i] == INTF_MODE_NONE)
>> -            continue;
>> -        id = i + INTF_0;
>> -        ret = _dpu_rm_reserve_intf(rm, global_state, enc_id, id);
>> -        if (ret)
>> -            return ret;
>> -    }
>> -
>> -    return ret;
>> -}
>> -
>>   static int _dpu_rm_make_reservation(
>>           struct dpu_rm *rm,
>>           struct dpu_global_state *global_state,
>> @@ -517,11 +468,6 @@ static int _dpu_rm_make_reservation(
>>           return ret;
>>       }
>> -    ret = _dpu_rm_reserve_intf_related_hw(rm, global_state, 
>> enc->base.id,
>> -                &reqs->hw_res);
>> -    if (ret)
>> -        return ret;
>> -
>>       return ret;
>>   }
>> @@ -530,8 +476,6 @@ static int _dpu_rm_populate_requirements(
>>           struct dpu_rm_requirements *reqs,
>>           struct msm_display_topology req_topology)
>>   {
>> -    dpu_encoder_get_hw_resources(enc, &reqs->hw_res);
>> -
>>       reqs->topology = req_topology;
>>       DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n",
>> @@ -561,8 +505,6 @@ void dpu_rm_release(struct dpu_global_state 
>> *global_state,
>>           ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id);
>>       _dpu_rm_clear_mapping(global_state->ctl_to_enc_id,
>>           ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
>> -    _dpu_rm_clear_mapping(global_state->intf_to_enc_id,
>> -        ARRAY_SIZE(global_state->intf_to_enc_id), enc->base.id);
>>   }
>>   int dpu_rm_reserve(
>> @@ -626,11 +568,6 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
>>           hw_to_enc_id = global_state->ctl_to_enc_id;
>>           max_blks = ARRAY_SIZE(rm->ctl_blks);
>>           break;
>> -    case DPU_HW_BLK_INTF:
>> -        hw_blks = rm->intf_blks;
>> -        hw_to_enc_id = global_state->intf_to_enc_id;
>> -        max_blks = ARRAY_SIZE(rm->intf_blks);
>> -        break;
>>       case DPU_HW_BLK_DSPP:
>>           hw_blks = rm->dspp_blks;
>>           hw_to_enc_id = global_state->dspp_to_enc_id;
>> @@ -656,3 +593,8 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
>>       return num_blks;
>>   }
>> +
>> +struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf 
>> intf_idx)
>> +{
>> +    return to_dpu_hw_intf(rm->intf_blks[intf_idx - INTF_0]);
>> +}
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
>> index 0f27759211b5..ee50f6651b6e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
>> @@ -84,5 +84,13 @@ void dpu_rm_release(struct dpu_global_state 
>> *global_state,
>>   int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
>>       struct dpu_global_state *global_state, uint32_t enc_id,
>>       enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int 
>> blks_size);
>> +
>> +/**
>> + * dpu_rm_get_intf - Return a struct dpu_hw_intf instance given it's 
>> index.
>> + * @rm: DPU Resource Manager handle
>> + * @intf_idx: INTF's index
>> + */
>> +struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf 
>> intf_idx);
>> +
>>   #endif /* __DPU_RM_H__ */


-- 
With best wishes
Dmitry


More information about the dri-devel mailing list