diff options
| author | Aurabindo Pillai <[email protected]> | 2024-05-21 19:46:31 +0000 |
|---|---|---|
| committer | Alex Deucher <[email protected]> | 2024-05-29 18:40:40 +0000 |
| commit | 234e94555800d644ae970ff8da50f1f03dbc6ff9 (patch) | |
| tree | 9fa48549801b6851d8337befa52d75eb111125e8 /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |
| parent | drm/amd/display: Add new GPINT command definitions (diff) | |
| download | kernel-234e94555800d644ae970ff8da50f1f03dbc6ff9.tar.gz kernel-234e94555800d644ae970ff8da50f1f03dbc6ff9.zip | |
drm/amd/display: Enable copying of bounding box data from VBIOS DMUB
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 <[email protected]>
Acked-by: Harry Wentland <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 121 |
1 files changed, 121 insertions, 0 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 6688b13d28e1..011981bee58c 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; |
