Merge branch 'drm-next-4.11' of git://people.freedesktop.org/~agd5f/linux into drm-next
Some additional fixes for 4.11. Delayed a bit due to Chinese New Year. Highlights: - Powerplay fixes - VCE and UVD powergating fixes - Clean up amdgpu SI gfx code to match CI and VI - Misc bug fixes * 'drm-next-4.11' of git://people.freedesktop.org/~agd5f/linux: (30 commits) drm/amdgpu: report the number of bytes moved at buffer creation drm/amdgpu: fix a potential deadlock in amdgpu_bo_create_restricted() drm/amdgpu: add support for new smc firmware on polaris drm/amd/powerplay: refine code to avoid potential bug that the memory not cleared. drm/amdgpu: shut up #warning for compile testing drm/amdgpu/virt: fix double kfree on bo_va drm/radeon: remove some dead code drm/radeon: avoid kernel segfault in vce when gpu fails to resume drm/amd/powerplay: set fan speed to max in profile peak mode only. drm/amd/gfx6: update gb_addr_config drm/amdgpu: update HAINAN_GB_ADDR_CONFIG_GOLDEN drm/amdgpu: update VERDE_GB_ADDR_CONFIG_GOLDEN drm/amdgpu: refine si_read_register drm/amdgpu/gfx6: clean up spi configuration drm/amdgpu/gfx6: clean up cu configuration drm/amdgpu/gfx6: clean up rb configuration drm/amdgpu: refine vce3.0 code and related powerplay pg code. drm/amdgpu: move subfunctions to the front of vce_v2_0.c. drm/amdgpu: enable vce pg feature on Kv. drm/amdgpu: refine code for VCE2.0 and related dpm code. ...
This commit is contained in:
commit
13f62f54d1
|
@ -1709,6 +1709,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data);
|
|||
int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,
|
||||
u32 ip_instance, u32 ring,
|
||||
struct amdgpu_ring **out_ring);
|
||||
void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes);
|
||||
void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *abo, u32 domain);
|
||||
bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo);
|
||||
int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages);
|
||||
|
|
|
@ -850,16 +850,37 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
|||
strcpy(fw_name, "amdgpu/fiji_smc.bin");
|
||||
break;
|
||||
case CHIP_POLARIS11:
|
||||
if (type == CGS_UCODE_ID_SMU)
|
||||
strcpy(fw_name, "amdgpu/polaris11_smc.bin");
|
||||
else if (type == CGS_UCODE_ID_SMU_SK)
|
||||
if (type == CGS_UCODE_ID_SMU) {
|
||||
if (((adev->pdev->device == 0x67ef) &&
|
||||
((adev->pdev->revision == 0xe0) ||
|
||||
(adev->pdev->revision == 0xe2) ||
|
||||
(adev->pdev->revision == 0xe5))) ||
|
||||
((adev->pdev->device == 0x67ff) &&
|
||||
((adev->pdev->revision == 0xcf) ||
|
||||
(adev->pdev->revision == 0xef) ||
|
||||
(adev->pdev->revision == 0xff))))
|
||||
strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
|
||||
else
|
||||
strcpy(fw_name, "amdgpu/polaris11_smc.bin");
|
||||
} else if (type == CGS_UCODE_ID_SMU_SK) {
|
||||
strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_POLARIS10:
|
||||
if (type == CGS_UCODE_ID_SMU)
|
||||
strcpy(fw_name, "amdgpu/polaris10_smc.bin");
|
||||
else if (type == CGS_UCODE_ID_SMU_SK)
|
||||
if (type == CGS_UCODE_ID_SMU) {
|
||||
if ((adev->pdev->device == 0x67df) &&
|
||||
((adev->pdev->revision == 0xe0) ||
|
||||
(adev->pdev->revision == 0xe3) ||
|
||||
(adev->pdev->revision == 0xe4) ||
|
||||
(adev->pdev->revision == 0xe5) ||
|
||||
(adev->pdev->revision == 0xe7) ||
|
||||
(adev->pdev->revision == 0xef)))
|
||||
strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
|
||||
else
|
||||
strcpy(fw_name, "amdgpu/polaris10_smc.bin");
|
||||
} else if (type == CGS_UCODE_ID_SMU_SK) {
|
||||
strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
|
||||
}
|
||||
break;
|
||||
case CHIP_POLARIS12:
|
||||
strcpy(fw_name, "amdgpu/polaris12_smc.bin");
|
||||
|
|
|
@ -344,8 +344,7 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev)
|
|||
* submission. This can result in a debt that can stop buffer migrations
|
||||
* temporarily.
|
||||
*/
|
||||
static void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev,
|
||||
u64 num_bytes)
|
||||
void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes)
|
||||
{
|
||||
spin_lock(&adev->mm_stats.lock);
|
||||
adev->mm_stats.accum_us -= bytes_to_us(adev, num_bytes);
|
||||
|
|
|
@ -487,67 +487,50 @@ static int amdgpu_gem_va_check(void *param, struct amdgpu_bo *bo)
|
|||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @bo_va: bo_va to update
|
||||
* @list: validation list
|
||||
* @operation: map or unmap
|
||||
*
|
||||
* Update the bo_va directly after setting it's address. Errors are not
|
||||
* Update the bo_va directly after setting its address. Errors are not
|
||||
* vital here, so they are not reported back to userspace.
|
||||
*/
|
||||
static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va,
|
||||
struct list_head *list,
|
||||
uint32_t operation)
|
||||
{
|
||||
struct ttm_validate_buffer tv, *entry;
|
||||
struct amdgpu_bo_list_entry vm_pd;
|
||||
struct ww_acquire_ctx ticket;
|
||||
struct list_head list, duplicates;
|
||||
int r;
|
||||
struct ttm_validate_buffer *entry;
|
||||
int r = -ERESTARTSYS;
|
||||
|
||||
INIT_LIST_HEAD(&list);
|
||||
INIT_LIST_HEAD(&duplicates);
|
||||
|
||||
tv.bo = &bo_va->bo->tbo;
|
||||
tv.shared = true;
|
||||
list_add(&tv.head, &list);
|
||||
|
||||
amdgpu_vm_get_pd_bo(bo_va->vm, &list, &vm_pd);
|
||||
|
||||
/* Provide duplicates to avoid -EALREADY */
|
||||
r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
|
||||
if (r)
|
||||
goto error_print;
|
||||
|
||||
list_for_each_entry(entry, &list, head) {
|
||||
list_for_each_entry(entry, list, head) {
|
||||
struct amdgpu_bo *bo =
|
||||
container_of(entry->bo, struct amdgpu_bo, tbo);
|
||||
|
||||
/* if anything is swapped out don't swap it in here,
|
||||
just abort and wait for the next CS */
|
||||
if (!amdgpu_bo_gpu_accessible(bo))
|
||||
goto error_unreserve;
|
||||
goto error;
|
||||
|
||||
if (bo->shadow && !amdgpu_bo_gpu_accessible(bo->shadow))
|
||||
goto error_unreserve;
|
||||
goto error;
|
||||
}
|
||||
|
||||
r = amdgpu_vm_validate_pt_bos(adev, bo_va->vm, amdgpu_gem_va_check,
|
||||
NULL);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
goto error;
|
||||
|
||||
r = amdgpu_vm_update_page_directory(adev, bo_va->vm);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
goto error;
|
||||
|
||||
r = amdgpu_vm_clear_freed(adev, bo_va->vm);
|
||||
if (r)
|
||||
goto error_unreserve;
|
||||
goto error;
|
||||
|
||||
if (operation == AMDGPU_VA_OP_MAP)
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
|
||||
error_unreserve:
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
|
||||
error_print:
|
||||
error:
|
||||
if (r && r != -ERESTARTSYS)
|
||||
DRM_ERROR("Couldn't update BO_VA (%d)\n", r);
|
||||
}
|
||||
|
@ -564,7 +547,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
|||
struct amdgpu_bo_list_entry vm_pd;
|
||||
struct ttm_validate_buffer tv;
|
||||
struct ww_acquire_ctx ticket;
|
||||
struct list_head list, duplicates;
|
||||
struct list_head list;
|
||||
uint32_t invalid_flags, va_flags = 0;
|
||||
int r = 0;
|
||||
|
||||
|
@ -602,14 +585,13 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
|||
return -ENOENT;
|
||||
abo = gem_to_amdgpu_bo(gobj);
|
||||
INIT_LIST_HEAD(&list);
|
||||
INIT_LIST_HEAD(&duplicates);
|
||||
tv.bo = &abo->tbo;
|
||||
tv.shared = true;
|
||||
tv.shared = false;
|
||||
list_add(&tv.head, &list);
|
||||
|
||||
amdgpu_vm_get_pd_bo(&fpriv->vm, &list, &vm_pd);
|
||||
|
||||
r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
|
||||
r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL);
|
||||
if (r) {
|
||||
drm_gem_object_unreference_unlocked(gobj);
|
||||
return r;
|
||||
|
@ -640,10 +622,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE) &&
|
||||
!amdgpu_vm_debug)
|
||||
amdgpu_gem_va_update_vm(adev, bo_va, args->operation);
|
||||
amdgpu_gem_va_update_vm(adev, bo_va, &list, args->operation);
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
|
||||
drm_gem_object_unreference_unlocked(gobj);
|
||||
return r;
|
||||
|
|
|
@ -323,6 +323,7 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
|
|||
struct amdgpu_bo *bo;
|
||||
enum ttm_bo_type type;
|
||||
unsigned long page_align;
|
||||
u64 initial_bytes_moved;
|
||||
size_t acc_size;
|
||||
int r;
|
||||
|
||||
|
@ -374,8 +375,10 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
|
|||
* See https://bugs.freedesktop.org/show_bug.cgi?id=88758
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_COMPILE_TEST
|
||||
#warning Please enable CONFIG_MTRR and CONFIG_X86_PAT for better performance \
|
||||
thanks to write-combining
|
||||
#endif
|
||||
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_CPU_GTT_USWC)
|
||||
DRM_INFO_ONCE("Please enable CONFIG_MTRR and CONFIG_X86_PAT for "
|
||||
|
@ -399,12 +402,20 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
|
|||
locked = ww_mutex_trylock(&bo->tbo.ttm_resv.lock);
|
||||
WARN_ON(!locked);
|
||||
}
|
||||
|
||||
initial_bytes_moved = atomic64_read(&adev->num_bytes_moved);
|
||||
r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type,
|
||||
&bo->placement, page_align, !kernel, NULL,
|
||||
acc_size, sg, resv ? resv : &bo->tbo.ttm_resv,
|
||||
&amdgpu_ttm_bo_destroy);
|
||||
if (unlikely(r != 0))
|
||||
amdgpu_cs_report_moved_bytes(adev,
|
||||
atomic64_read(&adev->num_bytes_moved) - initial_bytes_moved);
|
||||
|
||||
if (unlikely(r != 0)) {
|
||||
if (!resv)
|
||||
ww_mutex_unlock(&bo->tbo.resv->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
bo->tbo.priority = ilog2(bo->tbo.num_pages);
|
||||
if (kernel)
|
||||
|
|
|
@ -1142,12 +1142,22 @@ void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
|
|||
/* XXX select vce level based on ring/task */
|
||||
adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
} else {
|
||||
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_GATE);
|
||||
amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
adev->pm.dpm.vce_active = false;
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
}
|
||||
amdgpu_pm_compute_clocks(adev);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1113,6 +1113,11 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work)
|
|||
amdgpu_dpm_enable_uvd(adev, false);
|
||||
} else {
|
||||
amdgpu_asic_set_uvd_clocks(adev, 0, 0);
|
||||
/* shutdown the UVD block */
|
||||
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_GATE);
|
||||
amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_GATE);
|
||||
}
|
||||
} else {
|
||||
schedule_delayed_work(&adev->uvd.idle_work, UVD_IDLE_TIMEOUT);
|
||||
|
@ -1129,6 +1134,10 @@ void amdgpu_uvd_ring_begin_use(struct amdgpu_ring *ring)
|
|||
amdgpu_dpm_enable_uvd(adev, true);
|
||||
} else {
|
||||
amdgpu_asic_set_uvd_clocks(adev, 53300, 40000);
|
||||
amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -321,6 +321,10 @@ static void amdgpu_vce_idle_work_handler(struct work_struct *work)
|
|||
amdgpu_dpm_enable_vce(adev, false);
|
||||
} else {
|
||||
amdgpu_asic_set_vce_clocks(adev, 0, 0);
|
||||
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_GATE);
|
||||
amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
}
|
||||
} else {
|
||||
schedule_delayed_work(&adev->vce.idle_work, VCE_IDLE_TIMEOUT);
|
||||
|
@ -346,6 +350,11 @@ void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring)
|
|||
amdgpu_dpm_enable_vce(adev, true);
|
||||
} else {
|
||||
amdgpu_asic_set_vce_clocks(adev, 53300, 40000);
|
||||
amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
|
||||
}
|
||||
}
|
||||
mutex_unlock(&adev->vce.idle_mutex);
|
||||
|
|
|
@ -83,7 +83,6 @@ int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
DRM_ERROR("failed to do bo_map on static CSA, err=%d\n", r);
|
||||
amdgpu_vm_bo_rmv(adev, bo_va);
|
||||
ttm_eu_backoff_reservation(&ticket, &list);
|
||||
kfree(bo_va);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -2210,7 +2210,6 @@ static void ci_clear_vc(struct amdgpu_device *adev)
|
|||
|
||||
static int ci_upload_firmware(struct amdgpu_device *adev)
|
||||
{
|
||||
struct ci_power_info *pi = ci_get_pi(adev);
|
||||
int i, ret;
|
||||
|
||||
if (amdgpu_ci_is_smc_running(adev)) {
|
||||
|
@ -2227,7 +2226,7 @@ static int ci_upload_firmware(struct amdgpu_device *adev)
|
|||
amdgpu_ci_stop_smc_clock(adev);
|
||||
amdgpu_ci_reset_smc(adev);
|
||||
|
||||
ret = amdgpu_ci_load_smc_ucode(adev, pi->sram_end);
|
||||
ret = amdgpu_ci_load_smc_ucode(adev, SMC_RAM_END);
|
||||
|
||||
return ret;
|
||||
|
||||
|
@ -4257,12 +4256,6 @@ static int ci_update_vce_dpm(struct amdgpu_device *adev,
|
|||
|
||||
if (amdgpu_current_state->evclk != amdgpu_new_state->evclk) {
|
||||
if (amdgpu_new_state->evclk) {
|
||||
/* turn the clocks on when encoding */
|
||||
ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pi->smc_state_table.VceBootLevel = ci_get_vce_boot_level(adev);
|
||||
tmp = RREG32_SMC(ixDPM_TABLE_475);
|
||||
tmp &= ~DPM_TABLE_475__VceBootLevel_MASK;
|
||||
|
@ -4274,9 +4267,6 @@ static int ci_update_vce_dpm(struct amdgpu_device *adev,
|
|||
ret = ci_enable_vce_dpm(adev, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* turn the clocks off when not encoding */
|
||||
ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -6278,13 +6268,13 @@ static int ci_dpm_sw_init(void *handle)
|
|||
adev->pm.current_mclk = adev->clock.default_mclk;
|
||||
adev->pm.int_thermal_type = THERMAL_TYPE_NONE;
|
||||
|
||||
if (amdgpu_dpm == 0)
|
||||
return 0;
|
||||
|
||||
ret = ci_dpm_init_microcode(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (amdgpu_dpm == 0)
|
||||
return 0;
|
||||
|
||||
INIT_WORK(&adev->pm.dpm.thermal.work, amdgpu_dpm_thermal_work_handler);
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
ret = ci_dpm_init(adev);
|
||||
|
@ -6328,8 +6318,15 @@ static int ci_dpm_hw_init(void *handle)
|
|||
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (!amdgpu_dpm)
|
||||
if (!amdgpu_dpm) {
|
||||
ret = ci_upload_firmware(adev);
|
||||
if (ret) {
|
||||
DRM_ERROR("ci_upload_firmware failed\n");
|
||||
return ret;
|
||||
}
|
||||
ci_dpm_start_smc(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&adev->pm.mutex);
|
||||
ci_dpm_setup_asic(adev);
|
||||
|
@ -6351,6 +6348,8 @@ static int ci_dpm_hw_fini(void *handle)
|
|||
mutex_lock(&adev->pm.mutex);
|
||||
ci_dpm_disable(adev);
|
||||
mutex_unlock(&adev->pm.mutex);
|
||||
} else {
|
||||
ci_dpm_stop_smc(adev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1722,8 +1722,8 @@ static int cik_common_early_init(void *handle)
|
|||
AMD_PG_SUPPORT_GFX_SMG |
|
||||
AMD_PG_SUPPORT_GFX_DMG |*/
|
||||
AMD_PG_SUPPORT_UVD |
|
||||
/*AMD_PG_SUPPORT_VCE |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_VCE |
|
||||
/* AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_GDS |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS |
|
||||
AMD_PG_SUPPORT_ACP |
|
||||
|
|
|
@ -1325,21 +1325,19 @@ static u32 gfx_v6_0_create_bitmask(u32 bit_width)
|
|||
return (u32)(((u64)1 << bit_width) - 1);
|
||||
}
|
||||
|
||||
static u32 gfx_v6_0_get_rb_disabled(struct amdgpu_device *adev,
|
||||
u32 max_rb_num_per_se,
|
||||
u32 sh_per_se)
|
||||
static u32 gfx_v6_0_get_rb_active_bitmap(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 data, mask;
|
||||
|
||||
data = RREG32(mmCC_RB_BACKEND_DISABLE);
|
||||
data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK;
|
||||
data |= RREG32(mmGC_USER_RB_BACKEND_DISABLE);
|
||||
data = RREG32(mmCC_RB_BACKEND_DISABLE) |
|
||||
RREG32(mmGC_USER_RB_BACKEND_DISABLE);
|
||||
|
||||
data >>= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE__SHIFT;
|
||||
data = REG_GET_FIELD(data, GC_USER_RB_BACKEND_DISABLE, BACKEND_DISABLE);
|
||||
|
||||
mask = gfx_v6_0_create_bitmask(max_rb_num_per_se / sh_per_se);
|
||||
mask = gfx_v6_0_create_bitmask(adev->gfx.config.max_backends_per_se/
|
||||
adev->gfx.config.max_sh_per_se);
|
||||
|
||||
return data & mask;
|
||||
return ~data & mask;
|
||||
}
|
||||
|
||||
static void gfx_v6_0_raster_config(struct amdgpu_device *adev, u32 *rconf)
|
||||
|
@ -1468,68 +1466,55 @@ static void gfx_v6_0_write_harvested_raster_configs(struct amdgpu_device *adev,
|
|||
gfx_v6_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
}
|
||||
|
||||
static void gfx_v6_0_setup_rb(struct amdgpu_device *adev,
|
||||
u32 se_num, u32 sh_per_se,
|
||||
u32 max_rb_num_per_se)
|
||||
static void gfx_v6_0_setup_rb(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, j;
|
||||
u32 data, mask;
|
||||
u32 disabled_rbs = 0;
|
||||
u32 enabled_rbs = 0;
|
||||
u32 data;
|
||||
u32 raster_config = 0;
|
||||
u32 active_rbs = 0;
|
||||
u32 rb_bitmap_width_per_sh = adev->gfx.config.max_backends_per_se /
|
||||
adev->gfx.config.max_sh_per_se;
|
||||
unsigned num_rb_pipes;
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < se_num; i++) {
|
||||
for (j = 0; j < sh_per_se; j++) {
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
gfx_v6_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
data = gfx_v6_0_get_rb_disabled(adev, max_rb_num_per_se, sh_per_se);
|
||||
disabled_rbs |= data << ((i * sh_per_se + j) * 2);
|
||||
data = gfx_v6_0_get_rb_active_bitmap(adev);
|
||||
active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) *
|
||||
rb_bitmap_width_per_sh);
|
||||
}
|
||||
}
|
||||
gfx_v6_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
mask = 1;
|
||||
for (i = 0; i < max_rb_num_per_se * se_num; i++) {
|
||||
if (!(disabled_rbs & mask))
|
||||
enabled_rbs |= mask;
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
adev->gfx.config.backend_enable_mask = enabled_rbs;
|
||||
adev->gfx.config.num_rbs = hweight32(enabled_rbs);
|
||||
adev->gfx.config.backend_enable_mask = active_rbs;
|
||||
adev->gfx.config.num_rbs = hweight32(active_rbs);
|
||||
|
||||
num_rb_pipes = min_t(unsigned, adev->gfx.config.max_backends_per_se *
|
||||
adev->gfx.config.max_shader_engines, 16);
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < se_num; i++) {
|
||||
gfx_v6_0_select_se_sh(adev, i, 0xffffffff, 0xffffffff);
|
||||
data = 0;
|
||||
for (j = 0; j < sh_per_se; j++) {
|
||||
switch (enabled_rbs & 3) {
|
||||
case 1:
|
||||
data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
|
||||
break;
|
||||
case 2:
|
||||
data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
|
||||
break;
|
||||
}
|
||||
enabled_rbs >>= 2;
|
||||
}
|
||||
gfx_v6_0_raster_config(adev, &data);
|
||||
gfx_v6_0_raster_config(adev, &raster_config);
|
||||
|
||||
if (!adev->gfx.config.backend_enable_mask ||
|
||||
adev->gfx.config.num_rbs >= num_rb_pipes)
|
||||
WREG32(mmPA_SC_RASTER_CONFIG, data);
|
||||
else
|
||||
gfx_v6_0_write_harvested_raster_configs(adev, data,
|
||||
adev->gfx.config.backend_enable_mask,
|
||||
num_rb_pipes);
|
||||
if (!adev->gfx.config.backend_enable_mask ||
|
||||
adev->gfx.config.num_rbs >= num_rb_pipes) {
|
||||
WREG32(mmPA_SC_RASTER_CONFIG, raster_config);
|
||||
} else {
|
||||
gfx_v6_0_write_harvested_raster_configs(adev, raster_config,
|
||||
adev->gfx.config.backend_enable_mask,
|
||||
num_rb_pipes);
|
||||
}
|
||||
|
||||
/* cache the values for userspace */
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
gfx_v6_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
adev->gfx.config.rb_config[i][j].rb_backend_disable =
|
||||
RREG32(mmCC_RB_BACKEND_DISABLE);
|
||||
adev->gfx.config.rb_config[i][j].user_rb_backend_disable =
|
||||
RREG32(mmGC_USER_RB_BACKEND_DISABLE);
|
||||
adev->gfx.config.rb_config[i][j].raster_config =
|
||||
RREG32(mmPA_SC_RASTER_CONFIG);
|
||||
}
|
||||
}
|
||||
gfx_v6_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
@ -1540,36 +1525,44 @@ static void gmc_v6_0_init_compute_vmid(struct amdgpu_device *adev)
|
|||
}
|
||||
*/
|
||||
|
||||
static u32 gfx_v6_0_get_cu_enabled(struct amdgpu_device *adev, u32 cu_per_sh)
|
||||
static void gfx_v6_0_set_user_cu_inactive_bitmap(struct amdgpu_device *adev,
|
||||
u32 bitmap)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
if (!bitmap)
|
||||
return;
|
||||
|
||||
data = bitmap << GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT;
|
||||
data &= GC_USER_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK;
|
||||
|
||||
WREG32(mmGC_USER_SHADER_ARRAY_CONFIG, data);
|
||||
}
|
||||
|
||||
static u32 gfx_v6_0_get_cu_enabled(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 data, mask;
|
||||
|
||||
data = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG);
|
||||
data &= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK;
|
||||
data |= RREG32(mmGC_USER_SHADER_ARRAY_CONFIG);
|
||||
data = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG) |
|
||||
RREG32(mmGC_USER_SHADER_ARRAY_CONFIG);
|
||||
|
||||
data >>= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT;
|
||||
|
||||
mask = gfx_v6_0_create_bitmask(cu_per_sh);
|
||||
|
||||
return ~data & mask;
|
||||
mask = gfx_v6_0_create_bitmask(adev->gfx.config.max_cu_per_sh);
|
||||
return ~REG_GET_FIELD(data, CC_GC_SHADER_ARRAY_CONFIG, INACTIVE_CUS) & mask;
|
||||
}
|
||||
|
||||
|
||||
static void gfx_v6_0_setup_spi(struct amdgpu_device *adev,
|
||||
u32 se_num, u32 sh_per_se,
|
||||
u32 cu_per_sh)
|
||||
static void gfx_v6_0_setup_spi(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, j, k;
|
||||
u32 data, mask;
|
||||
u32 active_cu = 0;
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < se_num; i++) {
|
||||
for (j = 0; j < sh_per_se; j++) {
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
gfx_v6_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
data = RREG32(mmSPI_STATIC_THREAD_MGMT_3);
|
||||
active_cu = gfx_v6_0_get_cu_enabled(adev, cu_per_sh);
|
||||
active_cu = gfx_v6_0_get_cu_enabled(adev);
|
||||
|
||||
mask = 1;
|
||||
for (k = 0; k < 16; k++) {
|
||||
|
@ -1717,6 +1710,9 @@ static void gfx_v6_0_gpu_init(struct amdgpu_device *adev)
|
|||
gb_addr_config |= 2 << GB_ADDR_CONFIG__ROW_SIZE__SHIFT;
|
||||
break;
|
||||
}
|
||||
gb_addr_config &= ~GB_ADDR_CONFIG__NUM_SHADER_ENGINES_MASK;
|
||||
if (adev->gfx.config.max_shader_engines == 2)
|
||||
gb_addr_config |= 1 << GB_ADDR_CONFIG__NUM_SHADER_ENGINES__SHIFT;
|
||||
adev->gfx.config.gb_addr_config = gb_addr_config;
|
||||
|
||||
WREG32(mmGB_ADDR_CONFIG, gb_addr_config);
|
||||
|
@ -1735,13 +1731,9 @@ static void gfx_v6_0_gpu_init(struct amdgpu_device *adev)
|
|||
#endif
|
||||
gfx_v6_0_tiling_mode_table_init(adev);
|
||||
|
||||
gfx_v6_0_setup_rb(adev, adev->gfx.config.max_shader_engines,
|
||||
adev->gfx.config.max_sh_per_se,
|
||||
adev->gfx.config.max_backends_per_se);
|
||||
gfx_v6_0_setup_rb(adev);
|
||||
|
||||
gfx_v6_0_setup_spi(adev, adev->gfx.config.max_shader_engines,
|
||||
adev->gfx.config.max_sh_per_se,
|
||||
adev->gfx.config.max_cu_per_sh);
|
||||
gfx_v6_0_setup_spi(adev);
|
||||
|
||||
gfx_v6_0_get_cu_info(adev);
|
||||
|
||||
|
@ -2941,61 +2933,16 @@ static void gfx_v6_0_enable_gfx_cgpg(struct amdgpu_device *adev,
|
|||
}
|
||||
}
|
||||
|
||||
static u32 gfx_v6_0_get_cu_active_bitmap(struct amdgpu_device *adev,
|
||||
u32 se, u32 sh)
|
||||
{
|
||||
|
||||
u32 mask = 0, tmp, tmp1;
|
||||
int i;
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
gfx_v6_0_select_se_sh(adev, se, sh, 0xffffffff);
|
||||
tmp = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG);
|
||||
tmp1 = RREG32(mmGC_USER_SHADER_ARRAY_CONFIG);
|
||||
gfx_v6_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
tmp &= 0xffff0000;
|
||||
|
||||
tmp |= tmp1;
|
||||
tmp >>= 16;
|
||||
|
||||
for (i = 0; i < adev->gfx.config.max_cu_per_sh; i ++) {
|
||||
mask <<= 1;
|
||||
mask |= 1;
|
||||
}
|
||||
|
||||
return (~tmp) & mask;
|
||||
}
|
||||
|
||||
static void gfx_v6_0_init_ao_cu_mask(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 i, j, k, active_cu_number = 0;
|
||||
u32 tmp;
|
||||
|
||||
u32 mask, counter, cu_bitmap;
|
||||
u32 tmp = 0;
|
||||
WREG32(mmRLC_PG_ALWAYS_ON_CU_MASK, adev->gfx.cu_info.ao_cu_mask);
|
||||
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
mask = 1;
|
||||
cu_bitmap = 0;
|
||||
counter = 0;
|
||||
for (k = 0; k < adev->gfx.config.max_cu_per_sh; k++) {
|
||||
if (gfx_v6_0_get_cu_active_bitmap(adev, i, j) & mask) {
|
||||
if (counter < 2)
|
||||
cu_bitmap |= mask;
|
||||
counter++;
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
active_cu_number += counter;
|
||||
tmp |= (cu_bitmap << (i * 16 + j * 8));
|
||||
}
|
||||
}
|
||||
|
||||
WREG32(mmRLC_PG_AO_CU_MASK, tmp);
|
||||
WREG32_FIELD(RLC_MAX_PG_CU, MAX_POWERED_UP_CU, active_cu_number);
|
||||
tmp = RREG32(mmRLC_MAX_PG_CU);
|
||||
tmp &= ~RLC_MAX_PG_CU__MAX_POWERED_UP_CU_MASK;
|
||||
tmp |= (adev->gfx.cu_info.number << RLC_MAX_PG_CU__MAX_POWERED_UP_CU__SHIFT);
|
||||
WREG32(mmRLC_MAX_PG_CU, tmp);
|
||||
}
|
||||
|
||||
static void gfx_v6_0_enable_gfx_static_mgpg(struct amdgpu_device *adev,
|
||||
|
@ -3770,18 +3717,26 @@ static void gfx_v6_0_get_cu_info(struct amdgpu_device *adev)
|
|||
int i, j, k, counter, active_cu_number = 0;
|
||||
u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0;
|
||||
struct amdgpu_cu_info *cu_info = &adev->gfx.cu_info;
|
||||
unsigned disable_masks[4 * 2];
|
||||
|
||||
memset(cu_info, 0, sizeof(*cu_info));
|
||||
|
||||
amdgpu_gfx_parse_disable_cu(disable_masks, 4, 2);
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
|
||||
for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
|
||||
mask = 1;
|
||||
ao_bitmap = 0;
|
||||
counter = 0;
|
||||
bitmap = gfx_v6_0_get_cu_active_bitmap(adev, i, j);
|
||||
gfx_v6_0_select_se_sh(adev, i, j, 0xffffffff);
|
||||
if (i < 4 && j < 2)
|
||||
gfx_v6_0_set_user_cu_inactive_bitmap(
|
||||
adev, disable_masks[i * 2 + j]);
|
||||
bitmap = gfx_v6_0_get_cu_enabled(adev);
|
||||
cu_info->bitmap[i][j] = bitmap;
|
||||
|
||||
for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) {
|
||||
for (k = 0; k < 16; k++) {
|
||||
if (bitmap & mask) {
|
||||
if (counter < 2)
|
||||
ao_bitmap |= mask;
|
||||
|
@ -3794,6 +3749,9 @@ static void gfx_v6_0_get_cu_info(struct amdgpu_device *adev)
|
|||
}
|
||||
}
|
||||
|
||||
gfx_v6_0_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
|
||||
cu_info->number = active_cu_number;
|
||||
cu_info->ao_cu_mask = ao_cu_mask;
|
||||
}
|
||||
|
|
|
@ -1550,11 +1550,6 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
|
|||
|
||||
if (amdgpu_new_state->evclk > 0 && amdgpu_current_state->evclk == 0) {
|
||||
kv_dpm_powergate_vce(adev, false);
|
||||
/* turn the clocks on when encoding */
|
||||
ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (pi->caps_stable_p_state)
|
||||
pi->vce_boot_level = table->count - 1;
|
||||
else
|
||||
|
@ -1573,15 +1568,9 @@ static int kv_update_vce_dpm(struct amdgpu_device *adev,
|
|||
amdgpu_kv_send_msg_to_smc_with_parameter(adev,
|
||||
PPSMC_MSG_VCEDPM_SetEnabledMask,
|
||||
(1 << pi->vce_boot_level));
|
||||
|
||||
kv_enable_vce_dpm(adev, true);
|
||||
} else if (amdgpu_new_state->evclk == 0 && amdgpu_current_state->evclk > 0) {
|
||||
kv_enable_vce_dpm(adev, false);
|
||||
/* turn the clocks off when not encoding */
|
||||
ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
if (ret)
|
||||
return ret;
|
||||
kv_dpm_powergate_vce(adev, true);
|
||||
}
|
||||
|
||||
|
@ -1688,70 +1677,44 @@ static void kv_dpm_powergate_uvd(struct amdgpu_device *adev, bool gate)
|
|||
struct kv_power_info *pi = kv_get_pi(adev);
|
||||
int ret;
|
||||
|
||||
if (pi->uvd_power_gated == gate)
|
||||
return;
|
||||
|
||||
pi->uvd_power_gated = gate;
|
||||
|
||||
if (gate) {
|
||||
if (pi->caps_uvd_pg) {
|
||||
/* disable clockgating so we can properly shut down the block */
|
||||
ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
/* shutdown the UVD block */
|
||||
ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_GATE);
|
||||
/* XXX: check for errors */
|
||||
}
|
||||
/* stop the UVD block */
|
||||
ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_GATE);
|
||||
kv_update_uvd_dpm(adev, gate);
|
||||
if (pi->caps_uvd_pg)
|
||||
/* power off the UVD block */
|
||||
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_UVDPowerOFF);
|
||||
} else {
|
||||
if (pi->caps_uvd_pg) {
|
||||
if (pi->caps_uvd_pg)
|
||||
/* power on the UVD block */
|
||||
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_UVDPowerON);
|
||||
/* re-init the UVD block */
|
||||
ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
/* enable clockgating. hw will dynamically gate/ungate clocks on the fly */
|
||||
ret = amdgpu_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_GATE);
|
||||
/* XXX: check for errors */
|
||||
}
|
||||
kv_update_uvd_dpm(adev, gate);
|
||||
|
||||
ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
}
|
||||
}
|
||||
|
||||
static void kv_dpm_powergate_vce(struct amdgpu_device *adev, bool gate)
|
||||
{
|
||||
struct kv_power_info *pi = kv_get_pi(adev);
|
||||
int ret;
|
||||
|
||||
if (pi->vce_power_gated == gate)
|
||||
return;
|
||||
|
||||
pi->vce_power_gated = gate;
|
||||
|
||||
if (gate) {
|
||||
if (pi->caps_vce_pg) {
|
||||
/* shutdown the VCE block */
|
||||
ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_GATE);
|
||||
/* XXX: check for errors */
|
||||
/* power off the VCE block */
|
||||
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF);
|
||||
}
|
||||
} else {
|
||||
if (pi->caps_vce_pg) {
|
||||
/* power on the VCE block */
|
||||
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
|
||||
/* re-init the VCE block */
|
||||
ret = amdgpu_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
/* XXX: check for errors */
|
||||
}
|
||||
}
|
||||
if (!pi->caps_vce_pg)
|
||||
return;
|
||||
|
||||
if (gate)
|
||||
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerOFF);
|
||||
else
|
||||
amdgpu_kv_notify_message_to_smu(adev, PPSMC_MSG_VCEPowerON);
|
||||
}
|
||||
|
||||
static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate)
|
||||
|
@ -3009,8 +2972,7 @@ static int kv_dpm_late_init(void *handle)
|
|||
|
||||
kv_dpm_powergate_acp(adev, true);
|
||||
kv_dpm_powergate_samu(adev, true);
|
||||
kv_dpm_powergate_vce(adev, true);
|
||||
kv_dpm_powergate_uvd(adev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1010,24 +1010,81 @@ static struct amdgpu_allowed_register_entry si_allowed_read_registers[] = {
|
|||
{PA_SC_RASTER_CONFIG, false, true},
|
||||
};
|
||||
|
||||
static uint32_t si_read_indexed_register(struct amdgpu_device *adev,
|
||||
u32 se_num, u32 sh_num,
|
||||
u32 reg_offset)
|
||||
static uint32_t si_get_register_value(struct amdgpu_device *adev,
|
||||
bool indexed, u32 se_num,
|
||||
u32 sh_num, u32 reg_offset)
|
||||
{
|
||||
uint32_t val;
|
||||
if (indexed) {
|
||||
uint32_t val;
|
||||
unsigned se_idx = (se_num == 0xffffffff) ? 0 : se_num;
|
||||
unsigned sh_idx = (sh_num == 0xffffffff) ? 0 : sh_num;
|
||||
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
if (se_num != 0xffffffff || sh_num != 0xffffffff)
|
||||
amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff);
|
||||
switch (reg_offset) {
|
||||
case mmCC_RB_BACKEND_DISABLE:
|
||||
return adev->gfx.config.rb_config[se_idx][sh_idx].rb_backend_disable;
|
||||
case mmGC_USER_RB_BACKEND_DISABLE:
|
||||
return adev->gfx.config.rb_config[se_idx][sh_idx].user_rb_backend_disable;
|
||||
case mmPA_SC_RASTER_CONFIG:
|
||||
return adev->gfx.config.rb_config[se_idx][sh_idx].raster_config;
|
||||
}
|
||||
|
||||
val = RREG32(reg_offset);
|
||||
mutex_lock(&adev->grbm_idx_mutex);
|
||||
if (se_num != 0xffffffff || sh_num != 0xffffffff)
|
||||
amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff);
|
||||
|
||||
if (se_num != 0xffffffff || sh_num != 0xffffffff)
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
return val;
|
||||
val = RREG32(reg_offset);
|
||||
|
||||
if (se_num != 0xffffffff || sh_num != 0xffffffff)
|
||||
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
mutex_unlock(&adev->grbm_idx_mutex);
|
||||
return val;
|
||||
} else {
|
||||
unsigned idx;
|
||||
|
||||
switch (reg_offset) {
|
||||
case mmGB_ADDR_CONFIG:
|
||||
return adev->gfx.config.gb_addr_config;
|
||||
case mmMC_ARB_RAMCFG:
|
||||
return adev->gfx.config.mc_arb_ramcfg;
|
||||
case mmGB_TILE_MODE0:
|
||||
case mmGB_TILE_MODE1:
|
||||
case mmGB_TILE_MODE2:
|
||||
case mmGB_TILE_MODE3:
|
||||
case mmGB_TILE_MODE4:
|
||||
case mmGB_TILE_MODE5:
|
||||
case mmGB_TILE_MODE6:
|
||||
case mmGB_TILE_MODE7:
|
||||
case mmGB_TILE_MODE8:
|
||||
case mmGB_TILE_MODE9:
|
||||
case mmGB_TILE_MODE10:
|
||||
case mmGB_TILE_MODE11:
|
||||
case mmGB_TILE_MODE12:
|
||||
case mmGB_TILE_MODE13:
|
||||
case mmGB_TILE_MODE14:
|
||||
case mmGB_TILE_MODE15:
|
||||
case mmGB_TILE_MODE16:
|
||||
case mmGB_TILE_MODE17:
|
||||
case mmGB_TILE_MODE18:
|
||||
case mmGB_TILE_MODE19:
|
||||
case mmGB_TILE_MODE20:
|
||||
case mmGB_TILE_MODE21:
|
||||
case mmGB_TILE_MODE22:
|
||||
case mmGB_TILE_MODE23:
|
||||
case mmGB_TILE_MODE24:
|
||||
case mmGB_TILE_MODE25:
|
||||
case mmGB_TILE_MODE26:
|
||||
case mmGB_TILE_MODE27:
|
||||
case mmGB_TILE_MODE28:
|
||||
case mmGB_TILE_MODE29:
|
||||
case mmGB_TILE_MODE30:
|
||||
case mmGB_TILE_MODE31:
|
||||
idx = (reg_offset - mmGB_TILE_MODE0);
|
||||
return adev->gfx.config.tile_mode_array[idx];
|
||||
default:
|
||||
return RREG32(reg_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int si_read_register(struct amdgpu_device *adev, u32 se_num,
|
||||
u32 sh_num, u32 reg_offset, u32 *value)
|
||||
{
|
||||
|
@ -1039,10 +1096,9 @@ static int si_read_register(struct amdgpu_device *adev, u32 se_num,
|
|||
continue;
|
||||
|
||||
if (!si_allowed_read_registers[i].untouched)
|
||||
*value = si_allowed_read_registers[i].grbm_indexed ?
|
||||
si_read_indexed_register(adev, se_num,
|
||||
sh_num, reg_offset) :
|
||||
RREG32(reg_offset);
|
||||
*value = si_get_register_value(adev,
|
||||
si_allowed_read_registers[i].grbm_indexed,
|
||||
se_num, sh_num, reg_offset);
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
|
|
|
@ -143,8 +143,8 @@
|
|||
#define RLC_CLEAR_STATE_DESCRIPTOR_OFFSET 0x3D
|
||||
|
||||
#define TAHITI_GB_ADDR_CONFIG_GOLDEN 0x12011003
|
||||
#define VERDE_GB_ADDR_CONFIG_GOLDEN 0x12010002
|
||||
#define HAINAN_GB_ADDR_CONFIG_GOLDEN 0x02010001
|
||||
#define VERDE_GB_ADDR_CONFIG_GOLDEN 0x02010002
|
||||
#define HAINAN_GB_ADDR_CONFIG_GOLDEN 0x02011003
|
||||
|
||||
#define PACKET3(op, n) ((RADEON_PACKET_TYPE3 << 30) | \
|
||||
(((op) & 0xFF) << 8) | \
|
||||
|
|
|
@ -159,9 +159,6 @@ static int uvd_v4_2_hw_init(void *handle)
|
|||
|
||||
uvd_v4_2_enable_mgcg(adev, true);
|
||||
amdgpu_asic_set_uvd_clocks(adev, 10000, 10000);
|
||||
r = uvd_v4_2_start(adev);
|
||||
if (r)
|
||||
goto done;
|
||||
|
||||
ring->ready = true;
|
||||
r = amdgpu_ring_test_ring(ring);
|
||||
|
@ -198,7 +195,6 @@ static int uvd_v4_2_hw_init(void *handle)
|
|||
amdgpu_ring_commit(ring);
|
||||
|
||||
done:
|
||||
|
||||
if (!r)
|
||||
DRM_INFO("UVD initialized successfully.\n");
|
||||
|
||||
|
@ -217,7 +213,9 @@ static int uvd_v4_2_hw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = &adev->uvd.ring;
|
||||
|
||||
uvd_v4_2_stop(adev);
|
||||
if (RREG32(mmUVD_STATUS) != 0)
|
||||
uvd_v4_2_stop(adev);
|
||||
|
||||
ring->ready = false;
|
||||
|
||||
return 0;
|
||||
|
@ -267,37 +265,26 @@ static int uvd_v4_2_start(struct amdgpu_device *adev)
|
|||
struct amdgpu_ring *ring = &adev->uvd.ring;
|
||||
uint32_t rb_bufsz;
|
||||
int i, j, r;
|
||||
u32 tmp;
|
||||
/* disable byte swapping */
|
||||
u32 lmi_swap_cntl = 0;
|
||||
u32 mp_swap_cntl = 0;
|
||||
|
||||
WREG32(mmUVD_CGC_GATE, 0);
|
||||
/* set uvd busy */
|
||||
WREG32_P(mmUVD_STATUS, 1<<2, ~(1<<2));
|
||||
|
||||
uvd_v4_2_set_dcm(adev, true);
|
||||
|
||||
uvd_v4_2_mc_resume(adev);
|
||||
|
||||
/* disable interupt */
|
||||
WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1));
|
||||
|
||||
/* Stall UMC and register bus before resetting VCPU */
|
||||
WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
|
||||
mdelay(1);
|
||||
|
||||
/* put LMI, VCPU, RBC etc... into reset */
|
||||
WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
|
||||
mdelay(5);
|
||||
WREG32(mmUVD_CGC_GATE, 0);
|
||||
|
||||
/* take UVD block out of reset */
|
||||
WREG32_P(mmSRBM_SOFT_RESET, 0, ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK);
|
||||
mdelay(5);
|
||||
|
||||
/* initialize UVD memory controller */
|
||||
WREG32(mmUVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
|
||||
(1 << 21) | (1 << 9) | (1 << 20));
|
||||
/* enable VCPU clock */
|
||||
WREG32(mmUVD_VCPU_CNTL, 1 << 9);
|
||||
|
||||
/* disable interupt */
|
||||
WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1));
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
/* swap (8 in 32) RB and IB */
|
||||
|
@ -306,6 +293,11 @@ static int uvd_v4_2_start(struct amdgpu_device *adev)
|
|||
#endif
|
||||
WREG32(mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
|
||||
WREG32(mmUVD_MP_SWAP_CNTL, mp_swap_cntl);
|
||||
/* initialize UVD memory controller */
|
||||
WREG32(mmUVD_LMI_CTRL, 0x203108);
|
||||
|
||||
tmp = RREG32(mmUVD_MPC_CNTL);
|
||||
WREG32(mmUVD_MPC_CNTL, tmp | 0x10);
|
||||
|
||||
WREG32(mmUVD_MPC_SET_MUXA0, 0x40c2040);
|
||||
WREG32(mmUVD_MPC_SET_MUXA1, 0x0);
|
||||
|
@ -314,18 +306,20 @@ static int uvd_v4_2_start(struct amdgpu_device *adev)
|
|||
WREG32(mmUVD_MPC_SET_ALU, 0);
|
||||
WREG32(mmUVD_MPC_SET_MUX, 0x88);
|
||||
|
||||
/* take all subblocks out of reset, except VCPU */
|
||||
WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
|
||||
mdelay(5);
|
||||
uvd_v4_2_mc_resume(adev);
|
||||
|
||||
/* enable VCPU clock */
|
||||
WREG32(mmUVD_VCPU_CNTL, 1 << 9);
|
||||
tmp = RREG32_UVD_CTX(ixUVD_LMI_CACHE_CTRL);
|
||||
WREG32_UVD_CTX(ixUVD_LMI_CACHE_CTRL, tmp & (~0x10));
|
||||
|
||||
/* enable UMC */
|
||||
WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
|
||||
|
||||
/* boot up the VCPU */
|
||||
WREG32(mmUVD_SOFT_RESET, 0);
|
||||
WREG32_P(mmUVD_SOFT_RESET, 0, ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK);
|
||||
|
||||
WREG32_P(mmUVD_SOFT_RESET, 0, ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
|
||||
|
||||
WREG32_P(mmUVD_SOFT_RESET, 0, ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
|
||||
|
||||
mdelay(10);
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
|
@ -357,6 +351,8 @@ static int uvd_v4_2_start(struct amdgpu_device *adev)
|
|||
/* enable interupt */
|
||||
WREG32_P(mmUVD_MASTINT_EN, 3<<1, ~(3 << 1));
|
||||
|
||||
WREG32_P(mmUVD_STATUS, 0, ~(1<<2));
|
||||
|
||||
/* force RBC into idle state */
|
||||
WREG32(mmUVD_RBC_RB_CNTL, 0x11010101);
|
||||
|
||||
|
@ -393,22 +389,54 @@ static int uvd_v4_2_start(struct amdgpu_device *adev)
|
|||
*/
|
||||
static void uvd_v4_2_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
/* force RBC into idle state */
|
||||
uint32_t i, j;
|
||||
uint32_t status;
|
||||
|
||||
WREG32(mmUVD_RBC_RB_CNTL, 0x11010101);
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 100; ++j) {
|
||||
status = RREG32(mmUVD_STATUS);
|
||||
if (status & 2)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 100; ++j) {
|
||||
status = RREG32(mmUVD_LMI_STATUS);
|
||||
if (status & 0xf)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Stall UMC and register bus before resetting VCPU */
|
||||
WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
|
||||
mdelay(1);
|
||||
|
||||
/* put VCPU into reset */
|
||||
WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
|
||||
mdelay(5);
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 100; ++j) {
|
||||
status = RREG32(mmUVD_LMI_STATUS);
|
||||
if (status & 0x240)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* disable VCPU clock */
|
||||
WREG32(mmUVD_VCPU_CNTL, 0x0);
|
||||
WREG32_P(0x3D49, 0, ~(1 << 2));
|
||||
|
||||
/* Unstall UMC and register bus */
|
||||
WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
|
||||
WREG32_P(mmUVD_VCPU_CNTL, 0, ~(1 << 9));
|
||||
|
||||
/* put LMI, VCPU, RBC etc... into reset */
|
||||
WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK |
|
||||
UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
|
||||
|
||||
WREG32(mmUVD_STATUS, 0);
|
||||
|
||||
uvd_v4_2_set_dcm(adev, false);
|
||||
}
|
||||
|
@ -694,8 +722,24 @@ static int uvd_v4_2_set_powergating_state(void *handle,
|
|||
|
||||
if (state == AMD_PG_STATE_GATE) {
|
||||
uvd_v4_2_stop(adev);
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_UVD && amdgpu_dpm == 0) {
|
||||
if (!(RREG32_SMC(ixCURRENT_PG_STATUS) & 0x4)) {
|
||||
WREG32(mmUVD_PGFSM_CONFIG, (UVD_PGFSM_CONFIG__UVD_PGFSM_FSM_ADDR_MASK |
|
||||
UVD_PGFSM_CONFIG__UVD_PGFSM_POWER_DOWN_MASK |
|
||||
UVD_PGFSM_CONFIG__UVD_PGFSM_P1_SELECT_MASK));
|
||||
mdelay(20);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
if (adev->pg_flags & AMD_PG_SUPPORT_UVD && amdgpu_dpm == 0) {
|
||||
if (RREG32_SMC(ixCURRENT_PG_STATUS) & 0x4) {
|
||||
WREG32(mmUVD_PGFSM_CONFIG, (UVD_PGFSM_CONFIG__UVD_PGFSM_FSM_ADDR_MASK |
|
||||
UVD_PGFSM_CONFIG__UVD_PGFSM_POWER_UP_MASK |
|
||||
UVD_PGFSM_CONFIG__UVD_PGFSM_P1_SELECT_MASK));
|
||||
mdelay(30);
|
||||
}
|
||||
}
|
||||
return uvd_v4_2_start(adev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,9 +152,9 @@ static int uvd_v5_0_hw_init(void *handle)
|
|||
uint32_t tmp;
|
||||
int r;
|
||||
|
||||
r = uvd_v5_0_start(adev);
|
||||
if (r)
|
||||
goto done;
|
||||
amdgpu_asic_set_uvd_clocks(adev, 10000, 10000);
|
||||
uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE);
|
||||
uvd_v5_0_enable_mgcg(adev, true);
|
||||
|
||||
ring->ready = true;
|
||||
r = amdgpu_ring_test_ring(ring);
|
||||
|
@ -189,11 +189,13 @@ static int uvd_v5_0_hw_init(void *handle)
|
|||
amdgpu_ring_write(ring, 3);
|
||||
|
||||
amdgpu_ring_commit(ring);
|
||||
|
||||
done:
|
||||
if (!r)
|
||||
DRM_INFO("UVD initialized successfully.\n");
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,7 +210,9 @@ static int uvd_v5_0_hw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = &adev->uvd.ring;
|
||||
|
||||
uvd_v5_0_stop(adev);
|
||||
if (RREG32(mmUVD_STATUS) != 0)
|
||||
uvd_v5_0_stop(adev);
|
||||
|
||||
ring->ready = false;
|
||||
|
||||
return 0;
|
||||
|
@ -310,10 +314,6 @@ static int uvd_v5_0_start(struct amdgpu_device *adev)
|
|||
|
||||
uvd_v5_0_mc_resume(adev);
|
||||
|
||||
amdgpu_asic_set_uvd_clocks(adev, 10000, 10000);
|
||||
uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE);
|
||||
uvd_v5_0_enable_mgcg(adev, true);
|
||||
|
||||
/* disable interupt */
|
||||
WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1));
|
||||
|
||||
|
@ -456,6 +456,8 @@ static void uvd_v5_0_stop(struct amdgpu_device *adev)
|
|||
|
||||
/* Unstall UMC and register bus */
|
||||
WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
|
||||
|
||||
WREG32(mmUVD_STATUS, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -792,9 +794,6 @@ static int uvd_v5_0_set_clockgating_state(void *handle,
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
|
||||
|
||||
if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG))
|
||||
return 0;
|
||||
|
||||
if (enable) {
|
||||
/* wait for STATUS to clear */
|
||||
if (uvd_v5_0_wait_for_idle(handle))
|
||||
|
@ -824,9 +823,6 @@ static int uvd_v5_0_set_powergating_state(void *handle,
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret = 0;
|
||||
|
||||
if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
|
||||
return 0;
|
||||
|
||||
if (state == AMD_PG_STATE_GATE) {
|
||||
uvd_v5_0_stop(adev);
|
||||
adev->uvd.is_powergated = true;
|
||||
|
|
|
@ -155,9 +155,9 @@ static int uvd_v6_0_hw_init(void *handle)
|
|||
uint32_t tmp;
|
||||
int r;
|
||||
|
||||
r = uvd_v6_0_start(adev);
|
||||
if (r)
|
||||
goto done;
|
||||
amdgpu_asic_set_uvd_clocks(adev, 10000, 10000);
|
||||
uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE);
|
||||
uvd_v6_0_enable_mgcg(adev, true);
|
||||
|
||||
ring->ready = true;
|
||||
r = amdgpu_ring_test_ring(ring);
|
||||
|
@ -212,7 +212,9 @@ static int uvd_v6_0_hw_fini(void *handle)
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
struct amdgpu_ring *ring = &adev->uvd.ring;
|
||||
|
||||
uvd_v6_0_stop(adev);
|
||||
if (RREG32(mmUVD_STATUS) != 0)
|
||||
uvd_v6_0_stop(adev);
|
||||
|
||||
ring->ready = false;
|
||||
|
||||
return 0;
|
||||
|
@ -397,9 +399,6 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
|
|||
lmi_swap_cntl = 0;
|
||||
mp_swap_cntl = 0;
|
||||
|
||||
amdgpu_asic_set_uvd_clocks(adev, 10000, 10000);
|
||||
uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE);
|
||||
uvd_v6_0_enable_mgcg(adev, true);
|
||||
uvd_v6_0_mc_resume(adev);
|
||||
|
||||
/* disable interupt */
|
||||
|
@ -554,6 +553,8 @@ static void uvd_v6_0_stop(struct amdgpu_device *adev)
|
|||
|
||||
/* Unstall UMC and register bus */
|
||||
WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
|
||||
|
||||
WREG32(mmUVD_STATUS, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1018,9 +1019,6 @@ static int uvd_v6_0_set_clockgating_state(void *handle,
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
|
||||
|
||||
if (!(adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG))
|
||||
return 0;
|
||||
|
||||
if (enable) {
|
||||
/* wait for STATUS to clear */
|
||||
if (uvd_v6_0_wait_for_idle(handle))
|
||||
|
@ -1049,9 +1047,6 @@ static int uvd_v6_0_set_powergating_state(void *handle,
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret = 0;
|
||||
|
||||
if (!(adev->pg_flags & AMD_PG_SUPPORT_UVD))
|
||||
return 0;
|
||||
|
||||
WREG32(mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK);
|
||||
|
||||
if (state == AMD_PG_STATE_GATE) {
|
||||
|
|
|
@ -42,10 +42,9 @@
|
|||
#define VCE_V2_0_DATA_SIZE (23552 * AMDGPU_MAX_VCE_HANDLES)
|
||||
#define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK 0x02
|
||||
|
||||
static void vce_v2_0_mc_resume(struct amdgpu_device *adev);
|
||||
static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev);
|
||||
static void vce_v2_0_set_irq_funcs(struct amdgpu_device *adev);
|
||||
static int vce_v2_0_wait_for_idle(void *handle);
|
||||
|
||||
/**
|
||||
* vce_v2_0_ring_get_rptr - get read pointer
|
||||
*
|
||||
|
@ -140,6 +139,86 @@ static int vce_v2_0_firmware_loaded(struct amdgpu_device *adev)
|
|||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void vce_v2_0_disable_cg(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 7);
|
||||
}
|
||||
|
||||
static void vce_v2_0_init_cg(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_A);
|
||||
tmp &= ~0xfff;
|
||||
tmp |= ((0 << 0) | (4 << 4));
|
||||
tmp |= 0x40000;
|
||||
WREG32(mmVCE_CLOCK_GATING_A, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
|
||||
tmp &= ~0xfff;
|
||||
tmp |= ((0 << 0) | (4 << 4));
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_B);
|
||||
tmp |= 0x10;
|
||||
tmp &= ~0x100000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
}
|
||||
|
||||
static void vce_v2_0_mc_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t addr = adev->vce.gpu_addr;
|
||||
uint32_t size;
|
||||
|
||||
WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
|
||||
WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
|
||||
WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
|
||||
WREG32(mmVCE_CLOCK_GATING_B, 0xf7);
|
||||
|
||||
WREG32(mmVCE_LMI_CTRL, 0x00398000);
|
||||
WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
|
||||
WREG32(mmVCE_LMI_SWAP_CNTL, 0);
|
||||
WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
|
||||
WREG32(mmVCE_LMI_VM_CTRL, 0);
|
||||
|
||||
addr += AMDGPU_VCE_FIRMWARE_OFFSET;
|
||||
size = VCE_V2_0_FW_SIZE;
|
||||
WREG32(mmVCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
|
||||
WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
|
||||
|
||||
addr += size;
|
||||
size = VCE_V2_0_STACK_SIZE;
|
||||
WREG32(mmVCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);
|
||||
WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
|
||||
|
||||
addr += size;
|
||||
size = VCE_V2_0_DATA_SIZE;
|
||||
WREG32(mmVCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);
|
||||
WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
|
||||
|
||||
WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
|
||||
WREG32_FIELD(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, 1);
|
||||
}
|
||||
|
||||
static bool vce_v2_0_is_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
return !(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK);
|
||||
}
|
||||
|
||||
static int vce_v2_0_wait_for_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (vce_v2_0_is_idle(handle))
|
||||
return 0;
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* vce_v2_0_start - start VCE block
|
||||
*
|
||||
|
@ -152,11 +231,14 @@ static int vce_v2_0_start(struct amdgpu_device *adev)
|
|||
struct amdgpu_ring *ring;
|
||||
int r;
|
||||
|
||||
vce_v2_0_mc_resume(adev);
|
||||
|
||||
/* set BUSY flag */
|
||||
WREG32_P(mmVCE_STATUS, 1, ~1);
|
||||
|
||||
vce_v2_0_init_cg(adev);
|
||||
vce_v2_0_disable_cg(adev);
|
||||
|
||||
vce_v2_0_mc_resume(adev);
|
||||
|
||||
ring = &adev->vce.ring[0];
|
||||
WREG32(mmVCE_RB_RPTR, ring->wptr);
|
||||
WREG32(mmVCE_RB_WPTR, ring->wptr);
|
||||
|
@ -189,6 +271,145 @@ static int vce_v2_0_start(struct amdgpu_device *adev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vce_v2_0_stop(struct amdgpu_device *adev)
|
||||
{
|
||||
int i, j;
|
||||
int status;
|
||||
|
||||
if (vce_v2_0_lmi_clean(adev)) {
|
||||
DRM_INFO("vce is not idle \n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 100; ++j) {
|
||||
status = RREG32(mmVCE_FW_REG_STATUS);
|
||||
if (!(status & 1))
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
if (vce_v2_0_wait_for_idle(adev)) {
|
||||
DRM_INFO("VCE is busy, Can't set clock gateing");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Stall UMC and register bus before resetting VCPU */
|
||||
WREG32_P(mmVCE_LMI_CTRL2, 1 << 8, ~(1 << 8));
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 100; ++j) {
|
||||
status = RREG32(mmVCE_LMI_STATUS);
|
||||
if (status & 0x240)
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
WREG32_P(mmVCE_VCPU_CNTL, 0, ~0x80001);
|
||||
|
||||
/* put LMI, VCPU, RBC etc... into reset */
|
||||
WREG32_P(mmVCE_SOFT_RESET, 1, ~0x1);
|
||||
|
||||
WREG32(mmVCE_STATUS, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vce_v2_0_set_sw_cg(struct amdgpu_device *adev, bool gated)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
if (gated) {
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_B);
|
||||
tmp |= 0xe70000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
|
||||
tmp |= 0xff000000;
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
|
||||
tmp &= ~0x3fc;
|
||||
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
|
||||
|
||||
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
|
||||
} else {
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_B);
|
||||
tmp |= 0xe7;
|
||||
tmp &= ~0xe70000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
|
||||
tmp |= 0x1fe000;
|
||||
tmp &= ~0xff000000;
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
|
||||
tmp |= 0x3fc;
|
||||
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void vce_v2_0_set_dyn_cg(struct amdgpu_device *adev, bool gated)
|
||||
{
|
||||
u32 orig, tmp;
|
||||
|
||||
/* LMI_MC/LMI_UMC always set in dynamic,
|
||||
* set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {0, 0}
|
||||
*/
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_B);
|
||||
tmp &= ~0x00060006;
|
||||
|
||||
/* Exception for ECPU, IH, SEM, SYS blocks needs to be turned on/off by SW */
|
||||
if (gated) {
|
||||
tmp |= 0xe10000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
} else {
|
||||
tmp |= 0xe1;
|
||||
tmp &= ~0xe10000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
}
|
||||
|
||||
orig = tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
|
||||
tmp &= ~0x1fe000;
|
||||
tmp &= ~0xff000000;
|
||||
if (tmp != orig)
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
|
||||
|
||||
orig = tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
|
||||
tmp &= ~0x3fc;
|
||||
if (tmp != orig)
|
||||
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
|
||||
|
||||
/* set VCE_UENC_REG_CLOCK_GATING always in dynamic mode */
|
||||
WREG32(mmVCE_UENC_REG_CLOCK_GATING, 0x00);
|
||||
|
||||
if(gated)
|
||||
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
|
||||
}
|
||||
|
||||
static void vce_v2_0_enable_mgcg(struct amdgpu_device *adev, bool enable,
|
||||
bool sw_cg)
|
||||
{
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)) {
|
||||
if (sw_cg)
|
||||
vce_v2_0_set_sw_cg(adev, true);
|
||||
else
|
||||
vce_v2_0_set_dyn_cg(adev, true);
|
||||
} else {
|
||||
vce_v2_0_disable_cg(adev);
|
||||
|
||||
if (sw_cg)
|
||||
vce_v2_0_set_sw_cg(adev, false);
|
||||
else
|
||||
vce_v2_0_set_dyn_cg(adev, false);
|
||||
}
|
||||
}
|
||||
|
||||
static int vce_v2_0_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
@ -254,11 +475,8 @@ static int vce_v2_0_hw_init(void *handle)
|
|||
int r, i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = vce_v2_0_start(adev);
|
||||
/* this error mean vcpu not in running state, so just skip ring test, not stop driver initialize */
|
||||
if (r)
|
||||
return 0;
|
||||
|
||||
amdgpu_asic_set_vce_clocks(adev, 10000, 10000);
|
||||
vce_v2_0_enable_mgcg(adev, true, false);
|
||||
for (i = 0; i < adev->vce.num_rings; i++)
|
||||
adev->vce.ring[i].ready = false;
|
||||
|
||||
|
@ -312,190 +530,6 @@ static int vce_v2_0_resume(void *handle)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void vce_v2_0_set_sw_cg(struct amdgpu_device *adev, bool gated)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
if (gated) {
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_B);
|
||||
tmp |= 0xe70000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
|
||||
tmp |= 0xff000000;
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
|
||||
tmp &= ~0x3fc;
|
||||
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
|
||||
|
||||
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
|
||||
} else {
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_B);
|
||||
tmp |= 0xe7;
|
||||
tmp &= ~0xe70000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
|
||||
tmp |= 0x1fe000;
|
||||
tmp &= ~0xff000000;
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
|
||||
tmp |= 0x3fc;
|
||||
WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static void vce_v2_0_set_dyn_cg(struct amdgpu_device *adev, bool gated)
|
||||
{
|
||||
if (vce_v2_0_wait_for_idle(adev)) {
|
||||
DRM_INFO("VCE is busy, Can't set clock gateing");
|
||||
return;
|
||||
}
|
||||
|
||||
WREG32_P(mmVCE_LMI_CTRL2, 0x100, ~0x100);
|
||||
|
||||
if (vce_v2_0_lmi_clean(adev)) {
|
||||
DRM_INFO("LMI is busy, Can't set clock gateing");
|
||||
return;
|
||||
}
|
||||
|
||||
WREG32_P(mmVCE_VCPU_CNTL, 0, ~VCE_VCPU_CNTL__CLK_EN_MASK);
|
||||
WREG32_P(mmVCE_SOFT_RESET,
|
||||
VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
|
||||
~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
|
||||
WREG32(mmVCE_STATUS, 0);
|
||||
|
||||
if (gated)
|
||||
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
|
||||
/* LMI_MC/LMI_UMC always set in dynamic, set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {0, 0} */
|
||||
if (gated) {
|
||||
/* Force CLOCK OFF , set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {*, 1} */
|
||||
WREG32(mmVCE_CLOCK_GATING_B, 0xe90010);
|
||||
} else {
|
||||
/* Force CLOCK ON, set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {1, 0} */
|
||||
WREG32(mmVCE_CLOCK_GATING_B, 0x800f1);
|
||||
}
|
||||
|
||||
/* Set VCE_UENC_CLOCK_GATING always in dynamic mode {*_FORCE_ON, *_FORCE_OFF} = {0, 0}*/;
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, 0x40);
|
||||
|
||||
/* set VCE_UENC_REG_CLOCK_GATING always in dynamic mode */
|
||||
WREG32(mmVCE_UENC_REG_CLOCK_GATING, 0x00);
|
||||
|
||||
WREG32_P(mmVCE_LMI_CTRL2, 0, ~0x100);
|
||||
if(!gated) {
|
||||
WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK);
|
||||
mdelay(100);
|
||||
WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
|
||||
|
||||
vce_v2_0_firmware_loaded(adev);
|
||||
WREG32_P(mmVCE_STATUS, 0, ~VCE_STATUS__JOB_BUSY_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
static void vce_v2_0_disable_cg(struct amdgpu_device *adev)
|
||||
{
|
||||
WREG32(mmVCE_CGTT_CLK_OVERRIDE, 7);
|
||||
}
|
||||
|
||||
static void vce_v2_0_enable_mgcg(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
bool sw_cg = false;
|
||||
|
||||
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)) {
|
||||
if (sw_cg)
|
||||
vce_v2_0_set_sw_cg(adev, true);
|
||||
else
|
||||
vce_v2_0_set_dyn_cg(adev, true);
|
||||
} else {
|
||||
vce_v2_0_disable_cg(adev);
|
||||
|
||||
if (sw_cg)
|
||||
vce_v2_0_set_sw_cg(adev, false);
|
||||
else
|
||||
vce_v2_0_set_dyn_cg(adev, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void vce_v2_0_init_cg(struct amdgpu_device *adev)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_A);
|
||||
tmp &= ~0xfff;
|
||||
tmp |= ((0 << 0) | (4 << 4));
|
||||
tmp |= 0x40000;
|
||||
WREG32(mmVCE_CLOCK_GATING_A, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
|
||||
tmp &= ~0xfff;
|
||||
tmp |= ((0 << 0) | (4 << 4));
|
||||
WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
|
||||
|
||||
tmp = RREG32(mmVCE_CLOCK_GATING_B);
|
||||
tmp |= 0x10;
|
||||
tmp &= ~0x100000;
|
||||
WREG32(mmVCE_CLOCK_GATING_B, tmp);
|
||||
}
|
||||
|
||||
static void vce_v2_0_mc_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
uint64_t addr = adev->vce.gpu_addr;
|
||||
uint32_t size;
|
||||
|
||||
WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
|
||||
WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
|
||||
WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
|
||||
WREG32(mmVCE_CLOCK_GATING_B, 0xf7);
|
||||
|
||||
WREG32(mmVCE_LMI_CTRL, 0x00398000);
|
||||
WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
|
||||
WREG32(mmVCE_LMI_SWAP_CNTL, 0);
|
||||
WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
|
||||
WREG32(mmVCE_LMI_VM_CTRL, 0);
|
||||
|
||||
addr += AMDGPU_VCE_FIRMWARE_OFFSET;
|
||||
size = VCE_V2_0_FW_SIZE;
|
||||
WREG32(mmVCE_VCPU_CACHE_OFFSET0, addr & 0x7fffffff);
|
||||
WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
|
||||
|
||||
addr += size;
|
||||
size = VCE_V2_0_STACK_SIZE;
|
||||
WREG32(mmVCE_VCPU_CACHE_OFFSET1, addr & 0x7fffffff);
|
||||
WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
|
||||
|
||||
addr += size;
|
||||
size = VCE_V2_0_DATA_SIZE;
|
||||
WREG32(mmVCE_VCPU_CACHE_OFFSET2, addr & 0x7fffffff);
|
||||
WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
|
||||
|
||||
WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
|
||||
WREG32_FIELD(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, 1);
|
||||
|
||||
vce_v2_0_init_cg(adev);
|
||||
}
|
||||
|
||||
static bool vce_v2_0_is_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
return !(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK);
|
||||
}
|
||||
|
||||
static int vce_v2_0_wait_for_idle(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < adev->usec_timeout; i++) {
|
||||
if (vce_v2_0_is_idle(handle))
|
||||
return 0;
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int vce_v2_0_soft_reset(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
@ -539,33 +573,20 @@ static int vce_v2_0_process_interrupt(struct amdgpu_device *adev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void vce_v2_0_set_bypass_mode(struct amdgpu_device *adev, bool enable)
|
||||
{
|
||||
u32 tmp = RREG32_SMC(ixGCK_DFS_BYPASS_CNTL);
|
||||
|
||||
if (enable)
|
||||
tmp |= GCK_DFS_BYPASS_CNTL__BYPASSECLK_MASK;
|
||||
else
|
||||
tmp &= ~GCK_DFS_BYPASS_CNTL__BYPASSECLK_MASK;
|
||||
|
||||
WREG32_SMC(ixGCK_DFS_BYPASS_CNTL, tmp);
|
||||
}
|
||||
|
||||
|
||||
static int vce_v2_0_set_clockgating_state(void *handle,
|
||||
enum amd_clockgating_state state)
|
||||
{
|
||||
bool gate = false;
|
||||
bool sw_cg = false;
|
||||
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
|
||||
|
||||
|
||||
vce_v2_0_set_bypass_mode(adev, enable);
|
||||
|
||||
if (state == AMD_CG_STATE_GATE)
|
||||
if (state == AMD_CG_STATE_GATE) {
|
||||
gate = true;
|
||||
sw_cg = true;
|
||||
}
|
||||
|
||||
vce_v2_0_enable_mgcg(adev, gate);
|
||||
vce_v2_0_enable_mgcg(adev, gate, sw_cg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -582,12 +603,8 @@ static int vce_v2_0_set_powergating_state(void *handle,
|
|||
*/
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (!(adev->pg_flags & AMD_PG_SUPPORT_VCE))
|
||||
return 0;
|
||||
|
||||
if (state == AMD_PG_STATE_GATE)
|
||||
/* XXX do we need a vce_v2_0_stop()? */
|
||||
return 0;
|
||||
return vce_v2_0_stop(adev);
|
||||
else
|
||||
return vce_v2_0_start(adev);
|
||||
}
|
||||
|
|
|
@ -230,10 +230,6 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
|
|||
struct amdgpu_ring *ring;
|
||||
int idx, r;
|
||||
|
||||
vce_v3_0_override_vce_clock_gating(adev, true);
|
||||
if (!(adev->flags & AMD_IS_APU))
|
||||
amdgpu_asic_set_vce_clocks(adev, 10000, 10000);
|
||||
|
||||
ring = &adev->vce.ring[0];
|
||||
WREG32(mmVCE_RB_RPTR, ring->wptr);
|
||||
WREG32(mmVCE_RB_WPTR, ring->wptr);
|
||||
|
@ -436,9 +432,9 @@ static int vce_v3_0_hw_init(void *handle)
|
|||
int r, i;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = vce_v3_0_start(adev);
|
||||
if (r)
|
||||
return r;
|
||||
vce_v3_0_override_vce_clock_gating(adev, true);
|
||||
if (!(adev->flags & AMD_IS_APU))
|
||||
amdgpu_asic_set_vce_clocks(adev, 10000, 10000);
|
||||
|
||||
for (i = 0; i < adev->vce.num_rings; i++)
|
||||
adev->vce.ring[i].ready = false;
|
||||
|
@ -766,12 +762,11 @@ static int vce_v3_0_set_powergating_state(void *handle,
|
|||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
int ret = 0;
|
||||
|
||||
if (!(adev->pg_flags & AMD_PG_SUPPORT_VCE))
|
||||
return 0;
|
||||
|
||||
if (state == AMD_PG_STATE_GATE) {
|
||||
ret = vce_v3_0_stop(adev);
|
||||
if (ret)
|
||||
goto out;
|
||||
adev->vce.is_powergated = true;
|
||||
/* XXX do we need a vce_v3_0_stop()? */
|
||||
} else {
|
||||
ret = vce_v3_0_start(adev);
|
||||
if (ret)
|
||||
|
|
|
@ -1310,5 +1310,6 @@
|
|||
#define ixROM_SW_DATA_62 0xc060012c
|
||||
#define ixROM_SW_DATA_63 0xc0600130
|
||||
#define ixROM_SW_DATA_64 0xc0600134
|
||||
#define ixCURRENT_PG_STATUS 0xc020029c
|
||||
|
||||
#endif /* SMU_7_0_1_D_H */
|
||||
|
|
|
@ -161,28 +161,25 @@ int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
|
|||
{
|
||||
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
|
||||
|
||||
if (cz_hwmgr->uvd_power_gated == bgate)
|
||||
return 0;
|
||||
|
||||
cz_hwmgr->uvd_power_gated = bgate;
|
||||
|
||||
if (bgate) {
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_GATE);
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_GATE);
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_GATE);
|
||||
cz_dpm_update_uvd_dpm(hwmgr, true);
|
||||
cz_dpm_powerdown_uvd(hwmgr);
|
||||
} else {
|
||||
cz_dpm_powerup_uvd(hwmgr);
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
cz_dpm_update_uvd_dpm(hwmgr, false);
|
||||
}
|
||||
|
||||
|
@ -193,47 +190,34 @@ int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
|
|||
{
|
||||
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
|
||||
|
||||
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_VCEPowerGating)) {
|
||||
if (cz_hwmgr->vce_power_gated != bgate) {
|
||||
if (bgate) {
|
||||
cgs_set_clockgating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
cgs_set_powergating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_GATE);
|
||||
cz_enable_disable_vce_dpm(hwmgr, false);
|
||||
cz_dpm_powerdown_vce(hwmgr);
|
||||
cz_hwmgr->vce_power_gated = true;
|
||||
} else {
|
||||
cz_dpm_powerup_vce(hwmgr);
|
||||
cz_hwmgr->vce_power_gated = false;
|
||||
cgs_set_powergating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
cgs_set_clockgating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
cz_dpm_update_vce_dpm(hwmgr);
|
||||
cz_enable_disable_vce_dpm(hwmgr, true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (bgate) {
|
||||
cgs_set_powergating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_GATE);
|
||||
cgs_set_clockgating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
cz_enable_disable_vce_dpm(hwmgr, false);
|
||||
cz_dpm_powerdown_vce(hwmgr);
|
||||
cz_hwmgr->vce_power_gated = true;
|
||||
} else {
|
||||
cz_hwmgr->vce_power_gated = bgate;
|
||||
cz_dpm_powerup_vce(hwmgr);
|
||||
cz_hwmgr->vce_power_gated = false;
|
||||
cgs_set_clockgating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
cgs_set_powergating_state(
|
||||
hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
cz_dpm_update_vce_dpm(hwmgr);
|
||||
cz_enable_disable_vce_dpm(hwmgr, !bgate);
|
||||
cz_enable_disable_vce_dpm(hwmgr, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cz_hwmgr->vce_power_gated)
|
||||
cz_dpm_update_vce_dpm(hwmgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,22 +147,22 @@ int smu7_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
|
|||
data->uvd_power_gated = bgate;
|
||||
|
||||
if (bgate) {
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_GATE);
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_PG_STATE_GATE);
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_GATE);
|
||||
smu7_update_uvd_dpm(hwmgr, true);
|
||||
smu7_powerdown_uvd(hwmgr);
|
||||
} else {
|
||||
smu7_powerup_uvd(hwmgr);
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_UVD,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
smu7_update_uvd_dpm(hwmgr, false);
|
||||
}
|
||||
|
||||
|
@ -173,12 +173,12 @@ int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
|
|||
{
|
||||
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
|
||||
|
||||
if (data->vce_power_gated == bgate)
|
||||
return 0;
|
||||
|
||||
data->vce_power_gated = bgate;
|
||||
|
||||
if (bgate) {
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_GATE);
|
||||
|
@ -186,10 +186,13 @@ int smu7_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
|
|||
smu7_powerdown_vce(hwmgr);
|
||||
} else {
|
||||
smu7_powerup_vce(hwmgr);
|
||||
smu7_update_vce_dpm(hwmgr, false);
|
||||
cgs_set_clockgating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_CG_STATE_UNGATE);
|
||||
cgs_set_powergating_state(hwmgr->device,
|
||||
AMD_IP_BLOCK_TYPE_VCE,
|
||||
AMD_PG_STATE_UNGATE);
|
||||
smu7_update_vce_dpm(hwmgr, false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2624,6 +2624,7 @@ static int smu7_force_dpm_level(struct pp_hwmgr *hwmgr,
|
|||
smu7_force_clock_level(hwmgr, PP_SCLK, 1<<sclk_mask);
|
||||
smu7_force_clock_level(hwmgr, PP_MCLK, 1<<mclk_mask);
|
||||
smu7_force_clock_level(hwmgr, PP_PCIE, 1<<pcie_mask);
|
||||
|
||||
break;
|
||||
case AMD_DPM_FORCED_LEVEL_MANUAL:
|
||||
hwmgr->dpm_level = level;
|
||||
|
@ -2633,9 +2634,9 @@ static int smu7_force_dpm_level(struct pp_hwmgr *hwmgr,
|
|||
break;
|
||||
}
|
||||
|
||||
if (level & (AMD_DPM_FORCED_LEVEL_PROFILE_PEAK | AMD_DPM_FORCED_LEVEL_HIGH))
|
||||
if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->saved_dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
|
||||
smu7_fan_ctrl_set_fan_speed_percent(hwmgr, 100);
|
||||
else
|
||||
else if (level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->saved_dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
|
||||
smu7_fan_ctrl_reset_fan_speed_to_default(hwmgr);
|
||||
|
||||
return 0;
|
||||
|
@ -4397,16 +4398,14 @@ static int smu7_get_sclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks)
|
|||
if (table_info == NULL || table_info->vdd_dep_on_sclk == NULL)
|
||||
return -EINVAL;
|
||||
dep_sclk_table = table_info->vdd_dep_on_sclk;
|
||||
for (i = 0; i < dep_sclk_table->count; i++) {
|
||||
for (i = 0; i < dep_sclk_table->count; i++)
|
||||
clocks->clock[i] = dep_sclk_table->entries[i].clk;
|
||||
clocks->count++;
|
||||
}
|
||||
clocks->count = dep_sclk_table->count;
|
||||
} else if (hwmgr->pp_table_version == PP_TABLE_V0) {
|
||||
sclk_table = hwmgr->dyn_state.vddc_dependency_on_sclk;
|
||||
for (i = 0; i < sclk_table->count; i++) {
|
||||
for (i = 0; i < sclk_table->count; i++)
|
||||
clocks->clock[i] = sclk_table->entries[i].clk;
|
||||
clocks->count++;
|
||||
}
|
||||
clocks->count = sclk_table->count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -4440,14 +4439,13 @@ static int smu7_get_mclks(struct pp_hwmgr *hwmgr, struct amd_pp_clocks *clocks)
|
|||
clocks->clock[i] = dep_mclk_table->entries[i].clk;
|
||||
clocks->latency[i] = smu7_get_mem_latency(hwmgr,
|
||||
dep_mclk_table->entries[i].clk);
|
||||
clocks->count++;
|
||||
}
|
||||
clocks->count = dep_mclk_table->count;
|
||||
} else if (hwmgr->pp_table_version == PP_TABLE_V0) {
|
||||
mclk_table = hwmgr->dyn_state.vddc_dependency_on_mclk;
|
||||
for (i = 0; i < mclk_table->count; i++) {
|
||||
for (i = 0; i < mclk_table->count; i++)
|
||||
clocks->clock[i] = mclk_table->entries[i].clk;
|
||||
clocks->count++;
|
||||
}
|
||||
clocks->count = mclk_table->count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,10 @@ MODULE_FIRMWARE("amdgpu/tonga_k_smc.bin");
|
|||
MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_smc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_smc_sk.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris10_k_smc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_smc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_smc_sk.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris11_k_smc.bin");
|
||||
MODULE_FIRMWARE("amdgpu/polaris12_smc.bin");
|
||||
|
||||
|
||||
|
|
|
@ -638,10 +638,8 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
|
|||
vhdr->ImageLength,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!rdev->bios) {
|
||||
kfree(rdev->bios);
|
||||
if (!rdev->bios)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data)
|
|||
memset(&data[5], 0, 44);
|
||||
memcpy(&data[16], &sign[1], rdev->vce_fw->size - sizeof(*sign));
|
||||
|
||||
data += le32_to_cpu(data[4]) / 4;
|
||||
data += (le32_to_cpu(sign->len) + 64) / 4;
|
||||
data[0] = sign->val[i].sigval[0];
|
||||
data[1] = sign->val[i].sigval[1];
|
||||
data[2] = sign->val[i].sigval[2];
|
||||
|
|
Loading…
Reference in New Issue