Commit fd8c61eb authored by Dave Airlie's avatar Dave Airlie

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.
  ...
parents 30aab189 7c0ecda1
...@@ -1591,6 +1591,7 @@ struct amdgpu_uvd { ...@@ -1591,6 +1591,7 @@ struct amdgpu_uvd {
struct amdgpu_bo *vcpu_bo; struct amdgpu_bo *vcpu_bo;
void *cpu_addr; void *cpu_addr;
uint64_t gpu_addr; uint64_t gpu_addr;
void *saved_bo;
atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; atomic_t handles[AMDGPU_MAX_UVD_HANDLES];
struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES];
struct delayed_work idle_work; struct delayed_work idle_work;
......
...@@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, ...@@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
struct drm_device *ddev = adev->ddev; struct drm_device *ddev = adev->ddev;
struct drm_crtc *crtc; struct drm_crtc *crtc;
uint32_t line_time_us, vblank_lines; uint32_t line_time_us, vblank_lines;
struct cgs_mode_info *mode_info;
if (info == NULL) if (info == NULL)
return -EINVAL; return -EINVAL;
mode_info = info->mode_info;
if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
list_for_each_entry(crtc, list_for_each_entry(crtc,
&ddev->mode_config.crtc_list, head) { &ddev->mode_config.crtc_list, head) {
...@@ -828,7 +831,7 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, ...@@ -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->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
info->display_count++; info->display_count++;
} }
if (info->mode_info != NULL && if (mode_info != NULL &&
crtc->enabled && amdgpu_crtc->enabled && crtc->enabled && amdgpu_crtc->enabled &&
amdgpu_crtc->hw_mode.clock) { amdgpu_crtc->hw_mode.clock) {
line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / 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, ...@@ -836,10 +839,10 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
amdgpu_crtc->hw_mode.crtc_vdisplay + amdgpu_crtc->hw_mode.crtc_vdisplay +
(amdgpu_crtc->v_border * 2); (amdgpu_crtc->v_border * 2);
info->mode_info->vblank_time_us = vblank_lines * line_time_us; mode_info->vblank_time_us = vblank_lines * line_time_us;
info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
info->mode_info->ref_clock = adev->clock.spll.reference_freq; mode_info->ref_clock = adev->clock.spll.reference_freq;
info->mode_info++; mode_info = NULL;
} }
} }
} }
...@@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, ...@@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
return 0; 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 /** \brief evaluate acpi namespace object, handle or pathname must be valid
* \param cgs_device * \param cgs_device
* \param info input/output arguments for the control method * \param info input/output arguments for the control method
...@@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { ...@@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = {
amdgpu_cgs_set_powergating_state, amdgpu_cgs_set_powergating_state,
amdgpu_cgs_set_clockgating_state, amdgpu_cgs_set_clockgating_state,
amdgpu_cgs_get_active_displays_info, amdgpu_cgs_get_active_displays_info,
amdgpu_cgs_notify_dpm_enabled,
amdgpu_cgs_call_acpi_method, amdgpu_cgs_call_acpi_method,
amdgpu_cgs_query_system_info, amdgpu_cgs_query_system_info,
}; };
......
...@@ -57,7 +57,7 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work, ...@@ -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)) if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback))
return true; return true;
fence_put(*f); fence_put(fence);
return false; return false;
} }
......
...@@ -121,7 +121,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f) ...@@ -121,7 +121,7 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
{ {
struct amdgpu_device *adev = ring->adev; struct amdgpu_device *adev = ring->adev;
struct amdgpu_fence *fence; struct amdgpu_fence *fence;
struct fence **ptr; struct fence *old, **ptr;
uint32_t seq; uint32_t seq;
fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL);
...@@ -141,7 +141,11 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f) ...@@ -141,7 +141,11 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f)
/* This function can't be called concurrently anyway, otherwise /* This function can't be called concurrently anyway, otherwise
* emitting the fence would mess up the hardware ring buffer. * 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)); rcu_assign_pointer(*ptr, fence_get(&fence->base));
......
...@@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev) ...@@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev)
if (r) { if (r) {
return r; return r;
} }
adev->ddev->vblank_disable_allowed = true;
/* enable msi */ /* enable msi */
adev->irq.msi_enabled = false; adev->irq.msi_enabled = false;
......
...@@ -382,6 +382,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file ...@@ -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; struct drm_amdgpu_info_vram_gtt vram_gtt;
vram_gtt.vram_size = adev->mc.real_vram_size; 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->mc.visible_vram_size;
vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size; vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size;
vram_gtt.gtt_size = adev->mc.gtt_size; vram_gtt.gtt_size = adev->mc.gtt_size;
......
...@@ -476,6 +476,17 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev) ...@@ -476,6 +476,17 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev)
return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM); 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) int amdgpu_bo_init(struct amdgpu_device *adev)
{ {
/* Add an MTRR for the VRAM */ /* Add an MTRR for the VRAM */
...@@ -484,8 +495,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev) ...@@ -484,8 +495,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev)
DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n", DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
adev->mc.mc_vram_size >> 20, adev->mc.mc_vram_size >> 20,
(unsigned long long)adev->mc.aper_size >> 20); (unsigned long long)adev->mc.aper_size >> 20);
DRM_INFO("RAM width %dbits DDR\n", DRM_INFO("RAM width %dbits %s\n",
adev->mc.vram_width); adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]);
return amdgpu_ttm_init(adev); return amdgpu_ttm_init(adev);
} }
......
...@@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle) ...@@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle)
adev->powerplay.pp_handle); adev->powerplay.pp_handle);
#ifdef CONFIG_DRM_AMD_POWERPLAY #ifdef CONFIG_DRM_AMD_POWERPLAY
if (adev->pp_enabled) { if (adev->pp_enabled && adev->pm.dpm_enabled) {
amdgpu_pm_sysfs_init(adev); amdgpu_pm_sysfs_init(adev);
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL); amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);
} }
...@@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle) ...@@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle)
adev->powerplay.pp_handle); adev->powerplay.pp_handle);
#ifdef CONFIG_DRM_AMD_POWERPLAY #ifdef CONFIG_DRM_AMD_POWERPLAY
if (adev->pp_enabled) { if (adev->pp_enabled)
if (amdgpu_dpm == 0) adev->pm.dpm_enabled = true;
adev->pm.dpm_enabled = false;
else
adev->pm.dpm_enabled = true;
}
#endif #endif
return ret; return ret;
......
...@@ -241,32 +241,28 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) ...@@ -241,32 +241,28 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev)
int amdgpu_uvd_suspend(struct amdgpu_device *adev) int amdgpu_uvd_suspend(struct amdgpu_device *adev)
{ {
struct amdgpu_ring *ring = &adev->uvd.ring; unsigned size;
int i, r; void *ptr;
int i;
if (adev->uvd.vcpu_bo == NULL) if (adev->uvd.vcpu_bo == NULL)
return 0; return 0;
for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i)
uint32_t handle = atomic_read(&adev->uvd.handles[i]); if (atomic_read(&adev->uvd.handles[i]))
if (handle != 0) { break;
struct fence *fence;
amdgpu_uvd_note_usage(adev); if (i == AMDGPU_MAX_UVD_HANDLES)
return 0;
r = amdgpu_uvd_get_destroy_msg(ring, handle, false, &fence); size = amdgpu_bo_size(adev->uvd.vcpu_bo);
if (r) { ptr = adev->uvd.cpu_addr;
DRM_ERROR("Error destroying UVD (%d)!\n", r);
continue;
}
fence_wait(fence, false); adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL);
fence_put(fence); if (!adev->uvd.saved_bo)
return -ENOMEM;
adev->uvd.filp[i] = NULL; memcpy(adev->uvd.saved_bo, ptr, size);
atomic_set(&adev->uvd.handles[i], 0);
}
}
return 0; return 0;
} }
...@@ -275,23 +271,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) ...@@ -275,23 +271,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev)
{ {
unsigned size; unsigned size;
void *ptr; void *ptr;
const struct common_firmware_header *hdr;
unsigned offset;
if (adev->uvd.vcpu_bo == NULL) if (adev->uvd.vcpu_bo == NULL)
return -EINVAL; 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 = amdgpu_bo_size(adev->uvd.vcpu_bo);
size -= le32_to_cpu(hdr->ucode_size_bytes);
ptr = adev->uvd.cpu_addr; 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; return 0;
} }
......
...@@ -903,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle) ...@@ -903,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle)
gmc_v7_0_set_gart_funcs(adev); gmc_v7_0_set_gart_funcs(adev);
gmc_v7_0_set_irq_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; return 0;
} }
...@@ -927,6 +919,14 @@ static int gmc_v7_0_sw_init(void *handle) ...@@ -927,6 +919,14 @@ static int gmc_v7_0_sw_init(void *handle)
int dma_bits; int dma_bits;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; 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); r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
if (r) if (r)
return r; return r;
......
...@@ -863,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle) ...@@ -863,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle)
gmc_v8_0_set_gart_funcs(adev); gmc_v8_0_set_gart_funcs(adev);
gmc_v8_0_set_irq_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; return 0;
} }
...@@ -881,12 +873,27 @@ static int gmc_v8_0_late_init(void *handle) ...@@ -881,12 +873,27 @@ static int gmc_v8_0_late_init(void *handle)
return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); 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) static int gmc_v8_0_sw_init(void *handle)
{ {
int r; int r;
int dma_bits; int dma_bits;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; 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); r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault);
if (r) if (r)
return r; return r;
......
...@@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle) ...@@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle)
int r; int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = amdgpu_uvd_suspend(adev); r = uvd_v4_2_hw_fini(adev);
if (r) if (r)
return r; return r;
r = uvd_v4_2_hw_fini(adev); r = amdgpu_uvd_suspend(adev);
if (r) if (r)
return r; return r;
......
...@@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle) ...@@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle)
int r; int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
r = amdgpu_uvd_suspend(adev); r = uvd_v5_0_hw_fini(adev);
if (r) if (r)
return r; return r;
r = uvd_v5_0_hw_fini(adev); r = amdgpu_uvd_suspend(adev);
if (r) if (r)
return r; return r;
......
...@@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle) ...@@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle)
int r; int r;
struct amdgpu_device *adev = (struct amdgpu_device *)handle; 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 */ /* Skip this for APU for now */
if (!(adev->flags & AMD_IS_APU)) { if (!(adev->flags & AMD_IS_APU)) {
r = amdgpu_uvd_suspend(adev); r = amdgpu_uvd_suspend(adev);
if (r) if (r)
return r; return r;
} }
r = uvd_v6_0_hw_fini(adev);
if (r)
return r;
return r; return r;
} }
......
...@@ -589,6 +589,8 @@ typedef int(*cgs_get_active_displays_info)( ...@@ -589,6 +589,8 @@ typedef int(*cgs_get_active_displays_info)(
void *cgs_device, void *cgs_device,
struct cgs_display_info *info); 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, typedef int (*cgs_call_acpi_method)(void *cgs_device,
uint32_t acpi_method, uint32_t acpi_method,
uint32_t acpi_function, uint32_t acpi_function,
...@@ -644,6 +646,8 @@ struct cgs_ops { ...@@ -644,6 +646,8 @@ struct cgs_ops {
cgs_set_clockgating_state set_clockgating_state; cgs_set_clockgating_state set_clockgating_state;
/* display manager */ /* display manager */
cgs_get_active_displays_info get_active_displays_info; cgs_get_active_displays_info get_active_displays_info;
/* notify dpm enabled */
cgs_notify_dpm_enabled notify_dpm_enabled;
/* ACPI */ /* ACPI */
cgs_call_acpi_method call_acpi_method; cgs_call_acpi_method call_acpi_method;
/* get system info */ /* get system info */
...@@ -734,8 +738,12 @@ struct cgs_device ...@@ -734,8 +738,12 @@ struct cgs_device
CGS_CALL(set_powergating_state, dev, block_type, state) CGS_CALL(set_powergating_state, dev, block_type, state)
#define cgs_set_clockgating_state(dev, block_type, state) \ #define cgs_set_clockgating_state(dev, block_type, state) \
CGS_CALL(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) \ #define cgs_get_active_displays_info(dev, info) \
CGS_CALL(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) \ #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) 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) \ #define cgs_query_system_info(dev, sys_info) \
......
...@@ -137,14 +137,14 @@ static const pem_event_action *resume_event[] = { ...@@ -137,14 +137,14 @@ static const pem_event_action *resume_event[] = {
reset_display_configCounter_tasks, reset_display_configCounter_tasks,
update_dal_configuration_tasks, update_dal_configuration_tasks,
vari_bright_resume_tasks, vari_bright_resume_tasks,
block_adjust_power_state_tasks,
setup_asic_tasks, setup_asic_tasks,
enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */ enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */
enable_dynamic_state_management_tasks, enable_dynamic_state_management_tasks,
enable_clock_power_gatings_tasks, enable_clock_power_gatings_tasks,
enable_disable_bapm_tasks, enable_disable_bapm_tasks,
initialize_thermal_controller_tasks, initialize_thermal_controller_tasks,
reset_boot_state_tasks, get_2d_performance_state_tasks,
set_performance_state_tasks,
adjust_power_state_tasks, adjust_power_state_tasks,
enable_disable_fps_tasks, enable_disable_fps_tasks,
notify_hw_power_source_tasks, notify_hw_power_source_tasks,
......
...@@ -2389,6 +2389,7 @@ static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr, ...@@ -2389,6 +2389,7 @@ static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr,
for(count = 0; count < table->VceLevelCount; count++) { for(count = 0; count < table->VceLevelCount; count++) {
table->VceLevel[count].Frequency = mm_table->entries[count].eclk; table->VceLevel[count].Frequency = mm_table->entries[count].eclk;
table->VceLevel[count].MinVoltage = 0;
table->VceLevel[count].MinVoltage |= table->VceLevel[count].MinVoltage |=
(mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT;
table->VceLevel[count].MinVoltage |= table->VceLevel[count].MinVoltage |=
...@@ -2465,6 +2466,7 @@ static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr, ...@@ -2465,6 +2466,7 @@ static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr,
for (count = 0; count < table->SamuLevelCount; count++) { for (count = 0; count < table->SamuLevelCount; count++) {
/* not sure whether we need evclk or not */ /* 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].Frequency = mm_table->entries[count].samclock;
table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
VOLTAGE_SCALE) << VDDC_SHIFT; VOLTAGE_SCALE) << VDDC_SHIFT;
...@@ -2562,6 +2564,7 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, ...@@ -2562,6 +2564,7 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr,
table->UvdBootLevel = 0; table->UvdBootLevel = 0;
for (count = 0; count < table->UvdLevelCount; count++) { for (count = 0; count < table->UvdLevelCount; count++) {
table->UvdLevel[count].MinVoltage = 0;
table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk;
table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk;
table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc *
...@@ -2900,6 +2903,8 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr) ...@@ -2900,6 +2903,8 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control) if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control)
fiji_populate_smc_voltage_tables(hwmgr, table); fiji_populate_smc_voltage_tables(hwmgr, table);
table->SystemFlags = 0;
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_AutomaticDCTransition)) PHM_PlatformCaps_AutomaticDCTransition))
table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
...@@ -2997,6 +3002,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr) ...@@ -2997,6 +3002,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr)
table->MemoryThermThrottleEnable = 1; table->MemoryThermThrottleEnable = 1;
table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/ table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/
table->PCIeGenInterval = 1; table->PCIeGenInterval = 1;
table->VRConfig = 0;
result = fiji_populate_vr_config(hwmgr, table); result = fiji_populate_vr_config(hwmgr, table);
PP_ASSERT_WITH_CODE(0 == result, PP_ASSERT_WITH_CODE(0 == result,
...@@ -5195,6 +5201,67 @@ static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr, ...@@ -5195,6 +5201,67 @@ static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr,
return size; 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 = { static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
.backend_init = &fiji_hwmgr_backend_init, .backend_init = &fiji_hwmgr_backend_init,
.backend_fini = &tonga_hwmgr_backend_fini, .backend_fini = &tonga_hwmgr_backend_fini,
...@@ -5230,6 +5297,8 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = { ...@@ -5230,6 +5297,8 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
.register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt, .register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt,
.set_fan_control_mode = fiji_set_fan_control_mode, .set_fan_control_mode = fiji_set_fan_control_mode,
.get_fan_control_mode = fiji_get_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, .get_pp_table = fiji_get_pp_table,
.set_pp_table = fiji_set_pp_table, .set_pp_table = fiji_set_pp_table,
.force_clock_level = fiji_force_clock_level, .force_clock_level = fiji_force_clock_level,
......
...@@ -58,6 +58,9 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr) ...@@ -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_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) && if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) &&
acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION)) acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION))
phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
...@@ -130,18 +133,25 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr, ...@@ -130,18 +133,25 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr,
int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr)
{ {
int ret = 1;
bool enabled;
PHM_FUNC_CHECK(hwmgr); PHM_FUNC_CHECK(hwmgr);
if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
PHM_PlatformCaps_TablelessHardwareInterface)) { PHM_PlatformCaps_TablelessHardwareInterface)) {
if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable) 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 { } else {
return phm_dispatch_table(hwmgr, ret = phm_dispatch_table(hwmgr,
&(hwmgr->enable_dynamic_state_management), &(hwmgr->enable_dynamic_state_management),
NULL, NULL); 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) 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) ...@@ -275,13 +275,15 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
atombios_blank_crtc(crtc, ATOM_DISABLE); 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); radeon_crtc_load_lut(crtc);
break; break;
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF: 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) if (radeon_crtc->enabled)
atombios_blank_crtc(crtc, ATOM_ENABLE); atombios_blank_crtc(crtc, ATOM_ENABLE);
if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
......
...@@ -291,6 +291,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev) ...@@ -291,6 +291,8 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
if (r) { if (r) {
return r; return r;
} }
rdev->ddev->vblank_disable_allowed = true;
/* enable msi */ /* enable msi */
rdev->msi_enabled = 0; rdev->msi_enabled = 0;
......
...@@ -331,13 +331,15 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -331,13 +331,15 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
RADEON_CRTC_DISP_REQ_EN_B)); RADEON_CRTC_DISP_REQ_EN_B));
WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); 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); radeon_crtc_load_lut(crtc);
break; break;
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF: 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) if (radeon_crtc->crtc_id)
WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask)); WREG32_P(RADEON_CRTC2_GEN_CNTL, mask, ~(RADEON_CRTC2_EN | mask));
else { else {
......
...@@ -92,7 +92,7 @@ struct ttm_placement { ...@@ -92,7 +92,7 @@ struct ttm_placement {
*/ */
struct ttm_bus_placement { struct ttm_bus_placement {
void *addr; void *addr;
unsigned long base; phys_addr_t base;
unsigned long size; unsigned long size;
unsigned long offset; unsigned long offset;
bool is_iomem; bool is_iomem;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment