On 2024-05-23 15:20, Aurabindo Pillai wrote:
> Allocate some memory, send the address in chunks to dmub, and finally
> ask it to copy the bounding box data into the newly allocated memory.
> 
> Signed-off-by: Aurabindo Pillai <aurabindo.pil...@amd.com>

The entire series is
Acked-by: Harry Wentland <harry.wentl...@amd.com>

Harry

> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 121 ++++++++++++++++++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  10 ++
>  .../amd/display/amdgpu_dm/amdgpu_dm_helpers.c |  24 +---
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |   5 +
>  drivers/gpu/drm/amd/display/dc/dc.h           |   3 +
>  .../dc/dml2/dml21/dml21_translation_helper.c  |   6 +-
>  .../drm/amd/display/dc/dml2/dml2_wrapper.h    |   1 +
>  7 files changed, 146 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index bb4573603479..74accbcaae28 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -1627,6 +1627,117 @@ static void retrieve_dmi_info(struct 
> amdgpu_display_manager *dm)
>       }
>  }
>  
> +void*
> +dm_allocate_gpu_mem(
> +             struct amdgpu_device *adev,
> +             enum dc_gpu_mem_alloc_type type,
> +             size_t size,
> +             long long *addr)
> +{
> +     struct dal_allocation *da;
> +     u32 domain = (type == DC_MEM_ALLOC_TYPE_GART) ?
> +             AMDGPU_GEM_DOMAIN_GTT : AMDGPU_GEM_DOMAIN_VRAM;
> +     int ret;
> +
> +     da = kzalloc(sizeof(struct dal_allocation), GFP_KERNEL);
> +     if (!da)
> +             return NULL;
> +
> +     ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> +                                   domain, &da->bo,
> +                                   &da->gpu_addr, &da->cpu_ptr);
> +
> +     *addr = da->gpu_addr;
> +
> +     if (ret) {
> +             kfree(da);
> +             return NULL;
> +     }
> +
> +     /* add da to list in dm */
> +     list_add(&da->list, &adev->dm.da_list);
> +
> +     return da->cpu_ptr;
> +}
> +
> +static enum dmub_status
> +dm_dmub_send_vbios_gpint_command(struct amdgpu_device *adev,
> +                              enum dmub_gpint_command command_code,
> +                              uint16_t param,
> +                              uint32_t timeout_us)
> +{
> +     union dmub_gpint_data_register reg, test;
> +     uint32_t i;
> +
> +     /* Assume that VBIOS DMUB is ready to take commands */
> +
> +     reg.bits.status = 1;
> +     reg.bits.command_code = command_code;
> +     reg.bits.param = param;
> +
> +     cgs_write_register(adev->dm.cgs_device, 0x34c0 + 0x01f8, reg.all);
> +
> +     for (i = 0; i < timeout_us; ++i) {
> +             udelay(1);
> +
> +             /* Check if our GPINT got acked */
> +             reg.bits.status = 0;
> +             test = (union dmub_gpint_data_register)
> +                     cgs_read_register(adev->dm.cgs_device, 0x34c0 + 0x01f8);
> +
> +             if (test.all == reg.all)
> +                     return DMUB_STATUS_OK;
> +     }
> +
> +     return DMUB_STATUS_TIMEOUT;
> +}
> +
> +static struct dml2_soc_bb *dm_dmub_get_vbios_bounding_box(struct 
> amdgpu_device *adev)
> +{
> +     struct dml2_soc_bb *bb;
> +     long long addr;
> +     int i = 0;
> +     uint16_t chunk;
> +     enum dmub_gpint_command send_addrs[] = {
> +             DMUB_GPINT__SET_BB_ADDR_WORD0,
> +             DMUB_GPINT__SET_BB_ADDR_WORD1,
> +             DMUB_GPINT__SET_BB_ADDR_WORD2,
> +             DMUB_GPINT__SET_BB_ADDR_WORD3,
> +     };
> +     enum dmub_status ret;
> +
> +     switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
> +     case IP_VERSION(4, 0, 1):
> +             break;
> +     default:
> +             return NULL;
> +     }
> +
> +     bb =  dm_allocate_gpu_mem(adev,
> +                               DC_MEM_ALLOC_TYPE_GART,
> +                               sizeof(struct dml2_soc_bb),
> +                               &addr);
> +     if (!bb)
> +             return NULL;
> +
> +     for (i = 0; i < 4; i++) {
> +             /* Extract 16-bit chunk */
> +             chunk = ((uint64_t) addr >> (i * 16)) & 0xFFFF;
> +             /* Send the chunk */
> +             ret = dm_dmub_send_vbios_gpint_command(adev, send_addrs[i], 
> chunk, 30000);
> +             if (ret != DMUB_STATUS_OK)
> +                     /* No need to free bb here since it shall be done 
> unconditionally <elsewhere> */
> +                     return NULL;
> +     }
> +
> +     /* Now ask DMUB to copy the bb */
> +     ret = dm_dmub_send_vbios_gpint_command(adev, DMUB_GPINT__BB_COPY, 1, 
> 200000);
> +     if (ret != DMUB_STATUS_OK)
> +             return NULL;
> +
> +     return bb;
> +}
> +
>  static int amdgpu_dm_init(struct amdgpu_device *adev)
>  {
>       struct dc_init_data init_data;
> @@ -1748,6 +1859,11 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
>  
>       retrieve_dmi_info(&adev->dm);
>  
> +     if (adev->dm.bb_from_dmub)
> +             init_data.bb_from_dmub = adev->dm.bb_from_dmub;
> +     else
> +             init_data.bb_from_dmub = NULL;
> +
>       /* Display Core create. */
>       adev->dm.dc = dc_create(&init_data);
>  
> @@ -2305,6 +2421,8 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
>               return -EINVAL;
>       }
>  
> +     adev->dm.bb_from_dmub = dm_dmub_get_vbios_bounding_box(adev);
> +
>       return 0;
>  }
>  
> @@ -2334,6 +2452,9 @@ static int dm_sw_fini(void *handle)
>  {
>       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
>  
> +     kfree(adev->dm.bb_from_dmub);
> +     adev->dm.bb_from_dmub = NULL;
> +
>       kfree(adev->dm.dmub_fb_info);
>       adev->dm.dmub_fb_info = NULL;
>  
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index a01f3f5bf2c0..94fc4c15d2db 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -578,6 +578,11 @@ struct amdgpu_display_manager {
>        * Guards access to DPIA AUX
>        */
>       struct mutex dpia_aux_lock;
> +
> +     /*
> +      * Bounding box data read from dmub during early initialization for 
> DCN4+
> +      */
> +     struct dml2_soc_bb *bb_from_dmub;
>  };
>  
>  enum dsc_clock_force_state {
> @@ -964,4 +969,9 @@ amdgpu_dm_find_first_crtc_matching_connector(struct 
> drm_atomic_state *state,
>  
>  int convert_dc_color_depth_into_bpc(enum dc_color_depth display_color_depth);
>  struct idle_workqueue *idle_create_workqueue(struct amdgpu_device *adev);
> +
> +void *dm_allocate_gpu_mem(struct amdgpu_device *adev,
> +                                               enum dc_gpu_mem_alloc_type 
> type,
> +                                               size_t size,
> +                                               long long *addr);
>  #endif /* __AMDGPU_DM_H__ */
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> index 6d0f78b9ec0c..8eb2f10f2c38 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
> @@ -1045,30 +1045,8 @@ void *dm_helpers_allocate_gpu_mem(
>               long long *addr)
>  {
>       struct amdgpu_device *adev = ctx->driver_context;
> -     struct dal_allocation *da;
> -     u32 domain = (type == DC_MEM_ALLOC_TYPE_GART) ?
> -             AMDGPU_GEM_DOMAIN_GTT : AMDGPU_GEM_DOMAIN_VRAM;
> -     int ret;
> -
> -     da = kzalloc(sizeof(struct dal_allocation), GFP_KERNEL);
> -     if (!da)
> -             return NULL;
> -
> -     ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
> -                                   domain, &da->bo,
> -                                   &da->gpu_addr, &da->cpu_ptr);
> -
> -     *addr = da->gpu_addr;
> -
> -     if (ret) {
> -             kfree(da);
> -             return NULL;
> -     }
> -
> -     /* add da to list in dm */
> -     list_add(&da->list, &adev->dm.da_list);
>  
> -     return da->cpu_ptr;
> +     return dm_allocate_gpu_mem(adev, type, size, addr);
>  }
>  
>  void dm_helpers_free_gpu_mem(
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
> b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index 3a2101b052ea..1526ab0b4884 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -1014,6 +1014,11 @@ static bool dc_construct(struct dc *dc,
>  
>       dc->dcn_ip = dcn_ip;
>  
> +     if (init_params->bb_from_dmub)
> +             dc->dml2_options.bb_from_dmub = init_params->bb_from_dmub;
> +     else
> +             dc->dml2_options.bb_from_dmub = NULL;
> +
>       if (!dc_construct_ctx(dc, init_params)) {
>               dm_error("%s: failed to create ctx\n", __func__);
>               goto fail;
> diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
> b/drivers/gpu/drm/amd/display/dc/dc.h
> index 31e3371b1b2e..d0ed01ac460d 100644
> --- a/drivers/gpu/drm/amd/display/dc/dc.h
> +++ b/drivers/gpu/drm/amd/display/dc/dc.h
> @@ -1067,6 +1067,8 @@ struct dchub_init_data {
>       bool dchub_info_valid;
>  };
>  
> +struct dml2_soc_bb;
> +
>  struct dc_init_data {
>       struct hw_asic_id asic_id;
>       void *driver; /* ctx */
> @@ -1099,6 +1101,7 @@ struct dc_init_data {
>       uint32_t *dcn_reg_offsets;
>       uint32_t *nbio_reg_offsets;
>       uint32_t *clk_reg_offsets;
> +     struct dml2_soc_bb *bb_from_dmub;
>  };
>  
>  struct dc_callback_init {
> diff --git 
> a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c 
> b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
> index 37998f2c0b14..9f641ffdc924 100644
> --- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
> +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c
> @@ -26,7 +26,11 @@ static void dml21_init_socbb_params(struct 
> dml2_initialize_instance_in_out *dml_
>               break;
>       case DCN_VERSION_4_01:
>       default:
> -             soc_bb = &dml2_socbb_dcn401;
> +             if (config->bb_from_dmub)
> +                     soc_bb = config->bb_from_dmub;
> +             else
> +                     soc_bb = &dml2_socbb_dcn401;
> +
>               qos_params = &dml_dcn401_soc_qos_params;
>       }
>  
> diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h 
> b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
> index dcb4e6f4d916..20b3970c0857 100644
> --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
> +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
> @@ -236,6 +236,7 @@ struct dml2_configuration_options {
>  
>       bool use_clock_dc_limits;
>       bool gpuvm_enable;
> +     struct dml2_soc_bb *bb_from_dmub;
>  };
>  
>  /*

Reply via email to