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 has a bunch of nouveau fixes, as Ben has been hibernating and has
  lots of small fixes for lots of bugs across nouveau.

  Radeon has one major fix for hdmi/dp audio regression that is larger
  than Alex would like, but seems to fix up a fair few bugs, along with
  some misc fixes.

  And a few msm fixes, one of which is also a bit large.

  But nothing in here seems insane or crazy for this stage, just more
  than I'd like"

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (33 commits)
  drm/msm/mdp5: release SMB (shared memory blocks) in various cases
  drm/msm: change to uninterruptible wait in atomic commit
  drm/msm: mdp4: Fix drm_framebuffer dereference crash
  drm/msm: fix msm_gem_prime_get_sg_table()
  drm/amdgpu: add new parameter to seperate map and unmap
  drm/amdgpu: hdp_flush is not needed for inside IB
  drm/amdgpu: different emit_ib for gfx and compute
  drm/amdgpu: information leak in amdgpu_info_ioctl()
  drm/amdgpu: clean up init sequence for failures
  drm/radeon/combios: add some validation of lvds values
  drm/radeon: rework audio modeset to handle non-audio hdmi features
  drm/radeon: rework audio detect (v4)
  drm/amdgpu: Drop drm/ prefix for including drm.h in amdgpu_drm.h
  drm/radeon: Drop drm/ prefix for including drm.h in radeon_drm.h
  drm/nouveau/nouveau/ttm: fix tiled system memory with Maxwell
  drm/nouveau/kms/nv50-: guard against enabling cursor on disabled heads
  drm/nouveau/fbcon/g80: reduce PUSH_SPACE alloc, fire ring on accel init
  drm/nouveau/fbcon/gf100-: reduce RING_SPACE allocation
  drm/nouveau/fbcon/nv11-: correctly account for ring space usage
  drm/nouveau/bios: add proper support for opcode 0x59
  ...
  • Loading branch information
torvalds committed Jul 31, 2015
2 parents 8400935 + bdce3e7 commit fd56d1d
Show file tree
Hide file tree
Showing 43 changed files with 554 additions and 274 deletions.
8 changes: 7 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu.h
Expand Up @@ -1866,6 +1866,12 @@ typedef void (*amdgpu_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device*, uint32_t, uint32_t);
typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device*, uint32_t, uint32_t, uint32_t);

struct amdgpu_ip_block_status {
bool valid;
bool sw;
bool hw;
};

struct amdgpu_device {
struct device *dev;
struct drm_device *ddev;
Expand Down Expand Up @@ -2008,7 +2014,7 @@ struct amdgpu_device {

const struct amdgpu_ip_block_version *ip_blocks;
int num_ip_blocks;
bool *ip_block_enabled;
struct amdgpu_ip_block_status *ip_block_status;
struct mutex mn_lock;
DECLARE_HASHTABLE(mn_hash, 7);

Expand Down
38 changes: 22 additions & 16 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Expand Up @@ -1191,8 +1191,9 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
return -EINVAL;
}

adev->ip_block_enabled = kcalloc(adev->num_ip_blocks, sizeof(bool), GFP_KERNEL);
if (adev->ip_block_enabled == NULL)
adev->ip_block_status = kcalloc(adev->num_ip_blocks,
sizeof(struct amdgpu_ip_block_status), GFP_KERNEL);
if (adev->ip_block_status == NULL)
return -ENOMEM;

if (adev->ip_blocks == NULL) {
Expand All @@ -1203,18 +1204,18 @@ static int amdgpu_early_init(struct amdgpu_device *adev)
for (i = 0; i < adev->num_ip_blocks; i++) {
if ((amdgpu_ip_block_mask & (1 << i)) == 0) {
DRM_ERROR("disabled ip block: %d\n", i);
adev->ip_block_enabled[i] = false;
adev->ip_block_status[i].valid = false;
} else {
if (adev->ip_blocks[i].funcs->early_init) {
r = adev->ip_blocks[i].funcs->early_init((void *)adev);
if (r == -ENOENT)
adev->ip_block_enabled[i] = false;
adev->ip_block_status[i].valid = false;
else if (r)
return r;
else
adev->ip_block_enabled[i] = true;
adev->ip_block_status[i].valid = true;
} else {
adev->ip_block_enabled[i] = true;
adev->ip_block_status[i].valid = true;
}
}
}
Expand All @@ -1227,11 +1228,12 @@ static int amdgpu_init(struct amdgpu_device *adev)
int i, r;

for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_block_enabled[i])
if (!adev->ip_block_status[i].valid)
continue;
r = adev->ip_blocks[i].funcs->sw_init((void *)adev);
if (r)
return r;
adev->ip_block_status[i].sw = true;
/* need to do gmc hw init early so we can allocate gpu mem */
if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
r = amdgpu_vram_scratch_init(adev);
Expand All @@ -1243,18 +1245,20 @@ static int amdgpu_init(struct amdgpu_device *adev)
r = amdgpu_wb_init(adev);
if (r)
return r;
adev->ip_block_status[i].hw = true;
}
}

