Re: Mesa shader compiling/optimizing process is too slow
Presumably there needs to be a api-level mechanism to wait for the background optimization to finish, so that piglit etc can validate the behavior of the optimized shader? -- Chris On Tue, Jul 10, 2012 at 5:17 AM, Eric Anholt wrote: > 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. > > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel > ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
[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&bad 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(&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%08
[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
[Bug 45018] [bisected] rendering regression since added support for virtual address space on cayman v11
https://bugs.freedesktop.org/show_bug.cgi?id=45018 --- Comment #65 from Alexandre Demers 2012-07-10 00:23:46 PDT --- Created attachment 64053 --> https://bugs.freedesktop.org/attachment.cgi?id=64053 xsession with drm-next .xsession with drm-next branch -- 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 45018] [bisected] rendering regression since added support for virtual address space on cayman v11
https://bugs.freedesktop.org/show_bug.cgi?id=45018 --- Comment #64 from Alexandre Demers 2012-07-10 00:22:55 PDT --- Created attachment 64052 --> https://bugs.freedesktop.org/attachment.cgi?id=64052 dmesg drm-next dmesg with latest drm-next branch -- 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
[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(&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"); > 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, &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.
[Bug 45018] [bisected] rendering regression since added support for virtual address space on cayman v11
https://bugs.freedesktop.org/show_bug.cgi?id=45018 --- Comment #63 from Alexandre Demers 2012-07-10 00:21:56 PDT --- Now running latest drm-next just in case. Always the same error, but with a little something new: with regular kernel, once the GPU crashed, it stays this way. With the drm-next branch, it loops. Attaching some files in a moment. I just started Gnome Shell, then opened a terminal window and launched piglit r600 tests. I'm pretty sure (dmesg): [ 66.238981] radeon :01:00.0: bo 88020f46bc00 va 0x0183B000 conflict with (bo 88021b65d000 0x0183B000 0x0183C000) [ 66.271373] radeon :01:00.0: bo 880222cc9400 va 0x01814000 conflict with (bo 880221a50800 0x01814000 0x01815000) [ 66.334540] radeon :01:00.0: bo 880222b7 va 0x01809000 conflict with (bo 8802230a9000 0x01809000 0x0180A000) corresponds to (.xsession-error): radeon: Failed to allocate a buffer: radeon:size : 256 bytes radeon:alignment : 256 bytes radeon:domains : 2 EE r600_texture.c:869 r600_texture_get_transfer - failed to create temporary texture to hold untiled copy Mesa: User error: GL_OUT_OF_MEMORY in glTexSubImage radeon: Failed to allocate a buffer: radeon:size : 256 bytes radeon:alignment : 256 bytes radeon:domains : 2 EE r600_texture.c:869 r600_texture_get_transfer - failed to create temporary texture to hold untiled copy radeon: Failed to allocate a buffer: radeon:size : 256 bytes radeon:alignment : 256 bytes radeon:domains : 2 EE r600_texture.c:869 r600_texture_get_transfer - failed to create temporary texture to hold untiled copy Then (dmesg): [ 196.710933] radeon :01:00.0: GPU lockup CP stall for more than 1msec [ 196.710946] radeon :01:00.0: GPU lockup (waiting for 0x0675 last fence id 0x066c) [ 196.711129] radeon :01:00.0: couldn't schedule ib [ 196.711239] radeon :01:00.0: couldn't schedule ib [ 196.711805] radeon :01:00.0: couldn't schedule ib [ 196.715732] radeon :01:00.0: couldn't schedule ib [ 196.715975] radeon :01:00.0: couldn't schedule ib [ 196.716362] radeon :01:00.0: couldn't schedule ib [ 196.716627] radeon :01:00.0: couldn't schedule ib [ 196.718012] radeon :01:00.0: couldn't schedule ib [ 196.718262] radeon :01:00.0: couldn't schedule ib [ 196.718480] radeon :01:00.0: couldn't schedule ib [ 196.718985] radeon :01:00.0: couldn't schedule ib [ 196.920396] radeon :01:00.0: couldn't schedule ib [ 196.920703] radeon :01:00.0: couldn't schedule ib [ 196.921084] radeon :01:00.0: couldn't schedule ib [ 196.921318] radeon :01:00.0: couldn't schedule ib [ 196.921558] radeon :01:00.0: couldn't schedule ib [ 196.921898] radeon :01:00.0: couldn't schedule ib [ 196.952350] radeon :01:00.0: couldn't schedule ib [ 196.952386] [drm:radeon_cs_ib_chunk] *ERROR* Failed to schedule IB ! [ 196.952439] BUG: unable to handle kernel NULL pointer dereference at 0008 [ 196.952494] IP: [] radeon_fence_ref+0xd/0x40 [radeon] [ 196.952531] PGD 221dc4067 PUD 2228ff067 PMD 0 [ 196.952556] Oops: [#1] PREEMPT SMP [ 196.952579] CPU 1 [ 196.952617] Modules linked in: fuse snd_usb_audio snd_usbmidi_lib snd_rawmidi powernow_k8 snd_seq_device radeon ttm joydev snd_hda_codec_hdmi ppdev evdev pwc snd_hda_codec_realtek r8712u(C) r8169 mperf parport_pc parport sp5100_tco usb_storage uas drm_kms_helper drm videobuf2_vmalloc videobuf2_memops hid_logitech_dj pcspkr processor snd_hda_intel snd_hda_codec i2c_algo_bit mii hid_generic videobuf2_core videodev media wmi kvm_amd snd_hwdep snd_pcm snd_page_alloc snd_timer psmouse i2c_piix4 usbhid firewire_ohci hid serio_raw i2c_core firewire_core k10temp kvm microcode crc_itu_t snd edac_core button soundcore edac_mce_amd ext4 crc16 jbd2 mbcache pata_acpi sr_mod sd_mod cdrom pata_atiixp ata_generic ohci_hcd ahci libahci libata ehci_hcd usbcore scsi_mod usb_common [ 196.952957] [ 196.952969] Pid: 715, comm: Xorg Tainted: G C 3.5.0-rc4-VANILLA-46957-g74da01d #1 Gigabyte Technology Co., Ltd. GA-MA78GM-S2H/GA-MA78GM-S2H [ 196.953044] RIP: 0010:[] [] radeon_fence_ref+0xd/0x40 [radeon] [ 196.953092] RSP: 0018:8802230e9b48 EFLAGS: 00010286 ... and it loops. -- 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
[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 = &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); > 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 = &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_OFFS
[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(&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"); 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, &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 = &exynos_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 = &exynos_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(&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); +
[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(&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
[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 +++ b/drivers/gpu/drm/radeon/radeon_ring
[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, &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 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 = &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.sha
[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 = &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 radeon
[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 = &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 & 0xFFF
[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 = &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
[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 = &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
[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 = &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
[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 Glisse 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 --- 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); re
[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(&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
[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(&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
[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
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 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 = &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); 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 = &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 > -
[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- |
Re: 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. pgpkHIemNwJ9w.pgp Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
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>
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 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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(&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_mas
[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.
Re: [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 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 15/16] drm/radeon: implement ring commit tracking
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) 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(&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 > > __
[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.
Re: [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(&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"); 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, &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. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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. ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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 = &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); 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 = &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
Re: [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 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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(&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"); 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, &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 ___ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [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 = &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); 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 = &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 > -
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, &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
Re: [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 ___ 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 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. ___ 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 --- 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&bad 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
[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. ___ 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 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. ___ 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 --- 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(ri
[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(&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 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 +++ b/drivers/gpu/drm/radeon/radeon
[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, &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 =
[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
[PATCH 04/16] drm/radeon: add an exclusive lock for GPU reset v2
From: Jerome Glisse 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 --- 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);
[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 = &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_
[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 = &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 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 = &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 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 = &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
[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 = &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 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 = &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 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 ___ 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 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(&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 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: 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
[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 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(&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
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 > 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
[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. ___ 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 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 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