Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
Pull drm fixes from Dave Airlie:
 "This is mostly amdgpu/radeon fixes, and imx related fixes.

  There is also one one TTM fix, one nouveau fix, and one hdlcd fix.

  The AMD ones are some fixes for power management after suspend/resume
  one some GPUs, and some vblank fixes.

  The IMX ones are for more stricter plane checks and some cleanups.

  I'm off until Monday, so therre might be some fixes early next week if
  anyone missed me"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (34 commits)
  drm/nouveau/tegra: acquire and enable reference clock if needed
  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: ARM HDLCD - fix an error code
  drm: ARM HDLCD - get rid of devm_clk_put()
  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.
  ...
  • Loading branch information
torvalds committed Apr 7, 2016
2 parents c4004b0 + fd8c61e commit 741f37b
Show file tree
Hide file tree
Showing 33 changed files with 405 additions and 170 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 19 additions & 5 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -828,25 +831,35 @@ 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) /
amdgpu_crtc->hw_mode.clock;
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;
}
}
}

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
Expand Down Expand Up @@ -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,
};
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
8 changes: 6 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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));

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 13 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
}

Expand Down
10 changes: 3 additions & 7 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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;
Expand Down
58 changes: 30 additions & 28 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
16 changes: 8 additions & 8 deletions drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
23 changes: 15 additions & 8 deletions drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
7 changes: 4 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Loading

0 comments on commit 741f37b

Please sign in to comment.