for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_block_enabled[i])
if (!adev->ip_block_status[i].sw)
continue;
/* gmc hw init is done early */
if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC)
continue;
r = adev->ip_blocks[i].funcs->hw_init((void *)adev);
if (r)
return r;
adev->ip_block_status[i].hw = true;
}

return 0;
Expand All @@ -1265,7 +1269,7 @@ static int amdgpu_late_init(struct amdgpu_device *adev)
int i = 0, r;

for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_block_enabled[i])
if (!adev->ip_block_status[i].valid)
continue;
/* enable clockgating to save power */
r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
Expand All @@ -1287,7 +1291,7 @@ static int amdgpu_fini(struct amdgpu_device *adev)
int i, r;

for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_block_enabled[i])
if (!adev->ip_block_status[i].hw)
continue;
if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) {
amdgpu_wb_fini(adev);
Expand All @@ -1300,14 +1304,16 @@ static int amdgpu_fini(struct amdgpu_device *adev)
return r;
r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
/* XXX handle errors */
adev->ip_block_status[i].hw = false;
}

for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_block_enabled[i])
if (!adev->ip_block_status[i].sw)
continue;
r = adev->ip_blocks[i].funcs->sw_fini((void *)adev);
/* XXX handle errors */
adev->ip_block_enabled[i] = false;
adev->ip_block_status[i].sw = false;
adev->ip_block_status[i].valid = false;
}

return 0;
Expand All @@ -1318,7 +1324,7 @@ static int amdgpu_suspend(struct amdgpu_device *adev)
int i, r;

for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
if (!adev->ip_block_enabled[i])
if (!adev->ip_block_status[i].valid)
continue;
/* ungate blocks so that suspend can properly shut them down */
r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
Expand All @@ -1336,7 +1342,7 @@ static int amdgpu_resume(struct amdgpu_device *adev)
int i, r;

for (i = 0; i < adev->num_ip_blocks; i++) {
if (!adev->ip_block_enabled[i])
if (!adev->ip_block_status[i].valid)
continue;
r = adev->ip_blocks[i].funcs->resume(adev);
if (r)
Expand Down Expand Up @@ -1582,8 +1588,8 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
amdgpu_fence_driver_fini(adev);
amdgpu_fbdev_fini(adev);
r = amdgpu_fini(adev);
kfree(adev->ip_block_enabled);
adev->ip_block_enabled = NULL;
kfree(adev->ip_block_status);
adev->ip_block_status = NULL;
adev->accel_working = false;
/* free i2c buses */
amdgpu_i2c_fini(adev);
Expand Down
8 changes: 5 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
Expand Up @@ -449,7 +449,7 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
* 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 amdgpu_bo_va *bo_va, uint32_t operation)
{
struct ttm_validate_buffer tv, *entry;
struct amdgpu_bo_list_entry *vm_bos;
Expand Down Expand Up @@ -485,7 +485,9 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
if (r)
goto error_unlock;

r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem);

if (operation == AMDGPU_VA_OP_MAP)
r = amdgpu_vm_bo_update(adev, bo_va, &bo_va->bo->tbo.mem);

error_unlock:
mutex_unlock(&bo_va->vm->mutex);
Expand Down Expand Up @@ -580,7 +582,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
}

if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE))
amdgpu_gem_va_update_vm(adev, bo_va);
amdgpu_gem_va_update_vm(adev, bo_va, args->operation);

drm_gem_object_unreference_unlocked(gobj);
return r;
Expand Down
16 changes: 8 additions & 8 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
Expand Up @@ -180,16 +180,16 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs,
if (vm) {
/* do context switch */
amdgpu_vm_flush(ring, vm, ib->sync.last_vm_update);
}

if (vm && ring->funcs->emit_gds_switch)
amdgpu_ring_emit_gds_switch(ring, ib->vm->ids[ring->idx].id,
ib->gds_base, ib->gds_size,
ib->gws_base, ib->gws_size,
ib->oa_base, ib->oa_size);
if (ring->funcs->emit_gds_switch)
amdgpu_ring_emit_gds_switch(ring, ib->vm->ids[ring->idx].id,
ib->gds_base, ib->gds_size,
ib->gws_base, ib->gws_size,
ib->oa_base, ib->oa_size);

if (ring->funcs->emit_hdp_flush)
amdgpu_ring_emit_hdp_flush(ring);
if (ring->funcs->emit_hdp_flush)
amdgpu_ring_emit_hdp_flush(ring);
}

