forked from Minki/linux
Merge branch 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux into drm-fixes
Lots of misc bug fixes for radeon and amdgpu and one for ttm. - fix vram info fetching on Fiji and unposted boards - additional vblank fixes from the conversion to drm_vblank_on/off - UVD dGPU suspend and resume fixes - lots of powerplay fixes - fix a fence leak in the pageflip code - ttm fix for platforms where CPU is 32 bit, but physical addresses are >32bits * 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux: (21 commits) drm/amdgpu: total vram size also reduces pin size drm/amd/powerplay: add uvd/vce dpm enabling flag default. drm/amd/powerplay: fix issue that resume back, dpm can't work on FIJI. drm/amdgpu: save and restore the firwmware cache part when suspend resume drm/amdgpu: save and restore UVD context with suspend and resume drm/ttm: use phys_addr_t for ttm_bus_placement drm/radeon: Only call drm_vblank_on/off between drm_vblank_init/cleanup drm/amdgpu: fence wait old rcu slot drm/amdgpu: fix leaking fence in the pageflip code drm/amdgpu: print vram type rather than just DDR drm/amdgpu/gmc: use proper register for vram type on Fiji drm/amdgpu/gmc: move vram type fetching into sw_init drm/amdgpu: Set vblank_disable_allowed = true drm/radeon: Set vblank_disable_allowed = true drm/amd/powerplay: Need to change boot to performance state in resume. drm/amd/powerplay: add new Fiji function for not setting same ps. drm/amdgpu: check dpm state before pm system fs initialized. drm/amd/powerplay: notify amdgpu whether dpm is enabled or not. drm/amdgpu: Not support disable dpm in powerplay. drm/amdgpu: add an cgs interface to notify amdgpu the dpm state. ...
This commit is contained in:
commit
fd8c61ebd4
@ -1591,6 +1591,7 @@ struct amdgpu_uvd {
|
||||
struct amdgpu_bo *vcpu_bo;
|
||||
void *cpu_addr;
|
||||
uint64_t gpu_addr;
|
||||
void *saved_bo;
|
||||
atomic_t handles[AMDGPU_MAX_UVD_HANDLES];
|
||||
struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES];
|
||||
struct delayed_work idle_work;
|
||||
|
@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
|
||||
struct drm_device *ddev = adev->ddev;
|
||||
struct drm_crtc *crtc;
|
||||
uint32_t line_time_us, vblank_lines;
|
||||
struct cgs_mode_info *mode_info;
|
||||
|
||||
if (info == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
mode_info = info->mode_info;
|
||||
|
||||
if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
|
||||
list_for_each_entry(crtc,
|
||||
&ddev->mode_config.crtc_list, head) {
|
||||
@ -828,7 +831,7 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
|
||||
info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
|
||||
info->display_count++;
|
||||
}
|
||||
if (info->mode_info != NULL &&
|
||||
if (mode_info != NULL &&
|
||||
crtc->enabled && amdgpu_crtc->enabled &&
|
||||
amdgpu_crtc->hw_mode.clock) {
|
||||
line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
|
||||
@ -836,10 +839,10 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
|
||||
vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
|
||||
amdgpu_crtc->hw_mode.crtc_vdisplay +
|
||||
(amdgpu_crtc->v_border * 2);
|
||||
info->mode_info->vblank_time_us = vblank_lines * line_time_us;
|
||||
info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
|
||||
info->mode_info->ref_clock = adev->clock.spll.reference_freq;
|
||||
info->mode_info++;
|
||||
mode_info->vblank_time_us = vblank_lines * line_time_us;
|
||||
mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
|
||||
mode_info->ref_clock = adev->clock.spll.reference_freq;
|
||||
mode_info = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int amdgpu_cgs_notify_dpm_enabled(void *cgs_device, bool enabled)
|
||||
{
|
||||
CGS_FUNC_ADEV;
|
||||
|
||||
adev->pm.dpm_enabled = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief evaluate acpi namespace object, handle or pathname must be valid
|
||||
* \param cgs_device
|
||||
* \param info input/output arguments for the control method
|
||||
@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
|
||||
amdgpu_cgs_set_powergating_state,
|
||||
amdgpu_cgs_set_clockgating_state,
|
||||
amdgpu_cgs_get_active_displays_info,
|
||||
amdgpu_cgs_notify_dpm_enabled,
|
||||
amdgpu_cgs_call_acpi_method,
|
||||
amdgpu_cgs_query_system_info,
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
|
||||
if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback))
|
||||
return true;
|
||||
|
||||
fence_put(*f);
|
||||
fence_put(fence);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
struct amdgpu_fence *fence;
|
||||
struct fence **ptr;
|
||||
struct fence *old, **ptr;
|
||||
uint32_t seq;
|
||||
|
||||
fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL);
|
||||
@ -141,7 +141,11 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
|
||||
/* This function can't be called concurrently anyway, otherwise
|
||||
* emitting the fence would mess up the hardware ring buffer.
|
||||
*/
|
||||
BUG_ON(rcu_dereference_protected(*ptr, 1));
|
||||
old = rcu_dereference_protected(*ptr, 1);
|
||||
if (old && !fence_is_signaled(old)) {
|
||||
DRM_INFO("rcu slot is busy\n");
|
||||
fence_wait(old, false);
|
||||
}
|
||||
|
||||
rcu_assign_pointer(*ptr, fence_get(&fence->base));
|
||||
|
||||
|
@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
adev->ddev->vblank_disable_allowed = true;
|
||||
|
||||
/* enable msi */
|
||||
adev->irq.msi_enabled = false;
|
||||
|
||||
|
@ -382,6 +382,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
||||
struct drm_amdgpu_info_vram_gtt vram_gtt;
|
||||
|
||||
vram_gtt.vram_size = adev->mc.real_vram_size;
|
||||
vram_gtt.vram_size -= adev->vram_pin_size;
|
||||
vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size;
|
||||
vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size;
|
||||
vram_gtt.gtt_size = adev->mc.gtt_size;
|
||||
|
@ -476,6 +476,17 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev)
|
||||
return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM);
|
||||
}
|
||||
|
||||
static const char *amdgpu_vram_names[] = {
|
||||
"UNKNOWN",
|
||||
"GDDR1",
|
||||
"DDR2",
|
||||
"GDDR3",
|
||||
"GDDR4",
|
||||
"GDDR5",
|
||||
"HBM",
|
||||
"DDR3"
|
||||
};
|
||||
|
||||
int amdgpu_bo_init(struct amdgpu_device *adev)
|
||||
{
|
||||
/* Add an MTRR for the VRAM */
|
||||
@ -484,8 +495,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
|
||||
DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
|
||||
adev->mc.mc_vram_size >> 20,
|
||||
(unsigned long long)adev->mc.aper_size >> 20);
|
||||
DRM_INFO("RAM width %dbits DDR\n",
|
||||
adev->mc.vram_width);
|
||||
DRM_INFO("RAM width %dbits %s\n",
|
||||
adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]);
|
||||
return amdgpu_ttm_init(adev);
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle)
|
||||
adev->powerplay.pp_handle);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_POWERPLAY
|
||||
if (adev->pp_enabled) {
|
||||
if (adev->pp_enabled && adev->pm.dpm_enabled) {
|
||||
amdgpu_pm_sysfs_init(adev);
|
||||
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);
|
||||
}
|
||||
@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle)
|
||||
adev->powerplay.pp_handle);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_POWERPLAY
|
||||
if (adev->pp_enabled) {
|
||||
if (amdgpu_dpm == 0)
|
||||
adev->pm.dpm_enabled = false;
|
||||
else
|
||||
adev->pm.dpm_enabled = true;
|
||||
}
|
||||
if (adev->pp_enabled)
|
||||
adev->pm.dpm_enabled = true;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
@ -241,32 +241,28 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
|
||||
|
||||
int amdgpu_uvd_suspend(struct amdgpu_device *adev)
|
||||
{
|
||||
struct amdgpu_ring *ring = &adev->uvd.ring;
|
||||
int i, r;
|
||||
unsigned size;
|
||||
void *ptr;
|
||||
int i;
|
||||
|
||||
if (adev->uvd.vcpu_bo == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) {
|
||||
uint32_t handle = atomic_read(&adev->uvd.handles[i]);
|
||||
if (handle != 0) {
|
||||
struct fence *fence;
|
||||
for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i)
|
||||
if (atomic_read(&adev->uvd.handles[i]))
|
||||
break;
|
||||
|
||||
amdgpu_uvd_note_usage(adev);
|
||||
if (i == AMDGPU_MAX_UVD_HANDLES)
|
||||
return 0;
|
||||
|
||||
r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence);
|
||||
if (r) {
|
||||
DRM_ERROR("Error destroying UVD (%d)!\n", r);
|
||||
continue;
|
||||
}
|
||||
size = amdgpu_bo_size(adev->uvd.vcpu_bo);
|
||||
ptr = adev->uvd.cpu_addr;
|
||||
|
||||
fence_wait(fence, false);
|
||||
fence_put(fence);
|
||||
adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
|
||||
if (!adev->uvd.saved_bo)
|
||||
return -ENOMEM;
|
||||
|
||||
adev->uvd.filp[i] = NULL;
|
||||
atomic_set(&adev->uvd.handles[i], 0);
|
||||
}
|
||||
}
|
||||
memcpy(adev->uvd.saved_bo, ptr, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -275,23 +271,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned size;
|
||||
void *ptr;
|
||||
const struct common_firmware_header *hdr;
|
||||
unsigned offset;
|
||||
|
||||
if (adev->uvd.vcpu_bo == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
|
||||
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
||||
memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
|
||||
(adev->uvd.fw->size) - offset);
|
||||
|
||||
size = amdgpu_bo_size(adev->uvd.vcpu_bo);
|
||||
size -= le32_to_cpu(hdr->ucode_size_bytes);
|
||||
ptr = adev->uvd.cpu_addr;
|
||||
ptr += le32_to_cpu(hdr->ucode_size_bytes);
|
||||
|
||||
memset(ptr, 0, size);
|
||||
if (adev->uvd.saved_bo != NULL) {
|
||||
memcpy(ptr, adev->uvd.saved_bo, size);
|
||||
kfree(adev->uvd.saved_bo);
|
||||
adev->uvd.saved_bo = NULL;
|
||||
} else {
|
||||
const struct common_firmware_header *hdr;
|
||||
unsigned offset;
|
||||
|
||||
hdr = (const struct common_firmware_header *)adev->uvd.fw->data;
|
||||
offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
|
||||
memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset,
|
||||
(adev->uvd.fw->size) - offset);
|
||||
size -= le32_to_cpu(hdr->ucode_size_bytes);
|
||||
ptr += le32_to_cpu(hdr->ucode_size_bytes);
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -903,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle)
|
||||
gmc_v7_0_set_gart_funcs(adev);
|
||||
gmc_v7_0_set_irq_funcs(adev);
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
} else {
|
||||
u32 tmp = RREG32(mmMC_SEQ_MISC0);
|
||||
tmp &= MC_SEQ_MISC0__MT__MASK;
|
||||
adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -927,6 +919,14 @@ static int gmc_v7_0_sw_init(void *handle)
|
||||
int dma_bits;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
} else {
|
||||
u32 tmp = RREG32(mmMC_SEQ_MISC0);
|
||||
tmp &= MC_SEQ_MISC0__MT__MASK;
|
||||
adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp);
|
||||
}
|
||||
|
||||
r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -863,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle)
|
||||
gmc_v8_0_set_gart_funcs(adev);
|
||||
gmc_v8_0_set_irq_funcs(adev);
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
} else {
|
||||
u32 tmp = RREG32(mmMC_SEQ_MISC0);
|
||||
tmp &= MC_SEQ_MISC0__MT__MASK;
|
||||
adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -881,12 +873,27 @@ static int gmc_v8_0_late_init(void *handle)
|
||||
return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
|
||||
}
|
||||
|
||||
#define mmMC_SEQ_MISC0_FIJI 0xA71
|
||||
|
||||
static int gmc_v8_0_sw_init(void *handle)
|
||||
{
|
||||
int r;
|
||||
int dma_bits;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
if (adev->flags & AMD_IS_APU) {
|
||||
adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN;
|
||||
} else {
|
||||
u32 tmp;
|
||||
|
||||
if (adev->asic_type == CHIP_FIJI)
|
||||
tmp = RREG32(mmMC_SEQ_MISC0_FIJI);
|
||||
else
|
||||
tmp = RREG32(mmMC_SEQ_MISC0);
|
||||
tmp &= MC_SEQ_MISC0__MT__MASK;
|
||||
adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp);
|
||||
}
|
||||
|
||||
r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle)
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_uvd_suspend(adev);
|
||||
r = uvd_v4_2_hw_fini(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = uvd_v4_2_hw_fini(adev);
|
||||
r = amdgpu_uvd_suspend(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle)
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = amdgpu_uvd_suspend(adev);
|
||||
r = uvd_v5_0_hw_fini(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = uvd_v5_0_hw_fini(adev);
|
||||
r = amdgpu_uvd_suspend(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle)
|
||||
int r;
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
|
||||
r = uvd_v6_0_hw_fini(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* Skip this for APU for now */
|
||||
if (!(adev->flags & AMD_IS_APU)) {
|
||||
r = amdgpu_uvd_suspend(adev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
r = uvd_v6_0_hw_fini(adev);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -589,6 +589,8 @@ typedef int(*cgs_get_active_displays_info)(
|
||||
void *cgs_device,
|
||||
struct cgs_display_info *info);
|
||||
|
||||
typedef int (*cgs_notify_dpm_enabled)(void *cgs_device, bool enabled);
|
||||
|
||||
typedef int (*cgs_call_acpi_method)(void *cgs_device,
|
||||
uint32_t acpi_method,
|
||||
uint32_t acpi_function,
|
||||
@ -644,6 +646,8 @@ struct cgs_ops {
|
||||
cgs_set_clockgating_state set_clockgating_state;
|
||||
/* display manager */
|
||||
cgs_get_active_displays_info get_active_displays_info;
|
||||
/* notify dpm enabled */
|
||||
cgs_notify_dpm_enabled notify_dpm_enabled;
|
||||
/* ACPI */
|
||||
cgs_call_acpi_method call_acpi_method;
|
||||
/* get system info */
|
||||
@ -734,8 +738,12 @@ struct cgs_device
|
||||
CGS_CALL(set_powergating_state, dev, block_type, state)
|
||||
#define cgs_set_clockgating_state(dev, block_type, state) \
|
||||
CGS_CALL(set_clockgating_state, dev, block_type, state)
|
||||
#define cgs_notify_dpm_enabled(dev, enabled) \
|
||||
CGS_CALL(notify_dpm_enabled, dev, enabled)
|
||||
|
||||
#define cgs_get_active_displays_info(dev, info) \
|
||||
CGS_CALL(get_active_displays_info, dev, info)
|
||||
|
||||
#define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) \
|
||||
CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size)
|
||||
#define cgs_query_system_info(dev, sys_info) \
|
||||
|
@ -137,14 +137,14 @@ static const pem_event_action *resume_event[] = {
|
||||
reset_display_configCounter_tasks,
|
||||
update_dal_configuration_tasks,
|
||||
vari_bright_resume_tasks,
|
||||
block_adjust_power_state_tasks,
|
||||
setup_asic_tasks,
|
||||
enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */
|
||||
enable_dynamic_state_management_tasks,
|
||||
enable_clock_power_gatings_tasks,
|
||||
enable_disable_bapm_tasks,
|
||||
initialize_thermal_controller_tasks,
|
||||
reset_boot_state_tasks,
|
||||
get_2d_performance_state_tasks,
|
||||
set_performance_state_tasks,
|
||||
adjust_power_state_tasks,
|
||||
enable_disable_fps_tasks,
|
||||
notify_hw_power_source_tasks,
|
||||
|
@ -2389,6 +2389,7 @@ static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
|
||||
|
||||
for(count = 0; count < table->VceLevelCount; count++) {
|
||||
table->VceLevel[count].Frequency = mm_table->entries[count].eclk;
|
||||
table->VceLevel[count].MinVoltage = 0;
|
||||
table->VceLevel[count].MinVoltage |=
|
||||
(mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
|
||||
table->VceLevel[count].MinVoltage |=
|
||||
@ -2465,6 +2466,7 @@ static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
|
||||
|
||||
for (count = 0; count < table->SamuLevelCount; count++) {
|
||||
/* not sure whether we need evclk or not */
|
||||
table->SamuLevel[count].MinVoltage = 0;
|
||||
table->SamuLevel[count].Frequency = mm_table->entries[count].samclock;
|
||||
table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
|
||||
VOLTAGE_SCALE) << VDDC_SHIFT;
|
||||
@ -2562,6 +2564,7 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
|
||||
table->UvdBootLevel = 0;
|
||||
|
||||
for (count = 0; count < table->UvdLevelCount; count++) {
|
||||
table->UvdLevel[count].MinVoltage = 0;
|
||||
table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
|
||||
table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
|
||||
table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
|
||||
@ -2900,6 +2903,8 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
|
||||
if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control)
|
||||
fiji_populate_smc_voltage_tables(hwmgr, table);
|
||||
|
||||
table->SystemFlags = 0;
|
||||
|
||||
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_AutomaticDCTransition))
|
||||
table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
|
||||
@ -2997,6 +3002,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
|
||||
table->MemoryThermThrottleEnable = 1;
|
||||
table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/
|
||||
table->PCIeGenInterval = 1;
|
||||
table->VRConfig = 0;
|
||||
|
||||
result = fiji_populate_vr_config(hwmgr, table);
|
||||
PP_ASSERT_WITH_CODE(0 == result,
|
||||
@ -5195,6 +5201,67 @@ static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr,
|
||||
return size;
|
||||
}
|
||||
|
||||
static inline bool fiji_are_power_levels_equal(const struct fiji_performance_level *pl1,
|
||||
const struct fiji_performance_level *pl2)
|
||||
{
|
||||
return ((pl1->memory_clock == pl2->memory_clock) &&
|
||||
(pl1->engine_clock == pl2->engine_clock) &&
|
||||
(pl1->pcie_gen == pl2->pcie_gen) &&
|
||||
(pl1->pcie_lane == pl2->pcie_lane));
|
||||
}
|
||||
|
||||
int fiji_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal)
|
||||
{
|
||||
const struct fiji_power_state *psa = cast_const_phw_fiji_power_state(pstate1);
|
||||
const struct fiji_power_state *psb = cast_const_phw_fiji_power_state(pstate2);
|
||||
int i;
|
||||
|
||||
if (equal == NULL || psa == NULL || psb == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* If the two states don't even have the same number of performance levels they cannot be the same state. */
|
||||
if (psa->performance_level_count != psb->performance_level_count) {
|
||||
*equal = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < psa->performance_level_count; i++) {
|
||||
if (!fiji_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) {
|
||||
/* If we have found even one performance level pair that is different the states are different. */
|
||||
*equal = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If all performance levels are the same try to use the UVD clocks to break the tie.*/
|
||||
*equal = ((psa->uvd_clks.vclk == psb->uvd_clks.vclk) && (psa->uvd_clks.dclk == psb->uvd_clks.dclk));
|
||||
*equal &= ((psa->vce_clks.evclk == psb->vce_clks.evclk) && (psa->vce_clks.ecclk == psb->vce_clks.ecclk));
|
||||
*equal &= (psa->sclk_threshold == psb->sclk_threshold);
|
||||
*equal &= (psa->acp_clk == psb->acp_clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
|
||||
bool is_update_required = false;
|
||||
struct cgs_display_info info = {0,0,NULL};
|
||||
|
||||
cgs_get_active_displays_info(hwmgr->device, &info);
|
||||
|
||||
if (data->display_timing.num_existing_displays != info.display_count)
|
||||
is_update_required = true;
|
||||
/* TO DO NEED TO GET DEEP SLEEP CLOCK FROM DAL
|
||||
if (phm_cap_enabled(hwmgr->hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
|
||||
cgs_get_min_clock_settings(hwmgr->device, &min_clocks);
|
||||
if(min_clocks.engineClockInSR != data->display_timing.minClockInSR)
|
||||
is_update_required = true;
|
||||
*/
|
||||
return is_update_required;
|
||||
}
|
||||
|
||||
|
||||
static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
|
||||
.backend_init = &fiji_hwmgr_backend_init,
|
||||
.backend_fini = &tonga_hwmgr_backend_fini,
|
||||
@ -5230,6 +5297,8 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
|
||||
.register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt,
|
||||
.set_fan_control_mode = fiji_set_fan_control_mode,
|
||||
.get_fan_control_mode = fiji_get_fan_control_mode,
|
||||
.check_states_equal = fiji_check_states_equal,
|
||||
.check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration,
|
||||
.get_pp_table = fiji_get_pp_table,
|
||||
.set_pp_table = fiji_set_pp_table,
|
||||
.force_clock_level = fiji_force_clock_level,
|
||||
|
@ -58,6 +58,9 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr)
|
||||
|
||||
phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress);
|
||||
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
|
||||
|
||||
if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) &&
|
||||
acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION))
|
||||
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
|
||||
@ -130,18 +133,25 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr,
|
||||
|
||||
int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
|
||||
{
|
||||
int ret = 1;
|
||||
bool enabled;
|
||||
PHM_FUNC_CHECK(hwmgr);
|
||||
|
||||
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
|
||||
PHM_PlatformCaps_TablelessHardwareInterface)) {
|
||||
if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable)
|
||||
return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
|
||||
ret = hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr);
|
||||
} else {
|
||||
return phm_dispatch_table(hwmgr,
|
||||
ret = phm_dispatch_table(hwmgr,
|
||||
&(hwmgr->enable_dynamic_state_management),
|
||||
NULL, NULL);
|
||||
}
|
||||
return 0;
|
||||
|
||||
enabled = ret == 0 ? true : false;
|
||||
|
||||
cgs_notify_dpm_enabled(hwmgr->device, enabled);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level)
|
||||
|
@ -275,13 +275,15 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
|
||||
atombios_blank_crtc(crtc, ATOM_DISABLE);
|
||||
drm_vblank_on(dev, radeon_crtc->crtc_id);
|
||||
if (dev->num_crtcs > radeon_crtc->crtc_id)
|
||||
drm_vblank_on(dev, radeon_crtc->crtc_id);
|
||||
radeon_crtc_load_lut(crtc);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
drm_vblank_off(dev, radeon_crtc->crtc_id);
|
||||
if (dev->num_crtcs > radeon_crtc->crtc_id)
|
||||
drm_vblank_off(dev, radeon_crtc->crtc_id);
|
||||
if (radeon_crtc->enabled)
|
||||
atombios_blank_crtc(crtc, ATOM_ENABLE);
|
||||
if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
|
||||
|
@ -291,6 +291,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
rdev->ddev->vblank_disable_allowed = true;
|
||||
|
||||
/* enable msi */
|
||||
rdev->msi_enabled = 0;
|
||||
|
||||
|
@ -331,13 +331,15 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||
RADEON_CRTC_DISP_REQ_EN_B));
|
||||
WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
|
||||
}
|
||||
drm_vblank_on(dev, radeon_crtc->crtc_id);
|
||||
if (dev->num_crtcs > radeon_crtc->crtc_id)
|
||||
drm_vblank_on(dev, radeon_crtc->crtc_id);
|
||||
radeon_crtc_load_lut(crtc);
|
||||
break;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
drm_vblank_off(dev, radeon_crtc->crtc_id);
|
||||
if (dev->num_crtcs > radeon_crtc->crtc_id)
|
||||
drm_vblank_off(dev, radeon_crtc->crtc_id);
|
||||
if (radeon_crtc->crtc_id)
|
||||
WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
|
||||
else {
|
||||
|
@ -92,7 +92,7 @@ struct ttm_placement {
|
||||
*/
|
||||
struct ttm_bus_placement {
|
||||
void *addr;
|
||||
unsigned long base;
|
||||
phys_addr_t base;
|
||||
unsigned long size;
|
||||
unsigned long offset;
|
||||
bool is_iomem;
|
||||
|
Loading…
Reference in New Issue
Block a user