[REGRESSION] nouveau: Memory corruption using nva3 engine for 0xaf
On Mon, Jul 09, 2012 at 03:13:25PM +0200, Henrik Rydberg wrote: > On Thu, Jul 05, 2012 at 10:34:10AM +0200, Henrik Rydberg wrote: > > On Thu, Jul 05, 2012 at 08:54:46AM +0200, Henrik Rydberg wrote: > > > > Thanks for tracking down the source of this corruption. I don't have > > > > any such hardware, so until someone can figure it out, I think we > > > > should apply this patch. > > > > > > In that case, I would have to massage the patch a bit first; it > > > creates a problem with suspend/resume. Might be something with > > > nva3_pm.c, who knows. I am really stabbing in the dark here. :-) > > > > It seems the suspend/resume problem is unrelated (bad systemd update), > > so I am fine with applying this as is. Obviously not the best > > solution, and if I have time I will continue to look for problems in > > the nva3 copy code, but for now, > > > > Signed-off-by: Henrik Rydberg > > I have not encountered the problem in a long while, and I do not have > the patch applied. It is entirely possible that this was fixed by > something else. Unless you have already applied the patch, I would > suggest holding on to it to see if the problem reappears. > > Sorry for the churn. ... and there it was again, hours after giving up on it. Oh well. What makes this bug particularly difficult is that as soon as the patch is applied, the problem disappears and does not show itself again - with or without the patch applied. Sounds very much like the problem is a failure state that does not get reset by current mainline, but somehow gets reset with the patch applied. I also learnt that the problem is not in the nva3_copy code itself; I reverted nva3_copy.c and nva3_pm.c back to v3.4, but the problem persisted. A DMA problem elsewhere, in the drm code or in the pci layer, seems more likely than this particular hardware having problems with this particular copy engine. As it stands, though, applying the patch is the only thing known to work. Thanks, Henrik
Mesa shader compiling/optimizing process is too slow
I've done benchmarks and comparison between proprietary drivers and Mesa, Mesa seems to be up to 200x slower compiling the same shader, since i understand optimizing such part of code may take months or even more, i have thought to solve it this way: Upon calling glLinkProgram , an unoptimized version of the shader ( compiles much much faster ) is uploaded to the GPU Then a separate thread is launched that will optimize the shader and as soon it is done, on the next call to glUseProgram it will upload optimized version in place of unoptimized one. This will solve many performance issues and temporary freezes with games that load/unload content while running, while not reducing performance once the background optimization is done
[Bug 33309] [855GM] GPU freeze due to overlay hang
https://bugs.freedesktop.org/show_bug.cgi?id=33309 Chris Wilson changed: What|Removed |Added Status|NEEDINFO|RESOLVED Resolution||NOTOURBUG --- Comment #31 from Chris Wilson 2012-07-09 11:37:34 PDT --- Ok, I'm just as surprised; be wary of a surprise attack. In the meantime, have fun! -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug.
[Bug 33309] [855GM] GPU freeze due to overlay hang
https://bugs.freedesktop.org/show_bug.cgi?id=33309 --- Comment #30 from stefan 2012-07-09 11:18:52 PDT --- Hi Daniel, (In reply to comment #29) > (In reply to comment #28) > > are there any news on this issue? > > The 3.4 and 3.5-rc series seem stable wrt this issue, > > but unfortunately something broke resume from s2ram badly, > > the backlight stays off and the machine does not respond > > even to SysRq and I need to do a hard power-off. > > That's good news. Can you try to bisect the backlight regression that has > been introduce in 3.4 and open a new bug report? That usually helps in fixing > it ... It turns out to be an ACPICA regression not related to graphics at all. As for this issue, I did not observe any more hangs with v3.4 or 3.5-rc, *yet*. It is hard to tell for sure since it usually takes a while (sometimes hours) for it to occure. Which makes it also almost impossible to bisect and to find the commit that might have fixed it. Cheers, Stefan. -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug.
[RFC] drm/radeon: restoring ring commands in case of a lockup
On Mon, 2012-07-09 at 12:41 +0200, Christian K?nig wrote: > Hi, > > The following patchset tries to save and restore the not yet processed > commands > from the rings in case of a lockup and with that should make a userspace > problem with a single application far less problematic. > > The first four patches are just stuff this patchset is based upon, followed by > four patches which fix various bugs found while working on this feature. > > Followed by patches which change the way how memory is saved/restored on > suspend/resume, basically before we have unpinned most of the buffer objects > so > it could be move from vram into system memory. But that is mostly unnecessary > cause the buffer object either are already in system memory or their content > can be easily reinitialized. > > The last three patches implement the actual tracking and restoring of commands > in case of a lockup. Please take a look and review. Patches 3, 5 and 14 are Reviewed-by: Michel D?nzer -- Earthling Michel D?nzer | http://www.amd.com Libre software enthusiast | Debian, X and DRI developer
[Bug 51870] r600_streamout=1 nothing change
https://bugs.freedesktop.org/show_bug.cgi?id=51870 Marek Ol??k changed: What|Removed |Added Status|NEW |RESOLVED Resolution||NOTABUG --- Comment #1 from Marek Ol??k 2012-07-09 10:50:59 PDT --- Those environment variables aren't required anymore. GLSL 1.3 and streamout are enabled by default. The only thing missing is MSAA and there is no way to enable it at the moment. Closing. -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug.
[PATCH 15/16] drm/radeon: implement ring commit tracking
On 09.07.2012 17:36, Jerome Glisse wrote: > On Mon, Jul 9, 2012 at 6:42 AM, Christian K?nig > wrote: >> Signed-off-by: Christian K?nig > Bit too complex to my taste, what about attached patch, it's lot > simpler. (Haven't tested > the patch but it should work) Cool idea! Depending on the writeback mechanism might not be the best part of it, but in general speaking all rings should have more than enough scratch registers for that!!! Going to change it. Thanks, Christian. > > Cheers, > Jerome > >> --- >> drivers/gpu/drm/radeon/radeon.h |3 +++ >> drivers/gpu/drm/radeon/radeon_ring.c | 39 >> -- >> 2 files changed, 40 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/gpu/drm/radeon/radeon.h >> b/drivers/gpu/drm/radeon/radeon.h >> index fef4257..9c11be8 100644 >> --- a/drivers/gpu/drm/radeon/radeon.h >> +++ b/drivers/gpu/drm/radeon/radeon.h >> @@ -637,6 +637,9 @@ struct radeon_ring { >> u32 ptr_reg_shift; >> u32 ptr_reg_mask; >> u32 nop; >> + unsigned*track_back; >> + unsignedtrack_ptr; >> + unsignedtrack_mask; >> }; >> >> /* >> diff --git a/drivers/gpu/drm/radeon/radeon_ring.c >> b/drivers/gpu/drm/radeon/radeon_ring.c >> index d9b2e45..994c98c 100644 >> --- a/drivers/gpu/drm/radeon/radeon_ring.c >> +++ b/drivers/gpu/drm/radeon/radeon_ring.c >> @@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, >> struct radeon_ring *ring) >> DRM_MEMORYBARRIER(); >> WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & >> ring->ptr_reg_mask); >> (void)RREG32(ring->wptr_reg); >> + ring->track_back[ring->track_ptr++] = ring->wptr_old; >> + ring->track_ptr &= ring->track_mask; >> } >> >> void radeon_ring_unlock_commit(struct radeon_device *rdev, struct >> radeon_ring *ring) >> @@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device >> *rdev, struct radeon_ring *rin >> return false; >> } >> >> +static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring) >> +{ >> + unsigned i, c, result = ring->track_ptr; >> + i = ring->track_ptr - 1; >> + while (i != ring->track_ptr) { >> + i &= ring->track_mask; >> + c = ring->track_back[i]; >> + >> + if (ring->wptr >= ring->rptr) { >> + if (c < ring->rptr || c >= ring->wptr) >> + break; >> + } else { >> + if (c < ring->rptr && c >= ring->wptr) >> + break; >> + } >> + >> + result = i--; >> + } >> + return result; >> +} >> + >> int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, >> unsigned ring_size, unsigned align, >> unsigned rptr_offs, unsigned rptr_reg, unsigned >> wptr_reg, >> @@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct >> radeon_ring *ring, >> dev_err(rdev->dev, "(%d) ring map failed\n", r); >> return r; >> } >> + ring->track_back = kmalloc(ring_size / align, GFP_KERNEL); >> + memset(ring->track_back, 0, ring_size / align); >> + ring->track_ptr = 0; >> + ring->track_mask = ((ring->ring_size / 4) / align) - 1; >> } >> ring->ptr_mask = (ring->ring_size / 4) - 1; >> ring->ring_free_dw = ring->ring_size / 4; >> @@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct >> radeon_ring *ring) >> ring->ready = false; >> ring->ring = NULL; >> ring->ring_obj = NULL; >> + kfree(ring->track_back); >> mutex_unlock(>ring_lock); >> >> if (ring_obj) { >> @@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, >> void *data) >> struct radeon_device *rdev = dev->dev_private; >> int ridx = *(int*)node->info_ent->data; >> struct radeon_ring *ring = >ring[ridx]; >> - unsigned count, i, j; >> + unsigned count, i, j, commit; >> >> radeon_ring_free_size(rdev, ring); >> count = (ring->ring_size / 4) - ring->ring_free_dw; >> @@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, >> void *data) >> seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); >> seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); >> seq_printf(m, "%u dwords in ring\n", count); >> + commit = radeon_ring_first_valid_commit(ring); >> i = ring->rptr; >> for (j = 0; j <= count; j++) { >> - seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); >> + seq_printf(m, "r[%04x]=0x%08x", i,
[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code
On Mon, 2012-07-09 at 17:22 +0200, Christian K?nig wrote: > On 09.07.2012 17:06, Michel D?nzer wrote: > > On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote: > >> Making it easier to controlwhen it is executed. > >> > >> Signed-off-by: Christian K?nig > > [...] > >> diff --git a/drivers/gpu/drm/radeon/radeon_device.c > >> b/drivers/gpu/drm/radeon/radeon_device.c > >> index 254fdb4..bbd0971 100644 > >> --- a/drivers/gpu/drm/radeon/radeon_device.c > >> +++ b/drivers/gpu/drm/radeon/radeon_device.c > >> @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev, > >>if (r) > >>return r; > >> > >> + r = radeon_ib_ring_tests(rdev); > >> + if (r) > >> + DRM_ERROR("ib ring test failed (%d).\n", r); > >> + > >>if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { > >>/* Acceleration not working on AGP card try again > >> * with fallback to PCI or PCIE GART > > I think this needs to set rdev->accel_working = false on failure, so the > > AGP -> PCI(e) fallback can kick in. > > See the implementation of radeon_ib_ring_tests, it is already handling > that internally. Oops, I actually did check this when writing the above, but somehow I failed to see what I was looking for. :} -- Earthling Michel D?nzer | http://www.amd.com Libre software enthusiast | Debian, X and DRI developer
[PATCH 16/16] drm/radeon: implement ring saving on reset
On 09.07.2012 17:06, Michel D?nzer wrote: > On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote: >> Try to save whatever is on the rings when >> we encounter an lockup. >> >> Signed-off-by: Christian K?nig > [...] >> @@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev) >> resched = ttm_bo_lock_delayed_workqueue(>mman.bdev); >> radeon_suspend(rdev); >> >> +for (i = 0; i < RADEON_NUM_RINGS; ++i) { >> +ring_sizes[i] = radeon_ring_backup(rdev, >ring[i], >> + _data[i]); >> +if (ring_sizes[i]) { >> +saved = true; >> +dev_info(rdev->dev, "Saved %d dwords of commands " >> + "on ring %d.\n", ring_sizes[i], i); >> +} >> +} >> + >> +retry: >> r = radeon_asic_reset(rdev); >> if (!r) { >> -dev_info(rdev->dev, "GPU reset succeed\n"); >> +dev_info(rdev->dev, "GPU reset succeed trying to resume\n"); > Could fix the spelling of 'succeeded' while you're at it. :) Akk, fixed it. > > >> radeon_resume(rdev); >> +} >> >> -r = radeon_ib_ring_tests(rdev); >> -if (r) >> -DRM_ERROR("ib ring test failed (%d).\n", r); >> +radeon_restore_bios_scratch_regs(rdev); >> +drm_helper_resume_force_mode(rdev->ddev); >> + >> +if (!r) { >> +for (i = 0; i < RADEON_NUM_RINGS; ++i) { >> +radeon_ring_restore(rdev, >ring[i], >> +ring_sizes[i], ring_data[i]); >> +} > If radeon_asic_reset fails, this leaks the memory referenced by > ring_data, doesn't it? Oh yes indeed, going to fix that. > Also, the added functions aren't documented as mandated by the rules > Alex proposed. > True, also going to fix that. Christian.
[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code
On 09.07.2012 17:06, Michel D?nzer wrote: > On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote: >> Making it easier to controlwhen it is executed. >> >> Signed-off-by: Christian K?nig > [...] >> diff --git a/drivers/gpu/drm/radeon/radeon_device.c >> b/drivers/gpu/drm/radeon/radeon_device.c >> index 254fdb4..bbd0971 100644 >> --- a/drivers/gpu/drm/radeon/radeon_device.c >> +++ b/drivers/gpu/drm/radeon/radeon_device.c >> @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev, >> if (r) >> return r; >> >> +r = radeon_ib_ring_tests(rdev); >> +if (r) >> +DRM_ERROR("ib ring test failed (%d).\n", r); >> + >> if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { >> /* Acceleration not working on AGP card try again >> * with fallback to PCI or PCIE GART > I think this needs to set rdev->accel_working = false on failure, so the > AGP -> PCI(e) fallback can kick in. See the implementation of radeon_ib_ring_tests, it is already handling that internally. > Not sure about the other places where you're adding > radeon_ib_ring_tests() calls, might need more error handling as well. radeon_ib_ring_tests is already handling most errors internally, e. g. it sets the accel_working and the ring->ready flags to false if anything goes wrong. The return value is mostly for the case where we want to try the reset a second time if restoring the ring commands leads to another lockup. I just doesn't want to ignore the result completely, so the additional error message. Christian.
[PATCH 09/16] drm/radeon: make cp init on cayman more robust
On 09.07.2012 16:43, Jerome Glisse wrote: > On Mon, Jul 9, 2012 at 6:41 AM, Christian K?nig > wrote: >> It's not critical, but the current code isn't >> 100% correct. >> >> Signed-off-by: Christian K?nig >> --- >> drivers/gpu/drm/radeon/ni.c | 133 >> ++- >> 1 file changed, 56 insertions(+), 77 deletions(-) >> >> diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c >> index 32a6082..8b1df33 100644 >> --- a/drivers/gpu/drm/radeon/ni.c >> +++ b/drivers/gpu/drm/radeon/ni.c >> @@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev) >> >> int cayman_cp_resume(struct radeon_device *rdev) >> { >> + static const int ridx[] = { >> + RADEON_RING_TYPE_GFX_INDEX, >> + CAYMAN_RING_TYPE_CP1_INDEX, >> + CAYMAN_RING_TYPE_CP2_INDEX >> + }; >> + static const unsigned cp_rb_cntl[] = { >> + CP_RB0_CNTL, >> + CP_RB1_CNTL, >> + CP_RB2_CNTL, >> + }; >> + static const unsigned cp_rb_rptr_addr[] = { >> + CP_RB0_RPTR_ADDR, >> + CP_RB1_RPTR_ADDR, >> + CP_RB2_RPTR_ADDR >> + }; >> + static const unsigned cp_rb_rptr_addr_hi[] = { >> + CP_RB0_RPTR_ADDR_HI, >> + CP_RB1_RPTR_ADDR_HI, >> + CP_RB2_RPTR_ADDR_HI >> + }; >> + static const unsigned cp_rb_base[] = { >> + CP_RB0_BASE, >> + CP_RB1_BASE, >> + CP_RB2_BASE >> + }; >> struct radeon_ring *ring; >> - u32 tmp; >> - u32 rb_bufsz; >> - int r; >> + int i, r; >> >> /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset >> */ >> WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | >> @@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev) >> >> WREG32(CP_DEBUG, (1 << 27)); >> >> - /* ring 0 - compute and gfx */ >> - /* Set ring buffer size */ >> - ring = >ring[RADEON_RING_TYPE_GFX_INDEX]; >> - rb_bufsz = drm_order(ring->ring_size / 8); >> - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; >> -#ifdef __BIG_ENDIAN >> - tmp |= BUF_SWAP_32BIT; >> -#endif >> - WREG32(CP_RB0_CNTL, tmp); >> - >> - /* Initialize the ring buffer's read and write pointers */ >> - WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); >> - ring->wptr = 0; >> - WREG32(CP_RB0_WPTR, ring->wptr); >> - >> /* set the wb address wether it's enabled or not */ >> - WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + >> RADEON_WB_CP_RPTR_OFFSET) & 0xFFFC); >> - WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + >> RADEON_WB_CP_RPTR_OFFSET) & 0xFF); >> WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + >> RADEON_WB_SCRATCH_OFFSET) >> 8) & 0x); >> + WREG32(SCRATCH_UMSK, 0xff); > This looks wrong you set the mask unconditionaly even if writeback is > disabled. writeback is always enabled for NI and APUs, but the register docs say that this feature isn't validated for NI and shouldn't be used so I'm not sure if enabling it is the right thing to do. Anyway, it doesn't matter at all since we don't use the scratch register writeback anymore and use EOP instead. Christian. > > >> - if (rdev->wb.enabled) >> - WREG32(SCRATCH_UMSK, 0xff); >> - else { >> - tmp |= RB_NO_UPDATE; >> - WREG32(SCRATCH_UMSK, 0); >> - } >> - >> - mdelay(1); >> - WREG32(CP_RB0_CNTL, tmp); >> - >> - WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); >> - >> - ring->rptr = RREG32(CP_RB0_RPTR); >> + for (i = 0; i < 3; ++i) { >> + uint32_t rb_cntl; >> + uint64_t addr; >> >> - /* ring1 - compute only */ >> - /* Set ring buffer size */ >> - ring = >ring[CAYMAN_RING_TYPE_CP1_INDEX]; >> - rb_bufsz = drm_order(ring->ring_size / 8); >> - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; >> + /* Set ring buffer size */ >> + ring = >ring[ridx[i]]; >> + rb_cntl = drm_order(ring->ring_size / 8); >> + rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8; >> #ifdef __BIG_ENDIAN >> - tmp |= BUF_SWAP_32BIT; >> + rb_cntl |= BUF_SWAP_32BIT; >> #endif >> - WREG32(CP_RB1_CNTL, tmp); >> + WREG32(cp_rb_cntl[i], rb_cntl); >> >> - /* Initialize the ring buffer's read and write pointers */ >> - WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); >> - ring->wptr = 0; >> - WREG32(CP_RB1_WPTR, ring->wptr); >> - >> - /* set the wb address wether it's enabled or not */ >> - WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + >> RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC); >> - WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + >> RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); >> -
[PATCH] drm/exynos: Add exynos drm specific fb_mmap function
This patch adds a exynos drm specific implementation of fb_mmap which supports mapping a non-contiguous buffer to user space. This new function does not assume that the frame buffer is contiguous and calls dma_mmap_writecombine for mapping the buffer to user space. dma_mmap_writecombine will be able to map a contiguous buffer as well as non-contig buffer depending on whether an IOMMU mapping is created for drm or not. Signed-off-by: Prathyush K --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 16 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d5586cc..b53e638 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -46,8 +46,24 @@ struct exynos_drm_fbdev { struct exynos_drm_gem_obj *exynos_gem_obj; }; +static int exynos_drm_fb_mmap(struct fb_info *info, + struct vm_area_struct *vma) +{ + if ((vma->vm_end - vma->vm_start) > info->fix.smem_len) + return -EINVAL; + + vma->vm_pgoff = 0; + vma->vm_flags |= VM_IO | VM_RESERVED; + if (dma_mmap_writecombine(info->device, vma, info->screen_base, + info->fix.smem_start, vma->vm_end - vma->vm_start)) + return -EAGAIN; + + return 0; +} + static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, + .fb_mmap= exynos_drm_fb_mmap, .fb_fillrect= cfb_fillrect, .fb_copyarea= cfb_copyarea, .fb_imageblit = cfb_imageblit, -- 1.7.0.4
[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code
On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote: > Making it easier to controlwhen it is executed. > > Signed-off-by: Christian K?nig [...] > diff --git a/drivers/gpu/drm/radeon/radeon_device.c > b/drivers/gpu/drm/radeon/radeon_device.c > index 254fdb4..bbd0971 100644 > --- a/drivers/gpu/drm/radeon/radeon_device.c > +++ b/drivers/gpu/drm/radeon/radeon_device.c > @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev, > if (r) > return r; > > + r = radeon_ib_ring_tests(rdev); > + if (r) > + DRM_ERROR("ib ring test failed (%d).\n", r); > + > if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { > /* Acceleration not working on AGP card try again >* with fallback to PCI or PCIE GART I think this needs to set rdev->accel_working = false on failure, so the AGP -> PCI(e) fallback can kick in. Not sure about the other places where you're adding radeon_ib_ring_tests() calls, might need more error handling as well. -- Earthling Michel D?nzer | http://www.amd.com Libre software enthusiast | Debian, X and DRI developer
[PATCH 16/16] drm/radeon: implement ring saving on reset
On Mon, 2012-07-09 at 12:42 +0200, Christian K?nig wrote: > Try to save whatever is on the rings when > we encounter an lockup. > > Signed-off-by: Christian K?nig [...] > @@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev) > resched = ttm_bo_lock_delayed_workqueue(>mman.bdev); > radeon_suspend(rdev); > > + for (i = 0; i < RADEON_NUM_RINGS; ++i) { > + ring_sizes[i] = radeon_ring_backup(rdev, >ring[i], > +_data[i]); > + if (ring_sizes[i]) { > + saved = true; > + dev_info(rdev->dev, "Saved %d dwords of commands " > + "on ring %d.\n", ring_sizes[i], i); > + } > + } > + > +retry: > r = radeon_asic_reset(rdev); > if (!r) { > - dev_info(rdev->dev, "GPU reset succeed\n"); > + dev_info(rdev->dev, "GPU reset succeed trying to resume\n"); Could fix the spelling of 'succeeded' while you're at it. :) > radeon_resume(rdev); > + } > > - r = radeon_ib_ring_tests(rdev); > - if (r) > - DRM_ERROR("ib ring test failed (%d).\n", r); > + radeon_restore_bios_scratch_regs(rdev); > + drm_helper_resume_force_mode(rdev->ddev); > + > + if (!r) { > + for (i = 0; i < RADEON_NUM_RINGS; ++i) { > + radeon_ring_restore(rdev, >ring[i], > + ring_sizes[i], ring_data[i]); > + } If radeon_asic_reset fails, this leaks the memory referenced by ring_data, doesn't it? Also, the added functions aren't documented as mandated by the rules Alex proposed. -- Earthling Michel D?nzer | http://www.amd.com Libre software enthusiast | Debian, X and DRI developer
[PATCH v3] drm/exynos: use __free_page() to deallocate memory
this patch uses __free_page() to deallocate the pages allocated by alloc_page() and the pages doesn't need set_parge_dirty() and mark_page_accessed() because they aren't from page cache so removes them. this patch has a pair with previous patch below, http://www.spinics.net/lists/dri-devel/msg24382.html Changelog v2: remove unnecessary arguments. Changelog v3: fix npages type. - npages can have negative value. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 21 ++--- 1 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index dceb69f..3ccda0c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -126,23 +126,14 @@ fail: } static void exynos_gem_put_pages(struct drm_gem_object *obj, - struct page **pages, - bool dirty, bool accessed) + struct page **pages) { - int i, npages; + int npages; npages = obj->size >> PAGE_SHIFT; - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } + while (--npages >= 0) + __free_page(pages[npages]); drm_free_large(pages); } @@ -222,7 +213,7 @@ err1: kfree(buf->sgt); buf->sgt = NULL; err: - exynos_gem_put_pages(obj, pages, true, false); + exynos_gem_put_pages(obj, pages); return ret; } @@ -240,7 +231,7 @@ static void exynos_drm_gem_put_pages(struct drm_gem_object *obj) kfree(buf->sgt); buf->sgt = NULL; - exynos_gem_put_pages(obj, buf->pages, true, false); + exynos_gem_put_pages(obj, buf->pages); buf->pages = NULL; /* add some codes for UNCACHED type here. TODO */ -- 1.7.4.1
[PATCH v2] drm/exynos: use __free_page() to deallocate memory
this patch uses __free_page() to deallocate the pages allocated by alloc_page() and the pages doesn't need set_parge_dirty() and mark_page_accessed() because they aren't from page cache so removes them. this patch has a pair with previous patch below, http://www.spinics.net/lists/dri-devel/msg24382.html Changelog v2: remove unnecessary arguments. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 21 ++--- 1 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index dceb69f..e6ca2b3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -126,23 +126,14 @@ fail: } static void exynos_gem_put_pages(struct drm_gem_object *obj, - struct page **pages, - bool dirty, bool accessed) + struct page **pages) { - int i, npages; + unsigned int npages; npages = obj->size >> PAGE_SHIFT; - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } + while (--npages >= 0) + __free_page(pages[npages]); drm_free_large(pages); } @@ -222,7 +213,7 @@ err1: kfree(buf->sgt); buf->sgt = NULL; err: - exynos_gem_put_pages(obj, pages, true, false); + exynos_gem_put_pages(obj, pages); return ret; } @@ -240,7 +231,7 @@ static void exynos_drm_gem_put_pages(struct drm_gem_object *obj) kfree(buf->sgt); buf->sgt = NULL; - exynos_gem_put_pages(obj, buf->pages, true, false); + exynos_gem_put_pages(obj, buf->pages); buf->pages = NULL; /* add some codes for UNCACHED type here. TODO */ -- 1.7.4.1
[PATCH 2/2] drm/exynos: fixed exception to page allocation failure
this patch corrects to deallocate the pages allocated already at alloc_page failure. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_gem.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 4b8b988..d0b3059 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -118,7 +118,7 @@ struct page **exynos_gem_get_pages(struct drm_gem_object *obj, return pages; fail: - while (i--) + while (--i) __free_page(pages[i]); drm_free_large(pages); -- 1.7.4.1
[PATCH 1/2] drm/exynos: use __free_page() to deallocate memory
this patch uses __free_page() to deallocate the pages allocated by alloc_page() and the pages doesn't need set_parge_dirty() and mark_page_accessed() because they aren't from page cache so removes them. this patch has a pair with previous patch below, http://www.spinics.net/lists/dri-devel/msg24382.html Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 14 +++--- 1 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index dceb69f..4b8b988 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -129,20 +129,12 @@ static void exynos_gem_put_pages(struct drm_gem_object *obj, struct page **pages, bool dirty, bool accessed) { - int i, npages; + unsigned int npages; npages = obj->size >> PAGE_SHIFT; - for (i = 0; i < npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } + while (--npages >= 0) + __free_page(pages[npages]); drm_free_large(pages); } -- 1.7.4.1
[PATCH 0/2] fix memory deallocation and exception
this patch corrects to deallocate the pages allocated by alloc_page() and fixes exception to page allocation failure. Thanks. Inki Dae (2): drm/exynos: use __free_page() to deallocate memory drm/exynos: fixed exception to page allocation failure drivers/gpu/drm/exynos/exynos_drm_gem.c | 16 1 files changed, 4 insertions(+), 12 deletions(-) -- 1.7.4.1
[REGRESSION] nouveau: Memory corruption using nva3 engine for 0xaf
On Thu, Jul 05, 2012 at 10:34:10AM +0200, Henrik Rydberg wrote: > On Thu, Jul 05, 2012 at 08:54:46AM +0200, Henrik Rydberg wrote: > > > Thanks for tracking down the source of this corruption. I don't have > > > any such hardware, so until someone can figure it out, I think we > > > should apply this patch. > > > > In that case, I would have to massage the patch a bit first; it > > creates a problem with suspend/resume. Might be something with > > nva3_pm.c, who knows. I am really stabbing in the dark here. :-) > > It seems the suspend/resume problem is unrelated (bad systemd update), > so I am fine with applying this as is. Obviously not the best > solution, and if I have time I will continue to look for problems in > the nva3 copy code, but for now, > > Signed-off-by: Henrik Rydberg I have not encountered the problem in a long while, and I do not have the patch applied. It is entirely possible that this was fixed by something else. Unless you have already applied the patch, I would suggest holding on to it to see if the problem reappears. Sorry for the churn. Thanks, Henrik
[Bug 51870] r600_streamout=1 nothing change
https://bugs.freedesktop.org/show_bug.cgi?id=51870 Michel D?nzer changed: What|Removed |Added AssignedTo|xorg-driver-ati at lists.x.org |dri-devel at lists.freedesktop ||.org QAContact|xorg-team at lists.x.org | Product|xorg|Mesa Version|7.4 (2008.09) |git Component|Driver/Radeon |Drivers/Gallium/r600 -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug.
3.5-rc5: radeon acceleration regression on Transmeta system
> > > In 3.4, radeon worked with a glitch - window titles were see-throug (not > > > drawn). In 3.5-rc5, radeon driver seems to be more careful and disables > > > acceleration on this system at all. Full dmesg below. > > > > Does it always do it the same? got the dmesg from 3.4 and/or 2.6.32? > > That was a good question. I did some more tries, and it was not > repeatable. Sometimes it worked like 3.4 did - rv100 initialized fine, > no borders except when maximized, otherwise worked. Re-tested 3.4.0-rc7 that I had availble from 3.4 times, it worked 4 out of 4 times. > Initial windows border problem seems to have been introduced between > 2.6.37 and 2.6.38, bisect is slow. It's actually more complicated than that. Old kernel images started misbehaving from around 2.6.35-rc5 and any kernel older than that was OK. When I recompiled the older kernels with squeeze gcc (migh have been lenny gcc before, or different answers to make oldconfig), anything from current git down to 2.6.33 is broken with radeon.modeset=1 and works (I get window titles) with radeon.modeset=0. 2.6.32 works and has kernel modesetting enabled from dmesg but I think I did not notice screen going fbcon during boot... maybe it only used the modesetting when X started. So there are 2 different problems (maybe related), the new one above and the old one of not seeing some window borders when modesetting and acceleration are in use. Maximized windows do have borders. -- Meelis Roos (mroos at linux.ee)
[PATCH v2] drm/exynos: check if framebuffer and gem size are valid or not.
with addfb request by user, wrong framebuffer or gem size could be sent to kernel side so this could induce invalid memory access by dma of a device. this patch checks if framebuffer and gem size are valid or not to avoid this issue. Changelog v2: use fb->pitches instead of caculating it with fb->width and fb->bpp as line size. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_fb.c | 47 ++- 1 files changed, 45 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 4ccfe43..f1b1008 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -48,6 +48,44 @@ struct exynos_drm_fb { struct exynos_drm_gem_obj *exynos_gem_obj[MAX_FB_BUFFER]; }; +static int check_fb_gem_size(struct drm_device *drm_dev, + struct drm_framebuffer *fb, + unsigned int nr) +{ + unsigned long fb_size; + struct drm_gem_object *obj; + struct exynos_drm_gem_obj *exynos_gem_obj; + struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); + + /* in case of RGB format, only one plane is used. */ + if (nr < 2) { + exynos_gem_obj = exynos_fb->exynos_gem_obj[0]; + obj = _gem_obj->base; + fb_size = fb->pitches[0] * fb->height; + + if (fb_size != exynos_gem_obj->packed_size) { + DRM_ERROR("invalid fb or gem size.\n"); + return -EINVAL; + } + /* in case of NV12MT, YUV420M and so on, two and three planes. */ + } else { + unsigned int i; + + for (i = 0; i < nr; i++) { + exynos_gem_obj = exynos_fb->exynos_gem_obj[i]; + obj = _gem_obj->base; + fb_size = fb->pitches[i] * fb->height; + + if (fb_size != exynos_gem_obj->packed_size) { + DRM_ERROR("invalid fb or gem size.\n"); + return -EINVAL; + } + } + } + + return 0; +} + static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) { struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); @@ -134,8 +172,7 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, struct drm_gem_object *obj; struct drm_framebuffer *fb; struct exynos_drm_fb *exynos_fb; - int nr; - int i; + int nr, i, ret; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -166,6 +203,12 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj); } + ret = check_fb_gem_size(dev, fb, nr); + if (ret < 0) { + exynos_drm_fb_destroy(fb); + return ERR_PTR(ret); + } + return fb; } -- 1.7.4.1
[git pull] drm/exynos: updated exynos-drm-fixes
Hi Dave, Please pull from git://git.infradead.org/users/kmpark/linux-samsung exynos-drm-fixes these patch sets below had already been posted several weeks ago for review and include some fixes and exceptions. thes patch sets are based on git repository below: git://people.freedesktop.org/~airlied/linux.git drm-fixes commit-id: 9f846a16d213523fbe6daea17e20df6b8ac5a1e5 Thanks. Cooper Yuan (1): drm/exynos: fix buffer pitch calculation Inki Dae (11): drm/exynos: removed unnecessary declaration. drm/exynos: set edid fake data only for test. drm/exynos: check if raw edid data is fake or not for test drm/exynos: fixed edid data setting at vidi connection request drm/exynos: fixed build warning. drm/exynos: use alloc_page() to allocate pages. drm/exynos: set buffer type from exporter. drm/exynos: do not release memory region from exporter. drm/exynos: removed unnecessary variable drm/exynos: fixed a comment to gem size. drm/exynos: add packed_size not aligned in page unit. Sachin Kamat (4): drm/exynos: Add missing static storage class specifier drm/exynos: Use devm_* functions in exynos_drm_fimd.c drm/exynos: Use devm_* functions in exynos_hdmi.c drm/exynos: Use devm_* functions in exynos_mixer.c Subash Patel (2): drm/exynos: return NULL if exynos_pages_to_sg fails drm/exynos: check for null in return value of dma_buf_map_attachment() drivers/gpu/drm/exynos/exynos_drm_connector.c |3 +- drivers/gpu/drm/exynos/exynos_drm_core.c |5 -- drivers/gpu/drm/exynos/exynos_drm_dmabuf.c| 33 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 40 --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 28 +++-- drivers/gpu/drm/exynos/exynos_drm_gem.h |6 ++- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 53 +++-- drivers/gpu/drm/exynos/exynos_hdmi.c | 36 +++- drivers/gpu/drm/exynos/exynos_mixer.c | 48 +++ 9 files changed, 118 insertions(+), 134 deletions(-) -- 1.7.4.1
[PATCH 16/16] drm/radeon: implement ring saving on reset
Try to save whatever is on the rings when we encounter an lockup. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/radeon.h|4 ++ drivers/gpu/drm/radeon/radeon_device.c | 44 drivers/gpu/drm/radeon/radeon_ring.c | 69 3 files changed, 109 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9c11be8..1265840 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -770,6 +770,10 @@ int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); void radeon_ring_lockup_update(struct radeon_ring *ring); bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); +unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring, + uint32_t **data); +int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned size, uint32_t *data); int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, unsigned align, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index bbd0971..97696e5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -996,7 +996,12 @@ int radeon_resume_kms(struct drm_device *dev) int radeon_gpu_reset(struct radeon_device *rdev) { - int r; + unsigned ring_sizes[RADEON_NUM_RINGS]; + uint32_t *ring_data[RADEON_NUM_RINGS]; + + bool saved = false; + + int i, r; int resched; down_write(>exclusive_lock); @@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev) resched = ttm_bo_lock_delayed_workqueue(>mman.bdev); radeon_suspend(rdev); + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + ring_sizes[i] = radeon_ring_backup(rdev, >ring[i], + _data[i]); + if (ring_sizes[i]) { + saved = true; + dev_info(rdev->dev, "Saved %d dwords of commands " +"on ring %d.\n", ring_sizes[i], i); + } + } + +retry: r = radeon_asic_reset(rdev); if (!r) { - dev_info(rdev->dev, "GPU reset succeed\n"); + dev_info(rdev->dev, "GPU reset succeed trying to resume\n"); radeon_resume(rdev); + } - r = radeon_ib_ring_tests(rdev); - if (r) - DRM_ERROR("ib ring test failed (%d).\n", r); + radeon_restore_bios_scratch_regs(rdev); + drm_helper_resume_force_mode(rdev->ddev); + + if (!r) { + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + radeon_ring_restore(rdev, >ring[i], + ring_sizes[i], ring_data[i]); + } - radeon_restore_bios_scratch_regs(rdev); - drm_helper_resume_force_mode(rdev->ddev); - ttm_bo_unlock_delayed_workqueue(>mman.bdev, resched); + r = radeon_ib_ring_tests(rdev); + if (r) { + dev_err(rdev->dev, "ib ring test failed (%d).\n", r); + if (saved) { + radeon_suspend(rdev); + goto retry; + } + } } + ttm_bo_unlock_delayed_workqueue(>mman.bdev, resched); if (r) { /* bad news, how to tell it to userspace ? */ dev_info(rdev->dev, "GPU reset failed\n"); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 994c98c..6ce51d6 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -385,6 +385,75 @@ static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring) return result; } +unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring, + uint32_t **data) +{ + unsigned size, ptr, i; + int commit; + + /* just in case lock the ring */ + mutex_lock(>ring_lock); + *data = NULL; + + if (ring->ring_obj == NULL) { + mutex_unlock(>ring_lock); + return 0; + } + + /* first of all update the rptr directly from the hw */ + ring->rptr = (RREG32(ring->rptr_reg) & ring->ptr_reg_mask) +>> ring->ptr_reg_shift; + + /* find the first commit not processed so far */ + commit = radeon_ring_first_valid_commit(ring); + if (commit == ring->track_ptr) { +
[PATCH 15/16] drm/radeon: implement ring commit tracking
Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/radeon.h |3 +++ drivers/gpu/drm/radeon/radeon_ring.c | 39 -- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index fef4257..9c11be8 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -637,6 +637,9 @@ struct radeon_ring { u32 ptr_reg_shift; u32 ptr_reg_mask; u32 nop; + unsigned*track_back; + unsignedtrack_ptr; + unsignedtrack_mask; }; /* diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index d9b2e45..994c98c 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) DRM_MEMORYBARRIER(); WREG32(ring->wptr_reg, (ring->wptr << ring->ptr_reg_shift) & ring->ptr_reg_mask); (void)RREG32(ring->wptr_reg); + ring->track_back[ring->track_ptr++] = ring->wptr_old; + ring->track_ptr &= ring->track_mask; } void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) @@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *rin return false; } +static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring) +{ + unsigned i, c, result = ring->track_ptr; + i = ring->track_ptr - 1; + while (i != ring->track_ptr) { + i &= ring->track_mask; + c = ring->track_back[i]; + + if (ring->wptr >= ring->rptr) { + if (c < ring->rptr || c >= ring->wptr) + break; + } else { + if (c < ring->rptr && c >= ring->wptr) + break; + } + + result = i--; + } + return result; +} + int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, unsigned align, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, @@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, dev_err(rdev->dev, "(%d) ring map failed\n", r); return r; } + ring->track_back = kmalloc(ring_size / align, GFP_KERNEL); + memset(ring->track_back, 0, ring_size / align); + ring->track_ptr = 0; + ring->track_mask = ((ring->ring_size / 4) / align) - 1; } ring->ptr_mask = (ring->ring_size / 4) - 1; ring->ring_free_dw = ring->ring_size / 4; @@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) ring->ready = false; ring->ring = NULL; ring->ring_obj = NULL; + kfree(ring->track_back); mutex_unlock(>ring_lock); if (ring_obj) { @@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) struct radeon_device *rdev = dev->dev_private; int ridx = *(int*)node->info_ent->data; struct radeon_ring *ring = >ring[ridx]; - unsigned count, i, j; + unsigned count, i, j, commit; radeon_ring_free_size(rdev, ring); count = (ring->ring_size / 4) - ring->ring_free_dw; @@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); seq_printf(m, "%u dwords in ring\n", count); + commit = radeon_ring_first_valid_commit(ring); i = ring->rptr; for (j = 0; j <= count; j++) { - seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); + seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]); + if (commit != ring->track_ptr && ring->track_back[commit] == i) { + seq_printf(m, " <-"); + ++commit; + commit &= ring->track_mask; + } + seq_printf(m, "\n"); i = (i + 1) & ring->ptr_mask; } return 0; -- 1.7.9.5
[PATCH 14/16] drm/radeon: make align a ring_init parameter
Instead of setting it directly from the chipset code. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/evergreen.c |3 ++- drivers/gpu/drm/radeon/ni.c |3 ++- drivers/gpu/drm/radeon/r100.c|3 +-- drivers/gpu/drm/radeon/r600.c|3 +-- drivers/gpu/drm/radeon/radeon.h |3 ++- drivers/gpu/drm/radeon/radeon_ring.c |4 +++- drivers/gpu/drm/radeon/rv770.c |3 ++- drivers/gpu/drm/radeon/si.c |9 ++--- 8 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f39b900..f0bbbe1 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3075,7 +3075,8 @@ static int evergreen_startup(struct radeon_device *rdev) } evergreen_irq_set(rdev); - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring->ring_size, 16, +RADEON_WB_CP_RPTR_OFFSET, R600_CP_RB_RPTR, R600_CP_RB_WPTR, 0, 0xf, RADEON_CP_PACKET2); if (r) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index f2afefb..c69cebc 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1258,7 +1258,8 @@ static int cayman_startup(struct radeon_device *rdev) } evergreen_irq_set(rdev); - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring->ring_size, 16, +RADEON_WB_CP_RPTR_OFFSET, CP_RB0_RPTR, CP_RB0_WPTR, 0, 0xf, RADEON_CP_PACKET2); if (r) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e0f5ae8..116432f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -977,7 +977,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_bufsz = drm_order(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; r100_cp_load_microcode(rdev); - r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring_size, 16, RADEON_WB_CP_RPTR_OFFSET, RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR, 0, 0x7f, RADEON_CP_PACKET2); if (r) { @@ -988,7 +988,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_blksz = 9; /* cp will read 128bytes at a time (4 dwords) */ max_fetch = 1; - ring->align_mask = 16 - 1; /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */ pre_write_timer = 64; /* Force CP_RB_WPTR write if written more than one time before the diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c808fa9..7d15490 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2160,7 +2160,6 @@ void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsign rb_bufsz = drm_order(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; ring->ring_size = ring_size; - ring->align_mask = 16 - 1; } void r600_cp_fini(struct radeon_device *rdev) @@ -2376,7 +2375,7 @@ int r600_startup(struct radeon_device *rdev) } r600_irq_set(rdev); - r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring->ring_size, 16, RADEON_WB_CP_RPTR_OFFSET, R600_CP_RB_RPTR, R600_CP_RB_WPTR, 0, 0xf, RADEON_CP_PACKET2); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 872270c..fef4257 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -767,7 +767,8 @@ int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); void radeon_ring_lockup_update(struct radeon_ring *ring); bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); -int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, +int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, +unsigned ring_size, unsigned align, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 0873834..d9b2e45 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++
[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code
Making it easier to controlwhen it is executed. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/evergreen.c |4 drivers/gpu/drm/radeon/ni.c|4 drivers/gpu/drm/radeon/r100.c |4 drivers/gpu/drm/radeon/r300.c |4 drivers/gpu/drm/radeon/r420.c |4 drivers/gpu/drm/radeon/r520.c |4 drivers/gpu/drm/radeon/r600.c |4 drivers/gpu/drm/radeon/radeon_device.c | 15 +++ drivers/gpu/drm/radeon/rs400.c |4 drivers/gpu/drm/radeon/rs600.c |4 drivers/gpu/drm/radeon/rs690.c |4 drivers/gpu/drm/radeon/rv515.c |4 drivers/gpu/drm/radeon/rv770.c |4 drivers/gpu/drm/radeon/si.c| 21 - 14 files changed, 15 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 82f7aea..f39b900 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3093,10 +3093,6 @@ static int evergreen_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - r = r600_audio_init(rdev); if (r) { DRM_ERROR("radeon: audio init failed\n"); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ec5307c..f2afefb 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1276,10 +1276,6 @@ static int cayman_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - r = radeon_vm_manager_init(rdev); if (r) { dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 9524bd4..e0f5ae8 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3887,10 +3887,6 @@ static int r100_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index b396e34..646a192 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1397,10 +1397,6 @@ static int r300_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 0062938..f2f5bf6 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -281,10 +281,6 @@ static int r420_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 6df3e51..079d3c5 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -209,10 +209,6 @@ static int r520_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index af2f74a..c808fa9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2395,10 +2395,6 @@ int r600_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - r = r600_audio_init(rdev); if (r) { DRM_ERROR("radeon: audio init failed\n"); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 254fdb4..bbd0971 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev, if (r) return r; + r = radeon_ib_ring_tests(rdev); + if (r) + DRM_ERROR("ib ring test failed (%d).\n", r); + if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { /* Acceleration not working on AGP card try again * with fallback to PCI or PCIE GART @@ -946,6 +950,7 @@ int radeon_resume_kms(struct drm_device *dev) { struct drm_connector *connector; struct radeon_device *rdev = dev->dev_private; + int r; if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; @@ -960,6 +965,11 @@ int radeon_resume_kms(struct drm_device *dev) /* resume AGP if in use */ radeon_agp_resume(rdev);
[PATCH 12/16] drm/radeon: remove vm_manager start/suspend
Just restore the page table instead. Addressing three problem with this change: 1. Calling vm_manager_suspend in the suspend path is problematic cause it wants to wait for the VM use to end, which in case of a lockup never happens. 2. In case of a locked up memory controller unbinding the VM seems to make it even more unstable, creating an unrecoverable lockup in the end. 3. If we want to backup/restore the leftover ring content we must not unbind VMs in between. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/ni.c | 12 ++--- drivers/gpu/drm/radeon/radeon.h |2 - drivers/gpu/drm/radeon/radeon_gart.c | 83 +- drivers/gpu/drm/radeon/si.c | 12 ++--- 4 files changed, 59 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 4004376..ec5307c 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_vm_manager_start(rdev); - if (r) + r = radeon_vm_manager_init(rdev); + if (r) { + dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); return r; + } r = r600_audio_init(rdev); if (r) @@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - radeon_vm_manager_suspend(rdev); cayman_cp_enable(rdev, false); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); @@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev) return r; rdev->accel_working = true; - r = radeon_vm_manager_init(rdev); - if (r) { - dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); - } - r = cayman_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 8a8c3f8..872270c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size */ int radeon_vm_manager_init(struct radeon_device *rdev); void radeon_vm_manager_fini(struct radeon_device *rdev); -int radeon_vm_manager_start(struct radeon_device *rdev); -int radeon_vm_manager_suspend(struct radeon_device *rdev); int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index ee11c50..56752da 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev) * * TODO bind a default page at vm initialization for default address */ + int radeon_vm_manager_init(struct radeon_device *rdev) { + struct radeon_vm *vm; + struct radeon_bo_va *bo_va; int r; - rdev->vm_manager.enabled = false; + if (!rdev->vm_manager.enabled) { + /* mark first vm as always in use, it's the system one */ + r = radeon_sa_bo_manager_init(rdev, >vm_manager.sa_manager, + rdev->vm_manager.max_pfn * 8, + RADEON_GEM_DOMAIN_VRAM); + if (r) { + dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", + (rdev->vm_manager.max_pfn * 8) >> 10); + return r; + } - /* mark first vm as always in use, it's the system one */ - r = radeon_sa_bo_manager_init(rdev, >vm_manager.sa_manager, - rdev->vm_manager.max_pfn * 8, - RADEON_GEM_DOMAIN_VRAM); - if (r) { - dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", - (rdev->vm_manager.max_pfn * 8) >> 10); - return r; + r = rdev->vm_manager.funcs->init(rdev); + if (r) + return r; + + rdev->vm_manager.enabled = true; + + r = radeon_sa_bo_manager_start(rdev, >vm_manager.sa_manager); + if (r) + return r; } - r = rdev->vm_manager.funcs->init(rdev); - if (r == 0) - rdev->vm_manager.enabled = true; + /* restore page table */ + list_for_each_entry(vm, >vm_manager.lru_vm, list) { + if (vm->id == -1) +
[PATCH 11/16] drm/radeon: remove r600_blit_suspend
Just reinitialize the shader content on resume instead. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/evergreen.c |1 - drivers/gpu/drm/radeon/evergreen_blit_kms.c | 40 +-- drivers/gpu/drm/radeon/ni.c |1 - drivers/gpu/drm/radeon/r600.c | 15 -- drivers/gpu/drm/radeon/r600_blit_kms.c | 40 +-- drivers/gpu/drm/radeon/radeon.h |2 -- drivers/gpu/drm/radeon/rv770.c |1 - drivers/gpu/drm/radeon/si.c |3 -- 8 files changed, 40 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 64e06e6..82f7aea 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3139,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev) struct radeon_ring *ring = >ring[RADEON_RING_TYPE_GFX_INDEX]; r600_audio_fini(rdev); - r600_blit_suspend(rdev); r700_cp_stop(rdev); ring->ready = false; evergreen_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index e512560..89cb9fe 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -634,10 +634,6 @@ int evergreen_blit_init(struct radeon_device *rdev) rdev->r600_blit.max_dim = 16384; - /* pin copy shader into vram if already initialized */ - if (rdev->r600_blit.shader_obj) - goto done; - rdev->r600_blit.state_offset = 0; if (rdev->family < CHIP_CAYMAN) @@ -668,11 +664,26 @@ int evergreen_blit_init(struct radeon_device *rdev) obj_size += cayman_ps_size * 4; obj_size = ALIGN(obj_size, 256); - r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, -NULL, >r600_blit.shader_obj); - if (r) { - DRM_ERROR("evergreen failed to allocate shader\n"); - return r; + /* pin copy shader into vram if not already initialized */ + if (!rdev->r600_blit.shader_obj) { + r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, +RADEON_GEM_DOMAIN_VRAM, +NULL, >r600_blit.shader_obj); + if (r) { + DRM_ERROR("evergreen failed to allocate shader\n"); + return r; + } + + r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); + if (unlikely(r != 0)) + return r; + r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, + >r600_blit.shader_gpu_addr); + radeon_bo_unreserve(rdev->r600_blit.shader_obj); + if (r) { + dev_err(rdev->dev, "(%d) pin blit object failed\n", r); + return r; + } } DRM_DEBUG("evergreen blit allocated bo %08x vs %08x ps %08x\n", @@ -714,17 +725,6 @@ int evergreen_blit_init(struct radeon_device *rdev) radeon_bo_kunmap(rdev->r600_blit.shader_obj); radeon_bo_unreserve(rdev->r600_blit.shader_obj); -done: - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, - >r600_blit.shader_gpu_addr); - radeon_bo_unreserve(rdev->r600_blit.shader_obj); - if (r) { - dev_err(rdev->dev, "(%d) pin blit object failed\n", r); - return r; - } radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index fe55310..4004376 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1316,7 +1316,6 @@ int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); radeon_vm_manager_suspend(rdev); - r600_blit_suspend(rdev); cayman_cp_enable(rdev, false); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 9750f53..af2f74a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2307,20 +2307,6 @@ int r600_copy_blit(struct radeon_device *rdev, return 0; } -void r600_blit_suspend(struct radeon_device *rdev) -{ - int r; - - /* unpin shaders bo */ - if (rdev->r600_blit.shader_obj) { - r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); - if (!r) { - radeon_bo_unpin(rdev->r600_blit.shader_obj); -
[PATCH 10/16] drm/radeon: remove ip_pool start/suspend
The IB pool is in gart memory, so it is completely superfluous to unpin / repin it on suspend / resume. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/evergreen.c | 17 ++--- drivers/gpu/drm/radeon/ni.c | 16 ++-- drivers/gpu/drm/radeon/r100.c| 23 ++- drivers/gpu/drm/radeon/r300.c| 17 ++--- drivers/gpu/drm/radeon/r420.c| 17 ++--- drivers/gpu/drm/radeon/r520.c| 14 +- drivers/gpu/drm/radeon/r600.c| 17 ++--- drivers/gpu/drm/radeon/radeon.h |2 -- drivers/gpu/drm/radeon/radeon_asic.h |1 - drivers/gpu/drm/radeon/radeon_ring.c | 17 +++-- drivers/gpu/drm/radeon/rs400.c | 17 ++--- drivers/gpu/drm/radeon/rs600.c | 17 ++--- drivers/gpu/drm/radeon/rs690.c | 17 ++--- drivers/gpu/drm/radeon/rv515.c | 16 ++-- drivers/gpu/drm/radeon/rv770.c | 17 ++--- drivers/gpu/drm/radeon/si.c | 16 ++-- 16 files changed, 84 insertions(+), 157 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index eb9a71a..64e06e6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3087,9 +3087,11 @@ static int evergreen_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_start(rdev); - if (r) + r = radeon_ib_pool_init(rdev); + if (r) { + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); return r; + } r = radeon_ib_ring_tests(rdev); if (r) @@ -3137,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev) struct radeon_ring *ring = >ring[RADEON_RING_TYPE_GFX_INDEX]; r600_audio_fini(rdev); - radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); r700_cp_stop(rdev); ring->ready = false; @@ -3224,20 +3225,14 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_init(rdev); rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } - r = evergreen_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); r700_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_ib_pool_fini(rdev); radeon_irq_kms_fini(rdev); evergreen_pcie_gart_fini(rdev); rdev->accel_working = false; @@ -3264,7 +3259,7 @@ void evergreen_fini(struct radeon_device *rdev) r700_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_ib_pool_fini(rdev); radeon_irq_kms_fini(rdev); evergreen_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 8b1df33..fe55310 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1270,9 +1270,11 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_start(rdev); - if (r) + r = radeon_ib_pool_init(rdev); + if (r) { + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); return r; + } r = radeon_ib_ring_tests(rdev); if (r) @@ -1313,7 +1315,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); r600_blit_suspend(rdev); cayman_cp_enable(rdev, false); @@ -1391,12 +1392,7 @@ int cayman_init(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_init(rdev); rdev->accel_working = true; - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } r = radeon_vm_manager_init(rdev); if (r) { dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); @@ -1410,7 +1406,7 @@ int cayman_init(struct radeon_device *rdev) if (rdev->flags & RADEON_IS_IGP) si_rlc_fini(rdev); radeon_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_ib_pool_fini(rdev); radeon_vm_manager_fini(rdev); radeon_irq_kms_fini(rdev); cayman_pcie_gart_fini(rdev); @@ -1441,7 +1437,7 @@ void cayman_fini(struct
[PATCH 09/16] drm/radeon: make cp init on cayman more robust
It's not critical, but the current code isn't 100% correct. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/ni.c | 133 ++- 1 file changed, 56 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 32a6082..8b1df33 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev) int cayman_cp_resume(struct radeon_device *rdev) { + static const int ridx[] = { + RADEON_RING_TYPE_GFX_INDEX, + CAYMAN_RING_TYPE_CP1_INDEX, + CAYMAN_RING_TYPE_CP2_INDEX + }; + static const unsigned cp_rb_cntl[] = { + CP_RB0_CNTL, + CP_RB1_CNTL, + CP_RB2_CNTL, + }; + static const unsigned cp_rb_rptr_addr[] = { + CP_RB0_RPTR_ADDR, + CP_RB1_RPTR_ADDR, + CP_RB2_RPTR_ADDR + }; + static const unsigned cp_rb_rptr_addr_hi[] = { + CP_RB0_RPTR_ADDR_HI, + CP_RB1_RPTR_ADDR_HI, + CP_RB2_RPTR_ADDR_HI + }; + static const unsigned cp_rb_base[] = { + CP_RB0_BASE, + CP_RB1_BASE, + CP_RB2_BASE + }; struct radeon_ring *ring; - u32 tmp; - u32 rb_bufsz; - int r; + int i, r; /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | @@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev) WREG32(CP_DEBUG, (1 << 27)); - /* ring 0 - compute and gfx */ - /* Set ring buffer size */ - ring = >ring[RADEON_RING_TYPE_GFX_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB0_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB0_WPTR, ring->wptr); - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFC); - WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0x); + WREG32(SCRATCH_UMSK, 0xff); - if (rdev->wb.enabled) - WREG32(SCRATCH_UMSK, 0xff); - else { - tmp |= RB_NO_UPDATE; - WREG32(SCRATCH_UMSK, 0); - } - - mdelay(1); - WREG32(CP_RB0_CNTL, tmp); - - WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB0_RPTR); + for (i = 0; i < 3; ++i) { + uint32_t rb_cntl; + uint64_t addr; - /* ring1 - compute only */ - /* Set ring buffer size */ - ring = >ring[CAYMAN_RING_TYPE_CP1_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; + /* Set ring buffer size */ + ring = >ring[ridx[i]]; + rb_cntl = drm_order(ring->ring_size / 8); + rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8; #ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; + rb_cntl |= BUF_SWAP_32BIT; #endif - WREG32(CP_RB1_CNTL, tmp); + WREG32(cp_rb_cntl[i], rb_cntl); - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB1_WPTR, ring->wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC); - WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); - - mdelay(1); - WREG32(CP_RB1_CNTL, tmp); - - WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); - - ring->rptr = RREG32(CP_RB1_RPTR); - - /* ring2 - compute only */ - /* Set ring buffer size */ - ring = >ring[CAYMAN_RING_TYPE_CP2_INDEX]; - rb_bufsz = drm_order(ring->ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB2_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); - ring->wptr = 0; - WREG32(CP_RB2_WPTR, ring->wptr); + /* set the wb address wether it's enabled or not */ + addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET; + WREG32(cp_rb_rptr_addr[i], addr & 0xFFFC); +
[PATCH 08/16] drm/radeon: remove FIXME comment from chipset suspend
For a normal suspend/resume we allready wait for the rings to be empty, and for a suspend/reasume in case of a lockup we REALLY don't want to wait for anything. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/evergreen.c |1 - drivers/gpu/drm/radeon/ni.c|1 - drivers/gpu/drm/radeon/r600.c |1 - drivers/gpu/drm/radeon/rv770.c |1 - drivers/gpu/drm/radeon/si.c|1 - 5 files changed, 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f716e08..eb9a71a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3137,7 +3137,6 @@ int evergreen_suspend(struct radeon_device *rdev) struct radeon_ring *ring = >ring[RADEON_RING_TYPE_GFX_INDEX]; r600_audio_fini(rdev); - /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); r700_cp_stop(rdev); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 2366be3..32a6082 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1334,7 +1334,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); r600_blit_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 43d0c41..de4de2d 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2461,7 +2461,6 @@ int r600_suspend(struct radeon_device *rdev) r600_audio_fini(rdev); radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); - /* FIXME: we should wait for ring to be empty */ r600_cp_stop(rdev); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b4f51c5..7e230f6 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -996,7 +996,6 @@ int rv770_suspend(struct radeon_device *rdev) r600_audio_fini(rdev); radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); - /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 34603b3c8..78c790f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -3807,7 +3807,6 @@ int si_resume(struct radeon_device *rdev) int si_suspend(struct radeon_device *rdev) { - /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); #if 0 -- 1.7.9.5
[PATCH 07/16] drm/radeon: fix fence init after resume
Start with last signaled fence number instead of last emitted one. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/radeon_fence.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index a194a14..76c5b22 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -578,7 +578,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) } rdev->fence_drv[ring].cpu_addr = >wb.wb[index/4]; rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; - radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring); + radeon_fence_write(rdev, atomic64_read(>fence_drv[ring].last_seq), ring); rdev->fence_drv[ring].initialized = true; dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n", ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); -- 1.7.9.5
[PATCH 06/16] drm/radeon: fix fence value access
It is possible that radeon_fence_process is called after writeback is disabled for suspend, leading to an invalid read of register 0x0. This fixes a problem for me where the fence value is temporary incremented by 0x1 on suspend/resume. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/radeon_fence.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index be4e4f3..a194a14 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -42,21 +42,23 @@ static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) { - if (rdev->wb.enabled) { - *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq); + struct radeon_fence_driver *drv = >fence_drv[ring]; + if (likely(rdev->wb.enabled || !drv->scratch_reg)) { + *drv->cpu_addr = cpu_to_le32(seq); } else { - WREG32(rdev->fence_drv[ring].scratch_reg, seq); + WREG32(drv->scratch_reg, seq); } } static u32 radeon_fence_read(struct radeon_device *rdev, int ring) { + struct radeon_fence_driver *drv = >fence_drv[ring]; u32 seq = 0; - if (rdev->wb.enabled) { - seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr); + if (likely(rdev->wb.enabled || !drv->scratch_reg)) { + seq = le32_to_cpu(*drv->cpu_addr); } else { - seq = RREG32(rdev->fence_drv[ring].scratch_reg); + seq = RREG32(drv->scratch_reg); } return seq; } -- 1.7.9.5
[PATCH 05/16] drm/radeon: fix ring commit padding
We don't need to pad anything if the number of dwords written to the ring already matches the requirements. Fixes some "writting more dword to ring than expected" warnings. Signed-off-by: Christian K?nig --- drivers/gpu/drm/radeon/radeon_ring.c |7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 0826e77..674aaba 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -272,13 +272,8 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) { - unsigned count_dw_pad; - unsigned i; - /* We pad to match fetch size */ - count_dw_pad = (ring->align_mask + 1) - - (ring->wptr & ring->align_mask); - for (i = 0; i < count_dw_pad; i++) { + while (ring->wptr & ring->align_mask) { radeon_ring_write(ring, ring->nop); } DRM_MEMORYBARRIER(); -- 1.7.9.5
[PATCH 04/16] drm/radeon: add an exclusive lock for GPU reset v2
From: Jerome GlisseGPU reset need to be exclusive, one happening at a time. For this add a rw semaphore so that any path that trigger GPU activities have to take the semaphore as a reader thus allowing concurency. The GPU reset path take the semaphore as a writer ensuring that no concurrent reset take place. v2: init rw semaphore Signed-off-by: Jerome Glisse --- drivers/gpu/drm/radeon/radeon.h|1 + drivers/gpu/drm/radeon/radeon_cs.c |5 + drivers/gpu/drm/radeon/radeon_device.c |3 +++ drivers/gpu/drm/radeon/radeon_gem.c|8 4 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5861ec8..4487873 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1446,6 +1446,7 @@ struct radeon_device { struct device *dev; struct drm_device *ddev; struct pci_dev *pdev; + struct rw_semaphore exclusive_lock; /* ASIC */ union radeon_asic_configconfig; enum radeon_family family; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index d5aec09..553da67 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -499,7 +499,9 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) struct radeon_cs_parser parser; int r; + down_read(>exclusive_lock); if (!rdev->accel_working) { + up_read(>exclusive_lock); return -EBUSY; } /* initialize parser */ @@ -512,6 +514,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) { DRM_ERROR("Failed to initialize parser !\n"); radeon_cs_parser_fini(, r); + up_read(>exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; } @@ -520,6 +523,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r != -ERESTARTSYS) DRM_ERROR("Failed to parse relocation %d!\n", r); radeon_cs_parser_fini(, r); + up_read(>exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; } @@ -533,6 +537,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } out: radeon_cs_parser_fini(, r); + up_read(>exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index f654ba8..254fdb4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -734,6 +734,7 @@ int radeon_device_init(struct radeon_device *rdev, mutex_init(>gem.mutex); mutex_init(>pm.mutex); init_rwsem(>pm.mclk_lock); + init_rwsem(>exclusive_lock); init_waitqueue_head(>irq.vblank_queue); init_waitqueue_head(>irq.idle_queue); r = radeon_gem_init(rdev); @@ -988,6 +989,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) int r; int resched; + down_write(>exclusive_lock); radeon_save_bios_scratch_regs(rdev); /* block TTM */ resched = ttm_bo_lock_delayed_workqueue(>mman.bdev); @@ -1007,6 +1009,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) dev_info(rdev->dev, "GPU reset failed\n"); } + up_write(>exclusive_lock); return r; } diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index d9b0809..b0be9c4 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -215,12 +215,14 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, uint32_t handle; int r; + down_read(>exclusive_lock); /* create a gem object to contain this object in */ args->size = roundup(args->size, PAGE_SIZE); r = radeon_gem_object_create(rdev, args->size, args->alignment, args->initial_domain, false, false, ); if (r) { + up_read(>exclusive_lock); r = radeon_gem_handle_lockup(rdev, r); return r; } @@ -228,10 +230,12 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gobj); if (r) { + up_read(>exclusive_lock); r = radeon_gem_handle_lockup(rdev, r); return r; } args->handle = handle; + up_read(>exclusive_lock); return 0; } @@
[PATCH 03/16] drm/radeon: fix fence related segfault in CS
Don't return success if scheduling the IB fails, otherwise we end up with an oops in ttm_eu_fence_buffer_objects. Signed-off-by: Christian K?nig Cc: stable at vger.kernel.org --- drivers/gpu/drm/radeon/radeon_cs.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index f1b7527..d5aec09 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -358,7 +358,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, if (r) { DRM_ERROR("Failed to schedule IB !\n"); } - return 0; + return r; } static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, -- 1.7.9.5
[PATCH 02/16] drm/radeon: add error handling to radeon_vm_unbind_locked
Waiting for a fence can fail for different reasons, the most common is a deadlock. Signed-off-by: Christian K?nig Reviewed-by: Michel D?nzer --- drivers/gpu/drm/radeon/radeon_gart.c | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 2b34c1a..ee11c50 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -316,10 +316,21 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, } /* wait for vm use to end */ - if (vm->fence) { - radeon_fence_wait(vm->fence, false); - radeon_fence_unref(>fence); + while (vm->fence) { + int r; + r = radeon_fence_wait(vm->fence, false); + if (r) + DRM_ERROR("error while waiting for fence: %d\n", r); + if (r == -EDEADLK) { + mutex_unlock(>vm_manager.lock); + r = radeon_gpu_reset(rdev); + mutex_lock(>vm_manager.lock); + if (!r) + continue; + } + break; } + radeon_fence_unref(>fence); /* hw unbind */ rdev->vm_manager.funcs->unbind(rdev, vm); -- 1.7.9.5
[PATCH 01/16] drm/radeon: add error handling to fence_wait_empty_locked
Instead of returning the error handle it directly and while at it fix the comments about the ring lock. Signed-off-by: Christian K?nig Reviewed-by: Michel D?nzer --- drivers/gpu/drm/radeon/radeon.h |2 +- drivers/gpu/drm/radeon/radeon_fence.c | 33 + 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 77b4519b..5861ec8 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -239,7 +239,7 @@ void radeon_fence_process(struct radeon_device *rdev, int ring); bool radeon_fence_signaled(struct radeon_fence *fence); int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); -int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); +void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); int radeon_fence_wait_any(struct radeon_device *rdev, struct radeon_fence **fences, bool intr); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b55625..be4e4f3 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -440,14 +440,11 @@ int radeon_fence_wait_any(struct radeon_device *rdev, return 0; } +/* caller must hold ring lock */ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) { uint64_t seq; - /* We are not protected by ring lock when reading current seq but -* it's ok as worst case is we return to early while we could have -* wait. -*/ seq = atomic64_read(>fence_drv[ring].last_seq) + 1ULL; if (seq >= rdev->fence_drv[ring].sync_seq[ring]) { /* nothing to wait for, last_seq is @@ -457,15 +454,27 @@ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) return radeon_fence_wait_seq(rdev, seq, ring, false, false); } -int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) +/* caller must hold ring lock */ +void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) { - /* We are not protected by ring lock when reading current seq -* but it's ok as wait empty is call from place where no more -* activity can be scheduled so there won't be concurrent access -* to seq value. -*/ - return radeon_fence_wait_seq(rdev, rdev->fence_drv[ring].sync_seq[ring], -ring, false, false); + uint64_t seq = rdev->fence_drv[ring].sync_seq[ring]; + + while(1) { + int r; + r = radeon_fence_wait_seq(rdev, seq, ring, false, false); + if (r == -EDEADLK) { + mutex_unlock(>ring_lock); + r = radeon_gpu_reset(rdev); + mutex_lock(>ring_lock); + if (!r) + continue; + } + if (r) { + dev_err(rdev->dev, "error waiting for ring to become" + " idle (%d)\n", r); + } + return; + } } struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence) -- 1.7.9.5
[RFC] drm/radeon: restoring ring commands in case of a lockup
Hi, The following patchset tries to save and restore the not yet processed commands from the rings in case of a lockup and with that should make a userspace problem with a single application far less problematic. The first four patches are just stuff this patchset is based upon, followed by four patches which fix various bugs found while working on this feature. Followed by patches which change the way how memory is saved/restored on suspend/resume, basically before we have unpinned most of the buffer objects so it could be move from vram into system memory. But that is mostly unnecessary cause the buffer object either are already in system memory or their content can be easily reinitialized. The last three patches implement the actual tracking and restoring of commands in case of a lockup. Please take a look and review. Cheers, Christian.
[PATCH 15/16] drm/radeon: implement ring commit tracking
On Mon, Jul 9, 2012 at 11:48 AM, Christian K?nig wrote: > On 09.07.2012 17:36, Jerome Glisse wrote: >> >> On Mon, Jul 9, 2012 at 6:42 AM, Christian K?nig >> wrote: >>> >>> Signed-off-by: Christian K?nig >> >> Bit too complex to my taste, what about attached patch, it's lot >> simpler. (Haven't tested >> the patch but it should work) > > Cool idea! Depending on the writeback mechanism might not be the best part > of it, but in general speaking all rings should have more than enough > scratch registers for that!!! > > Going to change it. > > Thanks, > Christian. > Note that i haven't included the fence emit intentionally idea being if you resume ring you fence to emit the last fence as soon as possible and just pretend that the faulty ib succeeded. Cheers, Jerome
[RFC] drm/radeon: restoring ring commands in case of a lockup
On Mon, Jul 9, 2012 at 11:59 AM, Michel D?nzer wrote: > On Mon, 2012-07-09 at 12:41 +0200, Christian K?nig wrote: >> Hi, >> >> The following patchset tries to save and restore the not yet processed >> commands >> from the rings in case of a lockup and with that should make a userspace >> problem with a single application far less problematic. >> >> The first four patches are just stuff this patchset is based upon, followed >> by >> four patches which fix various bugs found while working on this feature. >> >> Followed by patches which change the way how memory is saved/restored on >> suspend/resume, basically before we have unpinned most of the buffer objects >> so >> it could be move from vram into system memory. But that is mostly unnecessary >> cause the buffer object either are already in system memory or their content >> can be easily reinitialized. >> >> The last three patches implement the actual tracking and restoring of >> commands >> in case of a lockup. Please take a look and review. > > Patches 3, 5 and 14 are > > Reviewed-by: Michel D?nzer > Patch 1-9 are Reviewed-by: Jerome Glisse Other looks good but i want to test them too and spend a bit more time to double check few things. Will try to do that tomorrow. Cheers, Jerome
[PATCH 15/16] drm/radeon: implement ring commit tracking
lt;= count; j++) { > - seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); > + seq_printf(m, "r[%04x]=0x%08x", i, ring->ring[i]); > + if (commit != ring->track_ptr && ring->track_back[commit] == > i) { > + seq_printf(m, " <-"); > + ++commit; > + commit &= ring->track_mask; > + } > + seq_printf(m, "\n"); > i = (i + 1) & ring->ptr_mask; > } > return 0; > -- > 1.7.9.5 > > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel -- next part -- A non-text attachment was scrubbed... Name: 0001-drm-radeon-record-what-is-next-valid-wptr-for-each-r.patch Type: application/octet-stream Size: 7152 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20120709/f0d368f6/attachment.obj>
[Bug 51870] r600_streamout=1 nothing change
https://bugs.freedesktop.org/show_bug.cgi?id=51870 --- Comment #2 from ErikAlesund 2012-07-09 11:13:09 UTC --- (In reply to comment #1) > Those environment variables aren't required anymore. GLSL 1.3 and streamout > are > enabled by default. The only thing missing is MSAA and there is no way to > enable it at the moment. Closing. If would be nice to avoid confusion remove this: 10 Requires env var R600_STREAMOUT=1 in the radeon's feature page: http://www.x.org/wiki/RadeonFeature/ Thanks -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug.
[PATCH 09/16] drm/radeon: make cp init on cayman more robust
On Mon, Jul 9, 2012 at 6:41 AM, Christian K?nig wrote: > It's not critical, but the current code isn't > 100% correct. > > Signed-off-by: Christian K?nig > --- > drivers/gpu/drm/radeon/ni.c | 133 > ++- > 1 file changed, 56 insertions(+), 77 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c > index 32a6082..8b1df33 100644 > --- a/drivers/gpu/drm/radeon/ni.c > +++ b/drivers/gpu/drm/radeon/ni.c > @@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev) > > int cayman_cp_resume(struct radeon_device *rdev) > { > + static const int ridx[] = { > + RADEON_RING_TYPE_GFX_INDEX, > + CAYMAN_RING_TYPE_CP1_INDEX, > + CAYMAN_RING_TYPE_CP2_INDEX > + }; > + static const unsigned cp_rb_cntl[] = { > + CP_RB0_CNTL, > + CP_RB1_CNTL, > + CP_RB2_CNTL, > + }; > + static const unsigned cp_rb_rptr_addr[] = { > + CP_RB0_RPTR_ADDR, > + CP_RB1_RPTR_ADDR, > + CP_RB2_RPTR_ADDR > + }; > + static const unsigned cp_rb_rptr_addr_hi[] = { > + CP_RB0_RPTR_ADDR_HI, > + CP_RB1_RPTR_ADDR_HI, > + CP_RB2_RPTR_ADDR_HI > + }; > + static const unsigned cp_rb_base[] = { > + CP_RB0_BASE, > + CP_RB1_BASE, > + CP_RB2_BASE > + }; > struct radeon_ring *ring; > - u32 tmp; > - u32 rb_bufsz; > - int r; > + int i, r; > > /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ > WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | > @@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev) > > WREG32(CP_DEBUG, (1 << 27)); > > - /* ring 0 - compute and gfx */ > - /* Set ring buffer size */ > - ring = >ring[RADEON_RING_TYPE_GFX_INDEX]; > - rb_bufsz = drm_order(ring->ring_size / 8); > - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; > -#ifdef __BIG_ENDIAN > - tmp |= BUF_SWAP_32BIT; > -#endif > - WREG32(CP_RB0_CNTL, tmp); > - > - /* Initialize the ring buffer's read and write pointers */ > - WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); > - ring->wptr = 0; > - WREG32(CP_RB0_WPTR, ring->wptr); > - > /* set the wb address wether it's enabled or not */ > - WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + > RADEON_WB_CP_RPTR_OFFSET) & 0xFFFC); > - WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + > RADEON_WB_CP_RPTR_OFFSET) & 0xFF); > WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) > >> 8) & 0x); > + WREG32(SCRATCH_UMSK, 0xff); This looks wrong you set the mask unconditionaly even if writeback is disabled. > - if (rdev->wb.enabled) > - WREG32(SCRATCH_UMSK, 0xff); > - else { > - tmp |= RB_NO_UPDATE; > - WREG32(SCRATCH_UMSK, 0); > - } > - > - mdelay(1); > - WREG32(CP_RB0_CNTL, tmp); > - > - WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); > - > - ring->rptr = RREG32(CP_RB0_RPTR); > + for (i = 0; i < 3; ++i) { > + uint32_t rb_cntl; > + uint64_t addr; > > - /* ring1 - compute only */ > - /* Set ring buffer size */ > - ring = >ring[CAYMAN_RING_TYPE_CP1_INDEX]; > - rb_bufsz = drm_order(ring->ring_size / 8); > - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; > + /* Set ring buffer size */ > + ring = >ring[ridx[i]]; > + rb_cntl = drm_order(ring->ring_size / 8); > + rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8; > #ifdef __BIG_ENDIAN > - tmp |= BUF_SWAP_32BIT; > + rb_cntl |= BUF_SWAP_32BIT; > #endif > - WREG32(CP_RB1_CNTL, tmp); > + WREG32(cp_rb_cntl[i], rb_cntl); > > - /* Initialize the ring buffer's read and write pointers */ > - WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); > - ring->wptr = 0; > - WREG32(CP_RB1_WPTR, ring->wptr); > - > - /* set the wb address wether it's enabled or not */ > - WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + > RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFC); > - WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + > RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); > - > - mdelay(1); > - WREG32(CP_RB1_CNTL, tmp); > - > - WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); > - > - ring->rptr = RREG32(CP_RB1_RPTR); > - > - /* ring2 - compute only */ > - /* Set ring buffer size */ > - ring = >ring[CAYMAN_RING_TYPE_CP2_INDEX]; > - rb_bufsz = drm_order(ring->ring_size / 8); > - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; > -#ifdef __BIG_ENDIAN > - tmp |= BUF_SWAP_32BIT; > -#endif > - WREG32(CP_RB2_CNTL,
[PATCH, RFC] i.MX DRM support
On Sun, Jul 08, 2012 at 08:35:55AM +0100, Dave Airlie wrote: > On Fri, Jul 6, 2012 at 11:58 PM, Greg Kroah-Hartman > wrote: > > On Mon, Jul 02, 2012 at 12:05:06PM +0200, Sascha Hauer wrote: > >> On Thu, Jun 14, 2012 at 03:43:22PM +0200, Sascha Hauer wrote: > >> > Hi All, > >> > > >> > The following is the state-of-the-art i.MX IPU (Image Processing Unit) > >> > DRM support. > >> > > >> > This code is around for quite some time now and has been posted several > >> > times with different APIs, first with plain old framebuffer support, now > >> > DRM, first platform device binding, now devicetree. Unfortunately there's > >> > quite much code needed to get something useful out of the IPU, so these > >> > patches haven't received a lot of attention from people not involved in > >> > i.MX. I think we have now come to a point where this code needs more > >> > public > >> > exposure and where it's easier to talk in incremental changes instead of > >> > blobs. Therefore I request this to go to staging for some cycles. > >> > >> Dave, Greg, > >> > >> Comments to this one? I addressed the comments I received so far and am > >> about to respin this series. Is it ok to put this to staging? If yes, > >> should I move the whole stuff into drivers/staging/ or should it stay > >> in drivers/gpu/drm with just a Kconfig dependency on STAGING? > > > > That's up to the DRM subsystem maintainer to choose. > > Sorry guys been out of the loop on arm drivers due to other things, > but probably should go in staging proper for now, until I can at least > spend time reviewing it. Right now we have dependencies on: http://www.mail-archive.com/dri-devel at lists.freedesktop.org/msg24409.html http://www.mail-archive.com/dri-devel at lists.freedesktop.org/msg24224.html We could move these two helpers into staging, but they are needed by other drivers from Laurent Pinchart and Lars-Peter Clausen aswell. So it would be good to have them available for them aswell. Could you have a look on these and consider applying? Thanks, Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Mesa shader compiling/optimizing process is too slow
Tiziano Bacocco writes: > I've done benchmarks and comparison between proprietary drivers and > Mesa, Mesa seems to be up to 200x slower compiling the same shader, > since i understand optimizing such part of code may take months or even > more, i have thought to solve it this way: > > Upon calling glLinkProgram , an unoptimized version of the shader ( > compiles much much faster ) is uploaded to the GPU > Then a separate thread is launched that will optimize the shader and as > soon it is done, on the next call to glUseProgram it will upload > optimized version in place of unoptimized one. > > This will solve many performance issues and temporary freezes with games > that load/unload content while running, while not reducing performance > once the background optimization is done Yeah, we've thought of this, and it would take some work. Sounds like a fun project for someone. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20120709/0b21e4c7/attachment.pgp>
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Fr?mmel changed: What|Removed |Added Attachment #75061|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Fr?mmel changed: What|Removed |Added Attachment #75121|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Fr?mmel changed: What|Removed |Added Attachment #75091|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Fr?mmel changed: What|Removed |Added Attachment #75071|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Fr?mmel changed: What|Removed |Added Attachment #75081|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
[Bug 42984] scrabled video with nouveau drivers on mac mini (320m)
https://bugzilla.kernel.org/show_bug.cgi?id=42984 m.b.lankhorst at gmail.com changed: What|Removed |Added CC||m.b.lankhorst at gmail.com --- Comment #15 from m.b.lankhorst at gmail.com 2012-07-09 08:33:00 --- This bug is fixed with commit a6a17859f1b and can be closed. It's backported to 3.2 stable and 3.4 with confirmation on 3.2.27 -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug.
question about drivers/gpu/drm/gma500/oaktrail_lvds.c
On Mon, 9 Jul 2012, Patrik Jakobsson wrote: > On Sun, Jul 8, 2012 at 10:16 PM, Alan Cox wrote: >> On Sun, 8 Jul 2012 10:39:43 +0200 (CEST) >> Julia Lawall wrote: >> >>> In the function oaktrail_lvds_mode_set, I don't think that the following >>> code makes any sense: >>> >>> /* Find the connector we're trying to set up */ >>> list_for_each_entry(connector, _config->connector_list, head) >>> { >>> if (!connector->encoder || connector->encoder->crtc != >>> crtc) >>> continue; >>> } >>> >>> if (!connector) { >>> DRM_ERROR("Couldn't find connector when setting mode"); >>> return; >>> } >>> >>> drm_connector_property_get_value( >>> connector, >>> dev->mode_config.scaling_mode_property, >>> ); >>> >>> The initial loop is a no-op, because it always continues. The test >>> !connector can never be true, because at the end of a list_for_each_entry >>> connector points to the list head, and calling >>> drm_connector_property_get_value on the list head probably does not make >>> sense. >> >> We test !connector->encoder rather than !connector ? > > It seems we should break on : > if (connector->encoder && connector->encoder == encoder) > > Then do a check after list iteration: > if (!connector || connector->encoder != encoder) >DRM_ERROR("Couldn't find connector when setting mode"); Possible. The !connector is still not needed, but the overall logic seems better. julia
question about drivers/gpu/drm/gma500/oaktrail_lvds.c
On Sun, Jul 8, 2012 at 10:16 PM, Alan Cox wrote: > On Sun, 8 Jul 2012 10:39:43 +0200 (CEST) > Julia Lawall wrote: > >> In the function oaktrail_lvds_mode_set, I don't think that the following >> code makes any sense: >> >> /* Find the connector we're trying to set up */ >> list_for_each_entry(connector, _config->connector_list, head) { >> if (!connector->encoder || connector->encoder->crtc != crtc) >> continue; >> } >> >> if (!connector) { >> DRM_ERROR("Couldn't find connector when setting mode"); >> return; >> } >> >> drm_connector_property_get_value( >> connector, >> dev->mode_config.scaling_mode_property, >> ); >> >> The initial loop is a no-op, because it always continues. The test >> !connector can never be true, because at the end of a list_for_each_entry >> connector points to the list head, and calling >> drm_connector_property_get_value on the list head probably does not make >> sense. > > We test !connector->encoder rather than !connector ? It seems we should break on : if (connector->encoder && connector->encoder == encoder) Then do a check after list iteration: if (!connector || connector->encoder != encoder) DRM_ERROR("Couldn't find connector when setting mode"); But my attention span is less than a jiffie right now... will look at it with fresh eyes tomorrow. -Patrik
[PATCH 3/3] drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c: remove invalid reference to list iterator variable
From: Julia LawallIf list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator. After the iteractor, entry->base.crtc.fb is not a meaningful value. What seems to be intended is crtc->fb, which gets the information from the last element of the list. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier c; expression E; iterator name list_for_each_entry; statement S; @@ list_for_each_entry(c,...) { ... when != break; when forall when strict } ... ( c = E | *c ) // Signed-off-by: Julia Lawall Acked-by: Paul Menzel --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 070fb23..634611a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -93,7 +93,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) if (crtc == NULL) return 0; - fb = entry->base.crtc.fb; + fb = crtc->fb; return vmw_kms_write_svga(dev_priv, w, h, fb->pitches[0], fb->bits_per_pixel, fb->depth);
[PATCH 2/3] drivers/gpu/drm/gma500/oaktrail_crtc.c: remove invalid reference to list iterator variable
From: Julia LawallIf list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator. A break is added after the switch; the break in the switch would jump out of the switch, but not out of the complete iteration. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier c; expression E; iterator name list_for_each_entry; statement S; @@ list_for_each_entry(c,...) { ... when != break; when forall when strict } ... ( c = E | *c ) // Signed-off-by: Julia Lawall Acked-by: Paul Menzel --- drivers/gpu/drm/gma500/oaktrail_crtc.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index f821c83..4b2172e 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -329,6 +329,7 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, is_mipi = true; break; } + break; } /* Disable the VGA plane that we never use */
[PATCH 1/3] drivers/gpu/drm/gma500/mdfld_intel_display.c: remove invalid reference to list iterator variable
From: Julia LawallIf list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator. A break is added after the switch; the break in the switch would jump out of the switch, but not out of the complete iteration. The null test on connector is also removed, because the iterator variable of list_for_each_entry is never null. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ identifier c; expression E; iterator name list_for_each_entry; statement S; @@ list_for_each_entry(c,...) { ... when != break; when forall when strict } ... ( c = E | *c ) // Signed-off-by: Julia Lawall Acked-by: Paul Menzel --- drivers/gpu/drm/gma500/mdfld_intel_display.c |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index 3f3cd61..fc1ced0 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -755,9 +755,6 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, sizeof(struct drm_display_mode)); list_for_each_entry(connector, _config->connector_list, head) { - if (!connector) - continue; - encoder = connector->encoder; if (!encoder) @@ -779,6 +776,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, is_hdmi = true; break; } + break; } /* Disable the VGA plane that we never use */
Re: question about drivers/gpu/drm/gma500/oaktrail_lvds.c
On Sun, 8 Jul 2012, Alan Cox wrote: On Sun, 8 Jul 2012 10:39:43 +0200 (CEST) Julia Lawall julia.law...@lip6.fr wrote: In the function oaktrail_lvds_mode_set, I don't think that the following code makes any sense: /* Find the connector we're trying to set up */ list_for_each_entry(connector, mode_config-connector_list, head) { if (!connector-encoder || connector-encoder-crtc != crtc) continue; } if (!connector) { DRM_ERROR(Couldn't find connector when setting mode); return; } drm_connector_property_get_value( connector, dev-mode_config.scaling_mode_property, v); The initial loop is a no-op, because it always continues. The test !connector can never be true, because at the end of a list_for_each_entry connector points to the list head, and calling drm_connector_property_get_value on the list head probably does not make sense. We test !connector-encoder rather than !connector ? There is a test of !connector-encoder inside the loop. But the whole loop body is a no-op because of the continue. The only effect of the loop is to set connector to the list head, which is the exit condition for the loop. The test of !connector is afterwards, but connector will not be NULL at that point, it will point to the list head. julia ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/7] drivers/gpu/drm: remove invalid reference to list iterator variable
On Sun, 8 Jul 2012, Paul Menzel wrote: Dear Julia, Am Sonntag, den 08.07.2012, 13:37 +0200 schrieb Julia Lawall: From: Julia Lawall julia.law...@lip6.fr If list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator. In the first two cases, a a break is added after the switch; the break in s,a a,a, Thanks. the switch would jump out of the switch, but not out of the complete iteration. In the first case, the null test on connector is removed, because the iterator variable of list_for_each_entry is never null. In the third case, entry-base.crtc.fb is not a meaningful value. What seems to be intended is crtc-fb, which gets the information from the last element of the list. maybe three separate patches would have been better? OK, I wasn't sure what would be best. I'll send three patches now. These problems were found using Coccinelle (http://coccinelle.lip6.fr/). I always liked your example Coccinelle code snippets. Could you add them again to your commit messages? That would be awesome! Sure. I didn't include it because there was a 0/7 message that has the complete semantic patch. julia Signed-off-by: Julia Lawall julia.law...@lip6.fr --- drivers/gpu/drm/gma500/mdfld_intel_display.c |4 +--- drivers/gpu/drm/gma500/oaktrail_crtc.c |1 + drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c |2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index 3f3cd61..fc1ced0 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -755,9 +755,6 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, sizeof(struct drm_display_mode)); list_for_each_entry(connector, mode_config-connector_list, head) { - if (!connector) - continue; - encoder = connector-encoder; if (!encoder) @@ -779,6 +776,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, is_hdmi = true; break; } + break; } /* Disable the VGA plane that we never use */ diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index f821c83..4b2172e 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -329,6 +329,7 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, is_mipi = true; break; } + break; } /* Disable the VGA plane that we never use */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 070fb23..634611a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -93,7 +93,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) if (crtc == NULL) return 0; - fb = entry-base.crtc.fb; + fb = crtc-fb; return vmw_kms_write_svga(dev_priv, w, h, fb-pitches[0], fb-bits_per_pixel, fb-depth); Acked-by: Paul Menzel paulepan...@users.sourceforge.net Thanks, Paul ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/3] drivers/gpu/drm/gma500/oaktrail_crtc.c: remove invalid reference to list iterator variable
From: Julia Lawall julia.law...@lip6.fr If list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator. A break is added after the switch; the break in the switch would jump out of the switch, but not out of the complete iteration. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // smpl @@ identifier c; expression E; iterator name list_for_each_entry; statement S; @@ list_for_each_entry(c,...) { ... when != break; when forall when strict } ... ( c = E | *c ) // /smpl Signed-off-by: Julia Lawall julia.law...@lip6.fr Acked-by: Paul Menzel paulepan...@users.sourceforge.net --- drivers/gpu/drm/gma500/oaktrail_crtc.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index f821c83..4b2172e 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -329,6 +329,7 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, is_mipi = true; break; } + break; } /* Disable the VGA plane that we never use */ ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/3] drivers/gpu/drm/gma500/mdfld_intel_display.c: remove invalid reference to list iterator variable
From: Julia Lawall julia.law...@lip6.fr If list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator. A break is added after the switch; the break in the switch would jump out of the switch, but not out of the complete iteration. The null test on connector is also removed, because the iterator variable of list_for_each_entry is never null. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // smpl @@ identifier c; expression E; iterator name list_for_each_entry; statement S; @@ list_for_each_entry(c,...) { ... when != break; when forall when strict } ... ( c = E | *c ) // /smpl Signed-off-by: Julia Lawall julia.law...@lip6.fr Acked-by: Paul Menzel paulepan...@users.sourceforge.net --- drivers/gpu/drm/gma500/mdfld_intel_display.c |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index 3f3cd61..fc1ced0 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -755,9 +755,6 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, sizeof(struct drm_display_mode)); list_for_each_entry(connector, mode_config-connector_list, head) { - if (!connector) - continue; - encoder = connector-encoder; if (!encoder) @@ -779,6 +776,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, is_hdmi = true; break; } + break; } /* Disable the VGA plane that we never use */ ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/3] drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c: remove invalid reference to list iterator variable
From: Julia Lawall julia.law...@lip6.fr If list_for_each_entry, etc complete a traversal of the list, the iterator variable ends up pointing to an address at an offset from the list head, and not a meaningful structure. Thus this value should not be used after the end of the iterator. After the iteractor, entry-base.crtc.fb is not a meaningful value. What seems to be intended is crtc-fb, which gets the information from the last element of the list. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // smpl @@ identifier c; expression E; iterator name list_for_each_entry; statement S; @@ list_for_each_entry(c,...) { ... when != break; when forall when strict } ... ( c = E | *c ) // /smpl Signed-off-by: Julia Lawall julia.law...@lip6.fr Acked-by: Paul Menzel paulepan...@users.sourceforge.net --- drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 070fb23..634611a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -93,7 +93,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) if (crtc == NULL) return 0; - fb = entry-base.crtc.fb; + fb = crtc-fb; return vmw_kms_write_svga(dev_priv, w, h, fb-pitches[0], fb-bits_per_pixel, fb-depth); ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: question about drivers/gpu/drm/gma500/oaktrail_lvds.c
On Mon, 9 Jul 2012, Patrik Jakobsson wrote: On Sun, Jul 8, 2012 at 10:16 PM, Alan Cox a...@lxorguk.ukuu.org.uk wrote: On Sun, 8 Jul 2012 10:39:43 +0200 (CEST) Julia Lawall julia.law...@lip6.fr wrote: In the function oaktrail_lvds_mode_set, I don't think that the following code makes any sense: /* Find the connector we're trying to set up */ list_for_each_entry(connector, mode_config-connector_list, head) { if (!connector-encoder || connector-encoder-crtc != crtc) continue; } if (!connector) { DRM_ERROR(Couldn't find connector when setting mode); return; } drm_connector_property_get_value( connector, dev-mode_config.scaling_mode_property, v); The initial loop is a no-op, because it always continues. The test !connector can never be true, because at the end of a list_for_each_entry connector points to the list head, and calling drm_connector_property_get_value on the list head probably does not make sense. We test !connector-encoder rather than !connector ? It seems we should break on : if (connector-encoder connector-encoder == encoder) Then do a check after list iteration: if (!connector || connector-encoder != encoder) DRM_ERROR(Couldn't find connector when setting mode); Possible. The !connector is still not needed, but the overall logic seems better. julia ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 0/2] fix memory deallocation and exception
this patch corrects to deallocate the pages allocated by alloc_page() and fixes exception to page allocation failure. Thanks. Inki Dae (2): drm/exynos: use __free_page() to deallocate memory drm/exynos: fixed exception to page allocation failure drivers/gpu/drm/exynos/exynos_drm_gem.c | 16 1 files changed, 4 insertions(+), 12 deletions(-) -- 1.7.4.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/2] drm/exynos: use __free_page() to deallocate memory
this patch uses __free_page() to deallocate the pages allocated by alloc_page() and the pages doesn't need set_parge_dirty() and mark_page_accessed() because they aren't from page cache so removes them. this patch has a pair with previous patch below, http://www.spinics.net/lists/dri-devel/msg24382.html Signed-off-by: Inki Dae inki@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 14 +++--- 1 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index dceb69f..4b8b988 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -129,20 +129,12 @@ static void exynos_gem_put_pages(struct drm_gem_object *obj, struct page **pages, bool dirty, bool accessed) { - int i, npages; + unsigned int npages; npages = obj-size PAGE_SHIFT; - for (i = 0; i npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } + while (--npages = 0) + __free_page(pages[npages]); drm_free_large(pages); } -- 1.7.4.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/2] drm/exynos: fixed exception to page allocation failure
this patch corrects to deallocate the pages allocated already at alloc_page failure. Signed-off-by: Inki Dae inki@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_gem.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 4b8b988..d0b3059 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -118,7 +118,7 @@ struct page **exynos_gem_get_pages(struct drm_gem_object *obj, return pages; fail: - while (i--) + while (--i) __free_page(pages[i]); drm_free_large(pages); -- 1.7.4.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2] drm/exynos: use __free_page() to deallocate memory
this patch uses __free_page() to deallocate the pages allocated by alloc_page() and the pages doesn't need set_parge_dirty() and mark_page_accessed() because they aren't from page cache so removes them. this patch has a pair with previous patch below, http://www.spinics.net/lists/dri-devel/msg24382.html Changelog v2: remove unnecessary arguments. Signed-off-by: Inki Dae inki@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 21 ++--- 1 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index dceb69f..e6ca2b3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -126,23 +126,14 @@ fail: } static void exynos_gem_put_pages(struct drm_gem_object *obj, - struct page **pages, - bool dirty, bool accessed) + struct page **pages) { - int i, npages; + unsigned int npages; npages = obj-size PAGE_SHIFT; - for (i = 0; i npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } + while (--npages = 0) + __free_page(pages[npages]); drm_free_large(pages); } @@ -222,7 +213,7 @@ err1: kfree(buf-sgt); buf-sgt = NULL; err: - exynos_gem_put_pages(obj, pages, true, false); + exynos_gem_put_pages(obj, pages); return ret; } @@ -240,7 +231,7 @@ static void exynos_drm_gem_put_pages(struct drm_gem_object *obj) kfree(buf-sgt); buf-sgt = NULL; - exynos_gem_put_pages(obj, buf-pages, true, false); + exynos_gem_put_pages(obj, buf-pages); buf-pages = NULL; /* add some codes for UNCACHED type here. TODO */ -- 1.7.4.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3] drm/exynos: use __free_page() to deallocate memory
this patch uses __free_page() to deallocate the pages allocated by alloc_page() and the pages doesn't need set_parge_dirty() and mark_page_accessed() because they aren't from page cache so removes them. this patch has a pair with previous patch below, http://www.spinics.net/lists/dri-devel/msg24382.html Changelog v2: remove unnecessary arguments. Changelog v3: fix npages type. - npages can have negative value. Signed-off-by: Inki Dae inki@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 21 ++--- 1 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index dceb69f..3ccda0c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -126,23 +126,14 @@ fail: } static void exynos_gem_put_pages(struct drm_gem_object *obj, - struct page **pages, - bool dirty, bool accessed) + struct page **pages) { - int i, npages; + int npages; npages = obj-size PAGE_SHIFT; - for (i = 0; i npages; i++) { - if (dirty) - set_page_dirty(pages[i]); - - if (accessed) - mark_page_accessed(pages[i]); - - /* Undo the reference we took when populating the table */ - page_cache_release(pages[i]); - } + while (--npages = 0) + __free_page(pages[npages]); drm_free_large(pages); } @@ -222,7 +213,7 @@ err1: kfree(buf-sgt); buf-sgt = NULL; err: - exynos_gem_put_pages(obj, pages, true, false); + exynos_gem_put_pages(obj, pages); return ret; } @@ -240,7 +231,7 @@ static void exynos_drm_gem_put_pages(struct drm_gem_object *obj) kfree(buf-sgt); buf-sgt = NULL; - exynos_gem_put_pages(obj, buf-pages, true, false); + exynos_gem_put_pages(obj, buf-pages); buf-pages = NULL; /* add some codes for UNCACHED type here. TODO */ -- 1.7.4.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 51870] r600_streamout=1 nothing change
https://bugs.freedesktop.org/show_bug.cgi?id=51870 Michel Dänzer mic...@daenzer.net changed: What|Removed |Added AssignedTo|xorg-driver-...@lists.x.org |dri-devel@lists.freedesktop ||.org QAContact|xorg-t...@lists.x.org | Product|xorg|Mesa Version|7.4 (2008.09) |git Component|Driver/Radeon |Drivers/Gallium/r600 -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 42984] scrabled video with nouveau drivers on mac mini (320m)
https://bugzilla.kernel.org/show_bug.cgi?id=42984 m.b.lankho...@gmail.com m.b.lankho...@gmail.com changed: What|Removed |Added CC||m.b.lankho...@gmail.com --- Comment #15 from m.b.lankho...@gmail.com m.b.lankho...@gmail.com 2012-07-09 08:33:00 --- This bug is fixed with commit a6a17859f1b and can be closed. It's backported to 3.2 stable and 3.4 with confirmation on 3.2.27 -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Frömmel cfroem...@web.de changed: What|Removed |Added Attachment #75081|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Frömmel cfroem...@web.de changed: What|Removed |Added Attachment #75071|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Frömmel cfroem...@web.de changed: What|Removed |Added Attachment #75091|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Frömmel cfroem...@web.de changed: What|Removed |Added Attachment #75121|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 44341] Radeon HD6990M: HDMI audio output works now! Kernel gives new warning
https://bugzilla.kernel.org/show_bug.cgi?id=44341 Christopher Frömmel cfroem...@web.de changed: What|Removed |Added Attachment #75061|application/octet-stream|text/plain mime type|| -- Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH, RFC] i.MX DRM support
On Sun, Jul 08, 2012 at 08:35:55AM +0100, Dave Airlie wrote: On Fri, Jul 6, 2012 at 11:58 PM, Greg Kroah-Hartman gre...@linuxfoundation.org wrote: On Mon, Jul 02, 2012 at 12:05:06PM +0200, Sascha Hauer wrote: On Thu, Jun 14, 2012 at 03:43:22PM +0200, Sascha Hauer wrote: Hi All, The following is the state-of-the-art i.MX IPU (Image Processing Unit) DRM support. This code is around for quite some time now and has been posted several times with different APIs, first with plain old framebuffer support, now DRM, first platform device binding, now devicetree. Unfortunately there's quite much code needed to get something useful out of the IPU, so these patches haven't received a lot of attention from people not involved in i.MX. I think we have now come to a point where this code needs more public exposure and where it's easier to talk in incremental changes instead of blobs. Therefore I request this to go to staging for some cycles. Dave, Greg, Comments to this one? I addressed the comments I received so far and am about to respin this series. Is it ok to put this to staging? If yes, should I move the whole stuff into drivers/staging/ or should it stay in drivers/gpu/drm with just a Kconfig dependency on STAGING? That's up to the DRM subsystem maintainer to choose. Sorry guys been out of the loop on arm drivers due to other things, but probably should go in staging proper for now, until I can at least spend time reviewing it. Right now we have dependencies on: http://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg24409.html http://www.mail-archive.com/dri-devel@lists.freedesktop.org/msg24224.html We could move these two helpers into staging, but they are needed by other drivers from Laurent Pinchart and Lars-Peter Clausen aswell. So it would be good to have them available for them aswell. Could you have a look on these and consider applying? Thanks, Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 02/16] drm/radeon: add error handling to radeon_vm_unbind_locked
Waiting for a fence can fail for different reasons, the most common is a deadlock. Signed-off-by: Christian König deathsim...@vodafone.de Reviewed-by: Michel Dänzer michel.daen...@amd.com --- drivers/gpu/drm/radeon/radeon_gart.c | 17 ++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 2b34c1a..ee11c50 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -316,10 +316,21 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, } /* wait for vm use to end */ - if (vm-fence) { - radeon_fence_wait(vm-fence, false); - radeon_fence_unref(vm-fence); + while (vm-fence) { + int r; + r = radeon_fence_wait(vm-fence, false); + if (r) + DRM_ERROR(error while waiting for fence: %d\n, r); + if (r == -EDEADLK) { + mutex_unlock(rdev-vm_manager.lock); + r = radeon_gpu_reset(rdev); + mutex_lock(rdev-vm_manager.lock); + if (!r) + continue; + } + break; } + radeon_fence_unref(vm-fence); /* hw unbind */ rdev-vm_manager.funcs-unbind(rdev, vm); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC] drm/radeon: restoring ring commands in case of a lockup
Hi, The following patchset tries to save and restore the not yet processed commands from the rings in case of a lockup and with that should make a userspace problem with a single application far less problematic. The first four patches are just stuff this patchset is based upon, followed by four patches which fix various bugs found while working on this feature. Followed by patches which change the way how memory is saved/restored on suspend/resume, basically before we have unpinned most of the buffer objects so it could be move from vram into system memory. But that is mostly unnecessary cause the buffer object either are already in system memory or their content can be easily reinitialized. The last three patches implement the actual tracking and restoring of commands in case of a lockup. Please take a look and review. Cheers, Christian. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 03/16] drm/radeon: fix fence related segfault in CS
Don't return success if scheduling the IB fails, otherwise we end up with an oops in ttm_eu_fence_buffer_objects. Signed-off-by: Christian König deathsim...@vodafone.de Cc: sta...@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_cs.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index f1b7527..d5aec09 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -358,7 +358,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, if (r) { DRM_ERROR(Failed to schedule IB !\n); } - return 0; + return r; } static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 01/16] drm/radeon: add error handling to fence_wait_empty_locked
Instead of returning the error handle it directly and while at it fix the comments about the ring lock. Signed-off-by: Christian König deathsim...@vodafone.de Reviewed-by: Michel Dänzer michel.daen...@amd.com --- drivers/gpu/drm/radeon/radeon.h |2 +- drivers/gpu/drm/radeon/radeon_fence.c | 33 + 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 77b4519b..5861ec8 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -239,7 +239,7 @@ void radeon_fence_process(struct radeon_device *rdev, int ring); bool radeon_fence_signaled(struct radeon_fence *fence); int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); -int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); +void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); int radeon_fence_wait_any(struct radeon_device *rdev, struct radeon_fence **fences, bool intr); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b55625..be4e4f3 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -440,14 +440,11 @@ int radeon_fence_wait_any(struct radeon_device *rdev, return 0; } +/* caller must hold ring lock */ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) { uint64_t seq; - /* We are not protected by ring lock when reading current seq but -* it's ok as worst case is we return to early while we could have -* wait. -*/ seq = atomic64_read(rdev-fence_drv[ring].last_seq) + 1ULL; if (seq = rdev-fence_drv[ring].sync_seq[ring]) { /* nothing to wait for, last_seq is @@ -457,15 +454,27 @@ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) return radeon_fence_wait_seq(rdev, seq, ring, false, false); } -int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) +/* caller must hold ring lock */ +void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) { - /* We are not protected by ring lock when reading current seq -* but it's ok as wait empty is call from place where no more -* activity can be scheduled so there won't be concurrent access -* to seq value. -*/ - return radeon_fence_wait_seq(rdev, rdev-fence_drv[ring].sync_seq[ring], -ring, false, false); + uint64_t seq = rdev-fence_drv[ring].sync_seq[ring]; + + while(1) { + int r; + r = radeon_fence_wait_seq(rdev, seq, ring, false, false); + if (r == -EDEADLK) { + mutex_unlock(rdev-ring_lock); + r = radeon_gpu_reset(rdev); + mutex_lock(rdev-ring_lock); + if (!r) + continue; + } + if (r) { + dev_err(rdev-dev, error waiting for ring to become +idle (%d)\n, r); + } + return; + } } struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence) -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 05/16] drm/radeon: fix ring commit padding
We don't need to pad anything if the number of dwords written to the ring already matches the requirements. Fixes some writting more dword to ring than expected warnings. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/radeon_ring.c |7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 0826e77..674aaba 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -272,13 +272,8 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) { - unsigned count_dw_pad; - unsigned i; - /* We pad to match fetch size */ - count_dw_pad = (ring-align_mask + 1) - - (ring-wptr ring-align_mask); - for (i = 0; i count_dw_pad; i++) { + while (ring-wptr ring-align_mask) { radeon_ring_write(ring, ring-nop); } DRM_MEMORYBARRIER(); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 06/16] drm/radeon: fix fence value access
It is possible that radeon_fence_process is called after writeback is disabled for suspend, leading to an invalid read of register 0x0. This fixes a problem for me where the fence value is temporary incremented by 0x1 on suspend/resume. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/radeon_fence.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index be4e4f3..a194a14 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -42,21 +42,23 @@ static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) { - if (rdev-wb.enabled) { - *rdev-fence_drv[ring].cpu_addr = cpu_to_le32(seq); + struct radeon_fence_driver *drv = rdev-fence_drv[ring]; + if (likely(rdev-wb.enabled || !drv-scratch_reg)) { + *drv-cpu_addr = cpu_to_le32(seq); } else { - WREG32(rdev-fence_drv[ring].scratch_reg, seq); + WREG32(drv-scratch_reg, seq); } } static u32 radeon_fence_read(struct radeon_device *rdev, int ring) { + struct radeon_fence_driver *drv = rdev-fence_drv[ring]; u32 seq = 0; - if (rdev-wb.enabled) { - seq = le32_to_cpu(*rdev-fence_drv[ring].cpu_addr); + if (likely(rdev-wb.enabled || !drv-scratch_reg)) { + seq = le32_to_cpu(*drv-cpu_addr); } else { - seq = RREG32(rdev-fence_drv[ring].scratch_reg); + seq = RREG32(drv-scratch_reg); } return seq; } -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 07/16] drm/radeon: fix fence init after resume
Start with last signaled fence number instead of last emitted one. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/radeon_fence.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index a194a14..76c5b22 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -578,7 +578,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) } rdev-fence_drv[ring].cpu_addr = rdev-wb.wb[index/4]; rdev-fence_drv[ring].gpu_addr = rdev-wb.gpu_addr + index; - radeon_fence_write(rdev, rdev-fence_drv[ring].sync_seq[ring], ring); + radeon_fence_write(rdev, atomic64_read(rdev-fence_drv[ring].last_seq), ring); rdev-fence_drv[ring].initialized = true; dev_info(rdev-dev, fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n, ring, rdev-fence_drv[ring].gpu_addr, rdev-fence_drv[ring].cpu_addr); -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 09/16] drm/radeon: make cp init on cayman more robust
It's not critical, but the current code isn't 100% correct. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/ni.c | 133 ++- 1 file changed, 56 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 32a6082..8b1df33 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -987,10 +987,33 @@ static void cayman_cp_fini(struct radeon_device *rdev) int cayman_cp_resume(struct radeon_device *rdev) { + static const int ridx[] = { + RADEON_RING_TYPE_GFX_INDEX, + CAYMAN_RING_TYPE_CP1_INDEX, + CAYMAN_RING_TYPE_CP2_INDEX + }; + static const unsigned cp_rb_cntl[] = { + CP_RB0_CNTL, + CP_RB1_CNTL, + CP_RB2_CNTL, + }; + static const unsigned cp_rb_rptr_addr[] = { + CP_RB0_RPTR_ADDR, + CP_RB1_RPTR_ADDR, + CP_RB2_RPTR_ADDR + }; + static const unsigned cp_rb_rptr_addr_hi[] = { + CP_RB0_RPTR_ADDR_HI, + CP_RB1_RPTR_ADDR_HI, + CP_RB2_RPTR_ADDR_HI + }; + static const unsigned cp_rb_base[] = { + CP_RB0_BASE, + CP_RB1_BASE, + CP_RB2_BASE + }; struct radeon_ring *ring; - u32 tmp; - u32 rb_bufsz; - int r; + int i, r; /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | @@ -1012,91 +1035,47 @@ int cayman_cp_resume(struct radeon_device *rdev) WREG32(CP_DEBUG, (1 27)); - /* ring 0 - compute and gfx */ - /* Set ring buffer size */ - ring = rdev-ring[RADEON_RING_TYPE_GFX_INDEX]; - rb_bufsz = drm_order(ring-ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB0_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); - ring-wptr = 0; - WREG32(CP_RB0_WPTR, ring-wptr); - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB0_RPTR_ADDR, (rdev-wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) 0xFFFC); - WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev-wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) 0xFF); WREG32(SCRATCH_ADDR, ((rdev-wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) 8) 0x); + WREG32(SCRATCH_UMSK, 0xff); - if (rdev-wb.enabled) - WREG32(SCRATCH_UMSK, 0xff); - else { - tmp |= RB_NO_UPDATE; - WREG32(SCRATCH_UMSK, 0); - } - - mdelay(1); - WREG32(CP_RB0_CNTL, tmp); - - WREG32(CP_RB0_BASE, ring-gpu_addr 8); - - ring-rptr = RREG32(CP_RB0_RPTR); + for (i = 0; i 3; ++i) { + uint32_t rb_cntl; + uint64_t addr; - /* ring1 - compute only */ - /* Set ring buffer size */ - ring = rdev-ring[CAYMAN_RING_TYPE_CP1_INDEX]; - rb_bufsz = drm_order(ring-ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) 8) | rb_bufsz; + /* Set ring buffer size */ + ring = rdev-ring[ridx[i]]; + rb_cntl = drm_order(ring-ring_size / 8); + rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) 8; #ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; + rb_cntl |= BUF_SWAP_32BIT; #endif - WREG32(CP_RB1_CNTL, tmp); + WREG32(cp_rb_cntl[i], rb_cntl); - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); - ring-wptr = 0; - WREG32(CP_RB1_WPTR, ring-wptr); - - /* set the wb address wether it's enabled or not */ - WREG32(CP_RB1_RPTR_ADDR, (rdev-wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) 0xFFFC); - WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev-wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) 0xFF); - - mdelay(1); - WREG32(CP_RB1_CNTL, tmp); - - WREG32(CP_RB1_BASE, ring-gpu_addr 8); - - ring-rptr = RREG32(CP_RB1_RPTR); - - /* ring2 - compute only */ - /* Set ring buffer size */ - ring = rdev-ring[CAYMAN_RING_TYPE_CP2_INDEX]; - rb_bufsz = drm_order(ring-ring_size / 8); - tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) 8) | rb_bufsz; -#ifdef __BIG_ENDIAN - tmp |= BUF_SWAP_32BIT; -#endif - WREG32(CP_RB2_CNTL, tmp); - - /* Initialize the ring buffer's read and write pointers */ - WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); - ring-wptr = 0; - WREG32(CP_RB2_WPTR, ring-wptr); + /* set the wb address wether it's enabled or not */ + addr = rdev-wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET; + WREG32(cp_rb_rptr_addr[i], addr 0xFFFC); +
[PATCH 08/16] drm/radeon: remove FIXME comment from chipset suspend
For a normal suspend/resume we allready wait for the rings to be empty, and for a suspend/reasume in case of a lockup we REALLY don't want to wait for anything. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/evergreen.c |1 - drivers/gpu/drm/radeon/ni.c|1 - drivers/gpu/drm/radeon/r600.c |1 - drivers/gpu/drm/radeon/rv770.c |1 - drivers/gpu/drm/radeon/si.c|1 - 5 files changed, 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f716e08..eb9a71a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3137,7 +3137,6 @@ int evergreen_suspend(struct radeon_device *rdev) struct radeon_ring *ring = rdev-ring[RADEON_RING_TYPE_GFX_INDEX]; r600_audio_fini(rdev); - /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); r700_cp_stop(rdev); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 2366be3..32a6082 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1334,7 +1334,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); r600_blit_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 43d0c41..de4de2d 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2461,7 +2461,6 @@ int r600_suspend(struct radeon_device *rdev) r600_audio_fini(rdev); radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); - /* FIXME: we should wait for ring to be empty */ r600_cp_stop(rdev); rdev-ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b4f51c5..7e230f6 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -996,7 +996,6 @@ int rv770_suspend(struct radeon_device *rdev) r600_audio_fini(rdev); radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); - /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); rdev-ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 34603b3c8..78c790f 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -3807,7 +3807,6 @@ int si_resume(struct radeon_device *rdev) int si_suspend(struct radeon_device *rdev) { - /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); #if 0 -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 10/16] drm/radeon: remove ip_pool start/suspend
The IB pool is in gart memory, so it is completely superfluous to unpin / repin it on suspend / resume. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/evergreen.c | 17 ++--- drivers/gpu/drm/radeon/ni.c | 16 ++-- drivers/gpu/drm/radeon/r100.c| 23 ++- drivers/gpu/drm/radeon/r300.c| 17 ++--- drivers/gpu/drm/radeon/r420.c| 17 ++--- drivers/gpu/drm/radeon/r520.c| 14 +- drivers/gpu/drm/radeon/r600.c| 17 ++--- drivers/gpu/drm/radeon/radeon.h |2 -- drivers/gpu/drm/radeon/radeon_asic.h |1 - drivers/gpu/drm/radeon/radeon_ring.c | 17 +++-- drivers/gpu/drm/radeon/rs400.c | 17 ++--- drivers/gpu/drm/radeon/rs600.c | 17 ++--- drivers/gpu/drm/radeon/rs690.c | 17 ++--- drivers/gpu/drm/radeon/rv515.c | 16 ++-- drivers/gpu/drm/radeon/rv770.c | 17 ++--- drivers/gpu/drm/radeon/si.c | 16 ++-- 16 files changed, 84 insertions(+), 157 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index eb9a71a..64e06e6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3087,9 +3087,11 @@ static int evergreen_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_start(rdev); - if (r) + r = radeon_ib_pool_init(rdev); + if (r) { + dev_err(rdev-dev, IB initialization failed (%d).\n, r); return r; + } r = radeon_ib_ring_tests(rdev); if (r) @@ -3137,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev) struct radeon_ring *ring = rdev-ring[RADEON_RING_TYPE_GFX_INDEX]; r600_audio_fini(rdev); - radeon_ib_pool_suspend(rdev); r600_blit_suspend(rdev); r700_cp_stop(rdev); ring-ready = false; @@ -3224,20 +3225,14 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_init(rdev); rdev-accel_working = true; - if (r) { - dev_err(rdev-dev, IB initialization failed (%d).\n, r); - rdev-accel_working = false; - } - r = evergreen_startup(rdev); if (r) { dev_err(rdev-dev, disabling GPU acceleration\n); r700_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_ib_pool_fini(rdev); radeon_irq_kms_fini(rdev); evergreen_pcie_gart_fini(rdev); rdev-accel_working = false; @@ -3264,7 +3259,7 @@ void evergreen_fini(struct radeon_device *rdev) r700_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_ib_pool_fini(rdev); radeon_irq_kms_fini(rdev); evergreen_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 8b1df33..fe55310 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1270,9 +1270,11 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_start(rdev); - if (r) + r = radeon_ib_pool_init(rdev); + if (r) { + dev_err(rdev-dev, IB initialization failed (%d).\n, r); return r; + } r = radeon_ib_ring_tests(rdev); if (r) @@ -1313,7 +1315,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); r600_blit_suspend(rdev); cayman_cp_enable(rdev, false); @@ -1391,12 +1392,7 @@ int cayman_init(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_pool_init(rdev); rdev-accel_working = true; - if (r) { - dev_err(rdev-dev, IB initialization failed (%d).\n, r); - rdev-accel_working = false; - } r = radeon_vm_manager_init(rdev); if (r) { dev_err(rdev-dev, vm manager initialization failed (%d).\n, r); @@ -1410,7 +1406,7 @@ int cayman_init(struct radeon_device *rdev) if (rdev-flags RADEON_IS_IGP) si_rlc_fini(rdev); radeon_wb_fini(rdev); - r100_ib_fini(rdev); + radeon_ib_pool_fini(rdev); radeon_vm_manager_fini(rdev); radeon_irq_kms_fini(rdev); cayman_pcie_gart_fini(rdev); @@ -1441,7 +1437,7 @@ void cayman_fini(struct
[PATCH 11/16] drm/radeon: remove r600_blit_suspend
Just reinitialize the shader content on resume instead. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/evergreen.c |1 - drivers/gpu/drm/radeon/evergreen_blit_kms.c | 40 +-- drivers/gpu/drm/radeon/ni.c |1 - drivers/gpu/drm/radeon/r600.c | 15 -- drivers/gpu/drm/radeon/r600_blit_kms.c | 40 +-- drivers/gpu/drm/radeon/radeon.h |2 -- drivers/gpu/drm/radeon/rv770.c |1 - drivers/gpu/drm/radeon/si.c |3 -- 8 files changed, 40 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 64e06e6..82f7aea 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3139,7 +3139,6 @@ int evergreen_suspend(struct radeon_device *rdev) struct radeon_ring *ring = rdev-ring[RADEON_RING_TYPE_GFX_INDEX]; r600_audio_fini(rdev); - r600_blit_suspend(rdev); r700_cp_stop(rdev); ring-ready = false; evergreen_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index e512560..89cb9fe 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -634,10 +634,6 @@ int evergreen_blit_init(struct radeon_device *rdev) rdev-r600_blit.max_dim = 16384; - /* pin copy shader into vram if already initialized */ - if (rdev-r600_blit.shader_obj) - goto done; - rdev-r600_blit.state_offset = 0; if (rdev-family CHIP_CAYMAN) @@ -668,11 +664,26 @@ int evergreen_blit_init(struct radeon_device *rdev) obj_size += cayman_ps_size * 4; obj_size = ALIGN(obj_size, 256); - r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, -NULL, rdev-r600_blit.shader_obj); - if (r) { - DRM_ERROR(evergreen failed to allocate shader\n); - return r; + /* pin copy shader into vram if not already initialized */ + if (!rdev-r600_blit.shader_obj) { + r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, +RADEON_GEM_DOMAIN_VRAM, +NULL, rdev-r600_blit.shader_obj); + if (r) { + DRM_ERROR(evergreen failed to allocate shader\n); + return r; + } + + r = radeon_bo_reserve(rdev-r600_blit.shader_obj, false); + if (unlikely(r != 0)) + return r; + r = radeon_bo_pin(rdev-r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, + rdev-r600_blit.shader_gpu_addr); + radeon_bo_unreserve(rdev-r600_blit.shader_obj); + if (r) { + dev_err(rdev-dev, (%d) pin blit object failed\n, r); + return r; + } } DRM_DEBUG(evergreen blit allocated bo %08x vs %08x ps %08x\n, @@ -714,17 +725,6 @@ int evergreen_blit_init(struct radeon_device *rdev) radeon_bo_kunmap(rdev-r600_blit.shader_obj); radeon_bo_unreserve(rdev-r600_blit.shader_obj); -done: - r = radeon_bo_reserve(rdev-r600_blit.shader_obj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev-r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, - rdev-r600_blit.shader_gpu_addr); - radeon_bo_unreserve(rdev-r600_blit.shader_obj); - if (r) { - dev_err(rdev-dev, (%d) pin blit object failed\n, r); - return r; - } radeon_ttm_set_active_vram_size(rdev, rdev-mc.real_vram_size); return 0; } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index fe55310..4004376 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1316,7 +1316,6 @@ int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); radeon_vm_manager_suspend(rdev); - r600_blit_suspend(rdev); cayman_cp_enable(rdev, false); rdev-ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 9750f53..af2f74a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2307,20 +2307,6 @@ int r600_copy_blit(struct radeon_device *rdev, return 0; } -void r600_blit_suspend(struct radeon_device *rdev) -{ - int r; - - /* unpin shaders bo */ - if (rdev-r600_blit.shader_obj) { - r = radeon_bo_reserve(rdev-r600_blit.shader_obj, false); - if (!r) { - radeon_bo_unpin(rdev-r600_blit.shader_obj);
[PATCH 04/16] drm/radeon: add an exclusive lock for GPU reset v2
From: Jerome Glisse jgli...@redhat.com GPU reset need to be exclusive, one happening at a time. For this add a rw semaphore so that any path that trigger GPU activities have to take the semaphore as a reader thus allowing concurency. The GPU reset path take the semaphore as a writer ensuring that no concurrent reset take place. v2: init rw semaphore Signed-off-by: Jerome Glisse jgli...@redhat.com --- drivers/gpu/drm/radeon/radeon.h|1 + drivers/gpu/drm/radeon/radeon_cs.c |5 + drivers/gpu/drm/radeon/radeon_device.c |3 +++ drivers/gpu/drm/radeon/radeon_gem.c|8 4 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5861ec8..4487873 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1446,6 +1446,7 @@ struct radeon_device { struct device *dev; struct drm_device *ddev; struct pci_dev *pdev; + struct rw_semaphore exclusive_lock; /* ASIC */ union radeon_asic_configconfig; enum radeon_family family; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index d5aec09..553da67 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -499,7 +499,9 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) struct radeon_cs_parser parser; int r; + down_read(rdev-exclusive_lock); if (!rdev-accel_working) { + up_read(rdev-exclusive_lock); return -EBUSY; } /* initialize parser */ @@ -512,6 +514,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) { DRM_ERROR(Failed to initialize parser !\n); radeon_cs_parser_fini(parser, r); + up_read(rdev-exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; } @@ -520,6 +523,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r != -ERESTARTSYS) DRM_ERROR(Failed to parse relocation %d!\n, r); radeon_cs_parser_fini(parser, r); + up_read(rdev-exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; } @@ -533,6 +537,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } out: radeon_cs_parser_fini(parser, r); + up_read(rdev-exclusive_lock); r = radeon_cs_handle_lockup(rdev, r); return r; } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index f654ba8..254fdb4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -734,6 +734,7 @@ int radeon_device_init(struct radeon_device *rdev, mutex_init(rdev-gem.mutex); mutex_init(rdev-pm.mutex); init_rwsem(rdev-pm.mclk_lock); + init_rwsem(rdev-exclusive_lock); init_waitqueue_head(rdev-irq.vblank_queue); init_waitqueue_head(rdev-irq.idle_queue); r = radeon_gem_init(rdev); @@ -988,6 +989,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) int r; int resched; + down_write(rdev-exclusive_lock); radeon_save_bios_scratch_regs(rdev); /* block TTM */ resched = ttm_bo_lock_delayed_workqueue(rdev-mman.bdev); @@ -1007,6 +1009,7 @@ int radeon_gpu_reset(struct radeon_device *rdev) dev_info(rdev-dev, GPU reset failed\n); } + up_write(rdev-exclusive_lock); return r; } diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index d9b0809..b0be9c4 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -215,12 +215,14 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, uint32_t handle; int r; + down_read(rdev-exclusive_lock); /* create a gem object to contain this object in */ args-size = roundup(args-size, PAGE_SIZE); r = radeon_gem_object_create(rdev, args-size, args-alignment, args-initial_domain, false, false, gobj); if (r) { + up_read(rdev-exclusive_lock); r = radeon_gem_handle_lockup(rdev, r); return r; } @@ -228,10 +230,12 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gobj); if (r) { + up_read(rdev-exclusive_lock); r = radeon_gem_handle_lockup(rdev, r); return r;
[PATCH 13/16] drm/radeon: move radeon_ib_ring_tests out of chipset code
Making it easier to controlwhen it is executed. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/evergreen.c |4 drivers/gpu/drm/radeon/ni.c|4 drivers/gpu/drm/radeon/r100.c |4 drivers/gpu/drm/radeon/r300.c |4 drivers/gpu/drm/radeon/r420.c |4 drivers/gpu/drm/radeon/r520.c |4 drivers/gpu/drm/radeon/r600.c |4 drivers/gpu/drm/radeon/radeon_device.c | 15 +++ drivers/gpu/drm/radeon/rs400.c |4 drivers/gpu/drm/radeon/rs600.c |4 drivers/gpu/drm/radeon/rs690.c |4 drivers/gpu/drm/radeon/rv515.c |4 drivers/gpu/drm/radeon/rv770.c |4 drivers/gpu/drm/radeon/si.c| 21 - 14 files changed, 15 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 82f7aea..f39b900 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3093,10 +3093,6 @@ static int evergreen_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - r = r600_audio_init(rdev); if (r) { DRM_ERROR(radeon: audio init failed\n); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ec5307c..f2afefb 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1276,10 +1276,6 @@ static int cayman_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - r = radeon_vm_manager_init(rdev); if (r) { dev_err(rdev-dev, vm manager initialization failed (%d).\n, r); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 9524bd4..e0f5ae8 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3887,10 +3887,6 @@ static int r100_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index b396e34..646a192 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1397,10 +1397,6 @@ static int r300_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 0062938..f2f5bf6 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -281,10 +281,6 @@ static int r420_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 6df3e51..079d3c5 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -209,10 +209,6 @@ static int r520_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - return 0; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index af2f74a..c808fa9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2395,10 +2395,6 @@ int r600_startup(struct radeon_device *rdev) return r; } - r = radeon_ib_ring_tests(rdev); - if (r) - return r; - r = r600_audio_init(rdev); if (r) { DRM_ERROR(radeon: audio init failed\n); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 254fdb4..bbd0971 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -822,6 +822,10 @@ int radeon_device_init(struct radeon_device *rdev, if (r) return r; + r = radeon_ib_ring_tests(rdev); + if (r) + DRM_ERROR(ib ring test failed (%d).\n, r); + if (rdev-flags RADEON_IS_AGP !rdev-accel_working) { /* Acceleration not working on AGP card try again * with fallback to PCI or PCIE GART @@ -946,6 +950,7 @@ int radeon_resume_kms(struct drm_device *dev) { struct drm_connector *connector; struct radeon_device *rdev = dev-dev_private; + int r; if (dev-switch_power_state == DRM_SWITCH_POWER_OFF) return 0; @@ -960,6 +965,11 @@ int radeon_resume_kms(struct drm_device *dev) /* resume AGP if in use */
[PATCH 12/16] drm/radeon: remove vm_manager start/suspend
Just restore the page table instead. Addressing three problem with this change: 1. Calling vm_manager_suspend in the suspend path is problematic cause it wants to wait for the VM use to end, which in case of a lockup never happens. 2. In case of a locked up memory controller unbinding the VM seems to make it even more unstable, creating an unrecoverable lockup in the end. 3. If we want to backup/restore the leftover ring content we must not unbind VMs in between. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/ni.c | 12 ++--- drivers/gpu/drm/radeon/radeon.h |2 - drivers/gpu/drm/radeon/radeon_gart.c | 83 +- drivers/gpu/drm/radeon/si.c | 12 ++--- 4 files changed, 59 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 4004376..ec5307c 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_vm_manager_start(rdev); - if (r) + r = radeon_vm_manager_init(rdev); + if (r) { + dev_err(rdev-dev, vm manager initialization failed (%d).\n, r); return r; + } r = r600_audio_init(rdev); if (r) @@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - radeon_vm_manager_suspend(rdev); cayman_cp_enable(rdev, false); rdev-ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); @@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev) return r; rdev-accel_working = true; - r = radeon_vm_manager_init(rdev); - if (r) { - dev_err(rdev-dev, vm manager initialization failed (%d).\n, r); - } - r = cayman_startup(rdev); if (r) { dev_err(rdev-dev, disabling GPU acceleration\n); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 8a8c3f8..872270c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size */ int radeon_vm_manager_init(struct radeon_device *rdev); void radeon_vm_manager_fini(struct radeon_device *rdev); -int radeon_vm_manager_start(struct radeon_device *rdev); -int radeon_vm_manager_suspend(struct radeon_device *rdev); int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index ee11c50..56752da 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev) * * TODO bind a default page at vm initialization for default address */ + int radeon_vm_manager_init(struct radeon_device *rdev) { + struct radeon_vm *vm; + struct radeon_bo_va *bo_va; int r; - rdev-vm_manager.enabled = false; + if (!rdev-vm_manager.enabled) { + /* mark first vm as always in use, it's the system one */ + r = radeon_sa_bo_manager_init(rdev, rdev-vm_manager.sa_manager, + rdev-vm_manager.max_pfn * 8, + RADEON_GEM_DOMAIN_VRAM); + if (r) { + dev_err(rdev-dev, failed to allocate vm bo (%dKB)\n, + (rdev-vm_manager.max_pfn * 8) 10); + return r; + } - /* mark first vm as always in use, it's the system one */ - r = radeon_sa_bo_manager_init(rdev, rdev-vm_manager.sa_manager, - rdev-vm_manager.max_pfn * 8, - RADEON_GEM_DOMAIN_VRAM); - if (r) { - dev_err(rdev-dev, failed to allocate vm bo (%dKB)\n, - (rdev-vm_manager.max_pfn * 8) 10); - return r; + r = rdev-vm_manager.funcs-init(rdev); + if (r) + return r; + + rdev-vm_manager.enabled = true; + + r = radeon_sa_bo_manager_start(rdev, rdev-vm_manager.sa_manager); + if (r) + return r; } - r = rdev-vm_manager.funcs-init(rdev); - if (r == 0) - rdev-vm_manager.enabled = true; + /* restore page table */ + list_for_each_entry(vm, rdev-vm_manager.lru_vm, list) { + if (vm-id == -1) +
[PATCH 14/16] drm/radeon: make align a ring_init parameter
Instead of setting it directly from the chipset code. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/evergreen.c |3 ++- drivers/gpu/drm/radeon/ni.c |3 ++- drivers/gpu/drm/radeon/r100.c|3 +-- drivers/gpu/drm/radeon/r600.c|3 +-- drivers/gpu/drm/radeon/radeon.h |3 ++- drivers/gpu/drm/radeon/radeon_ring.c |4 +++- drivers/gpu/drm/radeon/rv770.c |3 ++- drivers/gpu/drm/radeon/si.c |9 ++--- 8 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f39b900..f0bbbe1 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3075,7 +3075,8 @@ static int evergreen_startup(struct radeon_device *rdev) } evergreen_irq_set(rdev); - r = radeon_ring_init(rdev, ring, ring-ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring-ring_size, 16, +RADEON_WB_CP_RPTR_OFFSET, R600_CP_RB_RPTR, R600_CP_RB_WPTR, 0, 0xf, RADEON_CP_PACKET2); if (r) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index f2afefb..c69cebc 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1258,7 +1258,8 @@ static int cayman_startup(struct radeon_device *rdev) } evergreen_irq_set(rdev); - r = radeon_ring_init(rdev, ring, ring-ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring-ring_size, 16, +RADEON_WB_CP_RPTR_OFFSET, CP_RB0_RPTR, CP_RB0_WPTR, 0, 0xf, RADEON_CP_PACKET2); if (r) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e0f5ae8..116432f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -977,7 +977,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_bufsz = drm_order(ring_size / 8); ring_size = (1 (rb_bufsz + 1)) * 4; r100_cp_load_microcode(rdev); - r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring_size, 16, RADEON_WB_CP_RPTR_OFFSET, RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR, 0, 0x7f, RADEON_CP_PACKET2); if (r) { @@ -988,7 +988,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_blksz = 9; /* cp will read 128bytes at a time (4 dwords) */ max_fetch = 1; - ring-align_mask = 16 - 1; /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */ pre_write_timer = 64; /* Force CP_RB_WPTR write if written more than one time before the diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c808fa9..7d15490 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2160,7 +2160,6 @@ void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsign rb_bufsz = drm_order(ring_size / 8); ring_size = (1 (rb_bufsz + 1)) * 4; ring-ring_size = ring_size; - ring-align_mask = 16 - 1; } void r600_cp_fini(struct radeon_device *rdev) @@ -2376,7 +2375,7 @@ int r600_startup(struct radeon_device *rdev) } r600_irq_set(rdev); - r = radeon_ring_init(rdev, ring, ring-ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring-ring_size, 16, RADEON_WB_CP_RPTR_OFFSET, R600_CP_RB_RPTR, R600_CP_RB_WPTR, 0, 0xf, RADEON_CP_PACKET2); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 872270c..fef4257 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -767,7 +767,8 @@ int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); void radeon_ring_lockup_update(struct radeon_ring *ring); bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); -int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, +int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, +unsigned ring_size, unsigned align, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 0873834..d9b2e45 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++
[PATCH 15/16] drm/radeon: implement ring commit tracking
Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/radeon.h |3 +++ drivers/gpu/drm/radeon/radeon_ring.c | 39 -- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index fef4257..9c11be8 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -637,6 +637,9 @@ struct radeon_ring { u32 ptr_reg_shift; u32 ptr_reg_mask; u32 nop; + unsigned*track_back; + unsignedtrack_ptr; + unsignedtrack_mask; }; /* diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index d9b2e45..994c98c 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -276,6 +276,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) DRM_MEMORYBARRIER(); WREG32(ring-wptr_reg, (ring-wptr ring-ptr_reg_shift) ring-ptr_reg_mask); (void)RREG32(ring-wptr_reg); + ring-track_back[ring-track_ptr++] = ring-wptr_old; + ring-track_ptr = ring-track_mask; } void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) @@ -362,6 +364,27 @@ bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *rin return false; } +static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring) +{ + unsigned i, c, result = ring-track_ptr; + i = ring-track_ptr - 1; + while (i != ring-track_ptr) { + i = ring-track_mask; + c = ring-track_back[i]; + + if (ring-wptr = ring-rptr) { + if (c ring-rptr || c = ring-wptr) + break; + } else { + if (c ring-rptr c = ring-wptr) + break; + } + + result = i--; + } + return result; +} + int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, unsigned align, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, @@ -403,6 +426,10 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, dev_err(rdev-dev, (%d) ring map failed\n, r); return r; } + ring-track_back = kmalloc(ring_size / align, GFP_KERNEL); + memset(ring-track_back, 0, ring_size / align); + ring-track_ptr = 0; + ring-track_mask = ((ring-ring_size / 4) / align) - 1; } ring-ptr_mask = (ring-ring_size / 4) - 1; ring-ring_free_dw = ring-ring_size / 4; @@ -422,6 +449,7 @@ void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) ring-ready = false; ring-ring = NULL; ring-ring_obj = NULL; + kfree(ring-track_back); mutex_unlock(rdev-ring_lock); if (ring_obj) { @@ -447,7 +475,7 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) struct radeon_device *rdev = dev-dev_private; int ridx = *(int*)node-info_ent-data; struct radeon_ring *ring = rdev-ring[ridx]; - unsigned count, i, j; + unsigned count, i, j, commit; radeon_ring_free_size(rdev, ring); count = (ring-ring_size / 4) - ring-ring_free_dw; @@ -457,9 +485,16 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) seq_printf(m, driver's copy of the rptr: 0x%08x\n, ring-rptr); seq_printf(m, %u free dwords in ring\n, ring-ring_free_dw); seq_printf(m, %u dwords in ring\n, count); + commit = radeon_ring_first_valid_commit(ring); i = ring-rptr; for (j = 0; j = count; j++) { - seq_printf(m, r[%04d]=0x%08x\n, i, ring-ring[i]); + seq_printf(m, r[%04x]=0x%08x, i, ring-ring[i]); + if (commit != ring-track_ptr ring-track_back[commit] == i) { + seq_printf(m, -); + ++commit; + commit = ring-track_mask; + } + seq_printf(m, \n); i = (i + 1) ring-ptr_mask; } return 0; -- 1.7.9.5 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 16/16] drm/radeon: implement ring saving on reset
Try to save whatever is on the rings when we encounter an lockup. Signed-off-by: Christian König deathsim...@vodafone.de --- drivers/gpu/drm/radeon/radeon.h|4 ++ drivers/gpu/drm/radeon/radeon_device.c | 44 drivers/gpu/drm/radeon/radeon_ring.c | 69 3 files changed, 109 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9c11be8..1265840 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -770,6 +770,10 @@ int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); void radeon_ring_lockup_update(struct radeon_ring *ring); bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); +unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring, + uint32_t **data); +int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, + unsigned size, uint32_t *data); int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, unsigned align, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index bbd0971..97696e5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -996,7 +996,12 @@ int radeon_resume_kms(struct drm_device *dev) int radeon_gpu_reset(struct radeon_device *rdev) { - int r; + unsigned ring_sizes[RADEON_NUM_RINGS]; + uint32_t *ring_data[RADEON_NUM_RINGS]; + + bool saved = false; + + int i, r; int resched; down_write(rdev-exclusive_lock); @@ -1005,20 +1010,43 @@ int radeon_gpu_reset(struct radeon_device *rdev) resched = ttm_bo_lock_delayed_workqueue(rdev-mman.bdev); radeon_suspend(rdev); + for (i = 0; i RADEON_NUM_RINGS; ++i) { + ring_sizes[i] = radeon_ring_backup(rdev, rdev-ring[i], + ring_data[i]); + if (ring_sizes[i]) { + saved = true; + dev_info(rdev-dev, Saved %d dwords of commands +on ring %d.\n, ring_sizes[i], i); + } + } + +retry: r = radeon_asic_reset(rdev); if (!r) { - dev_info(rdev-dev, GPU reset succeed\n); + dev_info(rdev-dev, GPU reset succeed trying to resume\n); radeon_resume(rdev); + } - r = radeon_ib_ring_tests(rdev); - if (r) - DRM_ERROR(ib ring test failed (%d).\n, r); + radeon_restore_bios_scratch_regs(rdev); + drm_helper_resume_force_mode(rdev-ddev); + + if (!r) { + for (i = 0; i RADEON_NUM_RINGS; ++i) { + radeon_ring_restore(rdev, rdev-ring[i], + ring_sizes[i], ring_data[i]); + } - radeon_restore_bios_scratch_regs(rdev); - drm_helper_resume_force_mode(rdev-ddev); - ttm_bo_unlock_delayed_workqueue(rdev-mman.bdev, resched); + r = radeon_ib_ring_tests(rdev); + if (r) { + dev_err(rdev-dev, ib ring test failed (%d).\n, r); + if (saved) { + radeon_suspend(rdev); + goto retry; + } + } } + ttm_bo_unlock_delayed_workqueue(rdev-mman.bdev, resched); if (r) { /* bad news, how to tell it to userspace ? */ dev_info(rdev-dev, GPU reset failed\n); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 994c98c..6ce51d6 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -385,6 +385,75 @@ static unsigned radeon_ring_first_valid_commit(struct radeon_ring *ring) return result; } +unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring, + uint32_t **data) +{ + unsigned size, ptr, i; + int commit; + + /* just in case lock the ring */ + mutex_lock(rdev-ring_lock); + *data = NULL; + + if (ring-ring_obj == NULL) { + mutex_unlock(rdev-ring_lock); + return 0; + } + + /* first of all update the rptr directly from the hw */ + ring-rptr = (RREG32(ring-rptr_reg) ring-ptr_reg_mask) + ring-ptr_reg_shift; + + /* find the first commit not processed so far */ + commit = radeon_ring_first_valid_commit(ring); + if (commit
[Bug 51870] r600_streamout=1 nothing change
https://bugs.freedesktop.org/show_bug.cgi?id=51870 Marek Olšák mar...@gmail.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution||NOTABUG --- Comment #1 from Marek Olšák mar...@gmail.com 2012-07-09 10:50:59 PDT --- Those environment variables aren't required anymore. GLSL 1.3 and streamout are enabled by default. The only thing missing is MSAA and there is no way to enable it at the moment. Closing. -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 51870] r600_streamout=1 nothing change
https://bugs.freedesktop.org/show_bug.cgi?id=51870 --- Comment #2 from ErikAlesund fallosist...@gmail.com 2012-07-09 11:13:09 UTC --- (In reply to comment #1) Those environment variables aren't required anymore. GLSL 1.3 and streamout are enabled by default. The only thing missing is MSAA and there is no way to enable it at the moment. Closing. If would be nice to avoid confusion remove this: 10 Requires env var R600_STREAMOUT=1 in the radeon's feature page: http://www.x.org/wiki/RadeonFeature/ Thanks -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 33309] [855GM] GPU freeze due to overlay hang
https://bugs.freedesktop.org/show_bug.cgi?id=33309 --- Comment #30 from stefan fdo.12.ben...@xoxy.net 2012-07-09 11:18:52 PDT --- Hi Daniel, (In reply to comment #29) (In reply to comment #28) are there any news on this issue? The 3.4 and 3.5-rc series seem stable wrt this issue, but unfortunately something broke resume from s2ram badly, the backlight stays off and the machine does not respond even to SysRq and I need to do a hard power-off. That's goodbad news. Can you try to bisect the backlight regression that has been introduce in 3.4 and open a new bug report? That usually helps in fixing it ... It turns out to be an ACPICA regression not related to graphics at all. As for this issue, I did not observe any more hangs with v3.4 or 3.5-rc, *yet*. It is hard to tell for sure since it usually takes a while (sometimes hours) for it to occure. Which makes it also almost impossible to bisect and to find the commit that might have fixed it. Cheers, Stefan. -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: 3.5-rc5: radeon acceleration regression on Transmeta system
In 3.4, radeon worked with a glitch - window titles were see-throug (not drawn). In 3.5-rc5, radeon driver seems to be more careful and disables acceleration on this system at all. Full dmesg below. Does it always do it the same? got the dmesg from 3.4 and/or 2.6.32? That was a good question. I did some more tries, and it was not repeatable. Sometimes it worked like 3.4 did - rv100 initialized fine, no borders except when maximized, otherwise worked. Re-tested 3.4.0-rc7 that I had availble from 3.4 times, it worked 4 out of 4 times. Initial windows border problem seems to have been introduced between 2.6.37 and 2.6.38, bisect is slow. It's actually more complicated than that. Old kernel images started misbehaving from around 2.6.35-rc5 and any kernel older than that was OK. When I recompiled the older kernels with squeeze gcc (migh have been lenny gcc before, or different answers to make oldconfig), anything from current git down to 2.6.33 is broken with radeon.modeset=1 and works (I get window titles) with radeon.modeset=0. 2.6.32 works and has kernel modesetting enabled from dmesg but I think I did not notice screen going fbcon during boot... maybe it only used the modesetting when X started. So there are 2 different problems (maybe related), the new one above and the old one of not seeing some window borders when modesetting and acceleration are in use. Maximized windows do have borders. -- Meelis Roos (mr...@linux.ee) ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 33309] [855GM] GPU freeze due to overlay hang
https://bugs.freedesktop.org/show_bug.cgi?id=33309 Chris Wilson ch...@chris-wilson.co.uk changed: What|Removed |Added Status|NEEDINFO|RESOLVED Resolution||NOTOURBUG --- Comment #31 from Chris Wilson ch...@chris-wilson.co.uk 2012-07-09 11:37:34 PDT --- Ok, I'm just as surprised; be wary of a surprise attack. In the meantime, have fun! -- Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel