mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
Merge tag 'amd-drm-next-5.15-2021-08-06' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.15-2021-08-06: amdgpu: - Aldebaran fixes - Powergating fix for Renoir - Switch virtual DCE over to vkms based atomic modesetting - Misc typo fixes - PSP handling cleanups - DC FP cleanups - RAS fixes - Wave debug improvements - Freesync fix - BACO/BOCO fixes - Misc fixes amdkfd: - Expose gfx version in sysfs - Aldebaran fixes radeon: - Coding style fix - Typo fixes - Pageflip fix UAPI: - amdkfd: SVM address range query Proposed userspace: https://github.com/RadeonOpenCompute/ROCR-Runtime/tree/memory_model_queries Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210806205248.3864-1-alexander.deucher@amd.com
This commit is contained in:
commit
59b9d6baa1
|
|
@ -120,7 +120,7 @@ amdgpu-y += \
|
|||
amdgpu-y += \
|
||||
dce_v10_0.o \
|
||||
dce_v11_0.o \
|
||||
dce_virtual.o
|
||||
amdgpu_vkms.o
|
||||
|
||||
# add GFX block
|
||||
amdgpu-y += \
|
||||
|
|
|
|||
|
|
@ -916,6 +916,7 @@ struct amdgpu_device {
|
|||
|
||||
/* display */
|
||||
bool enable_virtual_display;
|
||||
struct amdgpu_vkms_output *amdgpu_vkms_output;
|
||||
struct amdgpu_mode_info mode_info;
|
||||
/* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */
|
||||
struct work_struct hotplug_work;
|
||||
|
|
|
|||
|
|
@ -1040,7 +1040,7 @@ void amdgpu_acpi_detect(void)
|
|||
*/
|
||||
bool amdgpu_acpi_is_s0ix_active(struct amdgpu_device *adev)
|
||||
{
|
||||
#if defined(CONFIG_AMD_PMC) || defined(CONFIG_AMD_PMC_MODULE)
|
||||
#if IS_ENABLED(CONFIG_AMD_PMC) && IS_ENABLED(CONFIG_PM_SLEEP)
|
||||
if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
|
||||
if (adev->flags & AMD_IS_APU)
|
||||
return pm_suspend_target_state == PM_SUSPEND_TO_IDLE;
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
|||
struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv,
|
||||
uint64_t *size);
|
||||
int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
||||
struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv);
|
||||
struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv, bool *table_freed);
|
||||
int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(
|
||||
struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv);
|
||||
int amdgpu_amdkfd_gpuvm_sync_memory(
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,8 @@ static void unmap_bo_from_gpuvm(struct kgd_mem *mem,
|
|||
|
||||
static int update_gpuvm_pte(struct kgd_mem *mem,
|
||||
struct kfd_mem_attachment *entry,
|
||||
struct amdgpu_sync *sync)
|
||||
struct amdgpu_sync *sync,
|
||||
bool *table_freed)
|
||||
{
|
||||
struct amdgpu_bo_va *bo_va = entry->bo_va;
|
||||
struct amdgpu_device *adev = entry->adev;
|
||||
|
|
@ -1068,7 +1069,7 @@ static int update_gpuvm_pte(struct kgd_mem *mem,
|
|||
return ret;
|
||||
|
||||
/* Update the page tables */
|
||||
ret = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
ret = amdgpu_vm_bo_update(adev, bo_va, false, table_freed);
|
||||
if (ret) {
|
||||
pr_err("amdgpu_vm_bo_update failed\n");
|
||||
return ret;
|
||||
|
|
@ -1080,7 +1081,8 @@ static int update_gpuvm_pte(struct kgd_mem *mem,
|
|||
static int map_bo_to_gpuvm(struct kgd_mem *mem,
|
||||
struct kfd_mem_attachment *entry,
|
||||
struct amdgpu_sync *sync,
|
||||
bool no_update_pte)
|
||||
bool no_update_pte,
|
||||
bool *table_freed)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -1097,7 +1099,7 @@ static int map_bo_to_gpuvm(struct kgd_mem *mem,
|
|||
if (no_update_pte)
|
||||
return 0;
|
||||
|
||||
ret = update_gpuvm_pte(mem, entry, sync);
|
||||
ret = update_gpuvm_pte(mem, entry, sync, table_freed);
|
||||
if (ret) {
|
||||
pr_err("update_gpuvm_pte() failed\n");
|
||||
goto update_gpuvm_pte_failed;
|
||||
|
|
@ -1605,7 +1607,8 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
|
|||
}
|
||||
|
||||
int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
||||
struct kgd_dev *kgd, struct kgd_mem *mem, void *drm_priv)
|
||||
struct kgd_dev *kgd, struct kgd_mem *mem,
|
||||
void *drm_priv, bool *table_freed)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct amdgpu_vm *avm = drm_priv_to_vm(drm_priv);
|
||||
|
|
@ -1693,7 +1696,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
|||
entry->va, entry->va + bo_size, entry);
|
||||
|
||||
ret = map_bo_to_gpuvm(mem, entry, ctx.sync,
|
||||
is_invalid_userptr);
|
||||
is_invalid_userptr, table_freed);
|
||||
if (ret) {
|
||||
pr_err("Failed to map bo to gpuvm\n");
|
||||
goto out_unreserve;
|
||||
|
|
@ -1717,6 +1720,12 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
|||
true);
|
||||
ret = unreserve_bo_and_vms(&ctx, false, false);
|
||||
|
||||
/* Only apply no TLB flush on Aldebaran to
|
||||
* workaround regressions on other Asics.
|
||||
*/
|
||||
if (table_freed && (adev->asic_type != CHIP_ALDEBARAN))
|
||||
*table_freed = true;
|
||||
|
||||
goto out;
|
||||
|
||||
out_unreserve:
|
||||
|
|
@ -2143,7 +2152,7 @@ static int validate_invalid_user_pages(struct amdkfd_process_info *process_info)
|
|||
continue;
|
||||
|
||||
kfd_mem_dmaunmap_attachment(mem, attachment);
|
||||
ret = update_gpuvm_pte(mem, attachment, &sync);
|
||||
ret = update_gpuvm_pte(mem, attachment, &sync, NULL);
|
||||
if (ret) {
|
||||
pr_err("%s: update PTE failed\n", __func__);
|
||||
/* make sure this gets validated again */
|
||||
|
|
@ -2349,7 +2358,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_bos(void *info, struct dma_fence **ef)
|
|||
continue;
|
||||
|
||||
kfd_mem_dmaunmap_attachment(mem, attachment);
|
||||
ret = update_gpuvm_pte(mem, attachment, &sync_obj);
|
||||
ret = update_gpuvm_pte(mem, attachment, &sync_obj, NULL);
|
||||
if (ret) {
|
||||
pr_debug("Memory eviction: update PTE failed. Try again\n");
|
||||
goto validate_map_fail;
|
||||
|
|
|
|||
|
|
@ -468,6 +468,46 @@ bool amdgpu_atomfirmware_dynamic_boot_config_supported(struct amdgpu_device *ade
|
|||
return (fw_cap & ATOM_FIRMWARE_CAP_DYNAMIC_BOOT_CFG_ENABLE) ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to query RAS EEPROM address
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Return true if vbios supports ras rom address reporting
|
||||
*/
|
||||
bool amdgpu_atomfirmware_ras_rom_addr(struct amdgpu_device *adev, uint8_t* i2c_address)
|
||||
{
|
||||
struct amdgpu_mode_info *mode_info = &adev->mode_info;
|
||||
int index;
|
||||
u16 data_offset, size;
|
||||
union firmware_info *firmware_info;
|
||||
u8 frev, crev;
|
||||
|
||||
if (i2c_address == NULL)
|
||||
return false;
|
||||
|
||||
*i2c_address = 0;
|
||||
|
||||
index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
|
||||
firmwareinfo);
|
||||
|
||||
if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context,
|
||||
index, &size, &frev, &crev, &data_offset)) {
|
||||
/* support firmware_info 3.4 + */
|
||||
if ((frev == 3 && crev >=4) || (frev > 3)) {
|
||||
firmware_info = (union firmware_info *)
|
||||
(mode_info->atom_context->bios + data_offset);
|
||||
*i2c_address = firmware_info->v34.ras_rom_i2c_slave_addr;
|
||||
}
|
||||
}
|
||||
|
||||
if (*i2c_address != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
union smu_info {
|
||||
struct atom_smu_info_v3_1 v31;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ int amdgpu_atomfirmware_get_clock_info(struct amdgpu_device *adev);
|
|||
int amdgpu_atomfirmware_get_gfx_info(struct amdgpu_device *adev);
|
||||
bool amdgpu_atomfirmware_mem_ecc_supported(struct amdgpu_device *adev);
|
||||
bool amdgpu_atomfirmware_sram_ecc_supported(struct amdgpu_device *adev);
|
||||
bool amdgpu_atomfirmware_ras_rom_addr(struct amdgpu_device *adev, uint8_t* i2c_address);
|
||||
bool amdgpu_atomfirmware_mem_training_supported(struct amdgpu_device *adev);
|
||||
bool amdgpu_atomfirmware_dynamic_boot_config_supported(struct amdgpu_device *adev);
|
||||
int amdgpu_atomfirmware_get_fw_reserved_fb_size(struct amdgpu_device *adev);
|
||||
|
|
|
|||
|
|
@ -799,7 +799,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false);
|
||||
r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
@ -810,7 +810,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
|||
if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
|
||||
bo_va = fpriv->csa_va;
|
||||
BUG_ON(!bo_va);
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
@ -829,7 +829,7 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
|
|||
if (bo_va == NULL)
|
||||
continue;
|
||||
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
|||
|
|
@ -3647,9 +3647,9 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
|
||||
fence_driver_init:
|
||||
/* Fence driver */
|
||||
r = amdgpu_fence_driver_init(adev);
|
||||
r = amdgpu_fence_driver_sw_init(adev);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "amdgpu_fence_driver_init failed\n");
|
||||
dev_err(adev->dev, "amdgpu_fence_driver_sw_init failed\n");
|
||||
amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_FENCE_INIT_FAIL, 0, 0);
|
||||
goto failed;
|
||||
}
|
||||
|
|
@ -3989,7 +3989,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
|
|||
}
|
||||
amdgpu_fence_driver_hw_init(adev);
|
||||
|
||||
|
||||
r = amdgpu_device_ip_late_init(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
|
|||
|
|
@ -1215,6 +1215,13 @@ static const struct pci_device_id pciidlist[] = {
|
|||
/* CYAN_SKILLFISH */
|
||||
{0x1002, 0x13FE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYAN_SKILLFISH|AMD_IS_APU},
|
||||
|
||||
/* BEIGE_GOBY */
|
||||
{0x1002, 0x7420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
||||
{0x1002, 0x7421, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
||||
{0x1002, 0x7422, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
||||
{0x1002, 0x7423, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
||||
{0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
|
|
@ -1231,7 +1238,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
|
|||
int ret, retry = 0;
|
||||
bool supports_atomic = false;
|
||||
|
||||
if (!amdgpu_virtual_display &&
|
||||
if (amdgpu_virtual_display ||
|
||||
amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
|
||||
supports_atomic = true;
|
||||
|
||||
|
|
@ -1566,6 +1573,8 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev)
|
|||
pci_ignore_hotplug(pdev);
|
||||
pci_set_power_state(pdev, PCI_D3cold);
|
||||
drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
|
||||
} else if (amdgpu_device_supports_boco(drm_dev)) {
|
||||
/* nothing to do */
|
||||
} else if (amdgpu_device_supports_baco(drm_dev)) {
|
||||
amdgpu_device_baco_enter(drm_dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ int amdgpu_fbdev_init(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
/* disable all the possible outputs/crtcs before entering KMS mode */
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
if (!amdgpu_device_has_dc_support(adev) && !amdgpu_virtual_display)
|
||||
drm_helper_disable_unused_functions(adev_to_drm(adev));
|
||||
|
||||
drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
|
||||
|
|
|
|||
|
|
@ -498,7 +498,7 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
|
|||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_driver_init - init the fence driver
|
||||
* amdgpu_fence_driver_sw_init - init the fence driver
|
||||
* for all possible rings.
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
|
|
@ -509,13 +509,13 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
|
|||
* amdgpu_fence_driver_start_ring().
|
||||
* Returns 0 for success.
|
||||
*/
|
||||
int amdgpu_fence_driver_init(struct amdgpu_device *adev)
|
||||
int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_fence_driver_fini - tear down the fence driver
|
||||
* amdgpu_fence_driver_hw_fini - tear down the fence driver
|
||||
* for all possible rings.
|
||||
*
|
||||
* @adev: amdgpu device pointer
|
||||
|
|
@ -531,8 +531,7 @@ void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev)
|
|||
|
||||
if (!ring || !ring->fence_drv.initialized)
|
||||
continue;
|
||||
if (!ring->no_scheduler)
|
||||
drm_sched_fini(&ring->sched);
|
||||
|
||||
/* You can't wait for HW to signal if it's gone */
|
||||
if (!drm_dev_is_unplugged(&adev->ddev))
|
||||
r = amdgpu_fence_wait_empty(ring);
|
||||
|
|
@ -560,6 +559,9 @@ void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev)
|
|||
if (!ring || !ring->fence_drv.initialized)
|
||||
continue;
|
||||
|
||||
if (!ring->no_scheduler)
|
||||
drm_sched_fini(&ring->sched);
|
||||
|
||||
for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
|
||||
dma_fence_put(ring->fence_drv.fences[j]);
|
||||
kfree(ring->fence_drv.fences);
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
|
|||
|
||||
if (operation == AMDGPU_VA_OP_MAP ||
|
||||
operation == AMDGPU_VA_OP_REPLACE) {
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
|
||||
if (r)
|
||||
goto error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@
|
|||
#include "amdgpu_securedisplay.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
|
||||
#include <drm/drm_drv.h>
|
||||
|
||||
static int psp_sysfs_init(struct amdgpu_device *adev);
|
||||
static void psp_sysfs_fini(struct amdgpu_device *adev);
|
||||
|
||||
|
|
@ -253,6 +251,12 @@ static int psp_sw_init(void *handle)
|
|||
struct psp_runtime_boot_cfg_entry boot_cfg_entry;
|
||||
struct psp_memory_training_context *mem_training_ctx = &psp->mem_train_ctx;
|
||||
|
||||
psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!psp->cmd) {
|
||||
DRM_ERROR("Failed to allocate memory to command buffer!\n");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
if (!amdgpu_sriov_vf(adev)) {
|
||||
ret = psp_init_microcode(psp);
|
||||
if (ret) {
|
||||
|
|
@ -315,25 +319,30 @@ static int psp_sw_init(void *handle)
|
|||
static int psp_sw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct psp_gfx_cmd_resp *cmd = psp->cmd;
|
||||
|
||||
psp_memory_training_fini(&adev->psp);
|
||||
if (adev->psp.sos_fw) {
|
||||
release_firmware(adev->psp.sos_fw);
|
||||
adev->psp.sos_fw = NULL;
|
||||
psp_memory_training_fini(psp);
|
||||
if (psp->sos_fw) {
|
||||
release_firmware(psp->sos_fw);
|
||||
psp->sos_fw = NULL;
|
||||
}
|
||||
if (adev->psp.asd_fw) {
|
||||
release_firmware(adev->psp.asd_fw);
|
||||
adev->psp.asd_fw = NULL;
|
||||
if (psp->asd_fw) {
|
||||
release_firmware(psp->asd_fw);
|
||||
psp->asd_fw = NULL;
|
||||
}
|
||||
if (adev->psp.ta_fw) {
|
||||
release_firmware(adev->psp.ta_fw);
|
||||
adev->psp.ta_fw = NULL;
|
||||
if (psp->ta_fw) {
|
||||
release_firmware(psp->ta_fw);
|
||||
psp->ta_fw = NULL;
|
||||
}
|
||||
|
||||
if (adev->asic_type == CHIP_NAVI10 ||
|
||||
adev->asic_type == CHIP_SIENNA_CICHLID)
|
||||
psp_sysfs_fini(adev);
|
||||
|
||||
kfree(cmd);
|
||||
cmd = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -417,8 +426,6 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||
if (!drm_dev_enter(&psp->adev->ddev, &idx))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&psp->mutex);
|
||||
|
||||
memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE);
|
||||
|
||||
memcpy(psp->cmd_buf_mem, cmd, sizeof(struct psp_gfx_cmd_resp));
|
||||
|
|
@ -478,11 +485,26 @@ psp_cmd_submit_buf(struct psp_context *psp,
|
|||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&psp->mutex);
|
||||
drm_dev_exit(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct psp_gfx_cmd_resp *acquire_psp_cmd_buf(struct psp_context *psp)
|
||||
{
|
||||
struct psp_gfx_cmd_resp *cmd = psp->cmd;
|
||||
|
||||
mutex_lock(&psp->mutex);
|
||||
|
||||
memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void release_psp_cmd_buf(struct psp_context *psp)
|
||||
{
|
||||
mutex_unlock(&psp->mutex);
|
||||
}
|
||||
|
||||
static void psp_prep_tmr_cmd_buf(struct psp_context *psp,
|
||||
struct psp_gfx_cmd_resp *cmd,
|
||||
uint64_t tmr_mc, struct amdgpu_bo *tmr_bo)
|
||||
|
|
@ -517,11 +539,8 @@ static int psp_load_toc(struct psp_context *psp,
|
|||
uint32_t *tmr_size)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
/* Copy toc to psp firmware private buffer */
|
||||
psp_copy_fw(psp, psp->toc.start_addr, psp->toc.size_bytes);
|
||||
|
||||
|
|
@ -531,7 +550,9 @@ static int psp_load_toc(struct psp_context *psp,
|
|||
psp->fence_buf_mc_addr);
|
||||
if (!ret)
|
||||
*tmr_size = psp->cmd_buf_mem->resp.tmr_size;
|
||||
kfree(cmd);
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -596,9 +617,7 @@ static int psp_tmr_load(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev) && psp_skip_tmr(psp))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_tmr_cmd_buf(psp, cmd, psp->tmr_mc_addr, psp->tmr_bo);
|
||||
DRM_INFO("reserve 0x%lx from 0x%llx for PSP TMR\n",
|
||||
|
|
@ -607,13 +626,13 @@ static int psp_tmr_load(struct psp_context *psp)
|
|||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void psp_prep_tmr_unload_cmd_buf(struct psp_context *psp,
|
||||
struct psp_gfx_cmd_resp *cmd)
|
||||
struct psp_gfx_cmd_resp *cmd)
|
||||
{
|
||||
if (amdgpu_sriov_vf(psp->adev))
|
||||
cmd->cmd_id = GFX_CMD_ID_DESTROY_VMR;
|
||||
|
|
@ -624,11 +643,7 @@ static void psp_prep_tmr_unload_cmd_buf(struct psp_context *psp,
|
|||
static int psp_tmr_unload(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_tmr_unload_cmd_buf(psp, cmd);
|
||||
DRM_INFO("free PSP TMR buffer\n");
|
||||
|
|
@ -636,7 +651,7 @@ static int psp_tmr_unload(struct psp_context *psp)
|
|||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -670,9 +685,7 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp,
|
|||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_GET_FW_ATTESTATION;
|
||||
|
||||
|
|
@ -684,7 +697,7 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp,
|
|||
((uint64_t)cmd->resp.uresp.fwar_db_info.fwar_db_addr_hi << 32);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -692,13 +705,13 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp,
|
|||
static int psp_boot_config_get(struct amdgpu_device *adev, uint32_t *boot_cfg)
|
||||
{
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct psp_gfx_cmd_resp *cmd = psp->cmd;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
int ret;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_BOOT_CFG;
|
||||
cmd->cmd.boot_cfg.sub_cmd = BOOTCFG_CMD_GET;
|
||||
|
|
@ -709,47 +722,59 @@ static int psp_boot_config_get(struct amdgpu_device *adev, uint32_t *boot_cfg)
|
|||
(cmd->resp.uresp.boot_cfg.boot_cfg & BOOT_CONFIG_GECC) ? 1 : 0;
|
||||
}
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_boot_config_set(struct amdgpu_device *adev, uint32_t boot_cfg)
|
||||
{
|
||||
int ret;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct psp_gfx_cmd_resp *cmd = psp->cmd;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_BOOT_CFG;
|
||||
cmd->cmd.boot_cfg.sub_cmd = BOOTCFG_CMD_SET;
|
||||
cmd->cmd.boot_cfg.boot_config = boot_cfg;
|
||||
cmd->cmd.boot_cfg.boot_config_valid = boot_cfg;
|
||||
|
||||
return psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_rl_load(struct amdgpu_device *adev)
|
||||
{
|
||||
int ret;
|
||||
struct psp_context *psp = &adev->psp;
|
||||
struct psp_gfx_cmd_resp *cmd = psp->cmd;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
if (!is_psp_fw_valid(psp->rl))
|
||||
return 0;
|
||||
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
|
||||
memcpy(psp->fw_pri_buf, psp->rl.start_addr, psp->rl.size_bytes);
|
||||
|
||||
memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
|
||||
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(psp->fw_pri_mc_addr);
|
||||
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(psp->fw_pri_mc_addr);
|
||||
cmd->cmd.cmd_load_ip_fw.fw_size = psp->rl.size_bytes;
|
||||
cmd->cmd.cmd_load_ip_fw.fw_type = GFX_FW_TYPE_REG_LIST;
|
||||
|
||||
return psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
|
||||
|
|
@ -777,9 +802,7 @@ static int psp_asd_load(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev) || !psp->asd_ucode_size)
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_copy_fw(psp, psp->asd_start_addr, psp->asd_ucode_size);
|
||||
|
||||
|
|
@ -793,7 +816,7 @@ static int psp_asd_load(struct psp_context *psp)
|
|||
psp->asd_context.session_id = cmd->resp.session_id;
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -816,9 +839,7 @@ static int psp_asd_unload(struct psp_context *psp)
|
|||
if (!psp->asd_context.asd_initialized)
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_unload_cmd_buf(cmd, psp->asd_context.session_id);
|
||||
|
||||
|
|
@ -827,7 +848,7 @@ static int psp_asd_unload(struct psp_context *psp)
|
|||
if (!ret)
|
||||
psp->asd_context.asd_initialized = false;
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -843,22 +864,21 @@ static void psp_prep_reg_prog_cmd_buf(struct psp_gfx_cmd_resp *cmd,
|
|||
int psp_reg_program(struct psp_context *psp, enum psp_reg_prog_id reg,
|
||||
uint32_t value)
|
||||
{
|
||||
struct psp_gfx_cmd_resp *cmd = NULL;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
int ret = 0;
|
||||
|
||||
if (reg >= PSP_REG_LAST)
|
||||
return -EINVAL;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_reg_prog_cmd_buf(cmd, reg, value);
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
if (ret)
|
||||
DRM_ERROR("PSP failed to program reg id %d", reg);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -909,18 +929,14 @@ static int psp_ta_invoke(struct psp_context *psp,
|
|||
uint32_t session_id)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_invoke_cmd_buf(cmd, ta_cmd_id, session_id);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -934,9 +950,7 @@ static int psp_xgmi_load(struct psp_context *psp)
|
|||
* TODO: bypass the loading in sriov for now
|
||||
*/
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_copy_fw(psp, psp->ta_xgmi_start_addr, psp->ta_xgmi_ucode_size);
|
||||
|
||||
|
|
@ -954,7 +968,7 @@ static int psp_xgmi_load(struct psp_context *psp)
|
|||
psp->xgmi_context.session_id = cmd->resp.session_id;
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -974,16 +988,14 @@ static int psp_xgmi_unload(struct psp_context *psp)
|
|||
* TODO: bypass the unloading in sriov for now
|
||||
*/
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_unload_cmd_buf(cmd, psp->xgmi_context.session_id);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1213,10 +1225,6 @@ static int psp_ras_load(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
psp_copy_fw(psp, psp->ta_ras_start_addr, psp->ta_ras_ucode_size);
|
||||
|
||||
ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf;
|
||||
|
|
@ -1226,6 +1234,8 @@ static int psp_ras_load(struct psp_context *psp)
|
|||
else
|
||||
ras_cmd->ras_in_message.init_flags.dgpu_mode = 1;
|
||||
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_load_cmd_buf(cmd,
|
||||
psp->fw_pri_mc_addr,
|
||||
psp->ta_ras_ucode_size,
|
||||
|
|
@ -1244,11 +1254,11 @@ static int psp_ras_load(struct psp_context *psp)
|
|||
dev_warn(psp->adev->dev, "RAS Init Status: 0x%X\n", ras_cmd->ras_status);
|
||||
}
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
if (ret || ras_cmd->ras_status)
|
||||
amdgpu_ras_fini(psp->adev);
|
||||
|
||||
kfree(cmd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1263,16 +1273,14 @@ static int psp_ras_unload(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_unload_cmd_buf(cmd, psp->ras.session_id);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1522,13 +1530,11 @@ static int psp_hdcp_load(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
psp_copy_fw(psp, psp->ta_hdcp_start_addr,
|
||||
psp->ta_hdcp_ucode_size);
|
||||
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_load_cmd_buf(cmd,
|
||||
psp->fw_pri_mc_addr,
|
||||
psp->ta_hdcp_ucode_size,
|
||||
|
|
@ -1543,7 +1549,7 @@ static int psp_hdcp_load(struct psp_context *psp)
|
|||
mutex_init(&psp->hdcp_context.mutex);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1587,15 +1593,13 @@ static int psp_hdcp_unload(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_unload_cmd_buf(cmd, psp->hdcp_context.session_id);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1673,12 +1677,10 @@ static int psp_dtm_load(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
psp_copy_fw(psp, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size);
|
||||
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_load_cmd_buf(cmd,
|
||||
psp->fw_pri_mc_addr,
|
||||
psp->ta_dtm_ucode_size,
|
||||
|
|
@ -1693,7 +1695,7 @@ static int psp_dtm_load(struct psp_context *psp)
|
|||
mutex_init(&psp->dtm_context.mutex);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1738,15 +1740,13 @@ static int psp_dtm_unload(struct psp_context *psp)
|
|||
if (amdgpu_sriov_vf(psp->adev))
|
||||
return 0;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_unload_cmd_buf(cmd, psp->dtm_context.session_id);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1818,12 +1818,10 @@ static int psp_rap_load(struct psp_context *psp)
|
|||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
psp_copy_fw(psp, psp->ta_rap_start_addr, psp->ta_rap_ucode_size);
|
||||
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_load_cmd_buf(cmd,
|
||||
psp->fw_pri_mc_addr,
|
||||
psp->ta_rap_ucode_size,
|
||||
|
|
@ -1838,7 +1836,7 @@ static int psp_rap_load(struct psp_context *psp)
|
|||
mutex_init(&psp->rap_context.mutex);
|
||||
}
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1846,17 +1844,13 @@ static int psp_rap_load(struct psp_context *psp)
|
|||
static int psp_rap_unload(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_unload_cmd_buf(cmd, psp->rap_context.session_id);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1982,11 +1976,7 @@ static int psp_securedisplay_init_shared_buf(struct psp_context *psp)
|
|||
static int psp_securedisplay_load(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
memset(psp->fw_pri_buf, 0, PSP_1_MEG);
|
||||
memcpy(psp->fw_pri_buf, psp->ta_securedisplay_start_addr, psp->ta_securedisplay_ucode_size);
|
||||
|
|
@ -1999,32 +1989,27 @@ static int psp_securedisplay_load(struct psp_context *psp)
|
|||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (!ret) {
|
||||
psp->securedisplay_context.securedisplay_initialized = true;
|
||||
psp->securedisplay_context.session_id = cmd->resp.session_id;
|
||||
mutex_init(&psp->securedisplay_context.mutex);
|
||||
}
|
||||
|
||||
psp->securedisplay_context.securedisplay_initialized = true;
|
||||
psp->securedisplay_context.session_id = cmd->resp.session_id;
|
||||
mutex_init(&psp->securedisplay_context.mutex);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
failed:
|
||||
kfree(cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int psp_securedisplay_unload(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
psp_prep_ta_unload_cmd_buf(cmd, psp->securedisplay_context.session_id);
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);
|
||||
|
||||
kfree(cmd);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2400,8 +2385,6 @@ static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode,
|
|||
int ret;
|
||||
uint64_t fw_mem_mc_addr = ucode->mc_addr;
|
||||
|
||||
memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp));
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW;
|
||||
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(fw_mem_mc_addr);
|
||||
cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(fw_mem_mc_addr);
|
||||
|
|
@ -2418,13 +2401,15 @@ static int psp_execute_non_psp_fw_load(struct psp_context *psp,
|
|||
struct amdgpu_firmware_info *ucode)
|
||||
{
|
||||
int ret = 0;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
ret = psp_prep_load_ip_fw_cmd_buf(ucode, psp->cmd);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = psp_prep_load_ip_fw_cmd_buf(ucode, cmd);
|
||||
if (!ret) {
|
||||
ret = psp_cmd_submit_buf(psp, ucode, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
}
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, ucode, psp->cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2579,10 +2564,6 @@ static int psp_load_fw(struct amdgpu_device *adev)
|
|||
goto skip_memalloc;
|
||||
}
|
||||
|
||||
psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!psp->cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,
|
||||
AMDGPU_GEM_DOMAIN_VRAM,
|
||||
|
|
@ -2736,9 +2717,6 @@ static int psp_hw_fini(void *handle)
|
|||
amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr,
|
||||
(void **)&psp->cmd_buf_mem);
|
||||
|
||||
kfree(psp->cmd);
|
||||
psp->cmd = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2902,17 +2880,15 @@ int psp_gpu_reset(struct amdgpu_device *adev)
|
|||
int psp_rlc_autoload_start(struct psp_context *psp)
|
||||
{
|
||||
int ret;
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
|
||||
cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_AUTOLOAD_RLC;
|
||||
|
||||
ret = psp_cmd_submit_buf(psp, NULL, cmd,
|
||||
psp->fence_buf_mc_addr);
|
||||
kfree(cmd);
|
||||
|
||||
release_psp_cmd_buf(psp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ enum psp_bootloader_cmd {
|
|||
PSP_BL__LOAD_SYSDRV = 0x10000,
|
||||
PSP_BL__LOAD_SOSDRV = 0x20000,
|
||||
PSP_BL__LOAD_KEY_DATABASE = 0x80000,
|
||||
PSP_BL__LOAD_SOCDRV = 0x90000,
|
||||
PSP_BL__LOAD_INTFDRV = 0xA0000,
|
||||
PSP_BL__LOAD_DBGDRV = 0xB0000,
|
||||
PSP_BL__LOAD_SOCDRV = 0xB0000,
|
||||
PSP_BL__LOAD_INTFDRV = 0xC0000,
|
||||
PSP_BL__LOAD_DBGDRV = 0xD0000,
|
||||
PSP_BL__DRAM_LONG_TRAIN = 0x100000,
|
||||
PSP_BL__DRAM_SHORT_TRAIN = 0x200000,
|
||||
PSP_BL__LOAD_TOS_SPL_TABLE = 0x10000000,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/bits.h>
|
||||
#include "atom.h"
|
||||
#include "amdgpu_eeprom.h"
|
||||
#include "amdgpu_atomfirmware.h"
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
|
|
@ -116,6 +117,22 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev,
|
|||
if (!control)
|
||||
return false;
|
||||
|
||||
control->i2c_address = 0;
|
||||
|
||||
if (amdgpu_atomfirmware_ras_rom_addr(adev, (uint8_t*)&control->i2c_address))
|
||||
{
|
||||
if (control->i2c_address == 0xA0)
|
||||
control->i2c_address = 0;
|
||||
else if (control->i2c_address == 0xA8)
|
||||
control->i2c_address = 0x40000;
|
||||
else {
|
||||
dev_warn(adev->dev, "RAS EEPROM I2C address not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA20:
|
||||
control->i2c_address = EEPROM_I2C_MADDR_VEGA20;
|
||||
|
|
|
|||
|
|
@ -54,11 +54,12 @@ static inline void amdgpu_res_first(struct ttm_resource *res,
|
|||
{
|
||||
struct drm_mm_node *node;
|
||||
|
||||
if (!res) {
|
||||
if (!res || res->mem_type == TTM_PL_SYSTEM) {
|
||||
cur->start = start;
|
||||
cur->size = size;
|
||||
cur->remaining = size;
|
||||
cur->node = NULL;
|
||||
WARN_ON(res && start + size > res->num_pages << PAGE_SHIFT);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ struct amdgpu_fence_driver {
|
|||
struct dma_fence **fences;
|
||||
};
|
||||
|
||||
int amdgpu_fence_driver_init(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
|
||||
|
||||
int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
|
||||
|
|
@ -115,9 +114,10 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
|
|||
int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
|
||||
struct amdgpu_irq_src *irq_src,
|
||||
unsigned irq_type);
|
||||
void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_hw_init(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_hw_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_fence_driver_sw_init(struct amdgpu_device *adev);
|
||||
void amdgpu_fence_driver_sw_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence,
|
||||
unsigned flags);
|
||||
int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s,
|
||||
|
|
|
|||
|
|
@ -1123,7 +1123,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev,
|
|||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||
|
||||
/* user pages are bound by amdgpu_ttm_tt_pin_userptr() */
|
||||
if (gtt && gtt->userptr) {
|
||||
if (gtt->userptr) {
|
||||
ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
|
||||
if (!ttm->sg)
|
||||
return -ENOMEM;
|
||||
|
|
@ -1148,7 +1148,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_device *bdev,
|
|||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||
struct amdgpu_device *adev;
|
||||
|
||||
if (gtt && gtt->userptr) {
|
||||
if (gtt->userptr) {
|
||||
amdgpu_ttm_tt_set_user_pages(ttm, NULL);
|
||||
kfree(ttm->sg);
|
||||
ttm->sg = NULL;
|
||||
|
|
|
|||
643
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
Normal file
643
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
Normal file
|
|
@ -0,0 +1,643 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_simple_kms_helper.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
#include "dce_v6_0.h"
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
#include "dce_v8_0.h"
|
||||
#endif
|
||||
#include "dce_v10_0.h"
|
||||
#include "dce_v11_0.h"
|
||||
#include "ivsrcid/ivsrcid_vislands30.h"
|
||||
#include "amdgpu_vkms.h"
|
||||
#include "amdgpu_display.h"
|
||||
|
||||
/**
|
||||
* DOC: amdgpu_vkms
|
||||
*
|
||||
* The amdgpu vkms interface provides a virtual KMS interface for several use
|
||||
* cases: devices without display hardware, platforms where the actual display
|
||||
* hardware is not useful (e.g., servers), SR-IOV virtual functions, device
|
||||
* emulation/simulation, and device bring up prior to display hardware being
|
||||
* usable. We previously emulated a legacy KMS interface, but there was a desire
|
||||
* to move to the atomic KMS interface. The vkms driver did everything we
|
||||
* needed, but we wanted KMS support natively in the driver without buffer
|
||||
* sharing and the ability to support an instance of VKMS per device. We first
|
||||
* looked at splitting vkms into a stub driver and a helper module that other
|
||||
* drivers could use to implement a virtual display, but this strategy ended up
|
||||
* being messy due to driver specific callbacks needed for buffer management.
|
||||
* Ultimately, it proved easier to import the vkms code as it mostly used core
|
||||
* drm helpers anyway.
|
||||
*/
|
||||
|
||||
static const u32 amdgpu_vkms_formats[] = {
|
||||
DRM_FORMAT_XRGB8888,
|
||||
};
|
||||
|
||||
static enum hrtimer_restart amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
|
||||
{
|
||||
struct amdgpu_vkms_output *output = container_of(timer,
|
||||
struct amdgpu_vkms_output,
|
||||
vblank_hrtimer);
|
||||
struct drm_crtc *crtc = &output->crtc;
|
||||
u64 ret_overrun;
|
||||
bool ret;
|
||||
|
||||
ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
|
||||
output->period_ns);
|
||||
WARN_ON(ret_overrun != 1);
|
||||
|
||||
ret = drm_crtc_handle_vblank(crtc);
|
||||
if (!ret)
|
||||
DRM_ERROR("amdgpu_vkms failure on handling vblank");
|
||||
|
||||
return HRTIMER_RESTART;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
unsigned int pipe = drm_crtc_index(crtc);
|
||||
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
||||
struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
|
||||
|
||||
drm_calc_timestamping_constants(crtc, &crtc->mode);
|
||||
|
||||
hrtimer_init(&out->vblank_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
out->vblank_hrtimer.function = &amdgpu_vkms_vblank_simulate;
|
||||
out->period_ns = ktime_set(0, vblank->framedur_ns);
|
||||
hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_vkms_disable_vblank(struct drm_crtc *crtc)
|
||||
{
|
||||
struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
|
||||
|
||||
hrtimer_cancel(&out->vblank_hrtimer);
|
||||
}
|
||||
|
||||
static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc *crtc,
|
||||
int *max_error,
|
||||
ktime_t *vblank_time,
|
||||
bool in_vblank_irq)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
unsigned int pipe = crtc->index;
|
||||
struct amdgpu_vkms_output *output = drm_crtc_to_amdgpu_vkms_output(crtc);
|
||||
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
|
||||
|
||||
if (!READ_ONCE(vblank->enabled)) {
|
||||
*vblank_time = ktime_get();
|
||||
return true;
|
||||
}
|
||||
|
||||
*vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
|
||||
|
||||
if (WARN_ON(*vblank_time == vblank->time))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* To prevent races we roll the hrtimer forward before we do any
|
||||
* interrupt processing - this is how real hw works (the interrupt is
|
||||
* only generated after all the vblank registers are updated) and what
|
||||
* the vblank core expects. Therefore we need to always correct the
|
||||
* timestampe by one frame.
|
||||
*/
|
||||
*vblank_time -= output->period_ns;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = {
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.destroy = drm_crtc_cleanup,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.reset = drm_atomic_helper_crtc_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
||||
.enable_vblank = amdgpu_vkms_enable_vblank,
|
||||
.disable_vblank = amdgpu_vkms_disable_vblank,
|
||||
.get_vblank_timestamp = amdgpu_vkms_get_vblank_timestamp,
|
||||
};
|
||||
|
||||
static void amdgpu_vkms_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
static void amdgpu_vkms_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
drm_crtc_vblank_off(crtc);
|
||||
}
|
||||
|
||||
static void amdgpu_vkms_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
if (crtc->state->event) {
|
||||
spin_lock(&crtc->dev->event_lock);
|
||||
|
||||
if (drm_crtc_vblank_get(crtc) != 0)
|
||||
drm_crtc_send_vblank_event(crtc, crtc->state->event);
|
||||
else
|
||||
drm_crtc_arm_vblank_event(crtc, crtc->state->event);
|
||||
|
||||
spin_unlock(&crtc->dev->event_lock);
|
||||
|
||||
crtc->state->event = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {
|
||||
.atomic_flush = amdgpu_vkms_crtc_atomic_flush,
|
||||
.atomic_enable = amdgpu_vkms_crtc_atomic_enable,
|
||||
.atomic_disable = amdgpu_vkms_crtc_atomic_disable,
|
||||
};
|
||||
|
||||
static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
|
||||
struct drm_plane *primary, struct drm_plane *cursor)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,
|
||||
&amdgpu_vkms_crtc_funcs, NULL);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to init CRTC\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
drm_crtc_helper_add(crtc, &amdgpu_vkms_crtc_helper_funcs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs amdgpu_vkms_connector_funcs = {
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = drm_connector_cleanup,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
};
|
||||
|
||||
static int amdgpu_vkms_conn_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_display_mode *mode = NULL;
|
||||
unsigned i;
|
||||
static const struct mode_size {
|
||||
int w;
|
||||
int h;
|
||||
} common_modes[] = {
|
||||
{ 640, 480},
|
||||
{ 720, 480},
|
||||
{ 800, 600},
|
||||
{ 848, 480},
|
||||
{1024, 768},
|
||||
{1152, 768},
|
||||
{1280, 720},
|
||||
{1280, 800},
|
||||
{1280, 854},
|
||||
{1280, 960},
|
||||
{1280, 1024},
|
||||
{1440, 900},
|
||||
{1400, 1050},
|
||||
{1680, 1050},
|
||||
{1600, 1200},
|
||||
{1920, 1080},
|
||||
{1920, 1200},
|
||||
{2560, 1440},
|
||||
{4096, 3112},
|
||||
{3656, 2664},
|
||||
{3840, 2160},
|
||||
{4096, 2160},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
|
||||
mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
}
|
||||
|
||||
drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
|
||||
|
||||
return ARRAY_SIZE(common_modes);
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs amdgpu_vkms_conn_helper_funcs = {
|
||||
.get_modes = amdgpu_vkms_conn_get_modes,
|
||||
};
|
||||
|
||||
static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||
};
|
||||
|
||||
static void amdgpu_vkms_plane_atomic_update(struct drm_plane *plane,
|
||||
struct drm_atomic_state *old_state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_plane_atomic_check(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
|
||||
plane);
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int ret;
|
||||
|
||||
if (!new_plane_state->fb || WARN_ON(!new_plane_state->crtc))
|
||||
return 0;
|
||||
|
||||
crtc_state = drm_atomic_get_crtc_state(state,
|
||||
new_plane_state->crtc);
|
||||
if (IS_ERR(crtc_state))
|
||||
return PTR_ERR(crtc_state);
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
false, true);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* for now primary plane must be visible and full screen */
|
||||
if (!new_plane_state->visible)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_prepare_fb(struct drm_plane *plane,
|
||||
struct drm_plane_state *new_state)
|
||||
{
|
||||
struct amdgpu_framebuffer *afb;
|
||||
struct drm_gem_object *obj;
|
||||
struct amdgpu_device *adev;
|
||||
struct amdgpu_bo *rbo;
|
||||
struct list_head list;
|
||||
struct ttm_validate_buffer tv;
|
||||
struct ww_acquire_ctx ticket;
|
||||
uint32_t domain;
|
||||
int r;
|
||||
|
||||
if (!new_state->fb) {
|
||||
DRM_DEBUG_KMS("No FB bound\n");
|
||||
return 0;
|
||||
}
|
||||
afb = to_amdgpu_framebuffer(new_state->fb);
|
||||
obj = new_state->fb->obj[0];
|
||||
rbo = gem_to_amdgpu_bo(obj);
|
||||
adev = amdgpu_ttm_adev(rbo->tbo.bdev);
|
||||
INIT_LIST_HEAD(&list);
|
||||
|
||||
tv.bo = &rbo->tbo;
|
||||
tv.num_shared = 1;
|
||||
list_add(&tv.head, &list);
|
||||
|
||||
r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (plane->type != DRM_PLANE_TYPE_CURSOR)
|
||||
domain = amdgpu_display_supported_domains(adev, rbo->flags);
|
||||
else
|
||||
domain = AMDGPU_GEM_DOMAIN_VRAM;
|
||||
|
||||
r = amdgpu_bo_pin(rbo, domain);
|
||||
if (unlikely(r != 0)) {
|
||||
if (r != -ERESTARTSYS)
|
||||
DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = amdgpu_ttm_alloc_gart(&rbo->tbo);
|
||||
if (unlikely(r != 0)) {
|
||||
amdgpu_bo_unpin(rbo);
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
DRM_ERROR("%p bind failed\n", rbo);
|
||||
return r;
|
||||
}
|
||||
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
|
||||
afb->address = amdgpu_bo_gpu_offset(rbo);
|
||||
|
||||
amdgpu_bo_ref(rbo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amdgpu_vkms_cleanup_fb(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
struct amdgpu_bo *rbo;
|
||||
int r;
|
||||
|
||||
if (!old_state->fb)
|
||||
return;
|
||||
|
||||
rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
|
||||
r = amdgpu_bo_reserve(rbo, false);
|
||||
if (unlikely(r)) {
|
||||
DRM_ERROR("failed to reserve rbo before unpin\n");
|
||||
return;
|
||||
}
|
||||
|
||||
amdgpu_bo_unpin(rbo);
|
||||
amdgpu_bo_unreserve(rbo);
|
||||
amdgpu_bo_unref(&rbo);
|
||||
}
|
||||
|
||||
static const struct drm_plane_helper_funcs amdgpu_vkms_primary_helper_funcs = {
|
||||
.atomic_update = amdgpu_vkms_plane_atomic_update,
|
||||
.atomic_check = amdgpu_vkms_plane_atomic_check,
|
||||
.prepare_fb = amdgpu_vkms_prepare_fb,
|
||||
.cleanup_fb = amdgpu_vkms_cleanup_fb,
|
||||
};
|
||||
|
||||
static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev,
|
||||
enum drm_plane_type type,
|
||||
int index)
|
||||
{
|
||||
struct drm_plane *plane;
|
||||
int ret;
|
||||
|
||||
plane = kzalloc(sizeof(*plane), GFP_KERNEL);
|
||||
if (!plane)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ret = drm_universal_plane_init(dev, plane, 1 << index,
|
||||
&amdgpu_vkms_plane_funcs,
|
||||
amdgpu_vkms_formats,
|
||||
ARRAY_SIZE(amdgpu_vkms_formats),
|
||||
NULL, type, NULL);
|
||||
if (ret) {
|
||||
kfree(plane);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
drm_plane_helper_add(plane, &amdgpu_vkms_primary_helper_funcs);
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
int amdgpu_vkms_output_init(struct drm_device *dev,
|
||||
struct amdgpu_vkms_output *output, int index)
|
||||
{
|
||||
struct drm_connector *connector = &output->connector;
|
||||
struct drm_encoder *encoder = &output->encoder;
|
||||
struct drm_crtc *crtc = &output->crtc;
|
||||
struct drm_plane *primary, *cursor = NULL;
|
||||
int ret;
|
||||
|
||||
primary = amdgpu_vkms_plane_init(dev, DRM_PLANE_TYPE_PRIMARY, index);
|
||||
if (IS_ERR(primary))
|
||||
return PTR_ERR(primary);
|
||||
|
||||
ret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);
|
||||
if (ret)
|
||||
goto err_crtc;
|
||||
|
||||
ret = drm_connector_init(dev, connector, &amdgpu_vkms_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VIRTUAL);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to init connector\n");
|
||||
goto err_connector;
|
||||
}
|
||||
|
||||
drm_connector_helper_add(connector, &amdgpu_vkms_conn_helper_funcs);
|
||||
|
||||
ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_VIRTUAL);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to init encoder\n");
|
||||
goto err_encoder;
|
||||
}
|
||||
encoder->possible_crtcs = 1 << index;
|
||||
|
||||
ret = drm_connector_attach_encoder(connector, encoder);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to attach connector to encoder\n");
|
||||
goto err_attach;
|
||||
}
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_attach:
|
||||
drm_encoder_cleanup(encoder);
|
||||
|
||||
err_encoder:
|
||||
drm_connector_cleanup(connector);
|
||||
|
||||
err_connector:
|
||||
drm_crtc_cleanup(crtc);
|
||||
|
||||
err_crtc:
|
||||
drm_plane_cleanup(primary);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct drm_mode_config_funcs amdgpu_vkms_mode_funcs = {
|
||||
.fb_create = amdgpu_display_user_framebuffer_create,
|
||||
.atomic_check = drm_atomic_helper_check,
|
||||
.atomic_commit = drm_atomic_helper_commit,
|
||||
};
|
||||
|
||||
static int amdgpu_vkms_sw_init(void *handle)
|
||||
{
|
||||
int r, i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
adev_to_drm(adev)->max_vblank_count = 0;
|
||||
|
||||
adev_to_drm(adev)->mode_config.funcs = &amdgpu_vkms_mode_funcs;
|
||||
|
||||
adev_to_drm(adev)->mode_config.max_width = XRES_MAX;
|
||||
adev_to_drm(adev)->mode_config.max_height = YRES_MAX;
|
||||
|
||||
adev_to_drm(adev)->mode_config.preferred_depth = 24;
|
||||
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
|
||||
|
||||
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
|
||||
|
||||
r = amdgpu_display_modeset_create_props(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev->amdgpu_vkms_output = kcalloc(adev->mode_info.num_crtc, sizeof(struct amdgpu_vkms_output), GFP_KERNEL);
|
||||
if (!adev->amdgpu_vkms_output)
|
||||
return -ENOMEM;
|
||||
|
||||
/* allocate crtcs, encoders, connectors */
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++) {
|
||||
r = amdgpu_vkms_output_init(adev_to_drm(adev), &adev->amdgpu_vkms_output[i], i);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
drm_kms_helper_poll_init(adev_to_drm(adev));
|
||||
|
||||
adev->mode_info.mode_config_initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_sw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++)
|
||||
if (adev->mode_info.crtcs[i])
|
||||
hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
|
||||
|
||||
kfree(adev->mode_info.bios_hardcoded_edid);
|
||||
kfree(adev->amdgpu_vkms_output);
|
||||
|
||||
drm_kms_helper_poll_fini(adev_to_drm(adev));
|
||||
|
||||
adev->mode_info.mode_config_initialized = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_hw_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
case CHIP_VERDE:
|
||||
case CHIP_OLAND:
|
||||
dce_v6_0_disable_dce(adev);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
dce_v8_0_disable_dce(adev);
|
||||
break;
|
||||
#endif
|
||||
case CHIP_FIJI:
|
||||
case CHIP_TONGA:
|
||||
dce_v10_0_disable_dce(adev);
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_VEGAM:
|
||||
dce_v11_0_disable_dce(adev);
|
||||
break;
|
||||
case CHIP_TOPAZ:
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
case CHIP_HAINAN:
|
||||
#endif
|
||||
/* no DCE */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_hw_fini(void *handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = drm_mode_config_helper_suspend(adev_to_drm(adev));
|
||||
if (r)
|
||||
return r;
|
||||
return amdgpu_vkms_hw_fini(handle);
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_resume(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_vkms_hw_init(handle);
|
||||
if (r)
|
||||
return r;
|
||||
return drm_mode_config_helper_resume(adev_to_drm(adev));
|
||||
}
|
||||
|
||||
static bool amdgpu_vkms_is_idle(void *handle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_wait_for_idle(void *handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_soft_reset(void *handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_set_clockgating_state(void *handle,
|
||||
enum amd_clockgating_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_vkms_set_powergating_state(void *handle,
|
||||
enum amd_powergating_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs amdgpu_vkms_ip_funcs = {
|
||||
.name = "amdgpu_vkms",
|
||||
.early_init = NULL,
|
||||
.late_init = NULL,
|
||||
.sw_init = amdgpu_vkms_sw_init,
|
||||
.sw_fini = amdgpu_vkms_sw_fini,
|
||||
.hw_init = amdgpu_vkms_hw_init,
|
||||
.hw_fini = amdgpu_vkms_hw_fini,
|
||||
.suspend = amdgpu_vkms_suspend,
|
||||
.resume = amdgpu_vkms_resume,
|
||||
.is_idle = amdgpu_vkms_is_idle,
|
||||
.wait_for_idle = amdgpu_vkms_wait_for_idle,
|
||||
.soft_reset = amdgpu_vkms_soft_reset,
|
||||
.set_clockgating_state = amdgpu_vkms_set_clockgating_state,
|
||||
.set_powergating_state = amdgpu_vkms_set_powergating_state,
|
||||
};
|
||||
|
||||
const struct amdgpu_ip_block_version amdgpu_vkms_ip_block =
|
||||
{
|
||||
.type = AMD_IP_BLOCK_TYPE_DCE,
|
||||
.major = 1,
|
||||
.minor = 0,
|
||||
.rev = 0,
|
||||
.funcs = &amdgpu_vkms_ip_funcs,
|
||||
};
|
||||
|
||||
26
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
Normal file
26
drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
|
||||
#ifndef _AMDGPU_VKMS_H_
|
||||
#define _AMDGPU_VKMS_H_
|
||||
|
||||
#define XRES_DEF 1024
|
||||
#define YRES_DEF 768
|
||||
|
||||
#define XRES_MAX 16384
|
||||
#define YRES_MAX 16384
|
||||
|
||||
#define drm_crtc_to_amdgpu_vkms_output(target) \
|
||||
container_of(target, struct amdgpu_vkms_output, crtc)
|
||||
|
||||
extern const struct amdgpu_ip_block_version amdgpu_vkms_ip_block;
|
||||
|
||||
struct amdgpu_vkms_output {
|
||||
struct drm_crtc crtc;
|
||||
struct drm_encoder encoder;
|
||||
struct drm_connector connector;
|
||||
struct hrtimer vblank_hrtimer;
|
||||
ktime_t period_ns;
|
||||
struct drm_pending_vblank_event *event;
|
||||
};
|
||||
|
||||
#endif /* _AMDGPU_VKMS_H_ */
|
||||
|
|
@ -1798,7 +1798,7 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
r = vm->update_funcs->commit(¶ms, fence);
|
||||
|
||||
if (table_freed)
|
||||
*table_freed = params.table_freed;
|
||||
*table_freed = *table_freed || params.table_freed;
|
||||
|
||||
error_unlock:
|
||||
amdgpu_vm_eviction_unlock(vm);
|
||||
|
|
@ -1856,6 +1856,7 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
|||
* @adev: amdgpu_device pointer
|
||||
* @bo_va: requested BO and VM object
|
||||
* @clear: if true clear the entries
|
||||
* @table_freed: return true if page table is freed
|
||||
*
|
||||
* Fill in the page table entries for @bo_va.
|
||||
*
|
||||
|
|
@ -1863,7 +1864,7 @@ void amdgpu_vm_get_memory(struct amdgpu_vm *vm, uint64_t *vram_mem,
|
|||
* 0 for success, -EINVAL for failure.
|
||||
*/
|
||||
int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
||||
bool clear)
|
||||
bool clear, bool *table_freed)
|
||||
{
|
||||
struct amdgpu_bo *bo = bo_va->base.bo;
|
||||
struct amdgpu_vm *vm = bo_va->base.vm;
|
||||
|
|
@ -1942,7 +1943,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va,
|
|||
resv, mapping->start,
|
||||
mapping->last, update_flags,
|
||||
mapping->offset, mem,
|
||||
pages_addr, last_update, NULL);
|
||||
pages_addr, last_update, table_freed);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
@ -2194,7 +2195,7 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
|
|||
|
||||
list_for_each_entry_safe(bo_va, tmp, &vm->moved, base.vm_status) {
|
||||
/* Per VM BOs never need to bo cleared in the page tables */
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
|
@ -2213,7 +2214,7 @@ int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
|
|||
else
|
||||
clear = true;
|
||||
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, clear);
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, clear, NULL);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
struct dma_fence **fence, bool *free_table);
|
||||
int amdgpu_vm_bo_update(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va,
|
||||
bool clear);
|
||||
bool clear, bool *table_freed);
|
||||
bool amdgpu_vm_evictable(struct amdgpu_bo *bo);
|
||||
void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo *bo, bool evicted);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
|
||||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_amdkfd.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "amdgpu_vkms.h"
|
||||
|
||||
static const struct amdgpu_video_codec_info cik_video_codecs_encode_array[] =
|
||||
{
|
||||
|
|
@ -2259,7 +2259,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2277,7 +2277,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2295,7 +2295,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2315,7 +2315,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &cik_sdma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &kv_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
|
|||
|
|
@ -1,780 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_pm.h"
|
||||
#include "amdgpu_i2c.h"
|
||||
#include "atom.h"
|
||||
#include "amdgpu_pll.h"
|
||||
#include "amdgpu_connectors.h"
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
#include "dce_v6_0.h"
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
#include "dce_v8_0.h"
|
||||
#endif
|
||||
#include "dce_v10_0.h"
|
||||
#include "dce_v11_0.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "ivsrcid/ivsrcid_vislands30.h"
|
||||
#include "amdgpu_display.h"
|
||||
|
||||
#define DCE_VIRTUAL_VBLANK_PERIOD 16666666
|
||||
|
||||
|
||||
static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
|
||||
static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
|
||||
int index);
|
||||
static int dce_virtual_pageflip(struct amdgpu_device *adev,
|
||||
unsigned crtc_id);
|
||||
static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer);
|
||||
static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
|
||||
int crtc,
|
||||
enum amdgpu_interrupt_state state);
|
||||
|
||||
static u32 dce_virtual_vblank_get_counter(struct amdgpu_device *adev, int crtc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dce_virtual_page_flip(struct amdgpu_device *adev,
|
||||
int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int dce_virtual_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
|
||||
u32 *vbl, u32 *position)
|
||||
{
|
||||
*vbl = 0;
|
||||
*position = 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static bool dce_virtual_hpd_sense(struct amdgpu_device *adev,
|
||||
enum amdgpu_hpd_id hpd)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void dce_virtual_hpd_set_polarity(struct amdgpu_device *adev,
|
||||
enum amdgpu_hpd_id hpd)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static u32 dce_virtual_hpd_get_gpio_reg(struct amdgpu_device *adev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dce_virtual_bandwidth_update - program display watermarks
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Calculate and program the display watermarks and line
|
||||
* buffer allocation (CIK).
|
||||
*/
|
||||
static void dce_virtual_bandwidth_update(struct amdgpu_device *adev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static int dce_virtual_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
|
||||
u16 *green, u16 *blue, uint32_t size,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dce_virtual_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
drm_crtc_cleanup(crtc);
|
||||
kfree(amdgpu_crtc);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs dce_virtual_crtc_funcs = {
|
||||
.cursor_set2 = NULL,
|
||||
.cursor_move = NULL,
|
||||
.gamma_set = dce_virtual_crtc_gamma_set,
|
||||
.set_config = amdgpu_display_crtc_set_config,
|
||||
.destroy = dce_virtual_crtc_destroy,
|
||||
.page_flip_target = amdgpu_display_crtc_page_flip_target,
|
||||
.get_vblank_counter = amdgpu_get_vblank_counter_kms,
|
||||
.enable_vblank = amdgpu_enable_vblank_kms,
|
||||
.disable_vblank = amdgpu_disable_vblank_kms,
|
||||
.get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
|
||||
};
|
||||
|
||||
static void dce_virtual_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(dev);
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
unsigned type;
|
||||
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
amdgpu_crtc->enabled = true;
|
||||
/* Make sure VBLANK interrupts are still enabled */
|
||||
type = amdgpu_display_crtc_idx_to_irq_type(adev,
|
||||
amdgpu_crtc->crtc_id);
|
||||
amdgpu_irq_update(adev, &adev->crtc_irq, type);
|
||||
drm_crtc_vblank_on(crtc);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
drm_crtc_vblank_off(crtc);
|
||||
amdgpu_crtc->enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void dce_virtual_crtc_prepare(struct drm_crtc *crtc)
|
||||
{
|
||||
dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||
}
|
||||
|
||||
static void dce_virtual_crtc_commit(struct drm_crtc *crtc)
|
||||
{
|
||||
dce_virtual_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
static void dce_virtual_crtc_disable(struct drm_crtc *crtc)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
struct drm_device *dev = crtc->dev;
|
||||
|
||||
if (dev->num_crtcs)
|
||||
drm_crtc_vblank_off(crtc);
|
||||
|
||||
amdgpu_crtc->enabled = false;
|
||||
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
amdgpu_crtc->encoder = NULL;
|
||||
amdgpu_crtc->connector = NULL;
|
||||
}
|
||||
|
||||
static int dce_virtual_crtc_mode_set(struct drm_crtc *crtc,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode,
|
||||
int x, int y, struct drm_framebuffer *old_fb)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
|
||||
/* update the hw version fpr dpm */
|
||||
amdgpu_crtc->hw_mode = *adjusted_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool dce_virtual_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int dce_virtual_crtc_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
struct drm_framebuffer *old_fb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_crtc_set_base_atomic(struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb,
|
||||
int x, int y, enum mode_set_atomic state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs dce_virtual_crtc_helper_funcs = {
|
||||
.dpms = dce_virtual_crtc_dpms,
|
||||
.mode_fixup = dce_virtual_crtc_mode_fixup,
|
||||
.mode_set = dce_virtual_crtc_mode_set,
|
||||
.mode_set_base = dce_virtual_crtc_set_base,
|
||||
.mode_set_base_atomic = dce_virtual_crtc_set_base_atomic,
|
||||
.prepare = dce_virtual_crtc_prepare,
|
||||
.commit = dce_virtual_crtc_commit,
|
||||
.disable = dce_virtual_crtc_disable,
|
||||
.get_scanout_position = amdgpu_crtc_get_scanout_position,
|
||||
};
|
||||
|
||||
static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
|
||||
amdgpu_crtc = kzalloc(sizeof(struct amdgpu_crtc) +
|
||||
(AMDGPUFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
|
||||
if (amdgpu_crtc == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
drm_crtc_init(adev_to_drm(adev), &amdgpu_crtc->base, &dce_virtual_crtc_funcs);
|
||||
|
||||
drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256);
|
||||
amdgpu_crtc->crtc_id = index;
|
||||
adev->mode_info.crtcs[index] = amdgpu_crtc;
|
||||
|
||||
amdgpu_crtc->pll_id = ATOM_PPLL_INVALID;
|
||||
amdgpu_crtc->encoder = NULL;
|
||||
amdgpu_crtc->connector = NULL;
|
||||
amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
|
||||
drm_crtc_helper_add(&amdgpu_crtc->base, &dce_virtual_crtc_helper_funcs);
|
||||
|
||||
hrtimer_init(&amdgpu_crtc->vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
hrtimer_set_expires(&amdgpu_crtc->vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD);
|
||||
amdgpu_crtc->vblank_timer.function = dce_virtual_vblank_timer_handle;
|
||||
hrtimer_start(&amdgpu_crtc->vblank_timer,
|
||||
DCE_VIRTUAL_VBLANK_PERIOD, HRTIMER_MODE_REL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
dce_virtual_set_display_funcs(adev);
|
||||
dce_virtual_set_irq_funcs(adev);
|
||||
|
||||
adev->mode_info.num_hpd = 1;
|
||||
adev->mode_info.num_dig = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_encoder *
|
||||
dce_virtual_encoder(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
|
||||
drm_connector_for_each_possible_encoder(connector, encoder) {
|
||||
if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
|
||||
return encoder;
|
||||
}
|
||||
|
||||
/* pick the first one */
|
||||
drm_connector_for_each_possible_encoder(connector, encoder)
|
||||
return encoder;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int dce_virtual_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_display_mode *mode = NULL;
|
||||
unsigned i;
|
||||
static const struct mode_size {
|
||||
int w;
|
||||
int h;
|
||||
} common_modes[] = {
|
||||
{ 640, 480},
|
||||
{ 720, 480},
|
||||
{ 800, 600},
|
||||
{ 848, 480},
|
||||
{1024, 768},
|
||||
{1152, 768},
|
||||
{1280, 720},
|
||||
{1280, 800},
|
||||
{1280, 854},
|
||||
{1280, 960},
|
||||
{1280, 1024},
|
||||
{1440, 900},
|
||||
{1400, 1050},
|
||||
{1680, 1050},
|
||||
{1600, 1200},
|
||||
{1920, 1080},
|
||||
{1920, 1200},
|
||||
{2560, 1440},
|
||||
{4096, 3112},
|
||||
{3656, 2664},
|
||||
{3840, 2160},
|
||||
{4096, 2160},
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
|
||||
mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum drm_mode_status dce_virtual_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
dce_virtual_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dce_virtual_set_property(struct drm_connector *connector,
|
||||
struct drm_property *property,
|
||||
uint64_t val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dce_virtual_destroy(struct drm_connector *connector)
|
||||
{
|
||||
drm_connector_unregister(connector);
|
||||
drm_connector_cleanup(connector);
|
||||
kfree(connector);
|
||||
}
|
||||
|
||||
static void dce_virtual_force(struct drm_connector *connector)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs dce_virtual_connector_helper_funcs = {
|
||||
.get_modes = dce_virtual_get_modes,
|
||||
.mode_valid = dce_virtual_mode_valid,
|
||||
.best_encoder = dce_virtual_encoder,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs dce_virtual_connector_funcs = {
|
||||
.dpms = dce_virtual_dpms,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = dce_virtual_set_property,
|
||||
.destroy = dce_virtual_destroy,
|
||||
.force = dce_virtual_force,
|
||||
};
|
||||
|
||||
static int dce_virtual_sw_init(void *handle)
|
||||
{
|
||||
int r, i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER, &adev->crtc_irq);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev_to_drm(adev)->max_vblank_count = 0;
|
||||
|
||||
adev_to_drm(adev)->mode_config.funcs = &amdgpu_mode_funcs;
|
||||
|
||||
adev_to_drm(adev)->mode_config.max_width = 16384;
|
||||
adev_to_drm(adev)->mode_config.max_height = 16384;
|
||||
|
||||
adev_to_drm(adev)->mode_config.preferred_depth = 24;
|
||||
adev_to_drm(adev)->mode_config.prefer_shadow = 1;
|
||||
|
||||
adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
|
||||
|
||||
r = amdgpu_display_modeset_create_props(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
adev_to_drm(adev)->mode_config.max_width = 16384;
|
||||
adev_to_drm(adev)->mode_config.max_height = 16384;
|
||||
|
||||
/* allocate crtcs, encoders, connectors */
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++) {
|
||||
r = dce_virtual_crtc_init(adev, i);
|
||||
if (r)
|
||||
return r;
|
||||
r = dce_virtual_connector_encoder_init(adev, i);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
drm_kms_helper_poll_init(adev_to_drm(adev));
|
||||
|
||||
adev->mode_info.mode_config_initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_sw_fini(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < adev->mode_info.num_crtc; i++)
|
||||
if (adev->mode_info.crtcs[i])
|
||||
hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);
|
||||
|
||||
kfree(adev->mode_info.bios_hardcoded_edid);
|
||||
|
||||
drm_kms_helper_poll_fini(adev_to_drm(adev));
|
||||
|
||||
drm_mode_config_cleanup(adev_to_drm(adev));
|
||||
/* clear crtcs pointer to avoid dce irq finish routine access freed data */
|
||||
memset(adev->mode_info.crtcs, 0, sizeof(adev->mode_info.crtcs[0]) * AMDGPU_MAX_CRTCS);
|
||||
adev->mode_info.mode_config_initialized = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_hw_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
case CHIP_TAHITI:
|
||||
case CHIP_PITCAIRN:
|
||||
case CHIP_VERDE:
|
||||
case CHIP_OLAND:
|
||||
dce_v6_0_disable_dce(adev);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_DRM_AMDGPU_CIK
|
||||
case CHIP_BONAIRE:
|
||||
case CHIP_HAWAII:
|
||||
case CHIP_KAVERI:
|
||||
case CHIP_KABINI:
|
||||
case CHIP_MULLINS:
|
||||
dce_v8_0_disable_dce(adev);
|
||||
break;
|
||||
#endif
|
||||
case CHIP_FIJI:
|
||||
case CHIP_TONGA:
|
||||
dce_v10_0_disable_dce(adev);
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_POLARIS10:
|
||||
case CHIP_POLARIS11:
|
||||
case CHIP_VEGAM:
|
||||
dce_v11_0_disable_dce(adev);
|
||||
break;
|
||||
case CHIP_TOPAZ:
|
||||
#ifdef CONFIG_DRM_AMDGPU_SI
|
||||
case CHIP_HAINAN:
|
||||
#endif
|
||||
/* no DCE */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_hw_fini(void *handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_suspend(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = amdgpu_display_suspend_helper(adev);
|
||||
if (r)
|
||||
return r;
|
||||
return dce_virtual_hw_fini(handle);
|
||||
}
|
||||
|
||||
static int dce_virtual_resume(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int r;
|
||||
|
||||
r = dce_virtual_hw_init(handle);
|
||||
if (r)
|
||||
return r;
|
||||
return amdgpu_display_resume_helper(adev);
|
||||
}
|
||||
|
||||
static bool dce_virtual_is_idle(void *handle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static int dce_virtual_wait_for_idle(void *handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_soft_reset(void *handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_set_clockgating_state(void *handle,
|
||||
enum amd_clockgating_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dce_virtual_set_powergating_state(void *handle,
|
||||
enum amd_powergating_state state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amd_ip_funcs dce_virtual_ip_funcs = {
|
||||
.name = "dce_virtual",
|
||||
.early_init = dce_virtual_early_init,
|
||||
.late_init = NULL,
|
||||
.sw_init = dce_virtual_sw_init,
|
||||
.sw_fini = dce_virtual_sw_fini,
|
||||
.hw_init = dce_virtual_hw_init,
|
||||
.hw_fini = dce_virtual_hw_fini,
|
||||
.suspend = dce_virtual_suspend,
|
||||
.resume = dce_virtual_resume,
|
||||
.is_idle = dce_virtual_is_idle,
|
||||
.wait_for_idle = dce_virtual_wait_for_idle,
|
||||
.soft_reset = dce_virtual_soft_reset,
|
||||
.set_clockgating_state = dce_virtual_set_clockgating_state,
|
||||
.set_powergating_state = dce_virtual_set_powergating_state,
|
||||
};
|
||||
|
||||
/* these are handled by the primary encoders */
|
||||
static void dce_virtual_encoder_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void dce_virtual_encoder_commit(struct drm_encoder *encoder)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dce_virtual_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void dce_virtual_encoder_disable(struct drm_encoder *encoder)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dce_virtual_encoder_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static bool dce_virtual_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs dce_virtual_encoder_helper_funcs = {
|
||||
.dpms = dce_virtual_encoder_dpms,
|
||||
.mode_fixup = dce_virtual_encoder_mode_fixup,
|
||||
.prepare = dce_virtual_encoder_prepare,
|
||||
.mode_set = dce_virtual_encoder_mode_set,
|
||||
.commit = dce_virtual_encoder_commit,
|
||||
.disable = dce_virtual_encoder_disable,
|
||||
};
|
||||
|
||||
static void dce_virtual_encoder_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(encoder);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_funcs dce_virtual_encoder_funcs = {
|
||||
.destroy = dce_virtual_encoder_destroy,
|
||||
};
|
||||
|
||||
static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
|
||||
int index)
|
||||
{
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_connector *connector;
|
||||
|
||||
/* add a new encoder */
|
||||
encoder = kzalloc(sizeof(struct drm_encoder), GFP_KERNEL);
|
||||
if (!encoder)
|
||||
return -ENOMEM;
|
||||
encoder->possible_crtcs = 1 << index;
|
||||
drm_encoder_init(adev_to_drm(adev), encoder, &dce_virtual_encoder_funcs,
|
||||
DRM_MODE_ENCODER_VIRTUAL, NULL);
|
||||
drm_encoder_helper_add(encoder, &dce_virtual_encoder_helper_funcs);
|
||||
|
||||
connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL);
|
||||
if (!connector) {
|
||||
kfree(encoder);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* add a new connector */
|
||||
drm_connector_init(adev_to_drm(adev), connector, &dce_virtual_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_VIRTUAL);
|
||||
drm_connector_helper_add(connector, &dce_virtual_connector_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
|
||||
/* link them */
|
||||
drm_connector_attach_encoder(connector, encoder);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amdgpu_display_funcs dce_virtual_display_funcs = {
|
||||
.bandwidth_update = &dce_virtual_bandwidth_update,
|
||||
.vblank_get_counter = &dce_virtual_vblank_get_counter,
|
||||
.backlight_set_level = NULL,
|
||||
.backlight_get_level = NULL,
|
||||
.hpd_sense = &dce_virtual_hpd_sense,
|
||||
.hpd_set_polarity = &dce_virtual_hpd_set_polarity,
|
||||
.hpd_get_gpio_reg = &dce_virtual_hpd_get_gpio_reg,
|
||||
.page_flip = &dce_virtual_page_flip,
|
||||
.page_flip_get_scanoutpos = &dce_virtual_crtc_get_scanoutpos,
|
||||
.add_encoder = NULL,
|
||||
.add_connector = NULL,
|
||||
};
|
||||
|
||||
static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->mode_info.funcs = &dce_virtual_display_funcs;
|
||||
}
|
||||
|
||||
static int dce_virtual_pageflip(struct amdgpu_device *adev,
|
||||
unsigned crtc_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct amdgpu_crtc *amdgpu_crtc;
|
||||
struct amdgpu_flip_work *works;
|
||||
|
||||
amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
|
||||
|
||||
if (crtc_id >= adev->mode_info.num_crtc) {
|
||||
DRM_ERROR("invalid pageflip crtc %d\n", crtc_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* IRQ could occur when in initial stage */
|
||||
if (amdgpu_crtc == NULL)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
|
||||
works = amdgpu_crtc->pflip_works;
|
||||
if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) {
|
||||
DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
|
||||
"AMDGPU_FLIP_SUBMITTED(%d)\n",
|
||||
amdgpu_crtc->pflip_status,
|
||||
AMDGPU_FLIP_SUBMITTED);
|
||||
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* page flip completed. clean up */
|
||||
amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE;
|
||||
amdgpu_crtc->pflip_works = NULL;
|
||||
|
||||
/* wakeup usersapce */
|
||||
if (works->event)
|
||||
drm_crtc_send_vblank_event(&amdgpu_crtc->base, works->event);
|
||||
|
||||
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
|
||||
|
||||
drm_crtc_vblank_put(&amdgpu_crtc->base);
|
||||
amdgpu_bo_unref(&works->old_abo);
|
||||
kfree(works->shared);
|
||||
kfree(works);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = container_of(vblank_timer,
|
||||
struct amdgpu_crtc, vblank_timer);
|
||||
struct drm_device *ddev = amdgpu_crtc->base.dev;
|
||||
struct amdgpu_device *adev = drm_to_adev(ddev);
|
||||
struct amdgpu_irq_src *source = adev->irq.client[AMDGPU_IRQ_CLIENTID_LEGACY].sources
|
||||
[VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER];
|
||||
int irq_type = amdgpu_display_crtc_idx_to_irq_type(adev,
|
||||
amdgpu_crtc->crtc_id);
|
||||
|
||||
if (amdgpu_irq_enabled(adev, source, irq_type)) {
|
||||
drm_handle_vblank(ddev, amdgpu_crtc->crtc_id);
|
||||
dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id);
|
||||
}
|
||||
hrtimer_start(vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD,
|
||||
HRTIMER_MODE_REL);
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
|
||||
int crtc,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
if (crtc >= adev->mode_info.num_crtc || !adev->mode_info.crtcs[crtc]) {
|
||||
DRM_DEBUG("invalid crtc %d\n", crtc);
|
||||
return;
|
||||
}
|
||||
|
||||
adev->mode_info.crtcs[crtc]->vsync_timer_enabled = state;
|
||||
DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc, state);
|
||||
}
|
||||
|
||||
|
||||
static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
unsigned type,
|
||||
enum amdgpu_interrupt_state state)
|
||||
{
|
||||
if (type > AMDGPU_CRTC_IRQ_VBLANK6)
|
||||
return -EINVAL;
|
||||
|
||||
dce_virtual_set_crtc_vblank_interrupt_state(adev, type, state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
|
||||
.set = dce_virtual_set_crtc_irq_state,
|
||||
.process = NULL,
|
||||
};
|
||||
|
||||
static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->crtc_irq.num_types = adev->mode_info.num_crtc;
|
||||
adev->crtc_irq.funcs = &dce_virtual_crtc_irq_funcs;
|
||||
}
|
||||
|
||||
const struct amdgpu_ip_block_version dce_virtual_ip_block =
|
||||
{
|
||||
.type = AMD_IP_BLOCK_TYPE_DCE,
|
||||
.major = 1,
|
||||
.minor = 0,
|
||||
.rev = 0,
|
||||
.funcs = &dce_virtual_ip_funcs,
|
||||
};
|
||||
|
|
@ -4621,6 +4621,7 @@ static void gfx_v10_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd,
|
|||
dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_STS2);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_DBG1);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_M0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_MODE);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
|
||||
|
|
|
|||
|
|
@ -3027,6 +3027,7 @@ static void gfx_v6_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd, u
|
|||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_TMA_HI);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_IB_DBG0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_M0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_MODE);
|
||||
}
|
||||
|
||||
static void gfx_v6_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
|
||||
|
|
|
|||
|
|
@ -4198,6 +4198,7 @@ static void gfx_v7_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd, u
|
|||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_TMA_HI);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_IB_DBG0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_M0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_MODE);
|
||||
}
|
||||
|
||||
static void gfx_v7_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
|
||||
|
|
|
|||
|
|
@ -5279,6 +5279,7 @@ static void gfx_v8_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd, u
|
|||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_TMA_HI);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_IB_DBG0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_M0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_MODE);
|
||||
}
|
||||
|
||||
static void gfx_v8_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
|
||||
|
|
|
|||
|
|
@ -1295,6 +1295,16 @@ static bool is_raven_kicker(struct amdgpu_device *adev)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool check_if_enlarge_doorbell_range(struct amdgpu_device *adev)
|
||||
{
|
||||
if ((adev->asic_type == CHIP_RENOIR) &&
|
||||
(adev->gfx.me_fw_version >= 0x000000a5) &&
|
||||
(adev->gfx.me_feature_version >= 52))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
|
||||
{
|
||||
if (gfx_v9_0_should_disable_gfxoff(adev->pdev))
|
||||
|
|
@ -2080,6 +2090,7 @@ static void gfx_v9_0_read_wave_data(struct amdgpu_device *adev, uint32_t simd, u
|
|||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_IB_STS);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_IB_DBG0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_M0);
|
||||
dst[(*no_fields)++] = wave_read_ind(adev, simd, wave, ixSQ_WAVE_MODE);
|
||||
}
|
||||
|
||||
static void gfx_v9_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t simd,
|
||||
|
|
@ -3675,7 +3686,16 @@ static int gfx_v9_0_kiq_init_register(struct amdgpu_ring *ring)
|
|||
if (ring->use_doorbell) {
|
||||
WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER,
|
||||
(adev->doorbell_index.kiq * 2) << 2);
|
||||
WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER,
|
||||
/* If GC has entered CGPG, ringing doorbell > first page
|
||||
* doesn't wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to
|
||||
* workaround this issue. And this change has to align with firmware
|
||||
* update.
|
||||
*/
|
||||
if (check_if_enlarge_doorbell_range(adev))
|
||||
WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER,
|
||||
(adev->doorbell.size - 4));
|
||||
else
|
||||
WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER,
|
||||
(adev->doorbell_index.userqueue_end * 2) << 2);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1171,8 +1171,8 @@ static void gmc_v9_0_set_umc_funcs(struct amdgpu_device *adev)
|
|||
break;
|
||||
case CHIP_ALDEBARAN:
|
||||
adev->umc.max_ras_err_cnt_per_query = UMC_V6_7_TOTAL_CHANNEL_NUM;
|
||||
adev->umc.channel_inst_num = UMC_V6_7_UMC_INSTANCE_NUM;
|
||||
adev->umc.umc_inst_num = UMC_V6_7_CHANNEL_INSTANCE_NUM;
|
||||
adev->umc.channel_inst_num = UMC_V6_7_CHANNEL_INSTANCE_NUM;
|
||||
adev->umc.umc_inst_num = UMC_V6_7_UMC_INSTANCE_NUM;
|
||||
adev->umc.channel_offs = UMC_V6_7_PER_CHANNEL_OFFSET;
|
||||
if (!adev->gmc.xgmi.connected_to_cpu)
|
||||
adev->umc.ras_funcs = &umc_v6_7_ras_funcs;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
#include "jpeg_v2_0.h"
|
||||
#include "vcn_v3_0.h"
|
||||
#include "jpeg_v3_0.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "amdgpu_vkms.h"
|
||||
#include "mes_v10_1.h"
|
||||
#include "mxgpu_nv.h"
|
||||
#include "smuio_v11_0.h"
|
||||
|
|
@ -721,7 +721,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
!amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -749,7 +749,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -779,7 +779,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -802,7 +802,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -823,7 +823,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -843,7 +843,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
is_support_sw_smu(adev))
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -865,7 +865,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -883,11 +883,11 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &psp_v13_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -905,7 +905,7 @@ int nv_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
}
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
#include "dce_v6_0.h"
|
||||
#include "si.h"
|
||||
#include "uvd_v3_1.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "amdgpu_vkms.h"
|
||||
#include "gca/gfx_6_0_d.h"
|
||||
#include "oss/oss_1_0_d.h"
|
||||
#include "oss/oss_1_0_sh_mask.h"
|
||||
|
|
@ -2759,7 +2759,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2777,7 +2777,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC) && defined(CONFIG_DRM_AMD_DC_SI)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2795,7 +2795,7 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &si_dma_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &si_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
#include "smuio_v9_0.h"
|
||||
#include "smuio_v11_0.h"
|
||||
#include "smuio_v13_0.h"
|
||||
#include "dce_virtual.h"
|
||||
#include "amdgpu_vkms.h"
|
||||
#include "mxgpu_ai.h"
|
||||
#include "amdgpu_ras.h"
|
||||
#include "amdgpu_xgmi.h"
|
||||
|
|
@ -843,7 +843,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
}
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -863,7 +863,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -885,7 +885,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);
|
||||
|
|
@ -909,7 +909,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &gfx_v9_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &sdma_v4_0_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
|
|||
|
|
@ -30,17 +30,17 @@
|
|||
|
||||
const uint32_t
|
||||
umc_v6_7_channel_idx_tbl_second[UMC_V6_7_UMC_INSTANCE_NUM][UMC_V6_7_CHANNEL_INSTANCE_NUM] = {
|
||||
{28, 12, 6, 22}, {19, 3, 9, 25},
|
||||
{20, 4, 30, 14}, {11, 27, 1, 17},
|
||||
{24, 8, 2, 18}, {15, 31, 5, 21},
|
||||
{16, 0, 26, 10}, {7, 23, 29, 13}
|
||||
{28, 20, 24, 16, 12, 4, 8, 0},
|
||||
{6, 30, 2, 26, 22, 14, 18, 10},
|
||||
{19, 11, 15, 7, 3, 27, 31, 23},
|
||||
{9, 1, 5, 29, 25, 17, 21, 13}
|
||||
};
|
||||
const uint32_t
|
||||
umc_v6_7_channel_idx_tbl_first[UMC_V6_7_UMC_INSTANCE_NUM][UMC_V6_7_CHANNEL_INSTANCE_NUM] = {
|
||||
{19, 3, 9, 25}, {28, 12, 6, 22},
|
||||
{11, 27, 1, 17}, {20, 4, 30, 14},
|
||||
{15, 31, 5, 21}, {24, 8, 2, 18},
|
||||
{7, 23, 29, 13}, {16, 0, 26, 10}
|
||||
{19, 11, 15, 7, 3, 27, 31, 23},
|
||||
{9, 1, 5, 29, 25, 17, 21, 13},
|
||||
{28, 20, 24, 16, 12, 4, 8, 0},
|
||||
{6, 30, 2, 26, 22, 14, 18, 10},
|
||||
};
|
||||
|
||||
static inline uint32_t get_umc_v6_7_reg_offset(struct amdgpu_device *adev,
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@
|
|||
#define UMC_V6_7_INST_DIST 0x40000
|
||||
|
||||
/* number of umc channel instance with memory map register access */
|
||||
#define UMC_V6_7_CHANNEL_INSTANCE_NUM 4
|
||||
#define UMC_V6_7_UMC_INSTANCE_NUM 4
|
||||
/* number of umc instance with memory map register access */
|
||||
#define UMC_V6_7_UMC_INSTANCE_NUM 8
|
||||
#define UMC_V6_7_CHANNEL_INSTANCE_NUM 8
|
||||
/* total channel instances in one umc block */
|
||||
#define UMC_V6_7_TOTAL_CHANNEL_NUM (UMC_V6_7_CHANNEL_INSTANCE_NUM * UMC_V6_7_UMC_INSTANCE_NUM)
|
||||
/* UMC regiser per channel offset */
|
||||
|
|
|
|||
|
|
@ -90,9 +90,7 @@ static int vcn_v3_0_early_init(void *handle)
|
|||
int i;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
for (i = 0; i < VCN_INSTANCES_SIENNA_CICHLID; i++)
|
||||
if (amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, i))
|
||||
adev->vcn.num_vcn_inst++;
|
||||
adev->vcn.num_vcn_inst = VCN_INSTANCES_SIENNA_CICHLID;
|
||||
adev->vcn.harvest_config = 0;
|
||||
adev->vcn.num_enc_rings = 1;
|
||||
|
||||
|
|
@ -153,8 +151,7 @@ static int vcn_v3_0_sw_init(void *handle)
|
|||
adev->firmware.fw_size +=
|
||||
ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
|
||||
|
||||
if ((adev->vcn.num_vcn_inst == VCN_INSTANCES_SIENNA_CICHLID) ||
|
||||
(amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID)) {
|
||||
if (adev->vcn.num_vcn_inst == VCN_INSTANCES_SIENNA_CICHLID) {
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1;
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw;
|
||||
adev->firmware.fw_size +=
|
||||
|
|
@ -328,17 +325,27 @@ static int vcn_v3_0_hw_init(void *handle)
|
|||
continue;
|
||||
|
||||
ring = &adev->vcn.inst[i].ring_dec;
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_dec_ring_set_wptr(ring);
|
||||
ring->sched.ready = true;
|
||||
if (amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, i)) {
|
||||
ring->sched.ready = false;
|
||||
dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
|
||||
} else {
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_dec_ring_set_wptr(ring);
|
||||
ring->sched.ready = true;
|
||||
}
|
||||
|
||||
for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
|
||||
ring = &adev->vcn.inst[i].ring_enc[j];
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_enc_ring_set_wptr(ring);
|
||||
ring->sched.ready = true;
|
||||
if (amdgpu_vcn_is_disabled_vcn(adev, VCN_ENCODE_RING, i)) {
|
||||
ring->sched.ready = false;
|
||||
dev_info(adev->dev, "ring %s is disabled by hypervisor\n", ring->name);
|
||||
} else {
|
||||
ring->wptr = 0;
|
||||
ring->wptr_old = 0;
|
||||
vcn_v3_0_enc_ring_set_wptr(ring);
|
||||
ring->sched.ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
#if defined(CONFIG_DRM_AMD_ACP)
|
||||
#include "amdgpu_acp.h"
|
||||
#endif
|
||||
#include "dce_virtual.h"
|
||||
#include "amdgpu_vkms.h"
|
||||
#include "mxgpu_vi.h"
|
||||
#include "amdgpu_dm.h"
|
||||
|
||||
|
|
@ -2102,7 +2102,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v2_4_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
break;
|
||||
case CHIP_FIJI:
|
||||
amdgpu_device_ip_block_add(adev, &vi_common_ip_block);
|
||||
|
|
@ -2112,7 +2112,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2132,7 +2132,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display || amdgpu_sriov_vf(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2155,7 +2155,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v3_1_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2173,7 +2173,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
@ -2194,7 +2194,7 @@ int vi_set_ip_blocks(struct amdgpu_device *adev)
|
|||
amdgpu_device_ip_block_add(adev, &sdma_v3_0_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &pp_smu_ip_block);
|
||||
if (adev->enable_virtual_display)
|
||||
amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block);
|
||||
amdgpu_device_ip_block_add(adev, &amdgpu_vkms_ip_block);
|
||||
#if defined(CONFIG_DRM_AMD_DC)
|
||||
else if (amdgpu_device_has_dc_support(adev))
|
||||
amdgpu_device_ip_block_add(adev, &dm_ip_block);
|
||||
|
|
|
|||
|
|
@ -1393,6 +1393,7 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
|
|||
long err = 0;
|
||||
int i;
|
||||
uint32_t *devices_arr = NULL;
|
||||
bool table_freed = false;
|
||||
|
||||
dev = kfd_device_by_id(GET_GPU_ID(args->handle));
|
||||
if (!dev)
|
||||
|
|
@ -1450,7 +1451,8 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
|
|||
goto get_mem_obj_from_handle_failed;
|
||||
}
|
||||
err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(
|
||||
peer->kgd, (struct kgd_mem *)mem, peer_pdd->drm_priv);
|
||||
peer->kgd, (struct kgd_mem *)mem,
|
||||
peer_pdd->drm_priv, &table_freed);
|
||||
if (err) {
|
||||
pr_err("Failed to map to gpu %d/%d\n",
|
||||
i, args->n_devices);
|
||||
|
|
@ -1468,16 +1470,17 @@ static int kfd_ioctl_map_memory_to_gpu(struct file *filep,
|
|||
}
|
||||
|
||||
/* Flush TLBs after waiting for the page table updates to complete */
|
||||
for (i = 0; i < args->n_devices; i++) {
|
||||
peer = kfd_device_by_id(devices_arr[i]);
|
||||
if (WARN_ON_ONCE(!peer))
|
||||
continue;
|
||||
peer_pdd = kfd_get_process_device_data(peer, p);
|
||||
if (WARN_ON_ONCE(!peer_pdd))
|
||||
continue;
|
||||
kfd_flush_tlb(peer_pdd, TLB_FLUSH_LEGACY);
|
||||
if (table_freed) {
|
||||
for (i = 0; i < args->n_devices; i++) {
|
||||
peer = kfd_device_by_id(devices_arr[i]);
|
||||
if (WARN_ON_ONCE(!peer))
|
||||
continue;
|
||||
peer_pdd = kfd_get_process_device_data(peer, p);
|
||||
if (WARN_ON_ONCE(!peer_pdd))
|
||||
continue;
|
||||
kfd_flush_tlb(peer_pdd, TLB_FLUSH_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(devices_arr);
|
||||
|
||||
return err;
|
||||
|
|
@ -1565,10 +1568,29 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
|||
}
|
||||
args->n_success = i+1;
|
||||
}
|
||||
kfree(devices_arr);
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
if (dev->device_info->asic_family == CHIP_ALDEBARAN) {
|
||||
err = amdgpu_amdkfd_gpuvm_sync_memory(dev->kgd,
|
||||
(struct kgd_mem *) mem, true);
|
||||
if (err) {
|
||||
pr_debug("Sync memory failed, wait interrupted by user signal\n");
|
||||
goto sync_memory_failed;
|
||||
}
|
||||
|
||||
/* Flush TLBs after waiting for the page table updates to complete */
|
||||
for (i = 0; i < args->n_devices; i++) {
|
||||
peer = kfd_device_by_id(devices_arr[i]);
|
||||
if (WARN_ON_ONCE(!peer))
|
||||
continue;
|
||||
peer_pdd = kfd_get_process_device_data(peer, p);
|
||||
if (WARN_ON_ONCE(!peer_pdd))
|
||||
continue;
|
||||
kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT);
|
||||
}
|
||||
}
|
||||
kfree(devices_arr);
|
||||
|
||||
return 0;
|
||||
|
||||
bind_process_to_device_failed:
|
||||
|
|
@ -1576,6 +1598,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
|
|||
unmap_memory_from_gpu_failed:
|
||||
mutex_unlock(&p->mutex);
|
||||
copy_from_user_failed:
|
||||
sync_memory_failed:
|
||||
kfree(devices_arr);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ static const struct kfd2kgd_calls *kfd2kgd_funcs[] = {
|
|||
static const struct kfd_device_info kaveri_device_info = {
|
||||
.asic_family = CHIP_KAVERI,
|
||||
.asic_name = "kaveri",
|
||||
.gfx_target_version = 70000,
|
||||
.max_pasid_bits = 16,
|
||||
/* max num of queues for KV.TODO should be a dynamic value */
|
||||
.max_no_of_hqd = 24,
|
||||
|
|
@ -110,6 +111,7 @@ static const struct kfd_device_info kaveri_device_info = {
|
|||
static const struct kfd_device_info carrizo_device_info = {
|
||||
.asic_family = CHIP_CARRIZO,
|
||||
.asic_name = "carrizo",
|
||||
.gfx_target_version = 80001,
|
||||
.max_pasid_bits = 16,
|
||||
/* max num of queues for CZ.TODO should be a dynamic value */
|
||||
.max_no_of_hqd = 24,
|
||||
|
|
@ -130,6 +132,7 @@ static const struct kfd_device_info carrizo_device_info = {
|
|||
static const struct kfd_device_info raven_device_info = {
|
||||
.asic_family = CHIP_RAVEN,
|
||||
.asic_name = "raven",
|
||||
.gfx_target_version = 90002,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -148,6 +151,7 @@ static const struct kfd_device_info raven_device_info = {
|
|||
static const struct kfd_device_info hawaii_device_info = {
|
||||
.asic_family = CHIP_HAWAII,
|
||||
.asic_name = "hawaii",
|
||||
.gfx_target_version = 70001,
|
||||
.max_pasid_bits = 16,
|
||||
/* max num of queues for KV.TODO should be a dynamic value */
|
||||
.max_no_of_hqd = 24,
|
||||
|
|
@ -167,6 +171,7 @@ static const struct kfd_device_info hawaii_device_info = {
|
|||
static const struct kfd_device_info tonga_device_info = {
|
||||
.asic_family = CHIP_TONGA,
|
||||
.asic_name = "tonga",
|
||||
.gfx_target_version = 80002,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -185,6 +190,7 @@ static const struct kfd_device_info tonga_device_info = {
|
|||
static const struct kfd_device_info fiji_device_info = {
|
||||
.asic_family = CHIP_FIJI,
|
||||
.asic_name = "fiji",
|
||||
.gfx_target_version = 80003,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -203,6 +209,7 @@ static const struct kfd_device_info fiji_device_info = {
|
|||
static const struct kfd_device_info fiji_vf_device_info = {
|
||||
.asic_family = CHIP_FIJI,
|
||||
.asic_name = "fiji",
|
||||
.gfx_target_version = 80003,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -222,6 +229,7 @@ static const struct kfd_device_info fiji_vf_device_info = {
|
|||
static const struct kfd_device_info polaris10_device_info = {
|
||||
.asic_family = CHIP_POLARIS10,
|
||||
.asic_name = "polaris10",
|
||||
.gfx_target_version = 80003,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -240,6 +248,7 @@ static const struct kfd_device_info polaris10_device_info = {
|
|||
static const struct kfd_device_info polaris10_vf_device_info = {
|
||||
.asic_family = CHIP_POLARIS10,
|
||||
.asic_name = "polaris10",
|
||||
.gfx_target_version = 80003,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -258,6 +267,7 @@ static const struct kfd_device_info polaris10_vf_device_info = {
|
|||
static const struct kfd_device_info polaris11_device_info = {
|
||||
.asic_family = CHIP_POLARIS11,
|
||||
.asic_name = "polaris11",
|
||||
.gfx_target_version = 80003,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -276,6 +286,7 @@ static const struct kfd_device_info polaris11_device_info = {
|
|||
static const struct kfd_device_info polaris12_device_info = {
|
||||
.asic_family = CHIP_POLARIS12,
|
||||
.asic_name = "polaris12",
|
||||
.gfx_target_version = 80003,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -294,6 +305,7 @@ static const struct kfd_device_info polaris12_device_info = {
|
|||
static const struct kfd_device_info vegam_device_info = {
|
||||
.asic_family = CHIP_VEGAM,
|
||||
.asic_name = "vegam",
|
||||
.gfx_target_version = 80003,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 4,
|
||||
|
|
@ -312,6 +324,7 @@ static const struct kfd_device_info vegam_device_info = {
|
|||
static const struct kfd_device_info vega10_device_info = {
|
||||
.asic_family = CHIP_VEGA10,
|
||||
.asic_name = "vega10",
|
||||
.gfx_target_version = 90000,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -330,6 +343,7 @@ static const struct kfd_device_info vega10_device_info = {
|
|||
static const struct kfd_device_info vega10_vf_device_info = {
|
||||
.asic_family = CHIP_VEGA10,
|
||||
.asic_name = "vega10",
|
||||
.gfx_target_version = 90000,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -348,6 +362,7 @@ static const struct kfd_device_info vega10_vf_device_info = {
|
|||
static const struct kfd_device_info vega12_device_info = {
|
||||
.asic_family = CHIP_VEGA12,
|
||||
.asic_name = "vega12",
|
||||
.gfx_target_version = 90004,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -366,6 +381,7 @@ static const struct kfd_device_info vega12_device_info = {
|
|||
static const struct kfd_device_info vega20_device_info = {
|
||||
.asic_family = CHIP_VEGA20,
|
||||
.asic_name = "vega20",
|
||||
.gfx_target_version = 90006,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -384,6 +400,7 @@ static const struct kfd_device_info vega20_device_info = {
|
|||
static const struct kfd_device_info arcturus_device_info = {
|
||||
.asic_family = CHIP_ARCTURUS,
|
||||
.asic_name = "arcturus",
|
||||
.gfx_target_version = 90008,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -402,6 +419,7 @@ static const struct kfd_device_info arcturus_device_info = {
|
|||
static const struct kfd_device_info aldebaran_device_info = {
|
||||
.asic_family = CHIP_ALDEBARAN,
|
||||
.asic_name = "aldebaran",
|
||||
.gfx_target_version = 90010,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -420,6 +438,7 @@ static const struct kfd_device_info aldebaran_device_info = {
|
|||
static const struct kfd_device_info renoir_device_info = {
|
||||
.asic_family = CHIP_RENOIR,
|
||||
.asic_name = "renoir",
|
||||
.gfx_target_version = 90002,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -438,6 +457,7 @@ static const struct kfd_device_info renoir_device_info = {
|
|||
static const struct kfd_device_info navi10_device_info = {
|
||||
.asic_family = CHIP_NAVI10,
|
||||
.asic_name = "navi10",
|
||||
.gfx_target_version = 100100,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -456,6 +476,7 @@ static const struct kfd_device_info navi10_device_info = {
|
|||
static const struct kfd_device_info navi12_device_info = {
|
||||
.asic_family = CHIP_NAVI12,
|
||||
.asic_name = "navi12",
|
||||
.gfx_target_version = 100101,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -474,6 +495,7 @@ static const struct kfd_device_info navi12_device_info = {
|
|||
static const struct kfd_device_info navi14_device_info = {
|
||||
.asic_family = CHIP_NAVI14,
|
||||
.asic_name = "navi14",
|
||||
.gfx_target_version = 100102,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -492,6 +514,7 @@ static const struct kfd_device_info navi14_device_info = {
|
|||
static const struct kfd_device_info sienna_cichlid_device_info = {
|
||||
.asic_family = CHIP_SIENNA_CICHLID,
|
||||
.asic_name = "sienna_cichlid",
|
||||
.gfx_target_version = 100300,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -510,6 +533,7 @@ static const struct kfd_device_info sienna_cichlid_device_info = {
|
|||
static const struct kfd_device_info navy_flounder_device_info = {
|
||||
.asic_family = CHIP_NAVY_FLOUNDER,
|
||||
.asic_name = "navy_flounder",
|
||||
.gfx_target_version = 100301,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -528,6 +552,7 @@ static const struct kfd_device_info navy_flounder_device_info = {
|
|||
static const struct kfd_device_info vangogh_device_info = {
|
||||
.asic_family = CHIP_VANGOGH,
|
||||
.asic_name = "vangogh",
|
||||
.gfx_target_version = 100303,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -546,6 +571,7 @@ static const struct kfd_device_info vangogh_device_info = {
|
|||
static const struct kfd_device_info dimgrey_cavefish_device_info = {
|
||||
.asic_family = CHIP_DIMGREY_CAVEFISH,
|
||||
.asic_name = "dimgrey_cavefish",
|
||||
.gfx_target_version = 100302,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -564,6 +590,7 @@ static const struct kfd_device_info dimgrey_cavefish_device_info = {
|
|||
static const struct kfd_device_info beige_goby_device_info = {
|
||||
.asic_family = CHIP_BEIGE_GOBY,
|
||||
.asic_name = "beige_goby",
|
||||
.gfx_target_version = 100304,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -582,6 +609,7 @@ static const struct kfd_device_info beige_goby_device_info = {
|
|||
static const struct kfd_device_info yellow_carp_device_info = {
|
||||
.asic_family = CHIP_YELLOW_CARP,
|
||||
.asic_name = "yellow_carp",
|
||||
.gfx_target_version = 100305,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
@ -600,6 +628,7 @@ static const struct kfd_device_info yellow_carp_device_info = {
|
|||
static const struct kfd_device_info cyan_skillfish_device_info = {
|
||||
.asic_family = CHIP_CYAN_SKILLFISH,
|
||||
.asic_name = "cyan_skillfish",
|
||||
.gfx_target_version = 100103,
|
||||
.max_pasid_bits = 16,
|
||||
.max_no_of_hqd = 24,
|
||||
.doorbell_size = 8,
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ struct kfd_event_interrupt_class {
|
|||
struct kfd_device_info {
|
||||
enum amd_asic_type asic_family;
|
||||
const char *asic_name;
|
||||
uint32_t gfx_target_version;
|
||||
const struct kfd_event_interrupt_class *event_interrupt_class;
|
||||
unsigned int max_pasid_bits;
|
||||
unsigned int max_no_of_hqd;
|
||||
|
|
|
|||
|
|
@ -714,7 +714,8 @@ static int kfd_process_alloc_gpuvm(struct kfd_process_device *pdd,
|
|||
if (err)
|
||||
goto err_alloc_mem;
|
||||
|
||||
err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, mem, pdd->drm_priv);
|
||||
err = amdgpu_amdkfd_gpuvm_map_memory_to_gpu(kdev->kgd, mem,
|
||||
pdd->drm_priv, NULL);
|
||||
if (err)
|
||||
goto err_map_mem;
|
||||
|
||||
|
|
|
|||
|
|
@ -3019,7 +3019,8 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
|||
struct svm_range *prange;
|
||||
uint32_t prefetch_loc = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
|
||||
uint32_t location = KFD_IOCTL_SVM_LOCATION_UNDEFINED;
|
||||
uint32_t flags = 0xffffffff;
|
||||
uint32_t flags_and = 0xffffffff;
|
||||
uint32_t flags_or = 0;
|
||||
int gpuidx;
|
||||
uint32_t i;
|
||||
|
||||
|
|
@ -3046,12 +3047,12 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
|||
get_accessible = true;
|
||||
break;
|
||||
case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
|
||||
case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
|
||||
get_flags = true;
|
||||
break;
|
||||
case KFD_IOCTL_SVM_ATTR_GRANULARITY:
|
||||
get_granularity = true;
|
||||
break;
|
||||
case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
|
||||
case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
|
||||
case KFD_IOCTL_SVM_ATTR_NO_ACCESS:
|
||||
fallthrough;
|
||||
|
|
@ -3069,7 +3070,8 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
|||
if (!node) {
|
||||
pr_debug("range attrs not found return default values\n");
|
||||
svm_range_set_default_attributes(&location, &prefetch_loc,
|
||||
&granularity, &flags);
|
||||
&granularity, &flags_and);
|
||||
flags_or = flags_and;
|
||||
if (p->xnack_enabled)
|
||||
bitmap_copy(bitmap_access, svms->bitmap_supported,
|
||||
MAX_GPU_INSTANCE);
|
||||
|
|
@ -3115,8 +3117,10 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
|||
bitmap_and(bitmap_aip, bitmap_aip,
|
||||
prange->bitmap_aip, MAX_GPU_INSTANCE);
|
||||
}
|
||||
if (get_flags)
|
||||
flags &= prange->flags;
|
||||
if (get_flags) {
|
||||
flags_and &= prange->flags;
|
||||
flags_or |= prange->flags;
|
||||
}
|
||||
|
||||
if (get_granularity && prange->granularity < granularity)
|
||||
granularity = prange->granularity;
|
||||
|
|
@ -3150,7 +3154,10 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
|
|||
attrs[i].type = KFD_IOCTL_SVM_ATTR_NO_ACCESS;
|
||||
break;
|
||||
case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
|
||||
attrs[i].value = flags;
|
||||
attrs[i].value = flags_and;
|
||||
break;
|
||||
case KFD_IOCTL_SVM_ATTR_CLR_FLAGS:
|
||||
attrs[i].value = ~flags_or;
|
||||
break;
|
||||
case KFD_IOCTL_SVM_ATTR_GRANULARITY:
|
||||
attrs[i].value = (uint32_t)granularity;
|
||||
|
|
|
|||
|
|
@ -478,6 +478,8 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
|
|||
dev->node_props.simd_per_cu);
|
||||
sysfs_show_32bit_prop(buffer, offs, "max_slots_scratch_cu",
|
||||
dev->node_props.max_slots_scratch_cu);
|
||||
sysfs_show_32bit_prop(buffer, offs, "gfx_target_version",
|
||||
dev->node_props.gfx_target_version);
|
||||
sysfs_show_32bit_prop(buffer, offs, "vendor_id",
|
||||
dev->node_props.vendor_id);
|
||||
sysfs_show_32bit_prop(buffer, offs, "device_id",
|
||||
|
|
@ -1360,6 +1362,7 @@ int kfd_topology_add_device(struct kfd_dev *gpu)
|
|||
dev->node_props.simd_arrays_per_engine =
|
||||
cu_info.num_shader_arrays_per_engine;
|
||||
|
||||
dev->node_props.gfx_target_version = gpu->device_info->gfx_target_version;
|
||||
dev->node_props.vendor_id = gpu->pdev->vendor;
|
||||
dev->node_props.device_id = gpu->pdev->device;
|
||||
dev->node_props.capability |=
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ struct kfd_node_properties {
|
|||
uint32_t simd_per_cu;
|
||||
uint32_t max_slots_scratch_cu;
|
||||
uint32_t engine_id;
|
||||
uint32_t gfx_target_version;
|
||||
uint32_t vendor_id;
|
||||
uint32_t device_id;
|
||||
uint32_t location_id;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
AMDGPUDM = amdgpu_dm.o amdgpu_dm_irq.o amdgpu_dm_mst_types.o amdgpu_dm_color.o
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
AMDGPUDM += dc_fpu.o
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_DRM_AMD_DC),)
|
||||
AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o amdgpu_dm_pp_smu.o amdgpu_dm_psr.o
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1066,19 +1066,15 @@ static void event_mall_stutter(struct work_struct *work)
|
|||
|
||||
static struct vblank_workqueue *vblank_create_workqueue(struct amdgpu_device *adev, struct dc *dc)
|
||||
{
|
||||
|
||||
int max_caps = dc->caps.max_links;
|
||||
struct vblank_workqueue *vblank_work;
|
||||
int i = 0;
|
||||
|
||||
vblank_work = kcalloc(max_caps, sizeof(*vblank_work), GFP_KERNEL);
|
||||
vblank_work = kzalloc(sizeof(*vblank_work), GFP_KERNEL);
|
||||
if (ZERO_OR_NULL_PTR(vblank_work)) {
|
||||
kfree(vblank_work);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < max_caps; i++)
|
||||
INIT_WORK(&vblank_work[i].mall_work, event_mall_stutter);
|
||||
INIT_WORK(&vblank_work->mall_work, event_mall_stutter);
|
||||
|
||||
return vblank_work;
|
||||
}
|
||||
|
|
@ -1548,6 +1544,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
|
|||
}
|
||||
|
||||
hdr = (const struct dmcub_firmware_header_v1_0 *)adev->dm.dmub_fw->data;
|
||||
adev->dm.dmcub_fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
|
||||
if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
|
||||
adev->firmware.ucode[AMDGPU_UCODE_ID_DMCUB].ucode_id =
|
||||
|
|
@ -1561,7 +1558,6 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
|
|||
adev->dm.dmcub_fw_version);
|
||||
}
|
||||
|
||||
adev->dm.dmcub_fw_version = le32_to_cpu(hdr->header.ucode_version);
|
||||
|
||||
adev->dm.dmub_srv = kzalloc(sizeof(*adev->dm.dmub_srv), GFP_KERNEL);
|
||||
dmub_srv = adev->dm.dmub_srv;
|
||||
|
|
@ -9620,7 +9616,12 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
|
|||
} else if (amdgpu_freesync_vid_mode && aconnector &&
|
||||
is_freesync_video_mode(&new_crtc_state->mode,
|
||||
aconnector)) {
|
||||
set_freesync_fixed_config(dm_new_crtc_state);
|
||||
struct drm_display_mode *high_mode;
|
||||
|
||||
high_mode = get_highest_refresh_rate_mode(aconnector, false);
|
||||
if (!drm_mode_equal(&new_crtc_state->mode, high_mode)) {
|
||||
set_freesync_fixed_config(dm_new_crtc_state);
|
||||
}
|
||||
}
|
||||
|
||||
ret = dm_atomic_get_state(state, &dm_state);
|
||||
|
|
|
|||
|
|
@ -637,6 +637,30 @@ TRACE_EVENT(amdgpu_refresh_rate_track,
|
|||
__entry->refresh_rate_ns)
|
||||
);
|
||||
|
||||
TRACE_EVENT(dcn_fpu,
|
||||
TP_PROTO(bool begin, const char *function, const int line, const int recursion_depth),
|
||||
TP_ARGS(begin, function, line, recursion_depth),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(bool, begin)
|
||||
__field(const char *, function)
|
||||
__field(int, line)
|
||||
__field(int, recursion_depth)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->begin = begin;
|
||||
__entry->function = function;
|
||||
__entry->line = line;
|
||||
__entry->recursion_depth = recursion_depth;
|
||||
),
|
||||
TP_printk("%s: recursion_depth: %d: %s()+%d:",
|
||||
__entry->begin ? "begin" : "end",
|
||||
__entry->recursion_depth,
|
||||
__entry->function,
|
||||
__entry->line
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* _AMDGPU_DM_TRACE_H_ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
|
|
|||
144
drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c
Normal file
144
drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dc_trace.h"
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
#include <asm/fpu/api.h>
|
||||
#elif defined(CONFIG_PPC64)
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/cputable.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DOC: DC FPU manipulation overview
|
||||
*
|
||||
* DC core uses FPU operations in multiple parts of the code, which requires a
|
||||
* more specialized way to manage these areas' entrance. To fulfill this
|
||||
* requirement, we created some wrapper functions that encapsulate
|
||||
* kernel_fpu_begin/end to better fit our need in the display component. In
|
||||
* summary, in this file, you can find functions related to FPU operation
|
||||
* management.
|
||||
*/
|
||||
|
||||
static DEFINE_PER_CPU(int, fpu_recursion_depth);
|
||||
|
||||
/**
|
||||
* dc_assert_fp_enabled - Check if FPU protection is enabled
|
||||
*
|
||||
* This function tells if the code is already under FPU protection or not. A
|
||||
* function that works as an API for a set of FPU operations can use this
|
||||
* function for checking if the caller invoked it after DC_FP_START(). For
|
||||
* example, take a look at dcn2x.c file.
|
||||
*/
|
||||
inline void dc_assert_fp_enabled(void)
|
||||
{
|
||||
int *pcpu, depth = 0;
|
||||
|
||||
pcpu = get_cpu_ptr(&fpu_recursion_depth);
|
||||
depth = *pcpu;
|
||||
put_cpu_ptr(&fpu_recursion_depth);
|
||||
|
||||
ASSERT(depth > 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_fpu_begin - Enables FPU protection
|
||||
* @function_name: A string containing the function name for debug purposes
|
||||
* (usually __func__)
|
||||
*
|
||||
* @line: A line number where DC_FP_START was invoked for debug purpose
|
||||
* (usually __LINE__)
|
||||
*
|
||||
* This function is responsible for managing the use of kernel_fpu_begin() with
|
||||
* the advantage of providing an event trace for debugging.
|
||||
*
|
||||
* Note: Do not call this function directly; always use DC_FP_START().
|
||||
*/
|
||||
void dc_fpu_begin(const char *function_name, const int line)
|
||||
{
|
||||
int *pcpu;
|
||||
|
||||
pcpu = get_cpu_ptr(&fpu_recursion_depth);
|
||||
*pcpu += 1;
|
||||
|
||||
if (*pcpu == 1) {
|
||||
#if defined(CONFIG_X86)
|
||||
kernel_fpu_begin();
|
||||
#elif defined(CONFIG_PPC64)
|
||||
if (cpu_has_feature(CPU_FTR_VSX_COMP)) {
|
||||
preempt_disable();
|
||||
enable_kernel_vsx();
|
||||
} else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) {
|
||||
preempt_disable();
|
||||
enable_kernel_altivec();
|
||||
} else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) {
|
||||
preempt_disable();
|
||||
enable_kernel_fp();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TRACE_DCN_FPU(true, function_name, line, *pcpu);
|
||||
put_cpu_ptr(&fpu_recursion_depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_fpu_end - Disable FPU protection
|
||||
* @function_name: A string containing the function name for debug purposes
|
||||
* @line: A-line number where DC_FP_END was invoked for debug purpose
|
||||
*
|
||||
* This function is responsible for managing the use of kernel_fpu_end() with
|
||||
* the advantage of providing an event trace for debugging.
|
||||
*
|
||||
* Note: Do not call this function directly; always use DC_FP_END().
|
||||
*/
|
||||
void dc_fpu_end(const char *function_name, const int line)
|
||||
{
|
||||
int *pcpu;
|
||||
|
||||
pcpu = get_cpu_ptr(&fpu_recursion_depth);
|
||||
*pcpu -= 1;
|
||||
if (*pcpu <= 0) {
|
||||
#if defined(CONFIG_X86)
|
||||
kernel_fpu_end();
|
||||
#elif defined(CONFIG_PPC64)
|
||||
if (cpu_has_feature(CPU_FTR_VSX_COMP)) {
|
||||
disable_kernel_vsx();
|
||||
preempt_enable();
|
||||
} else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) {
|
||||
disable_kernel_altivec();
|
||||
preempt_enable();
|
||||
} else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) {
|
||||
disable_kernel_fp();
|
||||
preempt_enable();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TRACE_DCN_FPU(false, function_name, line, *pcpu);
|
||||
put_cpu_ptr(&fpu_recursion_depth);
|
||||
}
|
||||
34
drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.h
Normal file
34
drivers/gpu/drm/amd/display/amdgpu_dm/dc_fpu.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_FPU_H__
|
||||
#define __DC_FPU_H__
|
||||
|
||||
void dc_assert_fp_enabled(void);
|
||||
void dc_fpu_begin(const char *function_name, const int line);
|
||||
void dc_fpu_end(const char *function_name, const int line);
|
||||
|
||||
#endif /* __DC_FPU_H__ */
|
||||
|
|
@ -66,9 +66,11 @@ int rn_get_active_display_cnt_wa(
|
|||
for (i = 0; i < context->stream_count; i++) {
|
||||
const struct dc_stream_state *stream = context->streams[i];
|
||||
|
||||
/* Extend the WA to DP for Linux*/
|
||||
if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A ||
|
||||
stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK ||
|
||||
stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK)
|
||||
stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK ||
|
||||
stream->signal == SIGNAL_TYPE_DISPLAY_PORT)
|
||||
tmds_present = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3595,29 +3595,12 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link)
|
|||
bool dp_retrieve_lttpr_cap(struct dc_link *link)
|
||||
{
|
||||
uint8_t lttpr_dpcd_data[6];
|
||||
bool vbios_lttpr_enable = false;
|
||||
bool vbios_lttpr_interop = false;
|
||||
struct dc_bios *bios = link->dc->ctx->dc_bios;
|
||||
bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
|
||||
bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
|
||||
enum dc_status status = DC_ERROR_UNEXPECTED;
|
||||
bool is_lttpr_present = false;
|
||||
|
||||
memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
|
||||
/* Query BIOS to determine if LTTPR functionality is forced on by system */
|
||||
if (bios->funcs->get_lttpr_caps) {
|
||||
enum bp_result bp_query_result;
|
||||
uint8_t is_vbios_lttpr_enable = 0;
|
||||
|
||||
bp_query_result = bios->funcs->get_lttpr_caps(bios, &is_vbios_lttpr_enable);
|
||||
vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
|
||||
}
|
||||
|
||||
if (bios->funcs->get_lttpr_interop) {
|
||||
enum bp_result bp_query_result;
|
||||
uint8_t is_vbios_interop_enabled = 0;
|
||||
|
||||
bp_query_result = bios->funcs->get_lttpr_interop(bios, &is_vbios_interop_enabled);
|
||||
vbios_lttpr_interop = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
* Logic to determine LTTPR mode
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ struct link_encoder *link_enc_cfg_get_next_avail_link_enc(
|
|||
const struct dc_state *state)
|
||||
{
|
||||
struct link_encoder *link_enc = NULL;
|
||||
enum engine_id eng_id = ENGINE_ID_UNKNOWN;
|
||||
enum engine_id eng_id;
|
||||
|
||||
eng_id = find_first_avail_link_enc(dc->ctx, state);
|
||||
if (eng_id != ENGINE_ID_UNKNOWN)
|
||||
|
|
|
|||
|
|
@ -1030,7 +1030,7 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
|||
|
||||
/* Timing borders are part of vactive that we are also supposed to skip in addition
|
||||
* to any stream dst offset. Since dm logic assumes dst is in addressable
|
||||
* space we need to add the the left and top borders to dst offsets temporarily.
|
||||
* space we need to add the left and top borders to dst offsets temporarily.
|
||||
* TODO: fix in DM, stream dst is supposed to be in vactive
|
||||
*/
|
||||
pipe_ctx->stream->dst.x += timing->h_border_left;
|
||||
|
|
@ -1051,6 +1051,11 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
|||
/* depends on scaling ratios and recout, does not calculate offset yet */
|
||||
calculate_viewport_size(pipe_ctx);
|
||||
|
||||
/* Stopgap for validation of ODM + MPO on one side of screen case */
|
||||
if (pipe_ctx->plane_res.scl_data.viewport.height < 1 ||
|
||||
pipe_ctx->plane_res.scl_data.viewport.width < 1)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* LB calculations depend on vp size, h/v_active and scaling ratios
|
||||
* Setting line buffer pixel depth to 24bpp yields banding
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
/* forward declaration */
|
||||
struct aux_payload;
|
||||
|
||||
#define DC_VER "3.2.146"
|
||||
#define DC_VER "3.2.147"
|
||||
|
||||
#define MAX_SURFACES 3
|
||||
#define MAX_PLANES 6
|
||||
|
|
@ -183,6 +183,8 @@ struct dc_caps {
|
|||
unsigned int cursor_cache_size;
|
||||
struct dc_plane_cap planes[MAX_PLANES];
|
||||
struct dc_color_caps color;
|
||||
bool vbios_lttpr_aware;
|
||||
bool vbios_lttpr_enable;
|
||||
};
|
||||
|
||||
struct dc_bug_wa {
|
||||
|
|
|
|||
|
|
@ -37,3 +37,6 @@
|
|||
|
||||
#define TRACE_DCN_CLOCK_STATE(dcn_clocks) \
|
||||
trace_amdgpu_dm_dc_clocks_state(dcn_clocks)
|
||||
|
||||
#define TRACE_DCN_FPU(begin, function, line, ref_count) \
|
||||
trace_dcn_fpu(begin, function, line, ref_count)
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ void optc2_lock_doublebuffer_enable(struct timing_generator *optc)
|
|||
|
||||
REG_UPDATE_2(OTG_GLOBAL_CONTROL1,
|
||||
MASTER_UPDATE_LOCK_DB_X,
|
||||
h_blank_start - 200 - 1,
|
||||
(h_blank_start - 200 - 1) / optc1->opp_count,
|
||||
MASTER_UPDATE_LOCK_DB_Y,
|
||||
v_blank_start - 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "include/irq_service_interface.h"
|
||||
#include "dcn20/dcn20_resource.h"
|
||||
|
||||
#include "dml/dcn2x/dcn2x.h"
|
||||
|
||||
#include "dcn10/dcn10_hubp.h"
|
||||
#include "dcn10/dcn10_ipp.h"
|
||||
#include "dcn20_hubbub.h"
|
||||
|
|
@ -1974,43 +1976,6 @@ void dcn20_split_stream_for_mpc(
|
|||
ASSERT(primary_pipe->plane_state);
|
||||
}
|
||||
|
||||
void dcn20_populate_dml_writeback_from_context(
|
||||
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes)
|
||||
{
|
||||
int pipe_cnt, i;
|
||||
|
||||
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct dc_writeback_info *wb_info = &res_ctx->pipe_ctx[i].stream->writeback_info[0];
|
||||
|
||||
if (!res_ctx->pipe_ctx[i].stream)
|
||||
continue;
|
||||
|
||||
/* Set writeback information */
|
||||
pipes[pipe_cnt].dout.wb_enable = (wb_info->wb_enabled == true) ? 1 : 0;
|
||||
pipes[pipe_cnt].dout.num_active_wb++;
|
||||
pipes[pipe_cnt].dout.wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_height;
|
||||
pipes[pipe_cnt].dout.wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_width;
|
||||
pipes[pipe_cnt].dout.wb.wb_dst_width = wb_info->dwb_params.dest_width;
|
||||
pipes[pipe_cnt].dout.wb.wb_dst_height = wb_info->dwb_params.dest_height;
|
||||
pipes[pipe_cnt].dout.wb.wb_htaps_luma = 1;
|
||||
pipes[pipe_cnt].dout.wb.wb_vtaps_luma = 1;
|
||||
pipes[pipe_cnt].dout.wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;
|
||||
pipes[pipe_cnt].dout.wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;
|
||||
pipes[pipe_cnt].dout.wb.wb_hratio = 1.0;
|
||||
pipes[pipe_cnt].dout.wb.wb_vratio = 1.0;
|
||||
if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {
|
||||
if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
|
||||
pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_8;
|
||||
else
|
||||
pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_10;
|
||||
} else
|
||||
pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_444_32;
|
||||
|
||||
pipe_cnt++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int dcn20_populate_dml_pipes_from_context(
|
||||
struct dc *dc,
|
||||
struct dc_state *context,
|
||||
|
|
@ -2392,7 +2357,9 @@ int dcn20_populate_dml_pipes_from_context(
|
|||
}
|
||||
|
||||
/* populate writeback information */
|
||||
DC_FP_START();
|
||||
dc->res_pool->funcs->populate_dml_writeback_from_context(dc, res_ctx, pipes);
|
||||
DC_FP_END();
|
||||
|
||||
return pipe_cnt;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ struct pipe_ctx *dcn20_acquire_idle_pipe_for_layer(
|
|||
struct dc_state *state,
|
||||
const struct resource_pool *pool,
|
||||
struct dc_stream_state *stream);
|
||||
void dcn20_populate_dml_writeback_from_context(
|
||||
struct dc *dc, struct resource_context *res_ctx, display_e2e_pipe_params_st *pipes);
|
||||
|
||||
struct stream_encoder *dcn20_stream_encoder_create(
|
||||
enum engine_id eng_id,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "include/irq_service_interface.h"
|
||||
#include "dcn20/dcn20_resource.h"
|
||||
|
||||
#include "dml/dcn2x/dcn2x.h"
|
||||
|
||||
#include "clk_mgr.h"
|
||||
#include "dcn10/dcn10_hubp.h"
|
||||
#include "dcn10/dcn10_ipp.h"
|
||||
|
|
|
|||
|
|
@ -2617,6 +2617,26 @@ static bool dcn30_resource_construct(
|
|||
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.mpc.ocsc = 1;
|
||||
|
||||
/* read VBIOS LTTPR caps */
|
||||
{
|
||||
if (ctx->dc_bios->funcs->get_lttpr_caps) {
|
||||
enum bp_result bp_query_result;
|
||||
uint8_t is_vbios_lttpr_enable = 0;
|
||||
|
||||
bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
|
||||
dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
|
||||
}
|
||||
|
||||
if (ctx->dc_bios->funcs->get_lttpr_interop) {
|
||||
enum bp_result bp_query_result;
|
||||
uint8_t is_vbios_interop_enabled = 0;
|
||||
|
||||
bp_query_result = ctx->dc_bios->funcs->get_lttpr_interop(ctx->dc_bios,
|
||||
&is_vbios_interop_enabled);
|
||||
dc->caps.vbios_lttpr_aware = (bp_query_result == BP_RESULT_OK) && !!is_vbios_interop_enabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
|
||||
dc->debug = debug_defaults_drv;
|
||||
else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
|
||||
|
|
|
|||
|
|
@ -146,8 +146,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_03_soc = {
|
|||
|
||||
.min_dcfclk = 500.0, /* TODO: set this to actual min DCFCLK */
|
||||
.num_states = 1,
|
||||
.sr_exit_time_us = 26.5,
|
||||
.sr_enter_plus_exit_time_us = 31,
|
||||
.sr_exit_time_us = 35.5,
|
||||
.sr_enter_plus_exit_time_us = 40,
|
||||
.urgent_latency_us = 4.0,
|
||||
.urgent_latency_pixel_data_only_us = 4.0,
|
||||
.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
|
||||
|
|
|
|||
|
|
@ -1968,6 +1968,22 @@ static bool dcn31_resource_construct(
|
|||
dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
|
||||
dc->caps.color.mpc.ocsc = 1;
|
||||
|
||||
/* read VBIOS LTTPR caps */
|
||||
{
|
||||
if (ctx->dc_bios->funcs->get_lttpr_caps) {
|
||||
enum bp_result bp_query_result;
|
||||
uint8_t is_vbios_lttpr_enable = 0;
|
||||
|
||||
bp_query_result = ctx->dc_bios->funcs->get_lttpr_caps(ctx->dc_bios, &is_vbios_lttpr_enable);
|
||||
dc->caps.vbios_lttpr_enable = (bp_query_result == BP_RESULT_OK) && !!is_vbios_lttpr_enable;
|
||||
}
|
||||
|
||||
/* interop bit is implicit */
|
||||
{
|
||||
dc->caps.vbios_lttpr_aware = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV)
|
||||
dc->debug = debug_defaults_drv;
|
||||
else if (dc->ctx->dce_environment == DCE_ENV_FPGA_MAXIMUS) {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
|
|||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn2x/dcn2x.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_ccflags)
|
||||
|
|
@ -70,6 +72,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_mode_vba_31.o := $(dml_ccflags) $(fram
|
|||
CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/display_rq_dlg_calc_31.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn2x/dcn2x.o := $(dml_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20.o := $(dml_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_rq_dlg_calc_20.o := $(dml_rcflags)
|
||||
CFLAGS_REMOVE_$(AMDDALPATH)/dc/dml/dcn20/display_mode_vba_20v2.o := $(dml_rcflags)
|
||||
|
|
@ -91,6 +94,7 @@ DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
|
|||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o
|
||||
DML += dcn2x/dcn2x.o
|
||||
DML += dcn20/display_rq_dlg_calc_20v2.o dcn20/display_mode_vba_20v2.o
|
||||
DML += dcn21/display_rq_dlg_calc_21.o dcn21/display_mode_vba_21.o
|
||||
DML += dcn30/display_mode_vba_30.o dcn30/display_rq_dlg_calc_30.o
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
|
|||
log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
|
||||
|
||||
// each 64b meta request for dcn is 8x8 meta elements and
|
||||
// a meta element covers one 256b block of the the data surface.
|
||||
// a meta element covers one 256b block of the data surface.
|
||||
log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
|
||||
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
|
||||
- log2_meta_req_height;
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
|
|||
log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
|
||||
|
||||
// each 64b meta request for dcn is 8x8 meta elements and
|
||||
// a meta element covers one 256b block of the the data surface.
|
||||
// a meta element covers one 256b block of the data surface.
|
||||
log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
|
||||
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
|
||||
- log2_meta_req_height;
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ static void get_meta_and_pte_attr(
|
|||
log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
|
||||
|
||||
// each 64b meta request for dcn is 8x8 meta elements and
|
||||
// a meta element covers one 256b block of the the data surface.
|
||||
// a meta element covers one 256b block of the data surface.
|
||||
log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
|
||||
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
|
||||
- log2_meta_req_height;
|
||||
|
|
|
|||
102
drivers/gpu/drm/amd/display/dc/dml/dcn2x/dcn2x.c
Normal file
102
drivers/gpu/drm/amd/display/dc/dml/dcn2x/dcn2x.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#include "dcn2x.h"
|
||||
|
||||
/**
|
||||
* DOC: DCN2x FPU manipulation Overview
|
||||
*
|
||||
* The DCN architecture relies on FPU operations, which require special
|
||||
* compilation flags and the use of kernel_fpu_begin/end functions; ideally, we
|
||||
* want to avoid spreading FPU access across multiple files. With this idea in
|
||||
* mind, this file aims to centralize all DCN20 and DCN2.1 (DCN2x) functions
|
||||
* that require FPU access in a single place. Code in this file follows the
|
||||
* following code pattern:
|
||||
*
|
||||
* 1. Functions that use FPU operations should be isolated in static functions.
|
||||
* 2. The FPU functions should have the noinline attribute to ensure anything
|
||||
* that deals with FP register is contained within this call.
|
||||
* 3. All function that needs to be accessed outside this file requires a
|
||||
* public interface that not uses any FPU reference.
|
||||
* 4. Developers **must not** use DC_FP_START/END in this file, but they need
|
||||
* to ensure that the caller invokes it before access any function available
|
||||
* in this file. For this reason, public functions in this file must invoke
|
||||
* dc_assert_fp_enabled();
|
||||
*
|
||||
* Let's expand a little bit more the idea in the code pattern. To fully
|
||||
* isolate FPU operations in a single place, we must avoid situations where
|
||||
* compilers spill FP values to registers due to FP enable in a specific C
|
||||
* file. Note that even if we isolate all FPU functions in a single file and
|
||||
* call its interface from other files, the compiler might enable the use of
|
||||
* FPU before we call DC_FP_START. Nevertheless, it is the programmer's
|
||||
* responsibility to invoke DC_FP_START/END in the correct place. To highlight
|
||||
* situations where developers forgot to use the FP protection before calling
|
||||
* the DC FPU interface functions, we introduce a helper that checks if the
|
||||
* function is invoked under FP protection. If not, it will trigger a kernel
|
||||
* warning.
|
||||
*/
|
||||
|
||||
void dcn20_populate_dml_writeback_from_context(struct dc *dc,
|
||||
struct resource_context *res_ctx,
|
||||
display_e2e_pipe_params_st *pipes)
|
||||
{
|
||||
int pipe_cnt, i;
|
||||
|
||||
dc_assert_fp_enabled();
|
||||
|
||||
for (i = 0, pipe_cnt = 0; i < dc->res_pool->pipe_count; i++) {
|
||||
struct dc_writeback_info *wb_info = &res_ctx->pipe_ctx[i].stream->writeback_info[0];
|
||||
|
||||
if (!res_ctx->pipe_ctx[i].stream)
|
||||
continue;
|
||||
|
||||
/* Set writeback information */
|
||||
pipes[pipe_cnt].dout.wb_enable = (wb_info->wb_enabled == true) ? 1 : 0;
|
||||
pipes[pipe_cnt].dout.num_active_wb++;
|
||||
pipes[pipe_cnt].dout.wb.wb_src_height = wb_info->dwb_params.cnv_params.crop_height;
|
||||
pipes[pipe_cnt].dout.wb.wb_src_width = wb_info->dwb_params.cnv_params.crop_width;
|
||||
pipes[pipe_cnt].dout.wb.wb_dst_width = wb_info->dwb_params.dest_width;
|
||||
pipes[pipe_cnt].dout.wb.wb_dst_height = wb_info->dwb_params.dest_height;
|
||||
pipes[pipe_cnt].dout.wb.wb_htaps_luma = 1;
|
||||
pipes[pipe_cnt].dout.wb.wb_vtaps_luma = 1;
|
||||
pipes[pipe_cnt].dout.wb.wb_htaps_chroma = wb_info->dwb_params.scaler_taps.h_taps_c;
|
||||
pipes[pipe_cnt].dout.wb.wb_vtaps_chroma = wb_info->dwb_params.scaler_taps.v_taps_c;
|
||||
pipes[pipe_cnt].dout.wb.wb_hratio = 1.0;
|
||||
pipes[pipe_cnt].dout.wb.wb_vratio = 1.0;
|
||||
if (wb_info->dwb_params.out_format == dwb_scaler_mode_yuv420) {
|
||||
if (wb_info->dwb_params.output_depth == DWB_OUTPUT_PIXEL_DEPTH_8BPC)
|
||||
pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_8;
|
||||
else
|
||||
pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_420_10;
|
||||
} else {
|
||||
pipes[pipe_cnt].dout.wb.wb_pixel_format = dm_444_32;
|
||||
}
|
||||
|
||||
pipe_cnt++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright 2014 Advanced Micro Devices, Inc.
|
||||
* Copyright 2021 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
|
|
@ -19,12 +20,15 @@
|
|||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DCE_VIRTUAL_H__
|
||||
#define __DCE_VIRTUAL_H__
|
||||
#ifndef __DCN2X_H__
|
||||
#define __DCN2X_H__
|
||||
|
||||
extern const struct amdgpu_ip_block_version dce_virtual_ip_block;
|
||||
|
||||
#endif
|
||||
void dcn20_populate_dml_writeback_from_context(struct dc *dc,
|
||||
struct resource_context *res_ctx,
|
||||
display_e2e_pipe_params_st *pipes);
|
||||
|
||||
#endif /* __DCN2X_H__ */
|
||||
|
|
@ -549,7 +549,7 @@ static void get_meta_and_pte_attr(struct display_mode_lib *mode_lib,
|
|||
log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
|
||||
|
||||
// each 64b meta request for dcn is 8x8 meta elements and
|
||||
// a meta element covers one 256b block of the the data surface.
|
||||
// a meta element covers one 256b block of the data surface.
|
||||
log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
|
||||
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
|
||||
- log2_meta_req_height;
|
||||
|
|
|
|||
|
|
@ -563,7 +563,7 @@ static void get_meta_and_pte_attr(
|
|||
log2_meta_req_bytes = 6; // meta request is 64b and is 8x8byte meta element
|
||||
|
||||
// each 64b meta request for dcn is 8x8 meta elements and
|
||||
// a meta element covers one 256b block of the the data surface.
|
||||
// a meta element covers one 256b block of the data surface.
|
||||
log2_meta_req_height = log2_blk256_height + 3; // meta req is 8x8 byte, each byte represent 1 blk256
|
||||
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element - log2_meta_req_height;
|
||||
meta_req_width = 1 << log2_meta_req_width;
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ static void dml1_rq_dlg_get_row_heights(
|
|||
log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
|
||||
|
||||
/* each 64b meta request for dcn is 8x8 meta elements and
|
||||
* a meta element covers one 256b block of the the data surface.
|
||||
* a meta element covers one 256b block of the data surface.
|
||||
*/
|
||||
log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 */
|
||||
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
|
||||
|
|
@ -718,7 +718,7 @@ static void get_surf_rq_param(
|
|||
log2_meta_req_bytes = 6; /* meta request is 64b and is 8x8byte meta element */
|
||||
|
||||
/* each 64b meta request for dcn is 8x8 meta elements and
|
||||
* a meta element covers one 256b block of the the data surface.
|
||||
* a meta element covers one 256b block of the data surface.
|
||||
*/
|
||||
log2_meta_req_height = log2_blk256_height + 3; /* meta req is 8x8 byte, each byte represent 1 blk256 */
|
||||
log2_meta_req_width = log2_meta_req_bytes + 8 - log2_bytes_per_element
|
||||
|
|
|
|||
|
|
@ -51,38 +51,9 @@
|
|||
#define dm_error(fmt, ...) DRM_ERROR(fmt, ##__VA_ARGS__)
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
#if defined(CONFIG_X86)
|
||||
#include <asm/fpu/api.h>
|
||||
#define DC_FP_START() kernel_fpu_begin()
|
||||
#define DC_FP_END() kernel_fpu_end()
|
||||
#elif defined(CONFIG_PPC64)
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/cputable.h>
|
||||
#define DC_FP_START() { \
|
||||
if (cpu_has_feature(CPU_FTR_VSX_COMP)) { \
|
||||
preempt_disable(); \
|
||||
enable_kernel_vsx(); \
|
||||
} else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) { \
|
||||
preempt_disable(); \
|
||||
enable_kernel_altivec(); \
|
||||
} else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) { \
|
||||
preempt_disable(); \
|
||||
enable_kernel_fp(); \
|
||||
} \
|
||||
}
|
||||
#define DC_FP_END() { \
|
||||
if (cpu_has_feature(CPU_FTR_VSX_COMP)) { \
|
||||
disable_kernel_vsx(); \
|
||||
preempt_enable(); \
|
||||
} else if (cpu_has_feature(CPU_FTR_ALTIVEC_COMP)) { \
|
||||
disable_kernel_altivec(); \
|
||||
preempt_enable(); \
|
||||
} else if (!cpu_has_feature(CPU_FTR_FPU_UNAVAILABLE)) { \
|
||||
disable_kernel_fp(); \
|
||||
preempt_enable(); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
#include "amdgpu_dm/dc_fpu.h"
|
||||
#define DC_FP_START() dc_fpu_begin(__func__, __LINE__)
|
||||
#define DC_FP_END() dc_fpu_end(__func__, __LINE__)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@
|
|||
|
||||
/* Firmware versioning. */
|
||||
#ifdef DMUB_EXPOSE_VERSION
|
||||
#define DMUB_FW_VERSION_GIT_HASH 0xe599e0896
|
||||
#define DMUB_FW_VERSION_GIT_HASH 0x6d13d5e2c
|
||||
#define DMUB_FW_VERSION_MAJOR 0
|
||||
#define DMUB_FW_VERSION_MINOR 0
|
||||
#define DMUB_FW_VERSION_REVISION 76
|
||||
#define DMUB_FW_VERSION_REVISION 77
|
||||
#define DMUB_FW_VERSION_TEST 0
|
||||
#define DMUB_FW_VERSION_VBIOS 0
|
||||
#define DMUB_FW_VERSION_HOTFIX 0
|
||||
|
|
|
|||
|
|
@ -270,11 +270,13 @@ void dmub_dcn31_set_outbox1_rptr(struct dmub_srv *dmub, uint32_t rptr_offset)
|
|||
|
||||
bool dmub_dcn31_is_hw_init(struct dmub_srv *dmub)
|
||||
{
|
||||
uint32_t is_hw_init;
|
||||
union dmub_fw_boot_status status;
|
||||
uint32_t is_enable;
|
||||
|
||||
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_hw_init);
|
||||
status.all = REG_READ(DMCUB_SCRATCH0);
|
||||
REG_GET(DMCUB_CNTL, DMCUB_ENABLE, &is_enable);
|
||||
|
||||
return is_hw_init != 0;
|
||||
return is_enable != 0 && status.bits.dal_fw;
|
||||
}
|
||||
|
||||
bool dmub_dcn31_is_supported(struct dmub_srv *dmub)
|
||||
|
|
|
|||
|
|
@ -508,6 +508,10 @@
|
|||
#define regCP_ME2_PIPE2_INT_STATUS_BASE_IDX 0
|
||||
#define regCP_ME2_PIPE3_INT_STATUS 0x1094
|
||||
#define regCP_ME2_PIPE3_INT_STATUS_BASE_IDX 0
|
||||
#define regCP_ME1_INT_STAT_DEBUG 0x1095
|
||||
#define regCP_ME1_INT_STAT_DEBUG_BASE_IDX 0
|
||||
#define regCP_ME2_INT_STAT_DEBUG 0x1096
|
||||
#define regCP_ME2_INT_STAT_DEBUG_BASE_IDX 0
|
||||
#define regCC_GC_EDC_CONFIG 0x1098
|
||||
#define regCC_GC_EDC_CONFIG_BASE_IDX 0
|
||||
#define regCP_ME1_PIPE_PRIORITY_CNTS 0x1099
|
||||
|
|
|
|||
|
|
@ -2989,6 +2989,60 @@
|
|||
#define CP_ME1_PIPE3_INT_STATUS__GENERIC2_INT_STATUS_MASK 0x20000000L
|
||||
#define CP_ME1_PIPE3_INT_STATUS__GENERIC1_INT_STATUS_MASK 0x40000000L
|
||||
#define CP_ME1_PIPE3_INT_STATUS__GENERIC0_INT_STATUS_MASK 0x80000000L
|
||||
//CP_ME1_INT_STAT_DEBUG
|
||||
#define CP_ME1_INT_STAT_DEBUG__CMP_QUERY_STATUS_INT_ASSERTED__SHIFT 0xc
|
||||
#define CP_ME1_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED__SHIFT 0xd
|
||||
#define CP_ME1_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED__SHIFT 0xe
|
||||
#define CP_ME1_INT_STAT_DEBUG__SUA_VIOLATION_INT_STATUS__SHIFT 0xf
|
||||
#define CP_ME1_INT_STAT_DEBUG__GPF_INT_ASSERTED__SHIFT 0x10
|
||||
#define CP_ME1_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED__SHIFT 0x11
|
||||
#define CP_ME1_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED__SHIFT 0x17
|
||||
#define CP_ME1_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED__SHIFT 0x18
|
||||
#define CP_ME1_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED__SHIFT 0x1a
|
||||
#define CP_ME1_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED__SHIFT 0x1b
|
||||
#define CP_ME1_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED__SHIFT 0x1d
|
||||
#define CP_ME1_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED__SHIFT 0x1e
|
||||
#define CP_ME1_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED__SHIFT 0x1f
|
||||
#define CP_ME1_INT_STAT_DEBUG__CMP_QUERY_STATUS_INT_ASSERTED_MASK 0x00001000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED_MASK 0x00002000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED_MASK 0x00004000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__SUA_VIOLATION_INT_STATUS_MASK 0x00008000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__GPF_INT_ASSERTED_MASK 0x00010000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED_MASK 0x00020000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED_MASK 0x00800000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED_MASK 0x01000000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED_MASK 0x04000000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED_MASK 0x08000000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED_MASK 0x20000000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED_MASK 0x40000000L
|
||||
#define CP_ME1_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED_MASK 0x80000000L
|
||||
//CP_ME2_INT_STAT_DEBUG
|
||||
#define CP_ME2_INT_STAT_DEBUG__CMP_QUERY_STATUS_INT_ASSERTED__SHIFT 0xc
|
||||
#define CP_ME2_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED__SHIFT 0xd
|
||||
#define CP_ME2_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED__SHIFT 0xe
|
||||
#define CP_ME2_INT_STAT_DEBUG__SUA_VIOLATION_INT_STATUS__SHIFT 0xf
|
||||
#define CP_ME2_INT_STAT_DEBUG__GPF_INT_ASSERTED__SHIFT 0x10
|
||||
#define CP_ME2_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED__SHIFT 0x11
|
||||
#define CP_ME2_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED__SHIFT 0x17
|
||||
#define CP_ME2_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED__SHIFT 0x18
|
||||
#define CP_ME2_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED__SHIFT 0x1a
|
||||
#define CP_ME2_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED__SHIFT 0x1b
|
||||
#define CP_ME2_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED__SHIFT 0x1d
|
||||
#define CP_ME2_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED__SHIFT 0x1e
|
||||
#define CP_ME2_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED__SHIFT 0x1f
|
||||
#define CP_ME2_INT_STAT_DEBUG__CMP_QUERY_STATUS_INT_ASSERTED_MASK 0x00001000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__DEQUEUE_REQUEST_INT_ASSERTED_MASK 0x00002000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__CP_ECC_ERROR_INT_ASSERTED_MASK 0x00004000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__SUA_VIOLATION_INT_STATUS_MASK 0x00008000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__GPF_INT_ASSERTED_MASK 0x00010000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__WRM_POLL_TIMEOUT_INT_ASSERTED_MASK 0x00020000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__PRIV_REG_INT_ASSERTED_MASK 0x00800000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__OPCODE_ERROR_INT_ASSERTED_MASK 0x01000000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__TIME_STAMP_INT_ASSERTED_MASK 0x04000000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__RESERVED_BIT_ERROR_INT_ASSERTED_MASK 0x08000000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__GENERIC2_INT_ASSERTED_MASK 0x20000000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__GENERIC1_INT_ASSERTED_MASK 0x40000000L
|
||||
#define CP_ME2_INT_STAT_DEBUG__GENERIC0_INT_ASSERTED_MASK 0x80000000L
|
||||
//CP_ME2_PIPE0_INT_STATUS
|
||||
#define CP_ME2_PIPE0_INT_STATUS__CMP_QUERY_STATUS_INT_STATUS__SHIFT 0xc
|
||||
#define CP_ME2_PIPE0_INT_STATUS__DEQUEUE_REQUEST_INT_STATUS__SHIFT 0xd
|
||||
|
|
|
|||
|
|
@ -590,7 +590,7 @@ struct atom_firmware_info_v3_4 {
|
|||
uint8_t board_i2c_feature_id; // enum of atom_board_i2c_feature_id_def
|
||||
uint8_t board_i2c_feature_gpio_id; // i2c id find in gpio_lut data table gpio_id
|
||||
uint8_t board_i2c_feature_slave_addr;
|
||||
uint8_t reserved3;
|
||||
uint8_t ras_rom_i2c_slave_addr;
|
||||
uint16_t bootup_mvddq_mv;
|
||||
uint16_t bootup_mvpp_mv;
|
||||
uint32_t zfbstartaddrin16mb;
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ enum smu_clk_type {
|
|||
__SMU_DUMMY_MAP(TDC), \
|
||||
__SMU_DUMMY_MAP(THERMAL), \
|
||||
__SMU_DUMMY_MAP(GFX_PER_CU_CG), \
|
||||
__SMU_DUMMY_MAP(DATA_CALCULATIONS), \
|
||||
__SMU_DUMMY_MAP(RM), \
|
||||
__SMU_DUMMY_MAP(DS_DCEFCLK), \
|
||||
__SMU_DUMMY_MAP(ACDC), \
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "amdgpu_smu.h"
|
||||
|
||||
#define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
|
||||
#define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x03
|
||||
#define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
|
||||
#define SMU13_DRIVER_IF_VERSION_ALDE 0x07
|
||||
|
||||
/* MP Apertures */
|
||||
|
|
|
|||
|
|
@ -111,7 +111,9 @@ typedef struct {
|
|||
uint32_t InWhisperMode : 1;
|
||||
uint32_t spare0 : 1;
|
||||
uint32_t ZstateStatus : 4;
|
||||
uint32_t spare1 :12;
|
||||
uint32_t spare1 : 4;
|
||||
uint32_t DstateFun : 4;
|
||||
uint32_t DstateDev : 4;
|
||||
// MP1_EXT_SCRATCH2
|
||||
uint32_t P2JobHandler :24;
|
||||
uint32_t RsmuPmiP2FinishedCnt : 8;
|
||||
|
|
|
|||
|
|
@ -1580,7 +1580,7 @@ static int smu10_set_fine_grain_clk_vol(struct pp_hwmgr *hwmgr,
|
|||
}
|
||||
|
||||
if (smu10_data->gfx_actual_soft_min_freq > smu10_data->gfx_actual_soft_max_freq) {
|
||||
pr_err("The setting minimun sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
|
||||
pr_err("The setting minimum sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
|
||||
smu10_data->gfx_actual_soft_min_freq, smu10_data->gfx_actual_soft_max_freq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -353,8 +353,7 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu)
|
|||
struct amdgpu_device *adev = smu->adev;
|
||||
uint32_t val;
|
||||
|
||||
if (powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_BACO ||
|
||||
powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_MACO) {
|
||||
if (powerplay_table->platform_caps & SMU_11_0_7_PP_PLATFORM_CAP_BACO) {
|
||||
val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
|
||||
smu_baco->platform_support =
|
||||
(val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true :
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ static int vangogh_tables_init(struct smu_context *smu)
|
|||
return 0;
|
||||
|
||||
err3_out:
|
||||
kfree(smu_table->clocks_table);
|
||||
kfree(smu_table->watermarks_table);
|
||||
err2_out:
|
||||
kfree(smu_table->gpu_metrics_table);
|
||||
err1_out:
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ static const struct cmn2asic_mapping aldebaran_clk_map[SMU_CLK_COUNT] = {
|
|||
};
|
||||
|
||||
static const struct cmn2asic_mapping aldebaran_feature_mask_map[SMU_FEATURE_COUNT] = {
|
||||
ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_PREFETCHER_BIT, FEATURE_DATA_CALCULATIONS),
|
||||
ALDEBARAN_FEA_MAP(SMU_FEATURE_DATA_CALCULATIONS_BIT, FEATURE_DATA_CALCULATIONS),
|
||||
ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_GFXCLK_BIT, FEATURE_DPM_GFXCLK_BIT),
|
||||
ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_UCLK_BIT, FEATURE_DPM_UCLK_BIT),
|
||||
ALDEBARAN_FEA_MAP(SMU_FEATURE_DPM_SOCCLK_BIT, FEATURE_DPM_SOCCLK_BIT),
|
||||
|
|
|
|||
|
|
@ -2802,8 +2802,8 @@ ucMaxNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of t
|
|||
ucMinNBVoltageHigh: Voltage regulator dependent PWM value. High 8 bits of the value for the min voltage.Set this one to 0x00 if VC without PWM or no VC at all.
|
||||
|
||||
|
||||
usInterNBVoltageLow: Voltage regulator dependent PWM value. The value makes the the voltage >=Min NB voltage but <=InterNBVoltageHigh. Set this to 0x0000 if VC without PWM or no VC at all.
|
||||
usInterNBVoltageHigh: Voltage regulator dependent PWM value. The value makes the the voltage >=InterNBVoltageLow but <=Max NB voltage.Set this to 0x0000 if VC without PWM or no VC at all.
|
||||
usInterNBVoltageLow: Voltage regulator dependent PWM value. The value makes the voltage >=Min NB voltage but <=InterNBVoltageHigh. Set this to 0x0000 if VC without PWM or no VC at all.
|
||||
usInterNBVoltageHigh: Voltage regulator dependent PWM value. The value makes the voltage >=InterNBVoltageLow but <=Max NB voltage.Set this to 0x0000 if VC without PWM or no VC at all.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "avivod.h"
|
||||
|
|
@ -1414,10 +1415,15 @@ void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base,
|
|||
bool async)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
|
||||
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
|
||||
|
||||
/* update the scanout addresses */
|
||||
/* flip at hsync for async, default is vsync */
|
||||
WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
|
||||
async ? EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
|
||||
/* update pitch */
|
||||
WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset,
|
||||
fb->pitches[0] / fb->format->cpp[0]);
|
||||
/* update the scanout addresses */
|
||||
WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
|
||||
upper_32_bits(crtc_base));
|
||||
WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
|
||||
|
|
|
|||
|
|
@ -162,6 +162,8 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
|
|||
void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
|
||||
uint32_t crtc_pitch, pitch_pixels;
|
||||
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
|
||||
u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
|
||||
int i;
|
||||
|
||||
|
|
@ -169,6 +171,13 @@ void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool
|
|||
/* update the scanout addresses */
|
||||
WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
|
||||
|
||||
/* update pitch */
|
||||
pitch_pixels = fb->pitches[0] / fb->format->cpp[0];
|
||||
crtc_pitch = DIV_ROUND_UP(pitch_pixels * fb->format->cpp[0] * 8,
|
||||
fb->format->cpp[0] * 8 * 8);
|
||||
crtc_pitch |= crtc_pitch << 16;
|
||||
WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
|
||||
|
||||
/* Wait for update_pending to go high. */
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@
|
|||
# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
|
||||
# define R300_PVS_CNTL_1_POS_END_SHIFT 10
|
||||
# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20
|
||||
/* Addresses are relative the the vertex program parameters area. */
|
||||
/* Addresses are relative the vertex program parameters area. */
|
||||
#define R300_VAP_PVS_CNTL_2 0x22D4
|
||||
# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0
|
||||
# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell)
|
|||
|
||||
/*
|
||||
* radeon_wb_*()
|
||||
* Writeback is the the method by which the the GPU updates special pages
|
||||
* Writeback is the method by which the GPU updates special pages
|
||||
* in memory with the status of certain GPU events (fences, ring pointers,
|
||||
* etc.).
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ radeonfb_open(struct fb_info *info, int user)
|
|||
struct radeon_fbdev *rfbdev = info->par;
|
||||
struct radeon_device *rdev = rfbdev->rdev;
|
||||
int ret = pm_runtime_get_sync(rdev->ddev->dev);
|
||||
|
||||
if (ret < 0 && ret != -EACCES) {
|
||||
pm_runtime_mark_last_busy(rdev->ddev->dev);
|
||||
pm_runtime_put_autosuspend(rdev->ddev->dev);
|
||||
|
|
@ -196,9 +197,8 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
|
|||
radeon_bo_check_tiling(rbo, 0, 0);
|
||||
ret = radeon_bo_kmap(rbo, NULL);
|
||||
radeon_bo_unreserve(rbo);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
goto out_unref;
|
||||
}
|
||||
|
||||
*gobj_p = gobj;
|
||||
return 0;
|
||||
|
|
@ -294,9 +294,6 @@ static int radeonfb_create(struct drm_fb_helper *helper,
|
|||
return 0;
|
||||
|
||||
out:
|
||||
if (rbo) {
|
||||
|
||||
}
|
||||
if (fb && ret) {
|
||||
drm_gem_object_put(gobj);
|
||||
drm_framebuffer_unregister_private(fb);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
* for GPU/CPU synchronization. When the fence is written,
|
||||
* it is expected that all buffers associated with that fence
|
||||
* are no longer in use by the associated ring on the GPU and
|
||||
* that the the relevant GPU caches have been flushed. Whether
|
||||
* that the relevant GPU caches have been flushed. Whether
|
||||
* we use a scratch register or memory location depends on the asic
|
||||
* and whether writeback is enabled.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
* (uncached system pages).
|
||||
* Each VM has an ID associated with it and there is a page table
|
||||
* associated with each VMID. When execting a command buffer,
|
||||
* the kernel tells the the ring what VMID to use for that command
|
||||
* the kernel tells the ring what VMID to use for that command
|
||||
* buffer. VMIDs are allocated dynamically as commands are submitted.
|
||||
* The userspace drivers maintain their own address space and the kernel
|
||||
* sets up their pages tables accordingly when they submit their
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "radeon.h"
|
||||
|
|
@ -118,6 +119,7 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
|
|||
void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
|
||||
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
|
||||
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
|
||||
int i;
|
||||
|
||||
|
|
@ -125,9 +127,13 @@ void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, boo
|
|||
tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
|
||||
WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
|
||||
|
||||
/* update the scanout addresses */
|
||||
/* flip at hsync for async, default is vsync */
|
||||
WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
|
||||
async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
|
||||
/* update pitch */
|
||||
WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset,
|
||||
fb->pitches[0] / fb->format->cpp[0]);
|
||||
/* update the scanout addresses */
|
||||
WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
|
||||
(u32)crtc_base);
|
||||
WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/radeon_drm.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "atom.h"
|
||||
#include "avivod.h"
|
||||
|
|
@ -809,6 +810,7 @@ u32 rv770_get_xclk(struct radeon_device *rdev)
|
|||
void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
|
||||
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
|
||||
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
|
||||
int i;
|
||||
|
||||
|
|
@ -816,9 +818,13 @@ void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, boo
|
|||
tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
|
||||
WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
|
||||
|
||||
/* update the scanout addresses */
|
||||
/* flip at hsync for async, default is vsync */
|
||||
WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
|
||||
async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
|
||||
/* update pitch */
|
||||
WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset,
|
||||
fb->pitches[0] / fb->format->cpp[0]);
|
||||
/* update the scanout addresses */
|
||||
if (radeon_crtc->crtc_id) {
|
||||
WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
|
||||
WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
|
||||
|
|
|
|||
|
|
@ -31,9 +31,10 @@
|
|||
* - 1.3 - Add SMI events support
|
||||
* - 1.4 - Indicate new SRAM EDC bit in device properties
|
||||
* - 1.5 - Add SVM API
|
||||
* - 1.6 - Query clear flags in SVM get_attr API
|
||||
*/
|
||||
#define KFD_IOCTL_MAJOR_VERSION 1
|
||||
#define KFD_IOCTL_MINOR_VERSION 5
|
||||
#define KFD_IOCTL_MINOR_VERSION 6
|
||||
|
||||
struct kfd_ioctl_get_version_args {
|
||||
__u32 major_version; /* from KFD */
|
||||
|
|
@ -575,18 +576,19 @@ struct kfd_ioctl_svm_attribute {
|
|||
* @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC or
|
||||
* @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC resepctively. For
|
||||
* @KFD_IOCTL_SVM_ATTR_SET_FLAGS, flags of all pages will be
|
||||
* aggregated by bitwise AND. The minimum migration granularity
|
||||
* throughout the range will be returned for
|
||||
* @KFD_IOCTL_SVM_ATTR_GRANULARITY.
|
||||
* aggregated by bitwise AND. That means, a flag will be set in the
|
||||
* output, if that flag is set for all pages in the range. For
|
||||
* @KFD_IOCTL_SVM_ATTR_CLR_FLAGS, flags of all pages will be
|
||||
* aggregated by bitwise NOR. That means, a flag will be set in the
|
||||
* output, if that flag is clear for all pages in the range.
|
||||
* The minimum migration granularity throughout the range will be
|
||||
* returned for @KFD_IOCTL_SVM_ATTR_GRANULARITY.
|
||||
*
|
||||
* Querying of accessibility attributes works by initializing the
|
||||
* attribute type to @KFD_IOCTL_SVM_ATTR_ACCESS and the value to the
|
||||
* GPUID being queried. Multiple attributes can be given to allow
|
||||
* querying multiple GPUIDs. The ioctl function overwrites the
|
||||
* attribute type to indicate the access for the specified GPU.
|
||||
*
|
||||
* @KFD_IOCTL_SVM_ATTR_CLR_FLAGS is invalid for
|
||||
* @KFD_IOCTL_SVM_OP_GET_ATTR.
|
||||
*/
|
||||
struct kfd_ioctl_svm_args {
|
||||
__u64 start_addr;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user