old_ctx = ring->current_ctx;
for (i = 0; i < num_ibs; ++i) {
Expand Down
6 changes: 3 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
Expand Up @@ -235,7 +235,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file

for (i = 0; i < adev->num_ip_blocks; i++) {
if (adev->ip_blocks[i].type == type &&
adev->ip_block_enabled[i]) {
adev->ip_block_status[i].valid) {
ip.hw_ip_version_major = adev->ip_blocks[i].major;
ip.hw_ip_version_minor = adev->ip_blocks[i].minor;
ip.capabilities_flags = 0;
Expand Down Expand Up @@ -274,7 +274,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file

for (i = 0; i < adev->num_ip_blocks; i++)
if (adev->ip_blocks[i].type == type &&
adev->ip_block_enabled[i] &&
adev->ip_block_status[i].valid &&
count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT)
count++;

Expand Down Expand Up @@ -416,7 +416,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
return n ? -EFAULT : 0;
}
case AMDGPU_INFO_DEV_INFO: {
struct drm_amdgpu_info_device dev_info;
struct drm_amdgpu_info_device dev_info = {};
struct amdgpu_cu_info cu_info;

dev_info.device_id = dev->pdev->device;
Expand Down
46 changes: 35 additions & 11 deletions drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
Expand Up @@ -2561,23 +2561,18 @@ static bool gfx_v7_0_ring_emit_semaphore(struct amdgpu_ring *ring,
* sheduling on the ring. This function schedules the IB
* on the gfx ring for execution by the GPU.
*/
static void gfx_v7_0_ring_emit_ib(struct amdgpu_ring *ring,
static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
struct amdgpu_ib *ib)
{
bool need_ctx_switch = ring->current_ctx != ib->ctx;
u32 header, control = 0;
u32 next_rptr = ring->wptr + 5;

/* drop the CE preamble IB for the same context */
if ((ring->type == AMDGPU_RING_TYPE_GFX) &&
(ib->flags & AMDGPU_IB_FLAG_PREAMBLE) &&
!need_ctx_switch)
if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && !need_ctx_switch)
return;

if (ring->type == AMDGPU_RING_TYPE_COMPUTE)
control |= INDIRECT_BUFFER_VALID;

if (need_ctx_switch && ring->type == AMDGPU_RING_TYPE_GFX)
if (need_ctx_switch)
next_rptr += 2;

next_rptr += 4;
Expand All @@ -2588,7 +2583,7 @@ static void gfx_v7_0_ring_emit_ib(struct amdgpu_ring *ring,
amdgpu_ring_write(ring, next_rptr);

/* insert SWITCH_BUFFER packet before first IB in the ring frame */
if (need_ctx_switch && ring->type == AMDGPU_RING_TYPE_GFX) {
if (need_ctx_switch) {
amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
amdgpu_ring_write(ring, 0);
}
Expand All @@ -2611,6 +2606,35 @@ static void gfx_v7_0_ring_emit_ib(struct amdgpu_ring *ring,
amdgpu_ring_write(ring, control);
}

static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
struct amdgpu_ib *ib)
{
u32 header, control = 0;
u32 next_rptr = ring->wptr + 5;

control |= INDIRECT_BUFFER_VALID;
next_rptr += 4;
amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
amdgpu_ring_write(ring, WRITE_DATA_DST_SEL(5) | WR_CONFIRM);
amdgpu_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
amdgpu_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xffffffff);
amdgpu_ring_write(ring, next_rptr);

header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);

control |= ib->length_dw |
(ib->vm ? (ib->vm->ids[ring->idx].id << 24) : 0);

amdgpu_ring_write(ring, header);
amdgpu_ring_write(ring,
#ifdef __BIG_ENDIAN
(2 << 0) |
#endif
(ib->gpu_addr & 0xFFFFFFFC));
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
amdgpu_ring_write(ring, control);
}

/**
* gfx_v7_0_ring_test_ib - basic ring IB test
*
Expand Down Expand Up @@ -5555,7 +5579,7 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_gfx = {
.get_wptr = gfx_v7_0_ring_get_wptr_gfx,
.set_wptr = gfx_v7_0_ring_set_wptr_gfx,
.parse_cs = NULL,
.emit_ib = gfx_v7_0_ring_emit_ib,
.emit_ib = gfx_v7_0_ring_emit_ib_gfx,
.emit_fence = gfx_v7_0_ring_emit_fence_gfx,
.emit_semaphore = gfx_v7_0_ring_emit_semaphore,
.emit_vm_flush = gfx_v7_0_ring_emit_vm_flush,
Expand All @@ -5571,7 +5595,7 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_compute = {
.get_wptr = gfx_v7_0_ring_get_wptr_compute,
.set_wptr = gfx_v7_0_ring_set_wptr_compute,
.parse_cs = NULL,
.emit_ib = gfx_v7_0_ring_emit_ib,
.emit_ib = gfx_v7_0_ring_emit_ib_compute,
.emit_fence = gfx_v7_0_ring_emit_fence_compute,
.emit_semaphore = gfx_v7_0_ring_emit_semaphore,
.emit_vm_flush = gfx_v7_0_ring_emit_vm_flush,
Expand Down

0 comments on commit fd56d1d

Please sign in to comment.