[PATCH v2 1/2] drm/amdgpu: export test ib debugfs interface
As Christian and David's suggestion, submit the test ib ring debug interfaces. It's useful for debugging with the command submission without VM case. Signed-off-by: Huang Rui--- V1 -> V2: - park the scheduler thread for each ring to avoid conflict with commands from active apps. --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 54 ++ 1 file changed, 54 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b93356b..19ac196 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -59,6 +59,7 @@ static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); +static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev); static const char *amdgpu_asic_name[] = { "TAHITI", @@ -2083,6 +2084,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (r) DRM_ERROR("registering register debugfs failed (%d).\n", r); + r = amdgpu_debugfs_test_ib_ring_init(adev); + if (r) + DRM_ERROR("registering register test ib ring debugfs failed (%d).\n", r); + r = amdgpu_debugfs_firmware_init(adev); if (r) DRM_ERROR("registering firmware debugfs failed (%d).\n", r); @@ -3603,6 +3608,51 @@ static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev) } } +static int amdgpu_debugfs_test_ib(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct amdgpu_device *adev = dev->dev_private; + int r = 0, i; + + /* hold on the scheduler */ + for (i = 0; i < AMDGPU_MAX_RINGS; i++) { + struct amdgpu_ring *ring = adev->rings[i]; + + if (!ring || !ring->sched.thread) + continue; + kthread_park(ring->sched.thread); + } + + seq_printf(m, "run ib test:\n"); + r = amdgpu_ib_ring_tests(adev); + if (r) + seq_printf(m, "ib ring tests failed (%d).\n", r); + else + seq_printf(m, "ib ring tests passed.\n"); + + /* go on the scheduler */ + for (i = 0; i < AMDGPU_MAX_RINGS; i++) { + struct amdgpu_ring *ring = adev->rings[i]; + + if (!ring || !ring->sched.thread) + continue; + kthread_unpark(ring->sched.thread); + } + + return 0; +} + +static const struct drm_info_list amdgpu_debugfs_test_ib_ring_list[] = { + {"amdgpu_test_ib", _debugfs_test_ib} +}; + +static int amdgpu_debugfs_test_ib_ring_init(struct amdgpu_device *adev) +{ + return amdgpu_debugfs_add_files(adev, + amdgpu_debugfs_test_ib_ring_list, 1); +} + int amdgpu_debugfs_init(struct drm_minor *minor) { return 0; @@ -3612,6 +3662,10 @@ void amdgpu_debugfs_cleanup(struct drm_minor *minor) { } #else +static int amdgpu_debugfs_test_ib_init(struct amdgpu_device *adev) +{ + return 0; +} static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) { return 0; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 2/2] drm/amdgpu: export test ring debugfs interface
On Wed, May 10, 2017 at 10:56 PM, Huang Ruiwrote: > On Thu, May 11, 2017 at 10:41:42AM +0800, Deucher, Alexander wrote: >> > -Original Message- >> > From: Deucher, Alexander >> > Sent: Wednesday, May 10, 2017 10:38 PM >> > To: Huang, Ray; amd-gfx@lists.freedesktop.org; Koenig, Christian >> > Cc: Zhou, David(ChunMing); Wang, Ken; Huan, Alvin; Huang, Ray >> > Subject: RE: [PATCH 2/2] drm/amdgpu: export test ring debugfs interface >> > >> > > -Original Message- >> > > From: Huang Rui [mailto:ray.hu...@amd.com] >> > > Sent: Wednesday, May 10, 2017 10:29 PM >> > > To: amd-gfx@lists.freedesktop.org; Deucher, Alexander; Koenig, Christian >> > > Cc: Zhou, David(ChunMing); Wang, Ken; Huan, Alvin; Huang, Ray >> > > Subject: [PATCH 2/2] drm/amdgpu: export test ring debugfs interface >> > > >> > > Signed-off-by: Huang Rui >> > >> > Reviewed-by: Alex Deucher >> >> Not sure if it's important for this since it's debugfs, but we don't have any >> sort of ring locks anymore (since everything should go through the scheduler >> once it's started) so we could theoretically get collisions if there are >> active >> apps using the GPU and you run these tests. >> > > Right. Any idea to hold on scheduler when I try to run this test? Park the scheduler thread for each ring like we do for GPU reset? That said, I think the expectation is that you should only run these tests when the GPU is idle. Alex ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/1] amdgpu: move asic id table to a separate file
On 11/05/17 06:10 AM, Li, Samuel wrote: > Also attach a sample ids file for reference. The names are from marketing, not > related to source code and no reviews necessary here:) Just because it's not source code doesn't mean no review is necessary. :) > It can be put in directory /usr/share/libdrm. What is the canonical location where distros or users building upstream libdrm can get this file from? There needs to be a good solution for that before this can land. -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Mesa and X developer ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/1] amdgpu: move asic id table to a separate file
From: Xiaojie YuanChange-Id: I12216da14910f5e2b0970bc1fafc2a20b0ef1ba9 Signed-off-by: Samuel Li --- amdgpu/Makefile.am | 2 + amdgpu/Makefile.sources | 2 +- amdgpu/amdgpu_asic_id.c | 198 +++ amdgpu/amdgpu_asic_id.h | 165 --- amdgpu/amdgpu_device.c | 28 +-- amdgpu/amdgpu_internal.h | 10 +++ 6 files changed, 232 insertions(+), 173 deletions(-) create mode 100644 amdgpu/amdgpu_asic_id.c delete mode 100644 amdgpu/amdgpu_asic_id.h diff --git a/amdgpu/Makefile.am b/amdgpu/Makefile.am index cf7bc1b..ecf9e82 100644 --- a/amdgpu/Makefile.am +++ b/amdgpu/Makefile.am @@ -30,6 +30,8 @@ AM_CFLAGS = \ $(PTHREADSTUBS_CFLAGS) \ -I$(top_srcdir)/include/drm +AM_CPPFLAGS = -DAMDGPU_ASIC_ID_TABLE=\"${datadir}/libdrm/amdgpu.ids\" + libdrm_amdgpu_la_LTLIBRARIES = libdrm_amdgpu.la libdrm_amdgpu_ladir = $(libdir) libdrm_amdgpu_la_LDFLAGS = -version-number 1:0:0 -no-undefined diff --git a/amdgpu/Makefile.sources b/amdgpu/Makefile.sources index 487b9e0..bc3abaa 100644 --- a/amdgpu/Makefile.sources +++ b/amdgpu/Makefile.sources @@ -1,5 +1,5 @@ LIBDRM_AMDGPU_FILES := \ - amdgpu_asic_id.h \ + amdgpu_asic_id.c \ amdgpu_bo.c \ amdgpu_cs.c \ amdgpu_device.c \ diff --git a/amdgpu/amdgpu_asic_id.c b/amdgpu/amdgpu_asic_id.c new file mode 100644 index 000..d50e21a --- /dev/null +++ b/amdgpu/amdgpu_asic_id.c @@ -0,0 +1,198 @@ +/* + * Copyright © 2017 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "amdgpu_drm.h" +#include "amdgpu_internal.h" + +static int parse_one_line(const char *line, struct amdgpu_asic_id *id) +{ + char *buf; + char *s_did; + char *s_rid; + char *s_name; + char *endptr; + int r = 0; + + buf = strdup(line); + if (!buf) + return -ENOMEM; + + /* ignore empty line and commented line */ + if (strlen(line) == 0 || line[0] == '#') { + r = -EAGAIN; + goto out; + } + + /* device id */ + s_did = strtok(buf, ","); + if (!s_did) { + r = -EINVAL; + goto out; + } + + id->did = strtol(s_did, , 16); + if (*endptr) { + r = -EINVAL; + goto out; + } + + /* revision id */ + s_rid = strtok(NULL, ","); + if (!s_rid) { + r = -EINVAL; + goto out; + } + + id->rid = strtol(s_rid, , 16); + if (*endptr) { + r = -EINVAL; + goto out; + } + + /* marketing name */ + s_name = strtok(NULL, ","); + if (!s_name) { + r = -EINVAL; + goto out; + } + + id->marketing_name = strdup(s_name); + if (id->marketing_name == NULL) { + r = -EINVAL; + goto out; + } + +out: + free(buf); + + return r; +} + +int amdgpu_parse_asic_ids(struct amdgpu_asic_id **p_asic_id_table) +{ + struct amdgpu_asic_id *asic_id_table; + struct amdgpu_asic_id *id; + FILE *fp; + char *line = NULL; + size_t len; + ssize_t n; + int line_num = 1; + size_t table_size = 0; + size_t table_max_size = 256; + int r = 0; + + fp = fopen(AMDGPU_ASIC_ID_TABLE, "r"); + if (!fp) { + fprintf(stderr, "%s: %s\n", AMDGPU_ASIC_ID_TABLE, + strerror(errno)); + return -EINVAL; + } + + asic_id_table = calloc(table_max_size, sizeof(struct amdgpu_asic_id)); + if (!asic_id_table) { + r = -ENOMEM; + goto
Re: FW: [PATCH] drm/amdgpu: reduce amdgpu_device_resume() time
On Wed, May 10, 2017 at 5:20 AM, S, Shirishwrote: > From: Shirish S > > amdgpu_device_resume() has a high time consuming > call of amdgpu_late_init() which sets the clock_gating > state of all IP blocks and is blocking. > This patch defers only this setting of clock gating state > operation to post resume of amdgpu driver but ideally before > the UI comes up or in some cases post ui as well. > > With this change the resume time of amdgpu_device comes down > from 1.299s to 0.199s which further helps in reducing the overall > system resume time. > > TEST:(For ChromiumOS on STONEY only) > * UI comes up > * S3 works multiple times > * Resume time is consistent and lower > * amdgpu_late_init() call gets called consistently and no errors reported. > > Signed-off-by: Shirish S > Reviewed-by: Huang Rui Please make sure this doesn't cause problems with S4. A few comments below. > --- > drivers/gpu/drm/amd/amdgpu/amdgpu.h| 3 ++ > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 57 > +++--- > 2 files changed, 47 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > index 1be8aed..addb204 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > @@ -1615,6 +1615,9 @@ struct amdgpu_device { > /* amdkfd interface */ > struct kfd_dev *kfd; > > + /* delayed work_func for deferring clockgating during resume */ > + struct delayed_work late_init_work; > + > struct amdgpu_virt virt; > > /* link all shadow bo */ > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > index cfc650c..a6850cf 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c > @@ -57,6 +57,8 @@ > > MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); > > +#define AMDGPU_RESUME_MS 2000 > + > static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); > static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); > > @@ -1655,22 +1657,11 @@ static int amdgpu_init(struct amdgpu_device *adev) > return 0; > } > > -static int amdgpu_late_init(struct amdgpu_device *adev) > +static int amdgpu_late_set_cg_state(struct amdgpu_device *adev) > { > int i = 0, r; > > for (i = 0; i < adev->num_ip_blocks; i++) { > - if (!adev->ip_blocks[i].status.valid) > - continue; > - if (adev->ip_blocks[i].version->funcs->late_init) { > - r = > adev->ip_blocks[i].version->funcs->late_init((void *)adev); > - if (r) { > - DRM_ERROR("late_init of IP block <%s> failed > %d\n", > - > adev->ip_blocks[i].version->funcs->name, r); > - return r; > - } > - adev->ip_blocks[i].status.late_initialized = true; > - } > /* skip CG for VCE/UVD, it's handled specially */ > if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD > && > adev->ip_blocks[i].version->type != > AMD_IP_BLOCK_TYPE_VCE) { > @@ -1688,6 +1679,27 @@ static int amdgpu_late_init(struct amdgpu_device *adev) > return 0; > } > > +static int amdgpu_late_init(struct amdgpu_device *adev) > +{ > + int i = 0, r; > + > + for (i = 0; i < adev->num_ip_blocks; i++) { > + if (!adev->ip_blocks[i].status.valid) > + continue; > + if (adev->ip_blocks[i].version->funcs->late_init) { > + r = > adev->ip_blocks[i].version->funcs->late_init((void *)adev); > + if (r) { > + DRM_ERROR("late_init of IP block <%s> failed > %d\n", > + > adev->ip_blocks[i].version->funcs->name, r); > + return r; > + } > + adev->ip_blocks[i].status.late_initialized = true; > + } > + } > + > + return 0; > +} > + > static int amdgpu_fini(struct amdgpu_device *adev) > { > int i, r; > @@ -1775,6 +1787,13 @@ static int amdgpu_fini(struct amdgpu_device *adev) > return 0; > } > > +static void amdgpu_late_init_func_handler(struct work_struct *work) > +{ > + struct amdgpu_device *adev = > + container_of(work, struct amdgpu_device, late_init_work.work); > + amdgpu_late_set_cg_state(adev); > +} > + > int amdgpu_suspend(struct amdgpu_device *adev) > { > int i, r; > @@ -2074,6 +2093,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, > INIT_LIST_HEAD(>gtt_list); >
(radeon?) WARNING: drivers/gpu/drm/drm_irq.c:1195 drm_vblank_put (v4.11-12441-g56868a4)
Hi, I just tested v4.11-12441-g56868a4 on HP xw6600 with radeon graphics, and I'm seeing the following WARNING triggered constantly. I have not seen this earlier e.g. with the distro kernel 4.10.13-200.fc25.x86_64 $ lspci|grep -i amd 60:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Curacao PRO [Radeon R7 370 / R9 270/370 OEM] 60:00.1 Audio device: Advanced Micro Devices, Inc. [AMD/ATI] Cape Verde/Pitcairn HDMI Audio [Radeon HD 7700/7800 Series] Complete kernel log: http://termbin.com/dzy5 [ 249.952546] [ cut here ] [ 249.952593] WARNING: CPU: 5 PID: 0 at /home/ttrantal/git/linux/drivers/gpu/drm/drm_irq.c:1195 drm_vblank_put+0xc4/0x120 [drm] [ 249.952596] Modules linked in: fuse tun bridge stp llc af_packet pl2303 usbserial shpchp acpi_cpufreq binfmt_misc amdgpu hid_generic uhci_hcd radeon 3c59x mii tg3 ehci_pci ehci_hcd i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm agpgart unix autofs4 [ 249.952675] CPU: 5 PID: 0 Comm: swapper/5 Tainted: GW 4.11.0+ #4 [ 249.952678] Hardware name: Hewlett-Packard HP xw6600 Workstation/0A9Ch, BIOS 786F4 v01.46 09/20/2012 [ 249.952681] task: 88080aea task.stack: c900031b [ 249.952695] RIP: 0010:drm_vblank_put+0xc4/0x120 [drm] [ 249.952698] RSP: 0018:88080f003d70 EFLAGS: 00010046 [ 249.952703] RAX: RBX: 880801d53000 RCX: [ 249.952706] RDX: RSI: RDI: 88080a4ac000 [ 249.952709] RBP: 88080f003d88 R08: 0001 R09: 0003 [ 249.952711] R10: 88080f003d08 R11: 001da540 R12: 88080a4ac000 [ 249.952714] R13: R14: 0086 R15: 8808019a [ 249.952717] FS: () GS:88080f00() knlGS: [ 249.952720] CS: 0010 DS: ES: CR0: 80050033 [ 249.952723] CR2: 7f8bcc3a5810 CR3: 000808789000 CR4: 06e0 [ 249.952726] Call Trace: [ 249.952731] [ 249.952746] drm_crtc_vblank_put+0x1b/0x30 [drm] [ 249.952813] radeon_crtc_handle_flip+0xdc/0x140 [radeon] [ 249.952843] si_irq_process+0x610/0x1e90 [radeon] [ 249.952872] radeon_driver_irq_handler_kms+0x39/0xc0 [radeon] [ 249.952881] __handle_irq_event_percpu+0x60/0x580 [ 249.952887] handle_irq_event_percpu+0x20/0x90 [ 249.952892] handle_irq_event+0x46/0xb0 [ 249.952897] handle_edge_irq+0x13d/0x370 [ 249.952903] handle_irq+0x66/0x210 [ 249.952908] ? __local_bh_enable+0x34/0x50 [ 249.952914] do_IRQ+0x7e/0x1b0 [ 249.952920] common_interrupt+0x95/0x95 [ 249.952924] RIP: 0010:mwait_idle+0x9c/0x3c0 [ 249.952927] RSP: 0018:c900031b3e68 EFLAGS: 0246 ORIG_RAX: ff4d [ 249.952932] RAX: RBX: 88080aea RCX: [ 249.952935] RDX: 0001 RSI: 0001 RDI: 88080aea [ 249.952938] RBP: c900031b3e98 R08: 0006 R09: [ 249.952941] R10: R11: R12: 88080aea [ 249.952943] R13: 0005 R14: 839ca0c8 R15: [ 249.952946] [ 249.952955] ? mwait_idle+0x93/0x3c0 [ 249.952961] arch_cpu_idle+0xa/0x10 [ 249.952965] default_idle_call+0x24/0x40 [ 249.952971] do_idle+0x154/0x1f0 [ 249.952976] cpu_startup_entry+0x18/0x20 [ 249.952981] start_secondary+0x159/0x1f0 [ 249.952987] secondary_startup_64+0x9f/0x9f [ 249.952995] Code: 0d 32 c7 9a e2 f7 ea 41 c1 fc 1f 48 8d 7b 60 c1 fa 06 44 29 e2 48 63 f2 48 01 ce e8 37 7d 1e e1 eb be 0f ff 5b 41 5c 41 5d 5d c3 <0f> ff eb b1 48 89 df e8 40 fe ff ff eb a7 41 0f b6 f4 48 c7 c7 [ 249.953135] ---[ end trace 399ab7917ed3b208 ]--- [ 251.185850] [ cut here ] [ 251.185896] WARNING: CPU: 5 PID: 4425 at /home/ttrantal/git/linux/drivers/gpu/drm/drm_irq.c:1195 drm_vblank_put+0xc4/0x120 [drm] [ 251.185899] Modules linked in: fuse tun bridge stp llc af_packet pl2303 usbserial shpchp acpi_cpufreq binfmt_misc amdgpu hid_generic uhci_hcd radeon 3c59x mii tg3 ehci_pci ehci_hcd i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm agpgart unix autofs4 [ 251.185979] CPU: 5 PID: 4425 Comm: in:imjournal Tainted: GW 4.11.0+ #4 [ 251.185982] Hardware name: Hewlett-Packard HP xw6600 Workstation/0A9Ch, BIOS 786F4 v01.46 09/20/2012 [ 251.185984] task: 880802f8b280 task.stack: c900034c8000 [ 251.185998] RIP: 0010:drm_vblank_put+0xc4/0x120 [drm] [ 251.186001] RSP: :88080f003d70 EFLAGS: 00010046 [ 251.186006] RAX: RBX: 880801d53000 RCX: [ 251.186009] RDX: RSI: RDI: 88080a4ac000 [ 251.186012] RBP: 88080f003d88 R08: 0001 R09: 0003 [ 251.186015] R10: 88080f003d08 R11: 001da540 R12: 88080a4ac000 [ 251.186017] R13: R14: 0086 R15: 8808019a [
RE: [PATCH 000/117] Raven Support
> -Original Message- > From: Christian König [mailto:deathsim...@vodafone.de] > Sent: Wednesday, May 10, 2017 3:29 PM > To: Alex Deucher; amd-gfx@lists.freedesktop.org > Cc: Deucher, Alexander > Subject: Re: [PATCH 000/117] Raven Support > > Am 10.05.2017 um 20:45 schrieb Alex Deucher: > > This patch set adds support for the new "Raven" APU. > > > > The first 12 patches add support for the new ACP > > audio hardware on Raven. Patches 11 and 12 are not > > meant for upstream, they are for early hardware testing. > > The rest add GPU support. Patches 17-24 are register > > headers (which are relatively large), so I'm not sending > > them out. > > > > You can view the whole patch set here: > > https://cgit.freedesktop.org/~agd5f/linux/log/?h=raven > > Patches #1-#13 are Acked-by: Christian König. > > Patches #14-#16 are Reviewed-by: Christian König > . > > Patches #17-#25 are somehow missing on the mailing lists at the moment. 17-24 are just register headers. I didn’t send them out because they are too big. Alex > > Going to take a look at the rest tomorrow. > > Christian. > > > > > Alex Deucher (12): > >drm/amdgpu: add gpu_info firmware (v3) > >drm/amdgpu: parse the gpu_info firmware (v4) > >drm/amdgpu/gfx9: drop duplicate gfx info init (v3) > >drm/amdgpu: add register headers for DCN 1.0 > >drm/amdgpu: add register headers for GC 9.1 > >drm/amdgpu: add register headers for MMHUB 9.1 > >drm/amdgpu: add register headers for MP 10.0 > >drm/amdgpu: add register headers for NBIO 7.0 > >drm/amdgpu: add register headers for SDMA 4.1 > >drm/amdgpu: add register headers for THM 10.0 > >drm/amdgpu: add register headers for VCN 1.0 > >drm/amdgpu/raven: power up/down VCN via the SMU (v2) > > > > Andrey Grodzovsky (1): > >drm/amd: Add DCN ivsrcids (v2) > > > > Chunming Zhou (17): > >drm/amdgpu: add RAVEN family id definition > >drm/amdgpu: add Raven ip blocks > >drm/amdgpu/soc15: add Raven golden setting > >drm/amdgpu: add Raven chip id case for ucode > >drm/amdgpu: add module firmware for raven > >drm/amdgpu: add gc9.1 golden setting (v2) > >drm/amdgpu/gfx9: add chip name for raven when initializing microcode > >drm/amdgpu/gfx9: add raven gfx config > >drm/amdgpu: add raven case for gmc9 golden setting > >drm/amdgpu/gmc9: set mc vm fb offset for raven > >drm/amdgpu/gmc9: change fb offset sequence so that used wider > >drm/amdgpu: add Raven sdma golden setting and chip id case > >drm/amdgpu: add nbio7 support > >drm/amdgpu: apply nbio7 for Raven (v3) > >drm/amd/powerplay/rv: power up/down sdma via the SMU > >drm/amdgpu/powerplay/raven: add smu block and enable powerplay > >drm/amdgpu: add RAVEN pci id > > > > Harry Wentland (7): > >drm/amdgpu/display: Add calcs code for DCN > >drm/amdgpu/display: Add core dc support for DCN > >drm/amdgpu/display: Add dml support for DCN > >drm/amdgpu/display: Add gpio support for DCN > >drm/amdgpu/display: Add i2c/aux support for DCN > >drm/amdgpu/display: Add irq support for DCN > >drm/amdgpu/display: Enable DCN in DC > > > > Hawking Zhang (13): > >drm/amd/amdgpu: fill in raven case in soc15 early init > >drm/amdgpu/gfx9: extend rlc fw setup > >drm/amdgpu/gfx9: enable cp interrupt for CGCG/CGLS/MGCG > >drm/amdgpu: correct gfx9 csb size > >drm/amdgpu/gfx9: add rlc bo init/fini > >drm/amdgpu/gfx9: rlc save list programming > >drm/amdgpu: init gfx power gating on raven > >drm/amdgpu/gfx9: enable/disable sck slowdown thru rlc-smu handshake > >drm/amdgpu/gfx9: add enable/disable funcs for cp power gating > >drm/amdgpu/gfx9: allow updating sck slowdown and cp pg state > >drm/amdgpu/gfx9: allow updating gfx cgpg state > >drm/amdgpu/gfx9: allow updating gfx mgpg state > >drm/amdgpu: enable dcn1.0 dc support on raven > > > > Huang Rui (17): > >drm/amdgpu/soc15: add clock gating functions for raven > >drm/amdgpu: enable soc15 clock gating flags for raven > >drm/amdgpu: add gfx clock gating for raven > >drm/amdgpu: add raven clock gating and light sleep for mmhub > >drm/amdgpu: enable MC MGCG and LS for raven > >drm/amdgpu: reuse sdma v4 MGCG and LS function for raven > >drm/amdgpu: enable sdma v4 MGCG and LS for raven > >drm/amdgpu: init sdma power gating for raven > >drm/amdgpu/sdma4: add dynamic power gating for raven > >drm/amdgpu: enable sdma power gating for raven > >drm/amdgpu: add nbio MGCG for raven > >drm/amdgpu: add psp v10 function callback for raven > >drm/amdgpu: add psp v10 ip block > >drm/amdgpu: register the psp v10 function pointers at psp sw_init > >drm/amdgpu/soc15: add psp ip block > >drm/amdgpu/vcn: add sw clock gating > >drm/amdgpu: enable sw clock gating for vcn > > > > Leo Liu (32): > >drm/amdgpu: add initial vcn support and decode
Re: Support for amdgpu VM update via CPU on large-bar systems
[HK]: From Compute perspective, all validations are synchronous. PT/PD BOs are validated when restored after evictions. However, the clearing of PT/PD BOs during creation are still done by GPU which mandates the waiting. [HK]: I am not clear on how to modify amdgpu_bo_kmap(). The function currently waits for the exclusive fence and now optionally it has to wait for all the shared fences. The clear operation is added as the exclusive fence, so we should already wait for that in amdgpu_bo_kmap(). So are you suggesting to modify kmap function to amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr, void *fence_owner). If fence_onwer != NULL it would wait for all the shared fences. Please clarify. No, that would indeed be quite a bit ugly. As far as I can see you can just completely drop the code, because we already wait for both clear as well as swap operations to finish in amdgpu_bo_kmap() by waiting for the exclusive fence. Regards, Christian. Am 10.05.2017 um 20:50 schrieb Kasiviswanathan, Harish: Thanks Christian for the review. One clarification required. Please see my comments and question inline. From: Christian König [mailto:deathsim...@vodafone.de] Sent: Wednesday, May 10, 2017 3:24 AM To: Kasiviswanathan, Harish; amd-gfx@lists.freedesktop.org Subject: Re: Support for amdgpu VM update via CPU on large-bar systems Hi Harish, for the next time please use git send-email to send patches to the mailing list. Looks pretty good in general, but a few notes all over the place. Patch #1: +static bool amdgpu_vm_is_large_bar(struct amdgpu_device *adev) +{ +if (adev->mc.visible_vram_size > 0 && +adev->mc.real_vram_size == adev->mc.visible_vram_size) +return true; +return false; +} The visible_vram_size > 0 check looks superfluous. The coding style looks off, the second line of the "if" is to far right. And in general that should rather look like "return adev->mc.real_vram_size == adev->mc.visible_vram_size;". +/* CPU update is only supported for large BAR system */ +vm->is_vm_update_mode_cpu = (vm_update_mode && + amdgpu_vm_is_large_bar(adev)); Mhm, it would be nice if we could enable this for testing even on systems with small BAR. [HK] : I will add bit in the module parameter that can override large-bar requirement. I would rather suggest to make the default value depend on if the BOX has a large or small BAR and let the user override the setting. Additional to that we should limit this to 64bit systems. +#define AMDGPU_VM_USE_CPU_UPDATE_FOR_GRAPHICS_MASK (1 << 0) +#define AMDGPU_VM_USE_CPU_UPDATE_FOR_COMPUTE_MASK (1 << 1) Not much of an issue, but the names are a bit long. Maybe use something like AMDGPU_VM_USE_CPU_FOR_GFX and AMDGPU_VM_USE_CPU_FOR_COMPUTE. +boolis_vm_update_mode_cpu : 1; Please no bitmasks when we don't need them. Patch #2: +u64 flags; unsigned shift = (adev->vm_manager.num_level - level) * adev->vm_manager.block_size; Reverse tree order. +flags = (vm->is_vm_update_mode_cpu) ? +AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : +AMDGPU_GEM_CREATE_NO_CPU_ACCESS | +AMDGPU_GEM_CREATE_SHADOW; + + ... - AMDGPU_GEM_CREATE_NO_CPU_ACCESS | - AMDGPU_GEM_CREATE_SHADOW | + flags | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | AMDGPU_GEM_CREATE_VRAM_CLEARED, I would rather write it like this: flags = AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | AMDGPU_GEM_CREATE_VRAM_CLEARED; if (vm->is_vm_update_mode_cpu) flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; else flags |= AMDGPU_GEM_CREATE_NO_CPU_ACCESS | AMDGPU_GEM_CREATE_SHADOW; +mb(); +amdgpu_gart_flush_gpu_tlb(params->adev, 0); You do this for the HDP flush, don't you? [HK]: Yes +dev_warn(adev->dev, "Page table update using CPU failed. Fallback to SDMA\n"); NACK, if kmapping the BO fails we most likely are either out of memory or out of address space. Falling back to the SDMA doesn't make the situation better, just return a proper error code here. +/* Wait for BO to be free. SDMA could be clearing it */ +amdgpu_sync_create(); +amdgpu_sync_resv(adev, , parent->bo->tbo.resv, + AMDGPU_FENCE_OWNER_VM); +amdgpu_sync_wait(); +amdgpu_sync_free(); Superfluous and a bit incorrect, amdgpu_bo_kmap already calls reservation_object_wait_timeout_rcu() but only for the exclusive fence. You probably ran into problems because of pipelined evictions, so that should be fixed in amdgpu_bo_kmap() instead. [HK]: From Compute perspective, all validations are synchronous. PT/PD BOs are validated when restored after evictions. However, the clearing of PT/PD BOs during creation are still done by GPU which mandates the waiting. [HK]: I am not
RE: [PATCH] drm/amdgpu: fix fundamental suspend/resume issue
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Christian König > Sent: Wednesday, May 10, 2017 2:09 PM > To: amd-gfx@lists.freedesktop.org > Subject: [PATCH] drm/amdgpu: fix fundamental suspend/resume issue > > From: Christian König> > Reinitializing the VM manager during suspend/resume is a very very bad > idea since all the VMs are still active and kicking. > > This can lead to random VM faults after resume when new processes > become the same client ID assigned. > > Signed-off-by: Christian König Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 22 > +- > drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 1 + > drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 15 ++- > drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 15 ++- > drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 15 ++- > drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 16 ++-- > 6 files changed, 30 insertions(+), 54 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > index ed97a2e..9803392 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c > @@ -790,6 +790,7 @@ void amdgpu_vm_reset_id(struct amdgpu_device > *adev, unsigned vmhub, > struct amdgpu_vm_id_manager *id_mgr = > >vm_manager.id_mgr[vmhub]; > struct amdgpu_vm_id *id = _mgr->ids[vmid]; > > + atomic64_set(>owner, 0); > id->gds_base = 0; > id->gds_size = 0; > id->gws_base = 0; > @@ -799,6 +800,26 @@ void amdgpu_vm_reset_id(struct amdgpu_device > *adev, unsigned vmhub, > } > > /** > + * amdgpu_vm_reset_all_id - reset VMID to zero > + * > + * @adev: amdgpu device structure > + * > + * Reset VMID to force flush on next use > + */ > +void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev) > +{ > + unsigned i, j; > + > + for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { > + struct amdgpu_vm_id_manager *id_mgr = > + >vm_manager.id_mgr[i]; > + > + for (j = 1; j < id_mgr->num_ids; ++j) > + amdgpu_vm_reset_id(adev, i, j); > + } > +} > + > +/** > * amdgpu_vm_bo_find - find the bo_va for a specific vm & bo > * > * @vm: requested vm > @@ -2393,7 +2414,6 @@ void amdgpu_vm_manager_init(struct > amdgpu_device *adev) > for (i = 0; i < AMDGPU_MAX_RINGS; ++i) > adev->vm_manager.seqno[i] = 0; > > - > atomic_set(>vm_manager.vm_pte_next_ring, 0); > atomic64_set(>vm_manager.client_counter, 0); > spin_lock_init(>vm_manager.prt_lock); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > index abc0bab..d62547d 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h > @@ -209,6 +209,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, > struct amdgpu_ring *ring, > int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job); > void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub, > unsigned vmid); > +void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev); > int amdgpu_vm_update_directories(struct amdgpu_device *adev, >struct amdgpu_vm *vm); > int amdgpu_vm_clear_freed(struct amdgpu_device *adev, > diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c > b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c > index a572979..d860939 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c > @@ -950,10 +950,6 @@ static int gmc_v6_0_suspend(void *handle) > { > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > > - if (adev->vm_manager.enabled) { > - gmc_v6_0_vm_fini(adev); > - adev->vm_manager.enabled = false; > - } > gmc_v6_0_hw_fini(adev); > > return 0; > @@ -968,16 +964,9 @@ static int gmc_v6_0_resume(void *handle) > if (r) > return r; > > - if (!adev->vm_manager.enabled) { > - r = gmc_v6_0_vm_init(adev); > - if (r) { > - dev_err(adev->dev, "vm manager initialization failed > (%d).\n", r); > - return r; > - } > - adev->vm_manager.enabled = true; > - } > + amdgpu_vm_reset_all_ids(adev); > > - return r; > + return 0; > } > > static bool gmc_v6_0_is_idle(void *handle) > diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c > b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c > index a9083a1..2750e5c 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c > @@ -1117,10 +1117,6 @@ static int gmc_v7_0_suspend(void *handle) > { > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > > - if (adev->vm_manager.enabled) { > -
[PATCH 117/117] drm/amdgpu: add RAVEN pci id
From: Chunming ZhouAdd the RAVEN pci id. Signed-off-by: Chunming Zhou Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 2211cd8..82796eda 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -465,6 +465,9 @@ static const struct pci_device_id pciidlist[] = { {0x1002, 0x6868, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, {0x1002, 0x686c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, {0x1002, 0x687f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VEGA10}, + /* Raven */ + {0x1002, 0x15dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RAVEN|AMD_IS_APU}, + {0, 0, 0} }; -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 107/117] drm/amdgpu/powerplay/raven: add smu block and enable powerplay
From: Chunming ZhouAdd the ip block and enable powerplay on raven. Reviewed-by: Hawking Zhang Signed-off-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c | 1 + drivers/gpu/drm/amd/amdgpu/soc15.c| 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index f5ae871..72c03c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -72,6 +72,7 @@ static int amdgpu_pp_early_init(void *handle) case CHIP_CARRIZO: case CHIP_STONEY: case CHIP_VEGA10: + case CHIP_RAVEN: adev->pp_enabled = true; if (amdgpu_create_pp_handle(adev)) return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index d6fa8dc..3b7f449 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -512,6 +512,7 @@ int soc15_set_ip_blocks(struct amdgpu_device *adev) amdgpu_ip_block_add(adev, _v9_0_ip_block); amdgpu_ip_block_add(adev, _ih_ip_block); amdgpu_ip_block_add(adev, _v10_0_ip_block); + amdgpu_ip_block_add(adev, _pp_ip_block); #if defined(CONFIG_DRM_AMD_DC) if (amdgpu_device_has_dc_support(adev)) amdgpu_ip_block_add(adev, _ip_block); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 108/117] drm/amd: Add DCN ivsrcids (v2)
From: Andrey Grodzovskyv2: squash in some updates (Alex) Signed-off-by: Andrey Grodzovsky Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- .../gpu/drm/amd/include/ivsrcid/irqsrcs_dcn_1_0.h | 1134 1 file changed, 1134 insertions(+) create mode 100644 drivers/gpu/drm/amd/include/ivsrcid/irqsrcs_dcn_1_0.h diff --git a/drivers/gpu/drm/amd/include/ivsrcid/irqsrcs_dcn_1_0.h b/drivers/gpu/drm/amd/include/ivsrcid/irqsrcs_dcn_1_0.h new file mode 100644 index 000..ac9fa3a --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/irqsrcs_dcn_1_0.h @@ -0,0 +1,1134 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __IRQSRCS_DCN_1_0_H__ +#define __IRQSRCS_DCN_1_0_H__ + + +#define DCN_1_0__SRCID__DC_I2C_SW_DONE 1 // DC_I2C SW done DC_I2C_SW_DONE_INTERRUPTDISP_INTERRUPT_STATUS Level +#define DCN_1_0__CTXID__DC_I2C_SW_DONE 0 + +#define DCN_1_0__SRCID__DC_I2C_DDC1_HW_DONE1 // DC_I2C DDC1 HW done DOUT_IHC_I2C_DDC1_HW_DONE_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level +#define DCN_1_0__CTXID__DC_I2C_DDC1_HW_DONE1 + +#define DCN_1_0__SRCID__DC_I2C_DDC2_HW_DONE1 // DC_I2C DDC2 HW done DOUT_IHC_I2C_DDC2_HW_DONE_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level +#define DCN_1_0__CTXID__DC_I2C_DDC2_HW_DONE2 + +#define DCN_1_0__SRCID__DC_I2C_DDC3_HW_DONE1 // DC_I2C DDC3 HW done DOUT_IHC_I2C_DDC3_HW_DONE_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level +#define DCN_1_0__CTXID__DC_I2C_DDC3_HW_DONE3 + +#define DCN_1_0__SRCID__DC_I2C_DDC4_HW_DONE1 // DC_I2C_DDC4 HW done DOUT_IHC_I2C_DDC4_HW_DONE_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level +#define DCN_1_0__CTXID__DC_I2C_DDC4_HW_DONE 4 + +#define DCN_1_0__SRCID__DC_I2C_DDC5_HW_DONE1 // DC_I2C_DDC5 HW done DOUT_IHC_I2C_DDC5_HW_DONE_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level +#define DCN_1_0__CTXID__DC_I2C_DDC5_HW_DONE5 + +#define DCN_1_0__SRCID__DC_I2C_DDC6_HW_DONE1 // DC_I2C_DDC6 HW done DOUT_IHC_I2C_DDC6_HW_DONE_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level +#define DCN_1_0__CTXID__DC_I2C_DDC6_HW_DONE6 + +#define DCN_1_0__SRCID__DC_I2C_DDCVGA_HW_DONE 1 // DC_I2C_DDCVGA HW doneDOUT_IHC_I2C_DDCVGA_HW_DONE_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level +#define DCN_1_0__CTXID__DC_I2C_DDCVGA_HW_DONE 7 + +#define DCN_1_0__SRCID__DC_I2C_DDC1_READ_REQUEST 1 // DC_I2C DDC1 read request DC_I2C_DDC1_READ_REQUEST_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level / Pulse +#define DCN_1_0__CTXID__DC_I2C_DDC1_READ_REQUEST 8 + +#define DCN_1_0__SRCID__DC_I2C_DDC2_READ_REQUEST 1 // DC_I2C DDC2 read request DC_I2C_DDC2_READ_REQUEST_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level / Pulse +#define DCN_1_0__CTXID__DC_I2C_DDC2_READ_REQUEST 9 + +#define DCN_1_0__SRCID__DC_I2C_DDC3_READ_REQUEST 1 // DC_I2C DDC3 read request DC_I2C_DDC3_READ_REQUEST_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level / Pulse +#define DCN_1_0__CTXID__DC_I2C_DDC3_READ_REQUEST 10 + +#define DCN_1_0__SRCID__DC_I2C_DDC4_READ_REQUEST 1 // DC_I2C_DDC4 read request DC_I2C_DDC4_READ_REQUEST_INTERRUPT DISP_INTERRUPT_STATUS_CONTINUE21Level / Pulse +#define DCN_1_0__CTXID__DC_I2C_DDC4_READ_REQUEST 11 + +#define DCN_1_0__SRCID__DC_I2C_DDC5_READ_REQUEST 1 // DC_I2C_DDC5 read request DC_I2C_DDC5_READ_REQUEST_INTERRUPT
[PATCH 090/117] drm/amdgpu: add vcn enc ring type and functions
From: Leo LiuAdd the ring function callbacks for the encode rings. Signed-off-by: Leo Liu Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 8 ++ drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c| 170 +++ 3 files changed, 180 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 7ee501f..b6a2272 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -48,7 +48,8 @@ enum amdgpu_ring_type { AMDGPU_RING_TYPE_VCE, AMDGPU_RING_TYPE_KIQ, AMDGPU_RING_TYPE_UVD_ENC, - AMDGPU_RING_TYPE_VCN_DEC + AMDGPU_RING_TYPE_VCN_DEC, + AMDGPU_RING_TYPE_VCN_ENC }; struct amdgpu_device; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 444fed5..d50ba06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -37,6 +37,14 @@ #define VCN_DEC_CMD_PACKET_START 0x000a #define VCN_DEC_CMD_PACKET_END 0x000b +#define VCN_ENC_CMD_NO_OP 0x +#define VCN_ENC_CMD_END0x0001 +#define VCN_ENC_CMD_IB 0x0002 +#define VCN_ENC_CMD_FENCE 0x0003 +#define VCN_ENC_CMD_TRAP 0x0004 +#define VCN_ENC_CMD_REG_WRITE 0x000b +#define VCN_ENC_CMD_REG_WAIT 0x000c + struct amdgpu_vcn { struct amdgpu_bo*vcpu_bo; void*cpu_addr; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index b8f4e77..e15a81f 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -38,6 +38,7 @@ static int vcn_v1_0_start(struct amdgpu_device *adev); static int vcn_v1_0_stop(struct amdgpu_device *adev); static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); +static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev); static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); /** @@ -54,6 +55,7 @@ static int vcn_v1_0_early_init(void *handle) adev->vcn.num_enc_rings = 2; vcn_v1_0_set_dec_ring_funcs(adev); + vcn_v1_0_set_enc_ring_funcs(adev); vcn_v1_0_set_irq_funcs(adev); return 0; @@ -688,6 +690,141 @@ static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring, vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask); } +/** + * vcn_v1_0_enc_ring_get_rptr - get enc read pointer + * + * @ring: amdgpu_ring pointer + * + * Returns the current hardware enc read pointer + */ +static uint64_t vcn_v1_0_enc_ring_get_rptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + if (ring == >vcn.ring_enc[0]) + return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_RPTR)); + else + return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_RPTR2)); +} + + /** + * vcn_v1_0_enc_ring_get_wptr - get enc write pointer + * + * @ring: amdgpu_ring pointer + * + * Returns the current hardware enc write pointer + */ +static uint64_t vcn_v1_0_enc_ring_get_wptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + if (ring == >vcn.ring_enc[0]) + return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR)); + else + return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR2)); +} + + /** + * vcn_v1_0_enc_ring_set_wptr - set enc write pointer + * + * @ring: amdgpu_ring pointer + * + * Commits the enc write pointer to the hardware + */ +static void vcn_v1_0_enc_ring_set_wptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + if (ring == >vcn.ring_enc[0]) + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR), + lower_32_bits(ring->wptr)); + else + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR2), + lower_32_bits(ring->wptr)); +} + +/** + * vcn_v1_0_enc_ring_emit_fence - emit an enc fence & trap command + * + * @ring: amdgpu_ring pointer + * @fence: fence to emit + * + * Write enc a fence and a trap command to the ring. + */ +static void vcn_v1_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, + u64 seq, unsigned flags) +{ + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); + + amdgpu_ring_write(ring, VCN_ENC_CMD_FENCE); + amdgpu_ring_write(ring, addr); + amdgpu_ring_write(ring, upper_32_bits(addr)); + amdgpu_ring_write(ring, seq); + amdgpu_ring_write(ring, VCN_ENC_CMD_TRAP); +} + +static void vcn_v1_0_enc_ring_insert_end(struct amdgpu_ring *ring) +{ +
[PATCH 103/117] drm/amd/powerplay: add raven support in smumgr. (v2)
From: Rex Zhusmumgr provides the interface for interacting with the smu firmware which handles power management. v2: squash in updates (Alex) Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/rv_inc.h | 43 +++ drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h | 76 + drivers/gpu/drm/amd/powerplay/inc/smumgr.h | 1 + drivers/gpu/drm/amd/powerplay/smumgr/Makefile| 2 +- drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.c | 352 +++ drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.h | 62 drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c| 9 + 7 files changed, 544 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/amd/powerplay/hwmgr/rv_inc.h create mode 100644 drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h create mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.c create mode 100644 drivers/gpu/drm/amd/powerplay/smumgr/rv_smumgr.h diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_inc.h b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_inc.h new file mode 100644 index 000..9a01493 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_inc.h @@ -0,0 +1,43 @@ +/* + * Copyright 2016 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RAVEN_INC_H +#define RAVEN_INC_H + + +#include "asic_reg/raven1/MP/mp_10_0_default.h" +#include "asic_reg/raven1/MP/mp_10_0_offset.h" +#include "asic_reg/raven1/MP/mp_10_0_sh_mask.h" + +#include "asic_reg/raven1/NBIO/nbio_7_0_default.h" +#include "asic_reg/raven1/NBIO/nbio_7_0_offset.h" +#include "asic_reg/raven1/NBIO/nbio_7_0_sh_mask.h" + +#include "asic_reg/raven1/THM/thm_10_0_default.h" +#include "asic_reg/raven1/THM/thm_10_0_offset.h" +#include "asic_reg/raven1/THM/thm_10_0_sh_mask.h" + + +#define ixDDI_PHY_GEN_STATUS 0x3FCE8 + +#endif diff --git a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h new file mode 100644 index 000..65149c7 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef RAVEN_PP_SMC_H +#define RAVEN_PP_SMC_H + +#pragma pack(push, 1) + +#define PPSMC_Result_OK0x1 +#define PPSMC_Result_Failed0xFF +#define PPSMC_Result_UnknownCmd0xFE +#define PPSMC_Result_CmdRejectedPrereq 0xFD +#define PPSMC_Result_CmdRejectedBusy 0xFC + +#define PPSMC_MSG_TestMessage 0x1 +#define PPSMC_MSG_GetSmuVersion 0x2 +#define PPSMC_MSG_GetDriverIfVersion0x3 +#define
[PATCH 097/117] drm/amdgpu: update vcn decode create msg
From: Leo LiuBased on new vcn firmware interface changes Signed-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 5c4057d..09190fa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -379,25 +379,20 @@ static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t hand } msg[0] = cpu_to_le32(0x0028); - msg[1] = cpu_to_le32(0x004c); + msg[1] = cpu_to_le32(0x0038); msg[2] = cpu_to_le32(0x0001); msg[3] = cpu_to_le32(0x); msg[4] = cpu_to_le32(handle); msg[5] = cpu_to_le32(0x); msg[6] = cpu_to_le32(0x0001); msg[7] = cpu_to_le32(0x0028); - msg[8] = cpu_to_le32(0x0024); + msg[8] = cpu_to_le32(0x0010); msg[9] = cpu_to_le32(0x); msg[10] = cpu_to_le32(0x0007); msg[11] = cpu_to_le32(0x); - msg[12] = cpu_to_le32(0x); - msg[13] = cpu_to_le32(0x0780); - msg[14] = cpu_to_le32(0x0440); - msg[15] = cpu_to_le32(0x); - msg[16] = cpu_to_le32(0x01b37000); - msg[17] = cpu_to_le32(0x); - msg[18] = cpu_to_le32(0x); - for (i = 19; i < 1024; ++i) + msg[12] = cpu_to_le32(0x0780); + msg[13] = cpu_to_le32(0x0440); + for (i = 14; i < 1024; ++i) msg[i] = cpu_to_le32(0x0); amdgpu_bo_kunmap(bo); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 101/117] drm/amdgpu: add raven related define in pptable.h.
From: Rex ZhuSigned-off-by: Rex Zhu Reviewed-by: Alex Deucher Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/pptable.h | 57 +-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/include/pptable.h b/drivers/gpu/drm/amd/include/pptable.h index ee6978b..0b6a057 100644 --- a/drivers/gpu/drm/amd/include/pptable.h +++ b/drivers/gpu/drm/amd/include/pptable.h @@ -61,13 +61,17 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER #define ATOM_PP_THERMALCONTROLLER_LM96163 17 #define ATOM_PP_THERMALCONTROLLER_CISLANDS 18 #define ATOM_PP_THERMALCONTROLLER_KAVERI19 +#define ATOM_PP_THERMALCONTROLLER_ICELAND 20 +#define ATOM_PP_THERMALCONTROLLER_TONGA 21 +#define ATOM_PP_THERMALCONTROLLER_FIJI 22 +#define ATOM_PP_THERMALCONTROLLER_POLARIS10 23 +#define ATOM_PP_THERMALCONTROLLER_VEGA1024 // Thermal controller 'combo type' to use an external controller for Fan control and an internal controller for thermal. // We probably should reserve the bit 0x80 for this use. // To keep the number of these types low we should also use the same code for all ASICs (i.e. do not distinguish RV6xx and RV7xx Internal here). // The driver can pick the correct internal controller based on the ASIC. - #define ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL 0x89// ADT7473 Fan Control + Internal Thermal Controller #define ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL 0x8D// EMC2103 Fan Control + Internal Thermal Controller @@ -104,6 +108,21 @@ typedef struct _ATOM_PPLIB_FANTABLE3 USHORT usFanOutputSensitivity; } ATOM_PPLIB_FANTABLE3; +typedef struct _ATOM_PPLIB_FANTABLE4 +{ +ATOM_PPLIB_FANTABLE3 basicTable3; +USHORT usFanRPMMax; +} ATOM_PPLIB_FANTABLE4; + +typedef struct _ATOM_PPLIB_FANTABLE5 +{ +ATOM_PPLIB_FANTABLE4 basicTable4; +USHORT usFanCurrentLow; +USHORT usFanCurrentHigh; +USHORT usFanRPMLow; +USHORT usFanRPMHigh; +} ATOM_PPLIB_FANTABLE5; + typedef struct _ATOM_PPLIB_EXTENDEDHEADER { USHORT usSize; @@ -119,6 +138,7 @@ typedef struct _ATOM_PPLIB_EXTENDEDHEADER USHORT usPowerTuneTableOffset; /* points to ATOM_PPLIB_CLOCK_Voltage_Dependency_Table for sclkVddgfxTable */ USHORT usSclkVddgfxTableOffset; +USHORT usVQBudgetingTableOffset; /* points to the vqBudgetingTable; */ } ATOM_PPLIB_EXTENDEDHEADER; ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps @@ -147,8 +167,9 @@ typedef struct _ATOM_PPLIB_EXTENDEDHEADER #define ATOM_PP_PLATFORM_CAP_TEMP_INVERSION 0x0040// Does the driver supports Temp Inversion feature. #define ATOM_PP_PLATFORM_CAP_EVV0x0080 #define ATOM_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL0x0100 -#define ATOM_PP_PLATFORM_LOAD_POST_PRODUCTION_FIRMWARE 0x0200 -#define ATOM_PP_PLATFORM_CAP_DISABLE_USING_ACTUAL_TEMPERATURE_FOR_POWER_CALC 0x0400 +#define ATOM_PP_PLATFORM_LOAD_POST_PRODUCTION_FIRMWARE0x0200 +#define ATOM_PP_PLATFORM_CAP_DISABLE_USING_ACTUAL_TEMPERATURE_FOR_POWER_CALC 0x0400 +#define ATOM_PP_PLATFORM_CAP_VRHOT_POLARITY_HIGH 0x0800 typedef struct _ATOM_PPLIB_POWERPLAYTABLE { @@ -427,6 +448,15 @@ typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO{ ULONG rsv2[2]; }ATOM_PPLIB_SUMO_CLOCK_INFO; +typedef struct _ATOM_PPLIB_KV_CLOCK_INFO { + USHORT usEngineClockLow; + UCHAR ucEngineClockHigh; + UCHAR vddcIndex; + USHORT tdpLimit; + USHORT rsv1; + ULONG rsv2[2]; +} ATOM_PPLIB_KV_CLOCK_INFO; + typedef struct _ATOM_PPLIB_CZ_CLOCK_INFO { UCHAR index; UCHAR rsv[3]; @@ -697,6 +727,27 @@ typedef struct _ATOM_PPLIB_PPM_Table ULONG ulTjmax; } ATOM_PPLIB_PPM_Table; +#defineVQ_DisplayConfig_NoneAWD 1 +#defineVQ_DisplayConfig_AWD 2 + +typedef struct ATOM_PPLIB_VQ_Budgeting_Record{ +ULONG ulDeviceID; +ULONG ulSustainableSOCPowerLimitLow; /* in mW */ +ULONG ulSustainableSOCPowerLimitHigh; /* in mW */ + +ULONG ulDClk; +ULONG ulEClk; +ULONG ulDispSclk; +UCHAR ucDispConfig; + +} ATOM_PPLIB_VQ_Budgeting_Record; + +typedef struct ATOM_PPLIB_VQ_Budgeting_Table { +UCHAR revid; +UCHAR numEntries; +ATOM_PPLIB_VQ_Budgeting_Record entries[1]; +} ATOM_PPLIB_VQ_Budgeting_Table; + #pragma pack() #endif -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 098/117] drm/amdgpu/vcn: add sw clock gating
From: Huang RuiAdd sw controlled clockgating for VCN. Signed-off-by: Huang Rui Reviewed-by: Hawking Zhang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 207 +- 1 file changed, 205 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 6f26a05..15a2c0f 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -281,6 +281,207 @@ static void vcn_v1_0_mc_resume(struct amdgpu_device *adev) } /** + * vcn_v1_0_disable_clock_gating - disable VCN clock gating + * + * @adev: amdgpu_device pointer + * @sw: enable SW clock gating + * + * Disable clock gating for VCN block + */ +static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev, bool sw) +{ + uint32_t data; + + /* JPEG disable CGC */ + data = RREG32(SOC15_REG_OFFSET(VCN, 0, mmJPEG_CGC_CTRL)); + + if (sw) + data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; + else + data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE_MASK; + + data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; + data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT; + WREG32(SOC15_REG_OFFSET(VCN, 0, mmJPEG_CGC_CTRL), data); + + data = RREG32(SOC15_REG_OFFSET(VCN, 0, mmJPEG_CGC_GATE)); + data &= ~(JPEG_CGC_GATE__JPEG_MASK | JPEG_CGC_GATE__JPEG2_MASK); + WREG32(SOC15_REG_OFFSET(VCN, 0, mmJPEG_CGC_GATE), data); + + /* UVD disable CGC */ + data = RREG32(SOC15_REG_OFFSET(VCN, 0, mmUVD_CGC_CTRL)); + if (sw) + data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT; + else + data &= ~ UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; + + data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT; + data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT; + WREG32(SOC15_REG_OFFSET(VCN, 0, mmUVD_CGC_CTRL), data); + + data = RREG32(SOC15_REG_OFFSET(VCN, 0, mmUVD_CGC_GATE)); + data &= ~(UVD_CGC_GATE__SYS_MASK + | UVD_CGC_GATE__UDEC_MASK + | UVD_CGC_GATE__MPEG2_MASK + | UVD_CGC_GATE__REGS_MASK + | UVD_CGC_GATE__RBC_MASK + | UVD_CGC_GATE__LMI_MC_MASK + | UVD_CGC_GATE__LMI_UMC_MASK + | UVD_CGC_GATE__IDCT_MASK + | UVD_CGC_GATE__MPRD_MASK + | UVD_CGC_GATE__MPC_MASK + | UVD_CGC_GATE__LBSI_MASK + | UVD_CGC_GATE__LRBBM_MASK + | UVD_CGC_GATE__UDEC_RE_MASK + | UVD_CGC_GATE__UDEC_CM_MASK + | UVD_CGC_GATE__UDEC_IT_MASK + | UVD_CGC_GATE__UDEC_DB_MASK + | UVD_CGC_GATE__UDEC_MP_MASK + | UVD_CGC_GATE__WCB_MASK + | UVD_CGC_GATE__VCPU_MASK + | UVD_CGC_GATE__SCPU_MASK); + WREG32(SOC15_REG_OFFSET(VCN, 0, mmUVD_CGC_GATE), data); + + data = RREG32(SOC15_REG_OFFSET(VCN, 0, mmUVD_CGC_CTRL)); + data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK + | UVD_CGC_CTRL__UDEC_CM_MODE_MASK + | UVD_CGC_CTRL__UDEC_IT_MODE_MASK + | UVD_CGC_CTRL__UDEC_DB_MODE_MASK + | UVD_CGC_CTRL__UDEC_MP_MODE_MASK + | UVD_CGC_CTRL__SYS_MODE_MASK + | UVD_CGC_CTRL__UDEC_MODE_MASK + | UVD_CGC_CTRL__MPEG2_MODE_MASK + | UVD_CGC_CTRL__REGS_MODE_MASK + | UVD_CGC_CTRL__RBC_MODE_MASK + | UVD_CGC_CTRL__LMI_MC_MODE_MASK + | UVD_CGC_CTRL__LMI_UMC_MODE_MASK + | UVD_CGC_CTRL__IDCT_MODE_MASK + | UVD_CGC_CTRL__MPRD_MODE_MASK + | UVD_CGC_CTRL__MPC_MODE_MASK + | UVD_CGC_CTRL__LBSI_MODE_MASK + | UVD_CGC_CTRL__LRBBM_MODE_MASK + | UVD_CGC_CTRL__WCB_MODE_MASK + | UVD_CGC_CTRL__VCPU_MODE_MASK + | UVD_CGC_CTRL__SCPU_MODE_MASK); + WREG32(SOC15_REG_OFFSET(VCN, 0, mmUVD_CGC_CTRL), data); + + /* turn on */ + data = RREG32(SOC15_REG_OFFSET(VCN, 0, mmUVD_SUVD_CGC_GATE)); + data |= (UVD_SUVD_CGC_GATE__SRE_MASK + | UVD_SUVD_CGC_GATE__SIT_MASK + | UVD_SUVD_CGC_GATE__SMP_MASK + | UVD_SUVD_CGC_GATE__SCM_MASK + | UVD_SUVD_CGC_GATE__SDB_MASK + | UVD_SUVD_CGC_GATE__SRE_H264_MASK + | UVD_SUVD_CGC_GATE__SRE_H264_MASK + | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK + | UVD_SUVD_CGC_GATE__SIT_H264_MASK + | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK + | UVD_SUVD_CGC_GATE__SCM_H264_MASK + | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK + | UVD_SUVD_CGC_GATE__SDB_H264_MASK + | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK + |
[PATCH 080/117] drm/amdgpu/vcn: implement ib tests with new message buffer interface
From: Leo LiuSigned-off-by: Leo Liu Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 40 - 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index e1493c1..14be761 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -373,19 +373,26 @@ static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t hand return r; } - /* stitch together an vcn create msg */ - msg[0] = cpu_to_le32(0x0de4); - msg[1] = cpu_to_le32(0x); - msg[2] = cpu_to_le32(handle); + msg[0] = cpu_to_le32(0x0028); + msg[1] = cpu_to_le32(0x004c); + msg[2] = cpu_to_le32(0x0001); msg[3] = cpu_to_le32(0x); - msg[4] = cpu_to_le32(0x); + msg[4] = cpu_to_le32(handle); msg[5] = cpu_to_le32(0x); - msg[6] = cpu_to_le32(0x); - msg[7] = cpu_to_le32(0x0780); - msg[8] = cpu_to_le32(0x0440); + msg[6] = cpu_to_le32(0x0001); + msg[7] = cpu_to_le32(0x0028); + msg[8] = cpu_to_le32(0x0024); msg[9] = cpu_to_le32(0x); - msg[10] = cpu_to_le32(0x01b37000); - for (i = 11; i < 1024; ++i) + msg[10] = cpu_to_le32(0x0007); + msg[11] = cpu_to_le32(0x); + msg[12] = cpu_to_le32(0x); + msg[13] = cpu_to_le32(0x0780); + msg[14] = cpu_to_le32(0x0440); + msg[15] = cpu_to_le32(0x); + msg[16] = cpu_to_le32(0x01b37000); + msg[17] = cpu_to_le32(0x); + msg[18] = cpu_to_le32(0x); + for (i = 19; i < 1024; ++i) msg[i] = cpu_to_le32(0x0); amdgpu_bo_kunmap(bo); @@ -423,12 +430,13 @@ static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han return r; } - /* stitch together an vcn destroy msg */ - msg[0] = cpu_to_le32(0x0de4); - msg[1] = cpu_to_le32(0x0002); - msg[2] = cpu_to_le32(handle); - msg[3] = cpu_to_le32(0x); - for (i = 4; i < 1024; ++i) + msg[0] = cpu_to_le32(0x0028); + msg[1] = cpu_to_le32(0x0018); + msg[2] = cpu_to_le32(0x); + msg[3] = cpu_to_le32(0x0002); + msg[4] = cpu_to_le32(handle); + msg[5] = cpu_to_le32(0x); + for (i = 6; i < 1024; ++i) msg[i] = cpu_to_le32(0x0); amdgpu_bo_kunmap(bo); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 081/117] uapi/drm: add AMDGPU_HW_IP_VCN_DEC for decode CS
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 929bc72..eeaa04a 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -433,7 +433,8 @@ struct drm_amdgpu_gem_va { #define AMDGPU_HW_IP_UVD 3 #define AMDGPU_HW_IP_VCE 4 #define AMDGPU_HW_IP_UVD_ENC 5 -#define AMDGPU_HW_IP_NUM 6 +#define AMDGPU_HW_IP_VCN_DEC 6 +#define AMDGPU_HW_IP_NUM 7 #define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1 -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 075/117] drm/amdgpu: move vcn ring test to amdgpu_vcn.c
From: Leo LiuHope it will be generic for vcn later Signed-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 36 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 2 ++ drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 45 + 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 5decef7..e1493c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -232,6 +232,42 @@ void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) schedule_delayed_work(>adev->vcn.idle_work, VCN_IDLE_TIMEOUT); } +int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + uint32_t tmp = 0; + unsigned i; + int r; + + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD); + r = amdgpu_ring_alloc(ring, 3); + if (r) { + DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", + ring->idx, r); + return r; + } + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); + amdgpu_ring_write(ring, 0xDEADBEEF); + amdgpu_ring_commit(ring); + for (i = 0; i < adev->usec_timeout; i++) { + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID)); + if (tmp == 0xDEADBEEF) + break; + DRM_UDELAY(1); + } + + if (i < adev->usec_timeout) { + DRM_INFO("ring test on %d succeeded in %d usecs\n", +ring->idx, i); + } else { + DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", + ring->idx, tmp); + r = -EINVAL; + } + return r; +} + static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, bool direct, struct dma_fence **fence) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 2fd22a5..937c6d9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -52,6 +52,8 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev); int amdgpu_vcn_resume(struct amdgpu_device *adev); void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring); void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring); + +int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring); int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout); int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring); diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 7f3c078..9cd6690 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -539,49 +539,6 @@ static void vcn_v1_0_dec_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) } /** - * vcn_v1_0_dec_ring_test_ring - register write test - * - * @ring: amdgpu_ring pointer - * - * Test if we can successfully write to the context register - */ -static int vcn_v1_0_dec_ring_test_ring(struct amdgpu_ring *ring) -{ - struct amdgpu_device *adev = ring->adev; - uint32_t tmp = 0; - unsigned i; - int r; - - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD); - r = amdgpu_ring_alloc(ring, 3); - if (r) { - DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", - ring->idx, r); - return r; - } - amdgpu_ring_write(ring, - PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); - amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_commit(ring); - for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID)); - if (tmp == 0xDEADBEEF) - break; - DRM_UDELAY(1); - } - - if (i < adev->usec_timeout) { - DRM_INFO("ring test on %d succeeded in %d usecs\n", -ring->idx, i); - } else { - DRM_ERROR("amdgpu: ring %d test failed (0x%08X)\n", - ring->idx, tmp); - r = -EINVAL; - } - return r; -} - -/** * vcn_v1_0_dec_ring_emit_ib - execute indirect buffer * * @ring: amdgpu_ring pointer @@ -732,7 +689,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { .emit_fence = vcn_v1_0_dec_ring_emit_fence, .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush, .emit_hdp_invalidate = vcn_v1_0_dec_ring_emit_hdp_invalidate, - .test_ring = vcn_v1_0_dec_ring_test_ring, +
[PATCH 070/117] drm/amdgpu: add vcn decode ring type and functions
From: Leo LiuAdd the ring function callbacks for the decode ring. Signed-off-by: Leo Liu Acked-by: Chunming Zhou Acked-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 3 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c| 266 +++ 2 files changed, 268 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 2b7b3c56..b4d4ed4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -47,7 +47,8 @@ enum amdgpu_ring_type { AMDGPU_RING_TYPE_UVD, AMDGPU_RING_TYPE_VCE, AMDGPU_RING_TYPE_KIQ, - AMDGPU_RING_TYPE_UVD_ENC + AMDGPU_RING_TYPE_UVD_ENC, + AMDGPU_RING_TYPE_VCN_DEC }; struct amdgpu_device; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 47bdc83..48aedd3 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -37,6 +37,7 @@ static int vcn_v1_0_start(struct amdgpu_device *adev); static int vcn_v1_0_stop(struct amdgpu_device *adev); +static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); /** * vcn_v1_0_early_init - set function pointers @@ -47,6 +48,10 @@ static int vcn_v1_0_stop(struct amdgpu_device *adev); */ static int vcn_v1_0_early_init(void *handle) { + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + vcn_v1_0_set_dec_ring_funcs(adev); + return 0; } @@ -439,6 +444,236 @@ static int vcn_v1_0_set_clockgating_state(void *handle, return 0; } +/** + * vcn_v1_0_dec_ring_get_rptr - get read pointer + * + * @ring: amdgpu_ring pointer + * + * Returns the current hardware read pointer + */ +static uint64_t vcn_v1_0_dec_ring_get_rptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_RPTR)); +} + +/** + * vcn_v1_0_dec_ring_get_wptr - get write pointer + * + * @ring: amdgpu_ring pointer + * + * Returns the current hardware write pointer + */ +static uint64_t vcn_v1_0_dec_ring_get_wptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + return RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR)); +} + +/** + * vcn_v1_0_dec_ring_set_wptr - set write pointer + * + * @ring: amdgpu_ring pointer + * + * Commits the write pointer to the hardware + */ +static void vcn_v1_0_dec_ring_set_wptr(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_WPTR), lower_32_bits(ring->wptr)); +} + +/** + * vcn_v1_0_dec_ring_emit_fence - emit an fence & trap command + * + * @ring: amdgpu_ring pointer + * @fence: fence to emit + * + * Write a fence and a trap command to the ring. + */ +static void vcn_v1_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, +unsigned flags) +{ + WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT); + + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); + amdgpu_ring_write(ring, seq); + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); + amdgpu_ring_write(ring, addr & 0x); + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); + amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff); + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); + amdgpu_ring_write(ring, 0); + + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); + amdgpu_ring_write(ring, 0); + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0)); + amdgpu_ring_write(ring, 0); + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); + amdgpu_ring_write(ring, 2); +} + +/** + * vcn_v1_0_dec_ring_hdp_invalidate - emit an hdp invalidate + * + * @ring: amdgpu_ring pointer + * + * Emits an hdp invalidate. + */ +static void vcn_v1_0_dec_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(HDP, 0, mmHDP_DEBUG0), 0)); + amdgpu_ring_write(ring, 1); +} + +/** + * vcn_v1_0_dec_ring_test_ring - register write test + * + * @ring: amdgpu_ring pointer + * + * Test if we can successfully write to the context register + */ +static int vcn_v1_0_dec_ring_test_ring(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + uint32_t tmp = 0; + unsigned i; + int r; + +
[PATCH 089/117] drm/amdgpu: add vcn enc rings
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 5 + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 28 +++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 14be761..91050ca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -126,6 +126,8 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) { + int i; + kfree(adev->vcn.saved_bo); amd_sched_entity_fini(>vcn.ring_dec.sched, >vcn.entity_dec); @@ -138,6 +140,9 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) amdgpu_ring_fini(>vcn.ring_dec); + for (i = 0; i < adev->vcn.num_enc_rings; ++i) + amdgpu_ring_fini(>vcn.ring_enc[i]); + release_firmware(adev->vcn.fw); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index 5506568..444fed5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -50,7 +50,7 @@ struct amdgpu_vcn { struct amdgpu_irq_src irq; struct amd_sched_entity entity_dec; struct amd_sched_entity entity_enc; - uint32_tsrbm_soft_reset; + unsignednum_enc_rings; }; int amdgpu_vcn_sw_init(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 2e65068..b8f4e77 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -51,6 +51,8 @@ static int vcn_v1_0_early_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + adev->vcn.num_enc_rings = 2; + vcn_v1_0_set_dec_ring_funcs(adev); vcn_v1_0_set_irq_funcs(adev); @@ -67,7 +69,7 @@ static int vcn_v1_0_early_init(void *handle) static int vcn_v1_0_sw_init(void *handle) { struct amdgpu_ring *ring; - int r; + int i, r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* VCN TRAP */ @@ -86,6 +88,16 @@ static int vcn_v1_0_sw_init(void *handle) ring = >vcn.ring_dec; sprintf(ring->name, "vcn_dec"); r = amdgpu_ring_init(adev, ring, 512, >vcn.irq, 0); + if (r) + return r; + + for (i = 0; i < adev->vcn.num_enc_rings; ++i) { + ring = >vcn.ring_enc[i]; + sprintf(ring->name, "vcn_enc%d", i); + r = amdgpu_ring_init(adev, ring, 512, >vcn.irq, 0); + if (r) + return r; + } return r; } @@ -401,6 +413,20 @@ static int vcn_v1_0_start(struct amdgpu_device *adev) WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0, ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK); + ring = >vcn.ring_enc[0]; + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_RPTR), lower_32_bits(ring->wptr)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR), lower_32_bits(ring->wptr)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_LO), ring->gpu_addr); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_HI), upper_32_bits(ring->gpu_addr)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_SIZE), ring->ring_size / 4); + + ring = >vcn.ring_enc[1]; + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_RPTR2), lower_32_bits(ring->wptr)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_WPTR2), lower_32_bits(ring->wptr)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_LO2), ring->gpu_addr); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_BASE_HI2), upper_32_bits(ring->gpu_addr)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_RB_SIZE2), ring->ring_size / 4); + return 0; } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 082/117] uapi/drm: add AMDGPU_HW_IP_VCN_ENC for encode CS
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index eeaa04a..c99fe63 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -434,7 +434,8 @@ struct drm_amdgpu_gem_va { #define AMDGPU_HW_IP_VCE 4 #define AMDGPU_HW_IP_UVD_ENC 5 #define AMDGPU_HW_IP_VCN_DEC 6 -#define AMDGPU_HW_IP_NUM 7 +#define AMDGPU_HW_IP_VCN_ENC 7 +#define AMDGPU_HW_IP_NUM 8 #define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1 -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 078/117] drm/amdgpu: implement vcn start RB command
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 21 - 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 643e4ce..2fd60de 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -489,6 +489,23 @@ static void vcn_v1_0_dec_ring_set_wptr(struct amdgpu_ring *ring) } /** + * vcn_v1_0_dec_ring_insert_start - insert a start command + * + * @ring: amdgpu_ring pointer + * + * Write a start command to the ring. + */ +static void vcn_v1_0_dec_ring_insert_start(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0)); + amdgpu_ring_write(ring, 0); + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); + amdgpu_ring_write(ring, VCN_CMD_PACKET_START << 1); +} + +/** * vcn_v1_0_dec_ring_emit_fence - emit an fence & trap command * * @ring: amdgpu_ring pointer @@ -683,7 +700,8 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { .emit_frame_size = 2 + /* vcn_v1_0_dec_ring_emit_hdp_invalidate */ 34 * AMDGPU_MAX_VMHUBS + /* vcn_v1_0_dec_ring_emit_vm_flush */ - 14 + 14, /* vcn_v1_0_dec_ring_emit_fence x2 vm fence */ + 14 + 14 + /* vcn_v1_0_dec_ring_emit_fence x2 vm fence */ + 4, .emit_ib_size = 8, /* vcn_v1_0_dec_ring_emit_ib */ .emit_ib = vcn_v1_0_dec_ring_emit_ib, .emit_fence = vcn_v1_0_dec_ring_emit_fence, @@ -692,6 +710,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { .test_ring = amdgpu_vcn_dec_ring_test_ring, .test_ib = amdgpu_vcn_dec_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .insert_start = vcn_v1_0_dec_ring_insert_start, .pad_ib = amdgpu_ring_generic_pad_ib, .begin_use = amdgpu_vcn_ring_begin_use, .end_use = amdgpu_vcn_ring_end_use, -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 086/117] drm/amdgpu: implement new vcn cache window programming
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 34 -- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index adf8e52..ee27c79 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -215,31 +215,29 @@ static int vcn_v1_0_resume(void *handle) */ static void vcn_v1_0_mc_resume(struct amdgpu_device *adev) { - uint64_t offset; - uint32_t size; + uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4); - /* programm memory controller bits 0-27 */ WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), lower_32_bits(adev->vcn.gpu_addr)); WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), upper_32_bits(adev->vcn.gpu_addr)); - - /* Current FW has no signed header, but will be added later on */ - /* offset = AMDGPU_VCN_FIRMWARE_OFFSET; */ - offset = 0; - size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4); - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), offset >> 3); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), 0); WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE0), size); - offset += size; - size = AMDGPU_VCN_HEAP_SIZE; - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), offset >> 3); - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE1), size); - - offset += size; - size = AMDGPU_VCN_STACK_SIZE + (AMDGPU_VCN_SESSION_SIZE * 40); - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), offset >> 3); - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2), size); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), + lower_32_bits(adev->vcn.gpu_addr + size)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), + upper_32_bits(adev->vcn.gpu_addr + size)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), 0); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_HEAP_SIZE); + + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), + lower_32_bits(adev->vcn.gpu_addr + size + AMDGPU_VCN_HEAP_SIZE)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), + upper_32_bits(adev->vcn.gpu_addr + size + AMDGPU_VCN_HEAP_SIZE)); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), 0); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CACHE_SIZE2), + AMDGPU_VCN_STACK_SIZE + (AMDGPU_VCN_SESSION_SIZE * 40)); WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_UDEC_ADDR_CONFIG), adev->gfx.config.gb_addr_config); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 091/117] drm/amdgpu: add vcn enc irq support
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 28 +--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index e15a81f..f09d2ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -74,11 +74,19 @@ static int vcn_v1_0_sw_init(void *handle) int i, r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - /* VCN TRAP */ + /* VCN DEC TRAP */ r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VCN, 124, >vcn.irq); if (r) return r; + /* VCN ENC TRAP */ + for (i = 0; i < adev->vcn.num_enc_rings; ++i) { + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VCN, i + 119, + >vcn.irq); + if (r) + return r; + } + r = amdgpu_vcn_sw_init(adev); if (r) return r; @@ -839,7 +847,21 @@ static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev, { DRM_DEBUG("IH: VCN TRAP\n"); - amdgpu_fence_process(>vcn.ring_dec); + switch (entry->src_id) { + case 124: + amdgpu_fence_process(>vcn.ring_dec); + break; + case 119: + amdgpu_fence_process(>vcn.ring_enc[0]); + break; + case 120: + amdgpu_fence_process(>vcn.ring_enc[1]); + break; + default: + DRM_ERROR("Unhandled interrupt: %d %d\n", + entry->src_id, entry->src_data[0]); + break; + } return 0; } @@ -938,7 +960,7 @@ static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = { static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev) { - adev->vcn.irq.num_types = 1; + adev->uvd.irq.num_types = adev->vcn.num_enc_rings + 1; adev->vcn.irq.funcs = _v1_0_irq_funcs; } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 092/117] drm/amdgpu: enable vcn encode ring tests
From: Leo LiuWire up the callback and enable them. Signed-off-by: Leo Liu Reviewed-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 2 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 15 +-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 91050ca..18fd565 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -497,7 +497,7 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) ring->idx, r); return r; } - amdgpu_ring_write(ring, VCE_CMD_END); + amdgpu_ring_write(ring, VCN_ENC_CMD_END); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index f09d2ae..4ddaec3 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -144,7 +144,7 @@ static int vcn_v1_0_hw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_ring *ring = >vcn.ring_dec; - int r; + int i, r; r = vcn_v1_0_start(adev); if (r) @@ -157,9 +157,19 @@ static int vcn_v1_0_hw_init(void *handle) goto done; } + for (i = 0; i < adev->vcn.num_enc_rings; ++i) { + ring = >vcn.ring_enc[i]; + ring->ready = true; + r = amdgpu_ring_test_ring(ring); + if (r) { + ring->ready = false; + goto done; + } + } + done: if (!r) - DRM_INFO("VCN decode initialized successfully.\n"); + DRM_INFO("VCN decode and encode initialized successfully.\n"); return r; } @@ -930,6 +940,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = { .emit_ib = vcn_v1_0_enc_ring_emit_ib, .emit_fence = vcn_v1_0_enc_ring_emit_fence, .emit_vm_flush = vcn_v1_0_enc_ring_emit_vm_flush, + .test_ring = amdgpu_vcn_enc_ring_test_ring, .insert_nop = amdgpu_ring_insert_nop, .insert_end = vcn_v1_0_enc_ring_insert_end, .pad_ib = amdgpu_ring_generic_pad_ib, -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 073/117] drm/amdgpu: move amdgpu_vcn structure to vcn header
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 26 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 22 ++ 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index e884f5c..1be8aed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -62,6 +62,7 @@ #include "amdgpu_acp.h" #include "amdgpu_uvd.h" #include "amdgpu_vce.h" +#include "amdgpu_vcn.h" #include "amdgpu_dm.h" #include "gpu_scheduler.h" @@ -1181,31 +1182,6 @@ void amdgpu_wb_free_64bit(struct amdgpu_device *adev, u32 wb); void amdgpu_get_pcie_info(struct amdgpu_device *adev); /* - * VCN - */ -#define AMDGPU_VCN_STACK_SIZE (200*1024) -#define AMDGPU_VCN_HEAP_SIZE (256*1024) -#define AMDGPU_VCN_SESSION_SIZE(50*1024) -#define AMDGPU_VCN_FIRMWARE_OFFSET 256 -#define AMDGPU_VCN_MAX_ENC_RINGS 3 - -struct amdgpu_vcn { - struct amdgpu_bo*vcpu_bo; - void*cpu_addr; - uint64_tgpu_addr; - unsignedfw_version; - void*saved_bo; - struct delayed_work idle_work; - const struct firmware *fw;/* VCN firmware */ - struct amdgpu_ring ring_dec; - struct amdgpu_ring ring_enc[AMDGPU_VCN_MAX_ENC_RINGS]; - struct amdgpu_irq_src irq; - struct amd_sched_entity entity_dec; - struct amd_sched_entity entity_enc; - uint32_tsrbm_soft_reset; -}; - -/* * SDMA */ struct amdgpu_sdma_instance { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index ec4d7ca..2fd22a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -24,6 +24,28 @@ #ifndef __AMDGPU_VCN_H__ #define __AMDGPU_VCN_H__ +#define AMDGPU_VCN_STACK_SIZE (200*1024) +#define AMDGPU_VCN_HEAP_SIZE (256*1024) +#define AMDGPU_VCN_SESSION_SIZE(50*1024) +#define AMDGPU_VCN_FIRMWARE_OFFSET 256 +#define AMDGPU_VCN_MAX_ENC_RINGS 3 + +struct amdgpu_vcn { + struct amdgpu_bo*vcpu_bo; + void*cpu_addr; + uint64_tgpu_addr; + unsignedfw_version; + void*saved_bo; + struct delayed_work idle_work; + const struct firmware *fw;/* VCN firmware */ + struct amdgpu_ring ring_dec; + struct amdgpu_ring ring_enc[AMDGPU_VCN_MAX_ENC_RINGS]; + struct amdgpu_irq_src irq; + struct amd_sched_entity entity_dec; + struct amd_sched_entity entity_enc; + uint32_tsrbm_soft_reset; +}; + int amdgpu_vcn_sw_init(struct amdgpu_device *adev); int amdgpu_vcn_sw_fini(struct amdgpu_device *adev); int amdgpu_vcn_suspend(struct amdgpu_device *adev); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 071/117] drm/amdgpu: add vcn irq functions
From: Leo LiuSigned-off-by: Leo Liu Acked-by: Chunming Zhou Acked-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 32 1 file changed, 32 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 48aedd3..c9a6b1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -38,6 +38,7 @@ static int vcn_v1_0_start(struct amdgpu_device *adev); static int vcn_v1_0_stop(struct amdgpu_device *adev); static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev); +static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev); /** * vcn_v1_0_early_init - set function pointers @@ -51,6 +52,7 @@ static int vcn_v1_0_early_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; vcn_v1_0_set_dec_ring_funcs(adev); + vcn_v1_0_set_irq_funcs(adev); return 0; } @@ -674,6 +676,25 @@ static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring, vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask); } +static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + unsigned type, + enum amdgpu_interrupt_state state) +{ + return 0; +} + +static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + struct amdgpu_iv_entry *entry) +{ + DRM_DEBUG("IH: VCN TRAP\n"); + + amdgpu_fence_process(>vcn.ring_dec); + + return 0; +} + static const struct amd_ip_funcs vcn_v1_0_ip_funcs = { .name = "vcn_v1_0", .early_init = vcn_v1_0_early_init, @@ -724,3 +745,14 @@ static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev) adev->vcn.ring_dec.funcs = _v1_0_dec_ring_vm_funcs; DRM_INFO("VCN decode is enabled in VM mode\n"); } + +static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = { + .set = vcn_v1_0_set_interrupt_state, + .process = vcn_v1_0_process_interrupt, +}; + +static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev) +{ + adev->vcn.irq.num_types = 1; + adev->vcn.irq.funcs = _v1_0_irq_funcs; +} -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 083/117] drm/amdgpu: add AMDGPU_HW_IP_VCN_DEC to info query
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 585b638..8d1d8dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -318,6 +318,12 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; ib_size_alignment = 1; break; + case AMDGPU_HW_IP_VCN_DEC: + type = AMD_IP_BLOCK_TYPE_VCN; + ring_mask = adev->vcn.ring_dec.ready ? 1 : 0; + ib_start_alignment = AMDGPU_GPU_PAGE_SIZE; + ib_size_alignment = 16; + break; default: return -EINVAL; } @@ -360,6 +366,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file case AMDGPU_HW_IP_UVD_ENC: type = AMD_IP_BLOCK_TYPE_UVD; break; + case AMDGPU_HW_IP_VCN_DEC: + type = AMD_IP_BLOCK_TYPE_VCN; + break; default: return -EINVAL; } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 074/117] drm/amdgpu: re-group the functions in amdgpu_vcn.c
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 140 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 9bb59cc..5decef7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -196,6 +196,42 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) return 0; } +static void amdgpu_vcn_idle_work_handler(struct work_struct *work) +{ + struct amdgpu_device *adev = + container_of(work, struct amdgpu_device, vcn.idle_work.work); + unsigned fences = amdgpu_fence_count_emitted(>vcn.ring_dec); + + if (fences == 0) { + if (adev->pm.dpm_enabled) { + amdgpu_dpm_enable_uvd(adev, false); + } else { + amdgpu_asic_set_uvd_clocks(adev, 0, 0); + } + } else { + schedule_delayed_work(>vcn.idle_work, VCN_IDLE_TIMEOUT); + } +} + +void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + bool set_clocks = !cancel_delayed_work_sync(>vcn.idle_work); + + if (set_clocks) { + if (adev->pm.dpm_enabled) { + amdgpu_dpm_enable_uvd(adev, true); + } else { + amdgpu_asic_set_uvd_clocks(adev, 53300, 4); + } + } +} + +void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) +{ + schedule_delayed_work(>adev->vcn.idle_work, VCN_IDLE_TIMEOUT); +} + static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, bool direct, struct dma_fence **fence) { @@ -365,42 +401,6 @@ static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han return amdgpu_vcn_dec_send_msg(ring, bo, direct, fence); } -static void amdgpu_vcn_idle_work_handler(struct work_struct *work) -{ - struct amdgpu_device *adev = - container_of(work, struct amdgpu_device, vcn.idle_work.work); - unsigned fences = amdgpu_fence_count_emitted(>vcn.ring_dec); - - if (fences == 0) { - if (adev->pm.dpm_enabled) { - amdgpu_dpm_enable_uvd(adev, false); - } else { - amdgpu_asic_set_uvd_clocks(adev, 0, 0); - } - } else { - schedule_delayed_work(>vcn.idle_work, VCN_IDLE_TIMEOUT); - } -} - -void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring) -{ - struct amdgpu_device *adev = ring->adev; - bool set_clocks = !cancel_delayed_work_sync(>vcn.idle_work); - - if (set_clocks) { - if (adev->pm.dpm_enabled) { - amdgpu_dpm_enable_uvd(adev, true); - } else { - amdgpu_asic_set_uvd_clocks(adev, 53300, 4); - } - } -} - -void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring) -{ - schedule_delayed_work(>adev->vcn.idle_work, VCN_IDLE_TIMEOUT); -} - int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence; @@ -435,6 +435,40 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) return r; } +int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + uint32_t rptr = amdgpu_ring_get_rptr(ring); + unsigned i; + int r; + + r = amdgpu_ring_alloc(ring, 16); + if (r) { + DRM_ERROR("amdgpu: vcn enc failed to lock ring %d (%d).\n", + ring->idx, r); + return r; + } + amdgpu_ring_write(ring, VCE_CMD_END); + amdgpu_ring_commit(ring); + + for (i = 0; i < adev->usec_timeout; i++) { + if (amdgpu_ring_get_rptr(ring) != rptr) + break; + DRM_UDELAY(1); + } + + if (i < adev->usec_timeout) { + DRM_INFO("ring test on %d succeeded in %d usecs\n", +ring->idx, i); + } else { + DRM_ERROR("amdgpu: ring %d test failed\n", + ring->idx); + r = -ETIMEDOUT; + } + + return r; +} + static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct dma_fence **fence) { @@ -561,40 +595,6 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han return r; } -int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) -{ - struct amdgpu_device *adev = ring->adev; - uint32_t rptr = amdgpu_ring_get_rptr(ring); - unsigned i;
[PATCH 067/117] drm/amdgpu: add encode tests for vcn
From: Leo LiuAdd encode ring and ib tests. Signed-off-by: Leo Liu Acked-by: Alex Deucher Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 203 drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 3 + 2 files changed, 206 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 97b09b6..9bb59cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -112,6 +112,15 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) return r; } + ring = >vcn.ring_enc[0]; + rq = >sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; + r = amd_sched_entity_init(>sched, >vcn.entity_enc, + rq, amdgpu_sched_jobs); + if (r != 0) { + DRM_ERROR("Failed setting up VCN enc run queue.\n"); + return r; + } + return 0; } @@ -121,6 +130,8 @@ int amdgpu_vcn_sw_fini(struct amdgpu_device *adev) amd_sched_entity_fini(>vcn.ring_dec.sched, >vcn.entity_dec); + amd_sched_entity_fini(>vcn.ring_enc[0].sched, >vcn.entity_enc); + amdgpu_bo_free_kernel(>vcn.vcpu_bo, >vcn.gpu_addr, (void **)>vcn.cpu_addr); @@ -423,3 +434,195 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: return r; } + +static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct dma_fence **fence) +{ + const unsigned ib_size_dw = 1024; + struct amdgpu_job *job; + struct amdgpu_ib *ib; + struct dma_fence *f = NULL; + uint64_t dummy; + int i, r; + + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, ); + if (r) + return r; + + ib = >ibs[0]; + + dummy = ib->gpu_addr + 1024; + + /* stitch together an VCN enc create msg */ + ib->length_dw = 0; + ib->ptr[ib->length_dw++] = 0x000c; /* len */ + ib->ptr[ib->length_dw++] = 0x0001; /* session cmd */ + ib->ptr[ib->length_dw++] = handle; + + ib->ptr[ib->length_dw++] = 0x0040; /* len */ + ib->ptr[ib->length_dw++] = 0x0101; /* create cmd */ + ib->ptr[ib->length_dw++] = 0x; + ib->ptr[ib->length_dw++] = 0x0042; + ib->ptr[ib->length_dw++] = 0x000a; + ib->ptr[ib->length_dw++] = 0x0001; + ib->ptr[ib->length_dw++] = 0x0080; + ib->ptr[ib->length_dw++] = 0x0060; + ib->ptr[ib->length_dw++] = 0x0100; + ib->ptr[ib->length_dw++] = 0x0100; + ib->ptr[ib->length_dw++] = 0x000c; + ib->ptr[ib->length_dw++] = 0x; + ib->ptr[ib->length_dw++] = 0x; + ib->ptr[ib->length_dw++] = 0x; + ib->ptr[ib->length_dw++] = 0x; + ib->ptr[ib->length_dw++] = 0x; + + ib->ptr[ib->length_dw++] = 0x0014; /* len */ + ib->ptr[ib->length_dw++] = 0x0505; /* feedback buffer */ + ib->ptr[ib->length_dw++] = upper_32_bits(dummy); + ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = 0x0001; + + for (i = ib->length_dw; i < ib_size_dw; ++i) + ib->ptr[i] = 0x0; + + r = amdgpu_ib_schedule(ring, 1, ib, NULL, ); + job->fence = dma_fence_get(f); + if (r) + goto err; + + amdgpu_job_free(job); + if (fence) + *fence = dma_fence_get(f); + dma_fence_put(f); + return 0; + +err: + amdgpu_job_free(job); + return r; +} + +static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, + bool direct, struct dma_fence **fence) +{ + const unsigned ib_size_dw = 1024; + struct amdgpu_job *job; + struct amdgpu_ib *ib; + struct dma_fence *f = NULL; + int i, r; + + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, ); + if (r) + return r; + + ib = >ibs[0]; + + /* stitch together an VCN enc destroy msg */ + ib->length_dw = 0; + ib->ptr[ib->length_dw++] = 0x000c; /* len */ + ib->ptr[ib->length_dw++] = 0x0001; /* session cmd */ + ib->ptr[ib->length_dw++] = handle; + + ib->ptr[ib->length_dw++] = 0x0020; /* len */ + ib->ptr[ib->length_dw++] = 0x0002; /* task info */ + ib->ptr[ib->length_dw++] = 0x; /* next task info, set to 0x if no */ + ib->ptr[ib->length_dw++] = 0x0001; /* destroy session */ + ib->ptr[ib->length_dw++] = 0x; + ib->ptr[ib->length_dw++] = 0x; + ib->ptr[ib->length_dw++] = 0x; /* feedback is not needed, set to
[PATCH 084/117] drm/amdgpu: get cs support of AMDGPU_HW_IP_VCN_DEC
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 4e6b950..60948a7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -91,6 +91,9 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, return -EINVAL; } break; + case AMDGPU_HW_IP_VCN_DEC: + *out_ring = >vcn.ring_dec; + break; } if (!(*out_ring && (*out_ring)->adev)) { -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 085/117] drm/amdgpu: Disable uvd and vce free handles for raven
From: Leo LiuNot required on raven. Signed-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 8d1d8dd..7d2bc4c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -822,8 +822,10 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev, amdgpu_ctx_mgr_fini(>ctx_mgr); - amdgpu_uvd_free_handles(adev, file_priv); - amdgpu_vce_free_handles(adev, file_priv); + if (adev->asic_type != CHIP_RAVEN) { + amdgpu_uvd_free_handles(adev, file_priv); + amdgpu_vce_free_handles(adev, file_priv); + } amdgpu_vm_bo_rmv(adev, fpriv->prt_va); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 079/117] drm/amdgpu: implement insert end ring function for vcn decode
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 2fd60de..adf8e52 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -506,6 +506,20 @@ static void vcn_v1_0_dec_ring_insert_start(struct amdgpu_ring *ring) } /** + * vcn_v1_0_dec_ring_insert_end - insert a end command + * + * @ring: amdgpu_ring pointer + * + * Write a end command to the ring. + */ +static void vcn_v1_0_dec_ring_insert_end(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0)); + amdgpu_ring_write(ring, VCN_CMD_PACKET_END << 1); +} + +/** * vcn_v1_0_dec_ring_emit_fence - emit an fence & trap command * * @ring: amdgpu_ring pointer @@ -701,7 +715,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { 2 + /* vcn_v1_0_dec_ring_emit_hdp_invalidate */ 34 * AMDGPU_MAX_VMHUBS + /* vcn_v1_0_dec_ring_emit_vm_flush */ 14 + 14 + /* vcn_v1_0_dec_ring_emit_fence x2 vm fence */ - 4, + 6, .emit_ib_size = 8, /* vcn_v1_0_dec_ring_emit_ib */ .emit_ib = vcn_v1_0_dec_ring_emit_ib, .emit_fence = vcn_v1_0_dec_ring_emit_fence, @@ -711,6 +725,7 @@ static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = { .test_ib = amdgpu_vcn_dec_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, .insert_start = vcn_v1_0_dec_ring_insert_start, + .insert_end = vcn_v1_0_dec_ring_insert_end, .pad_ib = amdgpu_ring_generic_pad_ib, .begin_use = amdgpu_vcn_ring_begin_use, .end_use = amdgpu_vcn_ring_end_use, -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 068/117] drm/amdgpu: add vcn ip block functions (v2)
From: Leo LiuFill in the core VCN 1.0 setup functionality. v2: squash in fixup (Alex) Signed-off-by: Leo Liu Acked-by: Chunming Zhou Acked-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/Makefile| 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 3 +- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 417 + 3 files changed, 421 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index f3c8245..766054a 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -101,7 +101,8 @@ amdgpu-y += \ # add VCN block amdgpu-y += \ - amdgpu_vcn.o + amdgpu_vcn.o \ + vcn_v1_0.o # add amdkfd interfaces amdgpu-y += \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index a3da1a1..3de8e74 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h @@ -62,8 +62,9 @@ enum amdgpu_ih_clientid AMDGPU_IH_CLIENTID_MP0 = 0x1e, AMDGPU_IH_CLIENTID_MP1 = 0x1f, -AMDGPU_IH_CLIENTID_MAX +AMDGPU_IH_CLIENTID_MAX, +AMDGPU_IH_CLIENTID_VCN = AMDGPU_IH_CLIENTID_UVD }; #define AMDGPU_IH_CLIENTID_LEGACY 0 diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c new file mode 100644 index 000..744268f --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -0,0 +1,417 @@ +/* + * Copyright 2016 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include "amdgpu.h" +#include "amdgpu_vcn.h" +#include "soc15d.h" +#include "soc15_common.h" + +#include "vega10/soc15ip.h" +#include "raven1/VCN/vcn_1_0_offset.h" +#include "raven1/VCN/vcn_1_0_sh_mask.h" +#include "vega10/HDP/hdp_4_0_offset.h" +#include "raven1/MMHUB/mmhub_9_1_offset.h" +#include "raven1/MMHUB/mmhub_9_1_sh_mask.h" + +static int vcn_v1_0_start(struct amdgpu_device *adev); +static int vcn_v1_0_stop(struct amdgpu_device *adev); + +/** + * vcn_v1_0_early_init - set function pointers + * + * @handle: amdgpu_device pointer + * + * Set ring and irq function pointers + */ +static int vcn_v1_0_early_init(void *handle) +{ + return 0; +} + +/** + * vcn_v1_0_sw_init - sw init for VCN block + * + * @handle: amdgpu_device pointer + * + * Load firmware and sw initialization + */ +static int vcn_v1_0_sw_init(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + /* VCN TRAP */ + r = amdgpu_irq_add_id(adev, AMDGPU_IH_CLIENTID_VCN, 124, >vcn.irq); + if (r) + return r; + + r = amdgpu_vcn_sw_init(adev); + if (r) + return r; + + r = amdgpu_vcn_resume(adev); + if (r) + return r; + + return r; +} + +/** + * vcn_v1_0_sw_fini - sw fini for VCN block + * + * @handle: amdgpu_device pointer + * + * VCN suspend and free up sw allocation + */ +static int vcn_v1_0_sw_fini(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + r = amdgpu_vcn_suspend(adev); + if (r) + return r; + + r = amdgpu_vcn_sw_fini(adev); + + return r; +} + +/** + * vcn_v1_0_hw_init - start and test VCN block + * + * @handle: amdgpu_device pointer + * + * Initialize the hardware, boot up the VCPU and do some testing + */ +static int vcn_v1_0_hw_init(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + struct amdgpu_ring *ring = >vcn.ring_dec; + int r; + + r = vcn_v1_0_start(adev); + if (r) + goto done; + + ring->ready =
[PATCH 052/117] drm/amdgpu: enable MC MGCG and LS for raven
From: Huang RuiSigned-off-by: Huang Rui Reviewed-by: Alex Deucher Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 3a36968..d46dbf3 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -614,7 +614,9 @@ static int soc15_common_early_init(void *handle) AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_DRM_MGCG | AMD_CG_SUPPORT_DRM_LS | - AMD_CG_SUPPORT_ROM_MGCG; + AMD_CG_SUPPORT_ROM_MGCG | + AMD_CG_SUPPORT_MC_MGCG | + AMD_CG_SUPPORT_MC_LS; adev->pg_flags = 0; adev->external_rev_id = 0x1; break; -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 044/117] drm/amdgpu/gfx9: add enable/disable funcs for cp power gating
From: Hawking ZhangUsed to enable/disable cp powergating. Signed-off-by: Hawking Zhang Reviewed-by: Alex Deucher Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 5be4676..c8f236d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1941,6 +1941,25 @@ static void gfx_v9_0_enable_sck_slow_down_on_power_down(struct amdgpu_device *ad } } +static void gfx_v9_0_enable_cp_power_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data = 0; + uint32_t default_data = 0; + + default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); + + if (enable == true) { + data &= ~RLC_PG_CNTL__CP_PG_DISABLE_MASK; + if(default_data != data) + WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); + } else { + data |= RLC_PG_CNTL__CP_PG_DISABLE_MASK; + if(default_data != data) + WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); + } +} + static void gfx_v9_0_init_pg(struct amdgpu_device *adev) { if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | @@ -1957,6 +1976,7 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev) WREG32(mmRLC_JUMP_TABLE_RESTORE, adev->gfx.rlc.cp_table_gpu_addr >> 8); gfx_v9_0_init_gfx_power_gating(adev); + if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) { gfx_v9_0_enable_sck_slow_down_on_power_up(adev, true); gfx_v9_0_enable_sck_slow_down_on_power_down(adev, true); @@ -1964,6 +1984,11 @@ static void gfx_v9_0_init_pg(struct amdgpu_device *adev) gfx_v9_0_enable_sck_slow_down_on_power_up(adev, false); gfx_v9_0_enable_sck_slow_down_on_power_down(adev, false); } + + if (adev->pg_flags & AMD_PG_SUPPORT_CP) + gfx_v9_0_enable_cp_power_gating(adev, true); + else + gfx_v9_0_enable_cp_power_gating(adev, false); } } } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 064/117] drm/amdgpu: register the psp v10 function pointers at psp sw_init
From: Huang RuiAdd the psp 10.0 callbacks for PSP. Signed-off-by: Huang Rui Reviewed-by: Alex Deucher Acked-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index dfdf4fd..4285f37 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -30,6 +30,7 @@ #include "amdgpu_ucode.h" #include "soc15_common.h" #include "psp_v3_1.h" +#include "psp_v10_0.h" static void psp_set_funcs(struct amdgpu_device *adev); @@ -61,6 +62,12 @@ static int psp_sw_init(void *handle) psp->compare_sram_data = psp_v3_1_compare_sram_data; psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; break; + case CHIP_RAVEN: + psp->prep_cmd_buf = psp_v10_0_prep_cmd_buf; + psp->ring_init = psp_v10_0_ring_init; + psp->cmd_submit = psp_v10_0_cmd_submit; + psp->compare_sram_data = psp_v10_0_compare_sram_data; + break; default: return -EINVAL; } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 058/117] drm/amdgpu: enable sdma power gating for raven
From: Huang RuiSigned-off-by: Huang Rui Reviewed-by: Hawking Zhang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index cd0be4a..26d415c 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -619,7 +619,7 @@ static int soc15_common_early_init(void *handle) AMD_CG_SUPPORT_MC_LS | AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS; - adev->pg_flags = 0; + adev->pg_flags = AMD_PG_SUPPORT_SDMA; adev->external_rev_id = 0x1; break; default: -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 047/117] drm/amdgpu/gfx9: allow updating gfx mgpg state
From: Hawking ZhangWire up the functions to control medium grained powergating. Signed-off-by: Hawking Zhang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 50 +++ 1 file changed, 50 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index bba13c7..a1e1b7a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1992,6 +1992,34 @@ static void gfx_v9_0_enable_gfx_pipeline_powergating(struct amdgpu_device *adev, data = RREG32(SOC15_REG_OFFSET(GC, 0, mmDB_RENDER_CONTROL)); } +void gfx_v9_0_enable_gfx_static_mg_power_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data, default_data; + + default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); + if (enable == true) + data |= RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; + else + data &= ~RLC_PG_CNTL__STATIC_PER_CU_PG_ENABLE_MASK; + if(default_data != data) + WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); +} + +void gfx_v9_0_enable_gfx_dynamic_mg_power_gating(struct amdgpu_device *adev, + bool enable) +{ + uint32_t data, default_data; + + default_data = data = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL)); + if (enable == true) + data |= RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; + else + data &= ~RLC_PG_CNTL__DYN_PER_CU_PG_ENABLE_MASK; + if(default_data != data) + WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_PG_CNTL), data); +} + static void gfx_v9_0_init_pg(struct amdgpu_device *adev) { if (adev->pg_flags & (AMD_PG_SUPPORT_GFX_PG | @@ -3259,6 +3287,25 @@ static void gfx_v9_0_update_gfx_cg_power_gating(struct amdgpu_device *adev, /* gfx_v9_0_exit_rlc_safe_mode(adev); */ } +static void gfx_v9_0_update_gfx_mg_power_gating(struct amdgpu_device *adev, + bool enable) +{ + /* TODO: double check if we need to perform under safe mode */ + /* gfx_v9_0_enter_rlc_safe_mode(adev); */ + + if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_SMG) && enable) + gfx_v9_0_enable_gfx_static_mg_power_gating(adev, true); + else + gfx_v9_0_enable_gfx_static_mg_power_gating(adev, false); + + if ((adev->pg_flags & AMD_PG_SUPPORT_GFX_DMG) && enable) + gfx_v9_0_enable_gfx_dynamic_mg_power_gating(adev, true); + else + gfx_v9_0_enable_gfx_dynamic_mg_power_gating(adev, false); + + /* gfx_v9_0_exit_rlc_safe_mode(adev); */ +} + static void gfx_v9_0_update_medium_grain_clock_gating(struct amdgpu_device *adev, bool enable) { @@ -3469,6 +3516,9 @@ static int gfx_v9_0_set_powergating_state(void *handle, /* update gfx cgpg state */ gfx_v9_0_update_gfx_cg_power_gating(adev, enable); + + /* update mgcg state */ + gfx_v9_0_update_gfx_mg_power_gating(adev, enable); break; default: break; -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 050/117] drm/amdgpu/gmc9: change fb offset sequence so that used wider
From: Chunming ZhouInitialize the values earlier. Signed-off-by: Chunming Zhou Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index d1e02de..7a875ff 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -415,6 +415,11 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev, amdgpu_vram_location(adev, >mc, base); adev->mc.gtt_base_align = 0; amdgpu_gtt_location(adev, mc); + /* base offset of vram pages */ + if (adev->flags & AMD_IS_APU) + adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev); + else + adev->vm_manager.vram_base_offset = 0; } /** @@ -547,12 +552,6 @@ static int gmc_v9_0_vm_init(struct amdgpu_device *adev) adev->vm_manager.num_level = 3; amdgpu_vm_manager_init(adev); - /* base offset of vram pages */ - if (adev->flags & AMD_IS_APU) - adev->vm_manager.vram_base_offset = gfxhub_v1_0_get_mc_fb_offset(adev); - else - adev->vm_manager.vram_base_offset = 0; - return 0; } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 034/117] drm/amdgpu/gfx9: add chip name for raven when initializing microcode
From: Chunming ZhouFetch the correct ucode for raven. Signed-off-by: Chunming Zhou Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index aa28873..74d6eae 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -328,6 +328,9 @@ static int gfx_v9_0_init_microcode(struct amdgpu_device *adev) case CHIP_VEGA10: chip_name = "vega10"; break; + case CHIP_RAVEN: + chip_name = "raven"; + break; default: BUG(); } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 056/117] drm/amdgpu: init sdma power gating for raven
From: Huang RuiInitialize sdma for powergating. Signed-off-by: Huang Rui Reviewed-by: Hawking Zhang Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 48 +- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 2afcadb..3d24e50 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -35,6 +35,7 @@ #include "vega10/MMHUB/mmhub_1_0_offset.h" #include "vega10/MMHUB/mmhub_1_0_sh_mask.h" #include "vega10/HDP/hdp_4_0_offset.h" +#include "raven1/SDMA0/sdma0_4_1_default.h" #include "soc15_common.h" #include "soc15.h" @@ -44,6 +45,9 @@ MODULE_FIRMWARE("amdgpu/vega10_sdma.bin"); MODULE_FIRMWARE("amdgpu/vega10_sdma1.bin"); MODULE_FIRMWARE("amdgpu/raven_sdma.bin"); +#define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x00F8L +#define SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK 0xFC00L + static void sdma_v4_0_set_ring_funcs(struct amdgpu_device *adev); static void sdma_v4_0_set_buffer_funcs(struct amdgpu_device *adev); static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev); @@ -665,6 +669,47 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev) return 0; } +static void sdma_v4_1_init_power_gating(struct amdgpu_device *adev) +{ + uint32_t def, data; + + /* Enable HW based PG. */ + def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL)); + data |= SDMA0_POWER_CNTL__PG_CNTL_ENABLE_MASK; + if (data != def) + WREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL), data); + + /* enable interrupt */ + def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CNTL)); + data |= SDMA0_CNTL__CTXEMPTY_INT_ENABLE_MASK; + if (data != def) + WREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_CNTL), data); + + /* Configure hold time to filter in-valid power on/off request. Use default right now */ + def = data = RREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL)); + data &= ~SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK; + data |= (mmSDMA0_POWER_CNTL_DEFAULT & SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK); + /* Configure switch time for hysteresis purpose. Use default right now */ + data &= ~SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK; + data |= (mmSDMA0_POWER_CNTL_DEFAULT & SDMA0_POWER_CNTL__ON_OFF_STATUS_DURATION_TIME_MASK); + if(data != def) + WREG32(SOC15_REG_OFFSET(SDMA0, 0, mmSDMA0_POWER_CNTL), data); +} + +static void sdma_v4_0_init_pg(struct amdgpu_device *adev) +{ + if (!(adev->pg_flags & AMD_PG_SUPPORT_SDMA)) + return; + + switch (adev->asic_type) { + case CHIP_RAVEN: + sdma_v4_1_init_power_gating(adev); + break; + default: + break; + } +} + /** * sdma_v4_0_rlc_resume - setup and start the async dma engines * @@ -675,7 +720,8 @@ static int sdma_v4_0_gfx_resume(struct amdgpu_device *adev) */ static int sdma_v4_0_rlc_resume(struct amdgpu_device *adev) { - /* XXX todo */ + sdma_v4_0_init_pg(adev); + return 0; } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 051/117] drm/amdgpu: add raven clock gating and light sleep for mmhub
From: Huang RuiSigned-off-by: Huang Rui Reviewed-by: Alex Deucher Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c | 50 + 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c index dbfe48d..ac9c95c 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -34,6 +34,9 @@ #include "soc15_common.h" +#define mmDAGB0_CNTL_MISC2_RV 0x008f +#define mmDAGB0_CNTL_MISC2_RV_BASE_IDX 0 + u64 mmhub_v1_0_get_fb_location(struct amdgpu_device *adev) { u64 base = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmMC_VM_FB_LOCATION_BASE)); @@ -407,11 +410,15 @@ static int mmhub_v1_0_soft_reset(void *handle) static void mmhub_v1_0_update_medium_grain_clock_gating(struct amdgpu_device *adev, bool enable) { - uint32_t def, data, def1, data1, def2, data2; + uint32_t def, data, def1, data1, def2 = 0, data2 = 0; def = data = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmATC_L2_MISC_CG)); - def1 = data1 = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB0_CNTL_MISC2)); - def2 = data2 = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB1_CNTL_MISC2)); + + if (adev->asic_type != CHIP_RAVEN) { + def1 = data1 = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB0_CNTL_MISC2)); + def2 = data2 = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB1_CNTL_MISC2)); + } else + def1 = data1 = RREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB0_CNTL_MISC2_RV)); if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) { data |= ATC_L2_MISC_CG__ENABLE_MASK; @@ -423,12 +430,13 @@ static void mmhub_v1_0_update_medium_grain_clock_gating(struct amdgpu_device *ad DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); - data2 &= ~(DAGB1_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_WRRET_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_RDRET_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); + if (adev->asic_type != CHIP_RAVEN) + data2 &= ~(DAGB1_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_WRRET_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_RDRET_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); } else { data &= ~ATC_L2_MISC_CG__ENABLE_MASK; @@ -439,21 +447,26 @@ static void mmhub_v1_0_update_medium_grain_clock_gating(struct amdgpu_device *ad DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); - data2 |= (DAGB1_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_WRRET_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_RDRET_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | - DAGB1_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); + if (adev->asic_type != CHIP_RAVEN) + data2 |= (DAGB1_CNTL_MISC2__DISABLE_WRREQ_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_WRRET_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_RDREQ_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_RDRET_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_TLBWR_CG_MASK | + DAGB1_CNTL_MISC2__DISABLE_TLBRD_CG_MASK); } if (def != data) WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmATC_L2_MISC_CG), data); - if (def1 != data1) - WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB0_CNTL_MISC2), data1); + if (def1 != data1) { + if (adev->asic_type != CHIP_RAVEN) + WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB0_CNTL_MISC2), data1); + else + WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB0_CNTL_MISC2_RV), data1); + } - if (def2 != data2) + if (adev->asic_type != CHIP_RAVEN && def2 != data2) WREG32(SOC15_REG_OFFSET(MMHUB, 0, mmDAGB1_CNTL_MISC2), data2); } @@ -516,6
[PATCH 010/117] ASoC: AMD: Add ACP3x system resume pm op
From: Maruthi Srinivas BayyavarapuWhen audio usecase in progress and system wide suspend happens, ACP will be powered off and when system resumes, for audio usecase to continue, all the runtime configuration data needs to be programmed again. Added 'resume'pm call back to ACP pm ops. Signed-off-by: Maruthi Bayyavarapu Signed-off-by: Alex Deucher --- sound/soc/amd/raven/acp3x-pcm-dma.c | 46 + 1 file changed, 46 insertions(+) diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index a5d3807..5246d28 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -709,6 +709,51 @@ static int acp3x_audio_remove(struct platform_device *pdev) return 0; } +static int acp3x_resume(struct device *dev) +{ + int status; + u32 val; + struct i2s_dev_data *adata = dev_get_drvdata(dev); + + status = acp3x_init(adata->acp3x_base); + if (status) + return -ENODEV; + + if (adata->play_stream && adata->play_stream->runtime) { + struct i2s_stream_instance *rtd = + adata->play_stream->runtime->private_data; + config_acp3x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK); + rv_writel((rtd->xfer_resolution << 3), + rtd->acp3x_base + mmACP_BTTDM_ITER); + if (adata->tdm_mode == true) { + rv_writel(adata->tdm_fmt, adata->acp3x_base + + mmACP_BTTDM_TXFRMT); + val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER); + rv_writel((val | 0x2), adata->acp3x_base + + mmACP_BTTDM_ITER); + } + } + + if (adata->capture_stream && adata->capture_stream->runtime) { + struct i2s_stream_instance *rtd = + adata->capture_stream->runtime->private_data; + config_acp3x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE); + rv_writel((rtd->xfer_resolution << 3), + rtd->acp3x_base + mmACP_BTTDM_IRER); + if (adata->tdm_mode == true) { + rv_writel(adata->tdm_fmt, adata->acp3x_base + + mmACP_BTTDM_RXFRMT); + val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER); + rv_writel((val | 0x2), adata->acp3x_base + + mmACP_BTTDM_IRER); + } + } + + rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); + return 0; +} + + static int acp3x_pcm_runtime_suspend(struct device *dev) { int status; @@ -740,6 +785,7 @@ static int acp3x_pcm_runtime_resume(struct device *dev) static const struct dev_pm_ops acp3x_pm_ops = { .runtime_suspend = acp3x_pcm_runtime_suspend, .runtime_resume = acp3x_pcm_runtime_resume, + .resume = acp3x_resume, }; static struct platform_driver acp3x_dma_driver = { -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 005/117] ASoC: AMD: handle ACP3x i2s watermark interrupt
From: Maruthi Srinivas Bayyavarapuwhenever audio data equal to I2S fifo watermark level is produced/consumed, interrupt is generated. Amount of data is equal to half of ALSA ring buffer size. Acknowledge the interrupt. Signed-off-by: Maruthi Bayyavarapu Signed-off-by: Alex Deucher --- sound/soc/amd/raven/acp3x-pcm-dma.c | 49 + 1 file changed, 49 insertions(+) diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index 3fd9f86..0ce04f0 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -25,6 +25,7 @@ #include "acp3x.h" struct i2s_dev_data { + unsigned int i2s_irq; void __iomem *acp3x_base; struct snd_pcm_substream *play_stream; struct snd_pcm_substream *capture_stream; @@ -135,6 +136,38 @@ static int acp3x_deinit(void __iomem *acp3x_base) return 0; } +static irqreturn_t i2s_irq_handler(int irq, void *dev_id) +{ + u16 play_flag, cap_flag; + u32 val; + struct i2s_dev_data *rv_i2s_data = dev_id; + + if (rv_i2s_data == NULL) + return IRQ_NONE; + + play_flag = cap_flag = 0; + + val = rv_readl(rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT); + if ((val & BIT(BT_TX_THRESHOLD)) && (rv_i2s_data->play_stream)) { + rv_writel(BIT(BT_TX_THRESHOLD), rv_i2s_data->acp3x_base + + mmACP_EXTERNAL_INTR_STAT); + snd_pcm_period_elapsed(rv_i2s_data->play_stream); + play_flag = 1; + } + + if ((val & BIT(BT_RX_THRESHOLD)) && rv_i2s_data->capture_stream) { + rv_writel(BIT(BT_RX_THRESHOLD), rv_i2s_data->acp3x_base + + mmACP_EXTERNAL_INTR_STAT); + snd_pcm_period_elapsed(rv_i2s_data->capture_stream); + cap_flag = 1; + } + + if (play_flag | cap_flag) + return IRQ_HANDLED; + else + return IRQ_NONE; +} + static struct snd_pcm_ops acp3x_dma_ops = { .open = NULL, .close = NULL, @@ -211,6 +244,13 @@ static int acp3x_audio_probe(struct platform_device *pdev) adata->acp3x_base = devm_ioremap(>dev, res->start, resource_size(res)); + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(>dev, "IORESOURCE_IRQ FAILED\n"); + return -ENODEV; + } + + adata->i2s_irq = res->start; adata->play_stream = NULL; adata->capture_stream = NULL; @@ -234,6 +274,15 @@ static int acp3x_audio_probe(struct platform_device *pdev) goto dev_err; } + status = devm_request_irq(>dev, adata->i2s_irq, i2s_irq_handler, + irqflags, "ACP3x_I2S_IRQ", adata); + if (status) { + dev_err(>dev, "ACP3x I2S IRQ request failed\n"); + snd_soc_unregister_platform(>dev); + snd_soc_unregister_component(>dev); + goto dev_err; + } + return 0; dev_err: status = acp3x_deinit(adata->acp3x_base); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 006/117] ASoC: AMD: add ACP3x PCM driver DMA ops
From: Maruthi Srinivas BayyavarapuACP3x has a DMA controller to access system memory. This controller transfers data from/to system memory to/from ACP internal fifo. The patch adds PCM driver DMA operations. Signed-off-by: Maruthi Bayyavarapu Signed-off-by: Alex Deucher --- sound/soc/amd/raven/acp3x-pcm-dma.c | 269 ++-- sound/soc/amd/raven/acp3x.h | 14 ++ 2 files changed, 275 insertions(+), 8 deletions(-) diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index 0ce04f0..346ebcb 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -31,6 +31,56 @@ struct i2s_dev_data { struct snd_pcm_substream *capture_stream; }; +struct i2s_stream_instance { + u16 num_pages; + u16 channels; + u32 xfer_resolution; + u32 fmt; + u32 val; + struct page *pg; + void __iomem *acp3x_base; +}; + +static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_BATCH | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_96000, + .rate_min = 8000, + .rate_max = 96000, + .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE, + .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, + .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, + .periods_min = PLAYBACK_MIN_NUM_PERIODS, + .periods_max = PLAYBACK_MAX_NUM_PERIODS, +}; + +static const struct snd_pcm_hardware acp3x_pcm_hardware_capture = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_BATCH | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .rate_min = 8000, + .rate_max = 48000, + .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE, + .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, + .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, + .periods_min = CAPTURE_MIN_NUM_PERIODS, + .periods_max = CAPTURE_MAX_NUM_PERIODS, +}; + static int acp3x_power_on(void __iomem *acp3x_base, bool on) { u16 val, mask; @@ -168,19 +218,222 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id) return IRQ_NONE; } +static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction) +{ + u16 page_idx; + u64 addr; + u32 low, high, val, acp_fifo_addr; + struct page *pg = rtd->pg; + + /* 8 scratch registers used to map one 64 bit address. +* For 2 pages (4096 * 2 bytes), it will be 16 registers. +*/ + if (direction == SNDRV_PCM_STREAM_PLAYBACK) + val = 0; + else + val = 16; + + /* Group Enable */ + rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp3x_base + + mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1); + rv_writel(PAGE_SIZE_4K_ENABLE, rtd->acp3x_base + + mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); + + for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) { + /* Load the low address of page int ACP SRAM through SRBM */ + addr = page_to_phys(pg); + low = lower_32_bits(addr); + high = upper_32_bits(addr); + + rv_writel(low, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val); + high |= BIT(31); + rv_writel(high, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val + + 4); + /* Move to next physically contiguos page */ + val += 8; + pg++; + } + + if (direction == SNDRV_PCM_STREAM_PLAYBACK) { + /* Config ringbuffer */ + rv_writel(MEM_WINDOW_START, rtd->acp3x_base + + mmACP_BT_TX_RINGBUFADDR); + rv_writel(MAX_BUFFER, rtd->acp3x_base + + mmACP_BT_TX_RINGBUFSIZE); + rv_writel(0x40, rtd->acp3x_base + mmACP_BT_TX_DMA_SIZE); + + /* Config audio fifo */ + acp_fifo_addr = ACP_SRAM_PTE_OFFSET + (rtd->num_pages * 8) + + 1024; + rv_writel(acp_fifo_addr, rtd->acp3x_base
[PATCH 004/117] ASoC: AMD: add ACP3x PCM platform driver
From: Maruthi Srinivas BayyavarapuPCM platform driver binds to the platform device creatd by ACP3x PCI device. PCM driver registers ALSA DMA and CPU DAI components with ASoC framework. Signed-off-by: Maruthi Bayyavarapu Signed-off-by: Alex Deucher --- sound/soc/amd/raven/acp3x-pcm-dma.c | 278 sound/soc/amd/raven/acp3x.h | 3 + 2 files changed, 281 insertions(+) create mode 100644 sound/soc/amd/raven/acp3x-pcm-dma.c diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c new file mode 100644 index 000..3fd9f86 --- /dev/null +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -0,0 +1,278 @@ +/* + * AMD ALSA SoC PCM Driver + * + * Copyright 2016 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "acp3x.h" + +struct i2s_dev_data { + void __iomem *acp3x_base; + struct snd_pcm_substream *play_stream; + struct snd_pcm_substream *capture_stream; +}; + +static int acp3x_power_on(void __iomem *acp3x_base, bool on) +{ + u16 val, mask; + u32 timeout; + + if (on == true) { + val = 1; + mask = 0; + } else { + val = 0; + mask = 2; + } + + rv_writel(val, acp3x_base + mmACP_PGFSM_CONTROL); + timeout = 0; + while (true) { + val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS); + if ((val & 0x3) == mask) + break; + if (timeout > 100) { + pr_err("ACP3x power state change failure\n"); + return -ENODEV; + } + timeout++; + cpu_relax(); + } + return 0; +} + +static int acp3x_reset(void __iomem *acp3x_base) +{ + u32 val, timeout; + + rv_writel(1, acp3x_base + mmACP_SOFT_RESET); + timeout = 0; + while (true) { + val = rv_readl(acp3x_base + mmACP_SOFT_RESET); + if ((val & 0x00010001) || timeout > 100) { + if (val & 0x00010001) + break; + return -ENODEV; + } + timeout++; + cpu_relax(); + } + + rv_writel(0, acp3x_base + mmACP_SOFT_RESET); + timeout = 0; + while (true) { + val = rv_readl(acp3x_base + mmACP_SOFT_RESET); + if (!val || timeout > 100) { + if (!val) + break; + return -ENODEV; + } + timeout++; + cpu_relax(); + } + return 0; +} + +static int acp3x_init(void __iomem *acp3x_base) +{ + int ret; + + /* power on */ + ret = acp3x_power_on(acp3x_base, true); + if (ret) { + pr_err("ACP3x power on failed\n"); + return ret; + } + + /* Reset */ + ret = acp3x_reset(acp3x_base); + if (ret) { + pr_err("ACP3x reset failed\n"); + return ret; + } + + pr_info("ACP Initialized\n"); + return 0; +} + +static int acp3x_deinit(void __iomem *acp3x_base) +{ + int ret; + + /* Reset */ + ret = acp3x_reset(acp3x_base); + if (ret) { + pr_err("ACP3x reset failed\n"); + return ret; + } + + /* power off */ + ret = acp3x_power_on(acp3x_base, false); + if (ret) { + pr_err("ACP3x power off failed\n"); + return ret; + } + + pr_info("ACP De-Initialized\n"); + return 0; +} + +static struct snd_pcm_ops acp3x_dma_ops = { + .open = NULL, + .close = NULL, + .ioctl = NULL, + .hw_params = NULL, + .hw_free = NULL, + .pointer = NULL, + .mmap = NULL, +}; + +static struct snd_soc_platform_driver acp3x_asoc_platform = { + .ops = _dma_ops, + .pcm_new = NULL, +}; + +struct snd_soc_dai_ops acp3x_dai_i2s_ops = { + .hw_params = NULL, + .trigger = NULL, + .set_fmt = NULL, +}; + +static struct snd_soc_dai_driver acp3x_i2s_dai_driver = { + .playback = { + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_U8 | +
[PATCH 002/117] ASoC: AMD: add ACP3.0 PCI driver
From: Maruthi Srinivas BayyavarapuACP 3.0 is a PCI audio device. This patch adds PCI driver to bind to this device and get PCI resources. Signed-off-by: Maruthi Bayyavarapu Signed-off-by: Alex Deucher --- sound/soc/amd/raven/acp3x.h | 13 ++ sound/soc/amd/raven/pci-acp3x.c | 97 + 2 files changed, 110 insertions(+) create mode 100644 sound/soc/amd/raven/acp3x.h create mode 100644 sound/soc/amd/raven/pci-acp3x.c diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h new file mode 100644 index 000..e9b4df0 --- /dev/null +++ b/sound/soc/amd/raven/acp3x.h @@ -0,0 +1,13 @@ +#include "chip_offset_byte.h" + +#define ACP3x_PHY_BASE_ADDRESS 0x124 + +static inline u32 rv_readl(void __iomem *base_addr) +{ + return readl(base_addr - ACP3x_PHY_BASE_ADDRESS); +} + +static inline void rv_writel(u32 val, void __iomem *base_addr) +{ + writel(val, base_addr - ACP3x_PHY_BASE_ADDRESS); +} diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c new file mode 100644 index 000..204212b --- /dev/null +++ b/sound/soc/amd/raven/pci-acp3x.c @@ -0,0 +1,97 @@ +/* + * AMD ALSA SoC PCM Driver + * + * Copyright 2016 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include + +#include "acp3x.h" + +struct acp3x_dev_data { + void __iomem *acp3x_base; +}; + +static int snd_acp3x_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + int ret; + u32 addr; + struct acp3x_dev_data *adata; + + if (pci_enable_device(pci)) { + dev_err(>dev, "pci_enable_device failed\n"); + return -ENODEV; + } + + ret = pci_request_regions(pci, "AMD ACP3x audio"); + if (ret < 0) { + dev_err(>dev, "pci_request_regions failed\n"); + goto disable_pci; + } + + adata = devm_kzalloc(>dev, sizeof(struct acp3x_dev_data), + GFP_KERNEL); + if (adata == NULL) { + ret = -ENOMEM; + goto release_regions; + } + + addr = pci_resource_start(pci, 0); + adata->acp3x_base = ioremap(addr, pci_resource_len(pci, 0)); + if (adata->acp3x_base == NULL) { + ret = -ENOMEM; + goto release_regions; + } + + pci_set_drvdata(pci, adata); + + return 0; + +release_regions: + pci_release_regions(pci); +disable_pci: + pci_disable_device(pci); + + return ret; +} + +static void snd_acp3x_remove(struct pci_dev *pci) +{ + struct acp3x_dev_data *adata = pci_get_drvdata(pci); + + iounmap(adata->acp3x_base); + pci_release_regions(pci); + pci_disable_device(pci); +} + +static const struct pci_device_id snd_acp3x_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x15e2), + .class = PCI_CLASS_MULTIMEDIA_OTHER << 8, + .class_mask = 0xff }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, snd_acp3x_ids); + +static struct pci_driver acp3x_driver = { + .name = KBUILD_MODNAME, + .id_table = snd_acp3x_ids, + .probe = snd_acp3x_probe, + .remove = snd_acp3x_remove, +}; + +module_pci_driver(acp3x_driver); + +MODULE_AUTHOR("maruthi.bayyavar...@amd.com"); +MODULE_DESCRIPTION("AMD ACP3x PCI driver"); +MODULE_LICENSE("GPL v2"); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: fix fundamental suspend/resume issue
From: Christian KönigReinitializing the VM manager during suspend/resume is a very very bad idea since all the VMs are still active and kicking. This can lead to random VM faults after resume when new processes become the same client ID assigned. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 22 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 1 + drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 15 ++- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 15 ++- drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 15 ++- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 16 ++-- 6 files changed, 30 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index ed97a2e..9803392 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -790,6 +790,7 @@ void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub, struct amdgpu_vm_id_manager *id_mgr = >vm_manager.id_mgr[vmhub]; struct amdgpu_vm_id *id = _mgr->ids[vmid]; + atomic64_set(>owner, 0); id->gds_base = 0; id->gds_size = 0; id->gws_base = 0; @@ -799,6 +800,26 @@ void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub, } /** + * amdgpu_vm_reset_all_id - reset VMID to zero + * + * @adev: amdgpu device structure + * + * Reset VMID to force flush on next use + */ +void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev) +{ + unsigned i, j; + + for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) { + struct amdgpu_vm_id_manager *id_mgr = + >vm_manager.id_mgr[i]; + + for (j = 1; j < id_mgr->num_ids; ++j) + amdgpu_vm_reset_id(adev, i, j); + } +} + +/** * amdgpu_vm_bo_find - find the bo_va for a specific vm & bo * * @vm: requested vm @@ -2393,7 +2414,6 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) for (i = 0; i < AMDGPU_MAX_RINGS; ++i) adev->vm_manager.seqno[i] = 0; - atomic_set(>vm_manager.vm_pte_next_ring, 0); atomic64_set(>vm_manager.client_counter, 0); spin_lock_init(>vm_manager.prt_lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index abc0bab..d62547d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -209,6 +209,7 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job); void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub, unsigned vmid); +void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev); int amdgpu_vm_update_directories(struct amdgpu_device *adev, struct amdgpu_vm *vm); int amdgpu_vm_clear_freed(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index a572979..d860939 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -950,10 +950,6 @@ static int gmc_v6_0_suspend(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->vm_manager.enabled) { - gmc_v6_0_vm_fini(adev); - adev->vm_manager.enabled = false; - } gmc_v6_0_hw_fini(adev); return 0; @@ -968,16 +964,9 @@ static int gmc_v6_0_resume(void *handle) if (r) return r; - if (!adev->vm_manager.enabled) { - r = gmc_v6_0_vm_init(adev); - if (r) { - dev_err(adev->dev, "vm manager initialization failed (%d).\n", r); - return r; - } - adev->vm_manager.enabled = true; - } + amdgpu_vm_reset_all_ids(adev); - return r; + return 0; } static bool gmc_v6_0_is_idle(void *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index a9083a1..2750e5c 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1117,10 +1117,6 @@ static int gmc_v7_0_suspend(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (adev->vm_manager.enabled) { - gmc_v7_0_vm_fini(adev); - adev->vm_manager.enabled = false; - } gmc_v7_0_hw_fini(adev); return 0; @@ -1135,16 +1131,9 @@ static int gmc_v7_0_resume(void *handle) if (r) return r; - if (!adev->vm_manager.enabled) { - r = gmc_v7_0_vm_init(adev); - if (r) { - dev_err(adev->dev, "vm manager initialization failed (%d).\n", r); - return
[PATCH libdrm 1/3] amdgpu: add raven family id
From: Hawking ZhangSigned-off-by: Hawking Zhang Signed-off-by: Chunming Zhou Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- include/drm/amdgpu_drm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h index 516a9f2..0de4cf6 100644 --- a/include/drm/amdgpu_drm.h +++ b/include/drm/amdgpu_drm.h @@ -816,6 +816,7 @@ struct drm_amdgpu_info_vce_clock_table { #define AMDGPU_FAMILY_VI 130 /* Iceland, Tonga */ #define AMDGPU_FAMILY_CZ 135 /* Carrizo, Stoney */ #define AMDGPU_FAMILY_AI 141 /* Vega10 */ +#define AMDGPU_FAMILY_RV 142 /* Raven */ #if defined(__cplusplus) } -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH libdrm 2/3] amdgpu/drm: add AMDGPU_HW_IP_VCN_DEC
From: Leo LiuSigned-off-by: Leo Liu Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- include/drm/amdgpu_drm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/drm/amdgpu_drm.h b/include/drm/amdgpu_drm.h index 0de4cf6..add5163 100644 --- a/include/drm/amdgpu_drm.h +++ b/include/drm/amdgpu_drm.h @@ -406,7 +406,8 @@ struct drm_amdgpu_gem_va { #define AMDGPU_HW_IP_UVD 3 #define AMDGPU_HW_IP_VCE 4 #define AMDGPU_HW_IP_UVD_ENC 5 -#define AMDGPU_HW_IP_NUM 6 +#define AMDGPU_HW_IP_VCN_DEC 6 +#define AMDGPU_HW_IP_NUM 7 #define AMDGPU_HW_IP_INSTANCE_MAX_COUNT 1 -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH xf86-video-amdgpu] Remove unused struct members from drmmode_display.h
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Michel Dänzer > Sent: Wednesday, May 10, 2017 5:14 AM > To: amd-gfx@lists.freedesktop.org > Subject: [PATCH xf86-video-amdgpu] Remove unused struct members from > drmmode_display.h > > From: Michel Dänzer> > Signed-off-by: Michel Dänzer Reviewed-by: Alex Deucher > --- > src/drmmode_display.c | 1 - > src/drmmode_display.h | 3 --- > 2 files changed, 4 deletions(-) > > diff --git a/src/drmmode_display.c b/src/drmmode_display.c > index 5b2431495..9996d2f70 100644 > --- a/src/drmmode_display.c > +++ b/src/drmmode_display.c > @@ -2370,7 +2370,6 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, > drmmode_ptr drmmode, int cpp) > xf86CrtcConfigInit(pScrn, _xf86crtc_config_funcs); > > drmmode->scrn = pScrn; > - drmmode->cpp = cpp; > mode_res = drmModeGetResources(pAMDGPUEnt->fd); > if (!mode_res) > return FALSE; > diff --git a/src/drmmode_display.h b/src/drmmode_display.h > index fa15a4f72..2d5698f61 100644 > --- a/src/drmmode_display.h > +++ b/src/drmmode_display.h > @@ -38,8 +38,6 @@ > > typedef struct { > unsigned fb_id; > - drmModeFBPtr mode_fb; > - int cpp; > ScrnInfoPtr scrn; > #ifdef HAVE_LIBUDEV > struct udev_monitor *uevent_monitor; > @@ -55,7 +53,6 @@ typedef struct { > } drmmode_rec, *drmmode_ptr; > > typedef struct { > - int fd; > unsigned old_fb_id; > int flip_count; > void *event_data; > -- > 2.11.0 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH xf86-video-ati] Apply gamma correction to HW cursor
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Michel Dänzer > Sent: Wednesday, May 10, 2017 4:25 AM > To: amd-gfx@lists.freedesktop.org > Subject: [PATCH xf86-video-ati] Apply gamma correction to HW cursor > > From: Michel Dänzer> > The display hardware CLUT we're currently using for gamma correction > doesn't affect the HW cursor, so we have to apply it manually when > uploading the HW cursor data. > > This currently only works in depth 24/32. > > (Ported from amdgpu commit 82fa615f38137add75f9cd4bb49c48dd88de916f) > > Signed-off-by: Michel Dänzer Reviewed-by: Alex Deucher > --- > src/drmmode_display.c | 66 > --- > 1 file changed, 58 insertions(+), 8 deletions(-) > > diff --git a/src/drmmode_display.c b/src/drmmode_display.c > index 84e7ef967..0b823754b 100644 > --- a/src/drmmode_display.c > +++ b/src/drmmode_display.c > @@ -812,6 +812,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, > DisplayModePtr mode, > } > } > > +static void > +drmmode_crtc_gamma_do_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t > *green, > + uint16_t *blue, int size) > +{ > + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; > + > + drmModeCrtcSetGamma(drmmode_crtc->drmmode->fd, > + drmmode_crtc->mode_crtc->crtc_id, size, red, > green, > + blue); > +} > + > static Bool > drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, >Rotation rotation, int x, int y) > @@ -873,8 +884,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, > DisplayModePtr mode, > if (drmmode_crtc->tear_free) > scanout_id = drmmode_crtc->scanout_id; > > - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc- > >gamma_green, > -crtc->gamma_blue, crtc->gamma_size); > + drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc- > >gamma_green, > + crtc->gamma_blue, crtc- > >gamma_size); > > drmmode_ConvertToKMode(crtc->scrn, , mode); > > @@ -1043,6 +1054,31 @@ drmmode_cursor_src_offset(Rotation rotation, > int width, int height, > > #endif > > +static uint32_t > +drmmode_cursor_gamma(xf86CrtcPtr crtc, uint32_t argb) > +{ > + uint32_t alpha = argb >> 24; > + uint32_t rgb[3]; > + int i; > + > + if (!alpha) > + return 0; > + > + if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32) > + return argb; > + > + /* Un-premultiply alpha */ > + for (i = 0; i < 3; i++) > + rgb[i] = ((argb >> (i * 8)) & 0xff) * 0xff / alpha; > + > + /* Apply gamma correction and pre-multiply alpha */ > + rgb[0] = (crtc->gamma_blue[rgb[0]] >> 8) * alpha / 0xff; > + rgb[1] = (crtc->gamma_green[rgb[1]] >> 8) * alpha / 0xff; > + rgb[2] = (crtc->gamma_red[rgb[2]] >> 8) * alpha / 0xff; > + > + return alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0]; > +} > + > static void > drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) > { > @@ -1068,7 +1104,8 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, > CARD32 *image) > dstx, > dsty); > > ptr[dsty * info->cursor_w + dstx] = > - cpu_to_le32(image[srcoffset]); > + > cpu_to_le32(drmmode_cursor_gamma(crtc, > + > image[srcoffset])); > } > } > } else > @@ -1078,7 +1115,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, > CARD32 *image) > int i; > > for (i = 0; i < cursor_size; i++) > - ptr[i] = cpu_to_le32(image[i]); > + ptr[i] = cpu_to_le32(drmmode_cursor_gamma(crtc, > image[i])); > } > } > > @@ -1209,11 +1246,24 @@ static void > drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t > *green, >uint16_t *blue, int size) > { > - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; > - drmmode_ptr drmmode = drmmode_crtc->drmmode; > + ScrnInfoPtr scrn = crtc->scrn; > + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); > + RADEONInfoPtr info = RADEONPTR(scrn); > + int i; > > - drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc- > >mode_crtc->crtc_id, > - size, red, green, blue); > + drmmode_crtc_gamma_do_set(crtc, red, green, blue, size); > + > + /* Compute index of this CRTC into xf86_config->crtc */ > + for (i = 0; xf86_config->crtc[i] != crtc; i++) {} > + > + if (info->hwcursor_disabled & (1 << i)) > + return; > + > +#ifdef HAVE_XF86_CURSOR_RESET_CURSOR > + xf86CursorResetCursor(scrn->pScreen); > +#else > +
[PATCH umr] add new vega10 DIDs
--- src/lib/discover_by_did.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/discover_by_did.c b/src/lib/discover_by_did.c index 2e06d5092847..7ecd7f353c92 100644 --- a/src/lib/discover_by_did.c +++ b/src/lib/discover_by_did.c @@ -221,7 +221,9 @@ static const struct { { 0x6860, _create_vega10 }, { 0x6861, _create_vega10 }, { 0x6863, _create_vega10 }, + { 0x6864, _create_vega10 }, { 0x6867, _create_vega10 }, + { 0x6868, _create_vega10 }, { 0x686c, _create_vega10 }, { 0x687f, _create_vega10 }, }; -- 2.12.0 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/2] drm/radeon: move vga_switcheroo registration
Move the registration later to avoid a possible race between driver initialization and a vga_switcheroo request. bug: https://bugzilla.redhat.com/show_bug.cgi?id=1411034 Signed-off-by: Alex Deucher--- drivers/gpu/drm/radeon/radeon.h| 2 ++ drivers/gpu/drm/radeon/radeon_device.c | 38 ++ drivers/gpu/drm/radeon/radeon_kms.c| 5 - 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 7e9d3b9..8cd4799 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2477,6 +2477,8 @@ struct radeon_device { }; bool radeon_is_px(struct drm_device *dev); +void radeon_device_switcheroo_init(struct radeon_device *rdev); +void radeon_device_switcheroo_fini(struct radeon_device *rdev); int radeon_device_init(struct radeon_device *rdev, struct drm_device *ddev, struct pci_dev *pdev, diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 34e138b..0c3de4f 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1298,6 +1298,26 @@ static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { .can_switch = radeon_switcheroo_can_switch, }; +void radeon_device_switcheroo_init(struct radeon_device *rdev) +{ + bool runtime = false; + + if (rdev->flags & RADEON_IS_PX) { + radeon_device_handle_px_quirks(rdev); + runtime = true; + } + vga_switcheroo_register_client(rdev->pdev, _switcheroo_ops, runtime); + if (runtime) + vga_switcheroo_init_domain_pm_ops(rdev->dev, >vga_pm_domain); +} + +void radeon_device_switcheroo_fini(struct radeon_device *rdev) +{ + vga_switcheroo_unregister_client(rdev->pdev); + if (rdev->flags & RADEON_IS_PX) + vga_switcheroo_fini_domain_pm_ops(rdev->dev); +} + /** * radeon_device_init - initialize the driver * @@ -1317,7 +1337,6 @@ int radeon_device_init(struct radeon_device *rdev, { int r, i; int dma_bits; - bool runtime = false; rdev->shutdown = false; rdev->dev = >dev; @@ -1458,20 +1477,11 @@ int radeon_device_init(struct radeon_device *rdev, if (rdev->rio_mem == NULL) DRM_ERROR("Unable to find PCI I/O BAR\n"); - if (rdev->flags & RADEON_IS_PX) - radeon_device_handle_px_quirks(rdev); - /* if we have > 1 VGA cards, then disable the radeon VGA resources */ /* this will fail for cards that aren't VGA class devices, just * ignore it */ vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); - if (rdev->flags & RADEON_IS_PX) - runtime = true; - vga_switcheroo_register_client(rdev->pdev, _switcheroo_ops, runtime); - if (runtime) - vga_switcheroo_init_domain_pm_ops(rdev->dev, >vga_pm_domain); - r = radeon_init(rdev); if (r) goto failed; @@ -1538,11 +1548,6 @@ int radeon_device_init(struct radeon_device *rdev, return 0; failed: - /* balance pm_runtime_get_sync() in radeon_driver_unload_kms() */ - if (radeon_is_px(ddev)) - pm_runtime_put_noidle(ddev->dev); - if (runtime) - vga_switcheroo_fini_domain_pm_ops(rdev->dev); return r; } @@ -1563,9 +1568,6 @@ void radeon_device_fini(struct radeon_device *rdev) /* evict vram memory */ radeon_bo_evict_vram(rdev); radeon_fini(rdev); - vga_switcheroo_unregister_client(rdev->pdev); - if (rdev->flags & RADEON_IS_PX) - vga_switcheroo_fini_domain_pm_ops(rdev->dev); vga_client_register(rdev->pdev, NULL, NULL, NULL); if (rdev->rio_mem) pci_iounmap(rdev->pdev, rdev->rio_mem); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 4388dde..140a060 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -71,9 +71,10 @@ int radeon_driver_unload_kms(struct drm_device *dev) radeon_kfd_device_fini(rdev); radeon_acpi_fini(rdev); - + radeon_modeset_fini(rdev); radeon_device_fini(rdev); + radeon_device_switcheroo_fini(rdev); done_free: kfree(rdev); @@ -149,6 +150,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) "Error during ACPI methods call\n"); } + radeon_device_switcheroo_init(rdev); + radeon_kfd_device_probe(rdev); radeon_kfd_device_init(rdev); -- 2.5.5 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2)
>Because stopping all the scheduler threads takes a moment and it is entirely >possible that the job finishes within that time. Sounds reasonable, but instead not, because if so why not increase timed_out value to + 0.5 sec ? that should cover the time on stop all schedulers, So the point is we should rely on and trust timedout parm since it is the only way to let kernel side aware GPU may hang … If there is a way to detect GPU hang (actually we have such method, implemented in RLCV side) in kernel driver side, that will convince me To check the fence at least one time, like: Void Gpu_reset() { Hang = Check_gpu_hang_or_busy(); If (!hang) { //looks like the job is still running, we can let it run … Return; } else { Signaled = fence_signaled(job); If (signaled) Return; //do nothing } … } I can say that we may still have chance to implement this hang_detection in kernel driver side, but it is not easy so currently I only trust timedout event BR Monk From: Christian König [mailto:deathsim...@vodafone.de] Sent: Wednesday, May 10, 2017 7:14 PM To: Liu, Monk; Koenig, Christian ; amd-gfx@lists.freedesktop.org Subject: Re: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2) You still avoid my question: what’s the theoretical backend you that you think check once instead of twice or even more is good*before* hw_job_reset() ? Because stopping all the scheduler threads takes a moment and it is entirely possible that the job finishes within that time. 1) if you check the fence and found it not signaled, then you will call hw_job_reset(), but there is still chance that between your check and the hw_job_reset() the Sched fence could signaled , isn’t it ? you still cannot avoid such race condition Crap, you're right. We would indeed need to check twice and that wouldn't be consistent anyway. Once after stopping the schedulers and before hw_job_reset() because then we can just start the schedulers again and continue as if nothing has happened. And another time after calling hw_job_reset() if we want to set the error code. Don’t forget your approach still have chance to hit the race condition, and to me I don’t think the race condition matters that’s why I don’t even consider it Yeah, you convinced me. Please go ahead with the current approach, but at least add a comment that we might want to improve that. Regards, Christian. Am 10.05.2017 um 13:02 schrieb Liu, Monk: > Checking a second time is pointless since it can't signal any more after > calling amd_sched_hw_job_reset(). [ML] you seems not response to me … I of cause know fence cannot signal after hw_job_reset() …. My question is , before you call hw_job_reset(), why you want to check the fence ? why not check twice ? You still avoid my question: what’s the theoretical backend you that you think check once instead of twice or even more is good*before* hw_job_reset() ? >No, the timeout is pretty meaningless. It's just the trigger that we need to >do something. 2) And even it signaled after entering gpu_reset(), it will automatically done like normal cases, that’s good. Why remove those callback instead ? > No, that's absolutely not good. We don't know if it's the hardware which > results in the job being signaled or our reset code. [ML] you are wrong, for SR-IOV case, the timeout is all that matters, because one VF can only have such time slice within timeout, and I’m doing the TDR on SR-IOV so don’t Always looks things with bare-metal mind >Otherwise we have a race condition here where we can't determine if the reset >finished the job or if it did just on it's own while we stopped the scheduler. [ML] you are wrong : 1) if you check the fence and found it not signaled, then you will call hw_job_reset(), but there is still chance that between your check and the hw_job_reset() the Sched fence could signaled , isn’t it ? you still cannot avoid such race condition 2) I don’t care if the fence is signaled due to its own finish or because we force the hw fence signaled, for SR-IOV case, as long as the job exceeds timeout, we consider It hang. 3) Even for bare-metal case, you still cannot sure if the fence is signaled due to its own or hw_fence force signal, reason is in #1) >No, you are insist on a vague rules not strict, like I said, what is the >theoretic to backend your approach that only check once on the in question job >? why not check again if not signaled ? >Because we have removed the connection between the job and the hardware fence >and because of this the job can never signal. [ML] like I said, before you call hw_job_reset(), you only check on the job once, why not check again and again ? I don’t see you have a reason to only check once, and If you don’t have such reason I think you should not check at all. If you have such reason, prove me that only check once is good and enough. Don’t forget your approach still have chance to hit the race
Re: [PATCH 01/11] drm/ttm: cleanup coding style in ttm_bo_api.h
Ping, could anybody take a look at this set? Thanks, Christian. Am 27.04.2017 um 18:23 schrieb Christian König: From: Christian KönigExtern is the default for function declerations anyway and this solves a bunch of 80char per line issues. Signed-off-by: Christian König --- include/drm/ttm/ttm_bo_api.h | 135 ++- 1 file changed, 56 insertions(+), 79 deletions(-) diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 3b302a5..425f3b4 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -288,8 +288,7 @@ ttm_bo_reference(struct ttm_buffer_object *bo) * Returns -EBUSY if no_wait is true and the buffer is busy. * Returns -ERESTARTSYS if interrupted by a signal. */ -extern int ttm_bo_wait(struct ttm_buffer_object *bo, - bool interruptible, bool no_wait); +int ttm_bo_wait(struct ttm_buffer_object *bo, bool interruptible, bool no_wait); /** * ttm_bo_mem_compat - Check if proposed placement is compatible with a bo @@ -300,9 +299,8 @@ extern int ttm_bo_wait(struct ttm_buffer_object *bo, * * Returns true if the placement is compatible */ -extern bool ttm_bo_mem_compat(struct ttm_placement *placement, - struct ttm_mem_reg *mem, - uint32_t *new_flags); +bool ttm_bo_mem_compat(struct ttm_placement *placement, struct ttm_mem_reg *mem, + uint32_t *new_flags); /** * ttm_bo_validate @@ -320,10 +318,10 @@ extern bool ttm_bo_mem_compat(struct ttm_placement *placement, * -EBUSY if no_wait is true and buffer busy. * -ERESTARTSYS if interrupted by a signal. */ -extern int ttm_bo_validate(struct ttm_buffer_object *bo, - struct ttm_placement *placement, - bool interruptible, - bool no_wait_gpu); +int ttm_bo_validate(struct ttm_buffer_object *bo, + struct ttm_placement *placement, + bool interruptible, + bool no_wait_gpu); /** * ttm_bo_unref @@ -332,7 +330,7 @@ extern int ttm_bo_validate(struct ttm_buffer_object *bo, * * Unreference and clear a pointer to a buffer object. */ -extern void ttm_bo_unref(struct ttm_buffer_object **bo); +void ttm_bo_unref(struct ttm_buffer_object **bo); /** @@ -344,8 +342,8 @@ extern void ttm_bo_unref(struct ttm_buffer_object **bo); * * Release @count lru list references to this buffer object. */ -extern void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, - bool never_free); +void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, +bool never_free); /** * ttm_bo_add_to_lru @@ -357,7 +355,7 @@ extern void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, * This function must be called with struct ttm_bo_global::lru_lock held, and * is typically called immediately prior to unreserving a bo. */ -extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo); +void ttm_bo_add_to_lru(struct ttm_buffer_object *bo); /** * ttm_bo_del_from_lru @@ -369,7 +367,7 @@ extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo); * and is usually called just immediately after the bo has been reserved to * avoid recursive reservation from lru lists. */ -extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo); +int ttm_bo_del_from_lru(struct ttm_buffer_object *bo); /** * ttm_bo_move_to_lru_tail @@ -380,7 +378,7 @@ extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo); * object. This function must be called with struct ttm_bo_global::lru_lock * held, and is used to make a BO less likely to be considered for eviction. */ -extern void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo); +void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo); /** * ttm_bo_lock_delayed_workqueue @@ -389,15 +387,14 @@ extern void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo); * Returns * True if the workqueue was queued at the time */ -extern int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev); +int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev); /** * ttm_bo_unlock_delayed_workqueue * * Allows the delayed workqueue to run. */ -extern void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, - int resched); +void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev, int resched); /** * ttm_bo_eviction_valuable @@ -424,8 +421,7 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, * -EBUSY if the buffer is busy and no_wait is true. * -ERESTARTSYS if interrupted by a signal. */ -extern int -ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait); +int
Re: [PATCH 0/3] GPU-DRM-Radeon: Fine-tuning for three function implementations
Am 10.05.2017 um 02:23 schrieb Michel Dänzer: On 03/05/17 09:46 PM, Christian König wrote: Am 02.05.2017 um 22:04 schrieb SF Markus Elfring: From: Markus ElfringDate: Tue, 2 May 2017 22:00:02 +0200 Three update suggestions were taken into account from static source code analysis. Markus Elfring (3): Use seq_putc() in radeon_sa_bo_dump_debug_info() Use seq_puts() in radeon_debugfs_pm_info() Use seq_puts() in r100_debugfs_cp_csq_fifo() Reviewed-by: Christian König Based on https://lists.freedesktop.org/archives/dri-devel/2017-May/140837.html and followups, I'm afraid we'll have to make sure Markus' patches have been tested adequately before applying them. I can't judge the background of that decision, but at least those tree patches for radeon looked trivial to me. I don't see much what could go wrong when merging them. On the other hand you are right that trying to find hardware to test that stuff could be challenging. Christian. ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2)
> Checking a second time is pointless since it can't signal any more after > calling amd_sched_hw_job_reset(). [ML] you seems not response to me … I of cause know fence cannot signal after hw_job_reset() …. My question is , before you call hw_job_reset(), why you want to check the fence ? why not check twice ? You still avoid my question: what’s the theoretical backend you that you think check once instead of twice or even more is good*before* hw_job_reset() ? >No, the timeout is pretty meaningless. It's just the trigger that we need to >do something. 2) And even it signaled after entering gpu_reset(), it will automatically done like normal cases, that’s good. Why remove those callback instead ? > No, that's absolutely not good. We don't know if it's the hardware which > results in the job being signaled or our reset code. [ML] you are wrong, for SR-IOV case, the timeout is all that matters, because one VF can only have such time slice within timeout, and I’m doing the TDR on SR-IOV so don’t Always looks things with bare-metal mind >Otherwise we have a race condition here where we can't determine if the reset >finished the job or if it did just on it's own while we stopped the scheduler. [ML] you are wrong : 1) if you check the fence and found it not signaled, then you will call hw_job_reset(), but there is still chance that between your check and the hw_job_reset() the Sched fence could signaled , isn’t it ? you still cannot avoid such race condition 2) I don’t care if the fence is signaled due to its own finish or because we force the hw fence signaled, for SR-IOV case, as long as the job exceeds timeout, we consider It hang. 3) Even for bare-metal case, you still cannot sure if the fence is signaled due to its own or hw_fence force signal, reason is in #1) >No, you are insist on a vague rules not strict, like I said, what is the >theoretic to backend your approach that only check once on the in question job >? why not check again if not signaled ? >Because we have removed the connection between the job and the hardware fence >and because of this the job can never signal. [ML] like I said, before you call hw_job_reset(), you only check on the job once, why not check again and again ? I don’t see you have a reason to only check once, and If you don’t have such reason I think you should not check at all. If you have such reason, prove me that only check once is good and enough. Don’t forget your approach still have chance to hit the race condition, and to me I don’t think the race condition matters that’s why I don’t even consider it BR Monk From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf Of Christian König Sent: Wednesday, May 10, 2017 6:26 PM To: Liu, Monk; Koenig, Christian ; amd-gfx@lists.freedesktop.org Subject: Re: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2) Am 10.05.2017 um 12:05 schrieb Liu, Monk: [ML] yes, but we cannot guarantee the job is 100% really hang when entering gpu_reset(), we can only trust our amdgpu_job_timeout as a deadline for each job. You approach that check the fence first before charge it as guilty/hang is incorrect looks to me because why you not check it twice, triple, and even more loops ? Because the job can't signal any more after calling amd_sched_hw_job_reset(). [ML] No … that’s where I think your approach is vague: 1) see that you check after scheduler stopped, see if job signaled, my question is if the job is not signaled (like most usual case) Why you not check it again and again ? maybe the second time you will find it signaled … Checking a second time is pointless since it can't signal any more after calling amd_sched_hw_job_reset(). My point is the checking here is meaningless, we already have timedout for the guard. No, the timeout is pretty meaningless. It's just the trigger that we need to do something. But to determine what to do we first need to stop the scheduler, remove the hardware fence and THEN check the current status. Otherwise we have a race condition here where we can't determine if the reset finished the job or if it did just on it's own while we stopped the scheduler. 2) And even it signaled after entering gpu_reset(), it will automatically done like normal cases, that’s good. Why remove those callback instead ? No, that's absolutely not good. We don't know if it's the hardware which results in the job being signaled or our reset code. So I refuse to check if @job is just signaled in gpu_reset, because this action is vague (and no one can guarantee the job won’t signal during gpu_reset, we should not argue on this event …), I prefer clean and restrict rules. Yeah, completely agree that we need to have struct rules for that. That's why I insists on doing this :) No, you are insist on a vague rules not strict, like I said, what is the theoretic to backend your approach that only check once on the in
Re: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2)
Am 10.05.2017 um 12:05 schrieb Liu, Monk: [ML] yes, but we cannot guarantee the job is 100% really hang when entering gpu_reset(), we can only trust our amdgpu_job_timeout as a deadline for each job. You approach that check the fence first before charge it as guilty/hang is incorrect looks to me because why you not check it twice, triple, and even more loops ? Because the job can't signal any more after calling amd_sched_hw_job_reset(). [ML] No … that’s where I think your approach is vague: 1) see that you check after scheduler stopped, see if job signaled, my question is if the job is not signaled (like most usual case) Why you not check it again and again ? maybe the second time you will find it signaled … Checking a second time is pointless since it can't signal any more after calling amd_sched_hw_job_reset(). My point is the checking here is meaningless, we already have timedout for the guard. No, the timeout is pretty meaningless. It's just the trigger that we need to do something. But to determine what to do we first need to stop the scheduler, remove the hardware fence and THEN check the current status. Otherwise we have a race condition here where we can't determine if the reset finished the job or if it did just on it's own while we stopped the scheduler. 2) And even it signaled after entering gpu_reset(), it will automatically done like normal cases, that’s good. Why remove those callback instead ? No, that's absolutely not good. We don't know if it's the hardware which results in the job being signaled or our reset code. So I refuse to check if @job is just signaled in gpu_reset, because this action is vague (and no one can guarantee the job won’t signal during gpu_reset, we should not argue on this event …), I prefer clean and restrict rules. Yeah, completely agree that we need to have struct rules for that. That's why I insists on doing this :) No, you are insist on a vague rules not strict, like I said, what is the theoretic to backend your approach that only check once on the in question job ? why not check again if not signaled ? Because we have removed the connection between the job and the hardware fence and because of this the job can never signal. Regards, Christian. I don’t agree this approach is clean and strict. You are abuse timedout parameter. See I just want to avoid problems for the case that the job signaled while we stop the scheduler (because stopping the scheduler actually can take a moment). Because when this happened the scheduler could already have pushed the next job to the hardware and then we abort it with the GPU reset and might create more problems than we solve. [ML] I don’t see my approach will have chance to fence twice… on the contrast I think my approach is more clear: no matter the in question job finally signaled or not, I just kick it out from mirror-list Without remove the callback from hw fence, that way even it really signaled during the gpu_reset() period the logic is still perfect and its sched fence will act like usual … We want to set an error code on the job before signaling it don't we? So we need to be sure how and when the job is signaled as finished. I mean letting it signal when we force the hardware fence to complete will work as well, but I still think that this isn't as clean as signaling it manually. Please also see the helper function the Intel guys introduced drm_fence_set_error(), we will run into a BUG_ON if we can't guarantee the order of execution here. Regards, Christian. Am 10.05.2017 um 06:00 schrieb Liu, Monk: Christian, Looks like we need more discuss with it… Here is your approach: 1. Stop the scheduler from feeding more jobs to the hardware when a jobs completes. //this is where I agree with you 2. Then call hw_job_reset to remove the connection between job and hardware fence. 3. Test if job is now completed. It is entirely possible that the job completed while we started the work to reset the hardware. Removing the connection between the hardware fence and the job is the deadline, if the job completes after that it is lost. 4. Check the karma and kick out the job if we found it guilty. 5. Get the whole stuff working again, e.g. reset the hardware, restart the scheduler etc... */[ML]: One thing I agree to change with your way: in gpu_reset() we should first stop the in question ring’s scheduler (not the all) before kick out the guilty job./* > Indeed, but I still think that this is a bad approach cause we then reset the hardware without a good reason. [ML] yes, but we cannot guarantee the job is 100% really hang when entering gpu_reset(), we can only trust our amdgpu_job_timeout as a deadline for each job. You approach that check the fence first before charge it as guilty/hang is incorrect
FW: [PATCH] drm/amdgpu: reduce amdgpu_device_resume() time
From: Shirish Samdgpu_device_resume() has a high time consuming call of amdgpu_late_init() which sets the clock_gating state of all IP blocks and is blocking. This patch defers only this setting of clock gating state operation to post resume of amdgpu driver but ideally before the UI comes up or in some cases post ui as well. With this change the resume time of amdgpu_device comes down from 1.299s to 0.199s which further helps in reducing the overall system resume time. TEST:(For ChromiumOS on STONEY only) * UI comes up * S3 works multiple times * Resume time is consistent and lower * amdgpu_late_init() call gets called consistently and no errors reported. Signed-off-by: Shirish S Reviewed-by: Huang Rui --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 3 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 57 +++--- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 1be8aed..addb204 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1615,6 +1615,9 @@ struct amdgpu_device { /* amdkfd interface */ struct kfd_dev *kfd; + /* delayed work_func for deferring clockgating during resume */ + struct delayed_work late_init_work; + struct amdgpu_virt virt; /* link all shadow bo */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index cfc650c..a6850cf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -57,6 +57,8 @@ MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); +#define AMDGPU_RESUME_MS 2000 + static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev); static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev); @@ -1655,22 +1657,11 @@ static int amdgpu_init(struct amdgpu_device *adev) return 0; } -static int amdgpu_late_init(struct amdgpu_device *adev) +static int amdgpu_late_set_cg_state(struct amdgpu_device *adev) { int i = 0, r; for (i = 0; i < adev->num_ip_blocks; i++) { - if (!adev->ip_blocks[i].status.valid) - continue; - if (adev->ip_blocks[i].version->funcs->late_init) { - r = adev->ip_blocks[i].version->funcs->late_init((void *)adev); - if (r) { - DRM_ERROR("late_init of IP block <%s> failed %d\n", - adev->ip_blocks[i].version->funcs->name, r); - return r; - } - adev->ip_blocks[i].status.late_initialized = true; - } /* skip CG for VCE/UVD, it's handled specially */ if (adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_UVD && adev->ip_blocks[i].version->type != AMD_IP_BLOCK_TYPE_VCE) { @@ -1688,6 +1679,27 @@ static int amdgpu_late_init(struct amdgpu_device *adev) return 0; } +static int amdgpu_late_init(struct amdgpu_device *adev) +{ + int i = 0, r; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.valid) + continue; + if (adev->ip_blocks[i].version->funcs->late_init) { + r = adev->ip_blocks[i].version->funcs->late_init((void *)adev); + if (r) { + DRM_ERROR("late_init of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + return r; + } + adev->ip_blocks[i].status.late_initialized = true; + } + } + + return 0; +} + static int amdgpu_fini(struct amdgpu_device *adev) { int i, r; @@ -1775,6 +1787,13 @@ static int amdgpu_fini(struct amdgpu_device *adev) return 0; } +static void amdgpu_late_init_func_handler(struct work_struct *work) +{ + struct amdgpu_device *adev = + container_of(work, struct amdgpu_device, late_init_work.work); + amdgpu_late_set_cg_state(adev); +} + int amdgpu_suspend(struct amdgpu_device *adev) { int i, r; @@ -2074,6 +2093,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, INIT_LIST_HEAD(>gtt_list); spin_lock_init(>gtt_list_lock); + INIT_DELAYED_WORK(>late_init_work, amdgpu_late_init_func_handler); + if (adev->asic_type >= CHIP_BONAIRE) { adev->rmmio_base = pci_resource_start(adev->pdev, 5); adev->rmmio_size = pci_resource_len(adev->pdev, 5); @@ -2239,6 +2260,12 @@ int amdgpu_device_init(struct amdgpu_device *adev, goto failed; } + r
RE: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2)
I mean letting it signal when we force the hardware fence to complete will work as well, but I still think that this isn't as clean as signaling it manually. Please also see the helper function the Intel guys introduced drm_fence_set_error(), we will run into a BUG_ON if we can't guarantee the order of execution here. [ML] this patch still not follow the intel way currently, so I don’t think this matters, and after we go intel way I will of cause this BUG_ON if it really introduced by that time I want clarify that checking the signaling on the in question job is absolutely vague, before hw_reset() on it you can check million times and you don’t have reason to say check one time is okay but two or more Is not needed, give me the reason for that please, otherwise how you can persuade me to do this way … BR Monk From: Christian König [mailto:deathsim...@vodafone.de] Sent: Wednesday, May 10, 2017 3:52 PM To: Liu, Monk; Koenig, Christian ; amd-gfx@lists.freedesktop.org Subject: Re: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2) [ML]: One thing I agree to change with your way: in gpu_reset() we should first stop the in question ring’s scheduler (not the all) before kick out the guilty job. Ok, that sounds good. [ML] yes, but we cannot guarantee the job is 100% really hang when entering gpu_reset(), we can only trust our amdgpu_job_timeout as a deadline for each job. You approach that check the fence first before charge it as guilty/hang is incorrect looks to me because why you not check it twice, triple, and even more loops ? Because the job can't signal any more after calling amd_sched_hw_job_reset(). So I refuse to check if @job is just signaled in gpu_reset, because this action is vague (and no one can guarantee the job won’t signal during gpu_reset, we should not argue on this event …), I prefer clean and restrict rules. Yeah, completely agree that we need to have struct rules for that. That's why I insists on doing this :) See I just want to avoid problems for the case that the job signaled while we stop the scheduler (because stopping the scheduler actually can take a moment). Because when this happened the scheduler could already have pushed the next job to the hardware and then we abort it with the GPU reset and might create more problems than we solve. [ML] I don’t see my approach will have chance to fence twice… on the contrast I think my approach is more clear: no matter the in question job finally signaled or not, I just kick it out from mirror-list Without remove the callback from hw fence, that way even it really signaled during the gpu_reset() period the logic is still perfect and its sched fence will act like usual … We want to set an error code on the job before signaling it don't we? So we need to be sure how and when the job is signaled as finished. I mean letting it signal when we force the hardware fence to complete will work as well, but I still think that this isn't as clean as signaling it manually. Please also see the helper function the Intel guys introduced drm_fence_set_error(), we will run into a BUG_ON if we can't guarantee the order of execution here. Regards, Christian. Am 10.05.2017 um 06:00 schrieb Liu, Monk: Christian, Looks like we need more discuss with it… Here is your approach: 1. Stop the scheduler from feeding more jobs to the hardware when a jobs completes. //this is where I agree with you 2. Then call hw_job_reset to remove the connection between job and hardware fence. 3. Test if job is now completed. It is entirely possible that the job completed while we started the work to reset the hardware. Removing the connection between the hardware fence and the job is the deadline, if the job completes after that it is lost. 4. Check the karma and kick out the job if we found it guilty. 5. Get the whole stuff working again, e.g. reset the hardware, restart the scheduler etc... [ML]: One thing I agree to change with your way: in gpu_reset() we should first stop the in question ring’s scheduler (not the all) before kick out the guilty job. > Indeed, but I still think that this is a bad approach cause we then reset the > hardware without a good reason. [ML] yes, but we cannot guarantee the job is 100% really hang when entering gpu_reset(), we can only trust our amdgpu_job_timeout as a deadline for each job. You approach that check the fence first before charge it as guilty/hang is incorrect looks to me because why you not check it twice, triple, and even more loops ? You check it one time and you found it just signaled that’s great and lucky(really lucky…), But what if it didn’t signaled (like most usual case) , why not check it again and again ? do you have a theoretic to support on how much time you need to check before finally consider it hang ? No I don’t think you have so please just cut this unnecessary checking, we already use
Re: [PATCH 1/3] drm/amdgpu: add sched sync for amdgpu job v2
Am 10.05.2017 um 11:42 schrieb Chunming Zhou: this is an improvement for previous patch, the sched_sync is to store fence that could be skipped as scheduled, when job is executed, we didn't need pipeline_sync if all fences in sched_sync are signalled, otherwise insert pipeline_sync still. v2: handle error when adding fence to sync failed. Change-Id: I26d3a2794272ba94b25753d4bf367326d12f6939 Signed-off-by: Chunming ZhouReviewed-by: Christian König for the whole series. --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 13 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 787acd7..ef018bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1162,6 +1162,7 @@ struct amdgpu_job { struct amdgpu_vm*vm; struct amdgpu_ring *ring; struct amdgpu_sync sync; + struct amdgpu_sync sched_sync; struct amdgpu_ib*ibs; struct fence*fence; /* the hw fence */ uint32_tpreamble_status; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 2c6624d..86ad507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -121,6 +121,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, { struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = [0]; + struct fence *tmp; bool skip_preamble, need_ctx_switch; unsigned patch_offset = ~0; struct amdgpu_vm *vm; @@ -167,8 +168,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, return r; } - if (ring->funcs->emit_pipeline_sync && job && job->need_pipeline_sync) + if (ring->funcs->emit_pipeline_sync && job && + (tmp = amdgpu_sync_get_fence(>sched_sync))) { + job->need_pipeline_sync = true; amdgpu_ring_emit_pipeline_sync(ring); + fence_put(tmp); + } if (vm) { amdgpu_ring_insert_nop(ring, extra_nop); /* prevent CE go too fast than DE */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index cfa97ab..ee7c9de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -60,6 +60,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->need_pipeline_sync = false; amdgpu_sync_create(&(*job)->sync); + amdgpu_sync_create(&(*job)->sched_sync); return 0; } @@ -98,6 +99,7 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job) fence_put(job->fence); amdgpu_sync_free(>sync); + amdgpu_sync_free(>sched_sync); kfree(job); } @@ -107,6 +109,7 @@ void amdgpu_job_free(struct amdgpu_job *job) fence_put(job->fence); amdgpu_sync_free(>sync); + amdgpu_sync_free(>sched_sync); kfree(job); } @@ -139,10 +142,10 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) struct amdgpu_vm *vm = job->vm; struct fence *fence = amdgpu_sync_get_fence(>sync); + int r; while (fence == NULL && vm && !job->vm_id) { struct amdgpu_ring *ring = job->ring; - int r; r = amdgpu_vm_grab_id(vm, ring, >sync, >base.s_fence->finished, @@ -153,9 +156,11 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) fence = amdgpu_sync_get_fence(>sync); } - if (amd_sched_dependency_optimized(fence, sched_job->s_entity)) - job->need_pipeline_sync = true; - + if (amd_sched_dependency_optimized(fence, sched_job->s_entity)) { + r = amdgpu_sync_fence(job->adev, >sched_sync, fence); + if (r) + DRM_ERROR("Error adding fence to sync (%d)\n", r); + } return fence; } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 4/4] drm/amdgpu/SRIOV:implement guilty job TDR (V2)
[ML] yes, but we cannot guarantee the job is 100% really hang when entering gpu_reset(), we can only trust our amdgpu_job_timeout as a deadline for each job. You approach that check the fence first before charge it as guilty/hang is incorrect looks to me because why you not check it twice, triple, and even more loops ? Because the job can't signal any more after calling amd_sched_hw_job_reset(). [ML] No … that’s where I think your approach is vague: 1) see that you check after scheduler stopped, see if job signaled, my question is if the job is not signaled (like most usual case) Why you not check it again and again ? maybe the second time you will find it signaled … My point is the checking here is meaningless, we already have timedout for the guard. 2) And even it signaled after entering gpu_reset(), it will automatically done like normal cases, that’s good. Why remove those callback instead ? So I refuse to check if @job is just signaled in gpu_reset, because this action is vague (and no one can guarantee the job won’t signal during gpu_reset, we should not argue on this event …), I prefer clean and restrict rules. Yeah, completely agree that we need to have struct rules for that. That's why I insists on doing this :) No, you are insist on a vague rules not strict, like I said, what is the theoretic to backend your approach that only check once on the in question job ? why not check again if not signaled ? I don’t agree this approach is clean and strict. You are abuse timedout parameter. See I just want to avoid problems for the case that the job signaled while we stop the scheduler (because stopping the scheduler actually can take a moment). Because when this happened the scheduler could already have pushed the next job to the hardware and then we abort it with the GPU reset and might create more problems than we solve. [ML] I don’t see my approach will have chance to fence twice… on the contrast I think my approach is more clear: no matter the in question job finally signaled or not, I just kick it out from mirror-list Without remove the callback from hw fence, that way even it really signaled during the gpu_reset() period the logic is still perfect and its sched fence will act like usual … We want to set an error code on the job before signaling it don't we? So we need to be sure how and when the job is signaled as finished. I mean letting it signal when we force the hardware fence to complete will work as well, but I still think that this isn't as clean as signaling it manually. Please also see the helper function the Intel guys introduced drm_fence_set_error(), we will run into a BUG_ON if we can't guarantee the order of execution here. Regards, Christian. Am 10.05.2017 um 06:00 schrieb Liu, Monk: Christian, Looks like we need more discuss with it… Here is your approach: 1. Stop the scheduler from feeding more jobs to the hardware when a jobs completes. //this is where I agree with you 2. Then call hw_job_reset to remove the connection between job and hardware fence. 3. Test if job is now completed. It is entirely possible that the job completed while we started the work to reset the hardware. Removing the connection between the hardware fence and the job is the deadline, if the job completes after that it is lost. 4. Check the karma and kick out the job if we found it guilty. 5. Get the whole stuff working again, e.g. reset the hardware, restart the scheduler etc... [ML]: One thing I agree to change with your way: in gpu_reset() we should first stop the in question ring’s scheduler (not the all) before kick out the guilty job. > Indeed, but I still think that this is a bad approach cause we then reset the > hardware without a good reason. [ML] yes, but we cannot guarantee the job is 100% really hang when entering gpu_reset(), we can only trust our amdgpu_job_timeout as a deadline for each job. You approach that check the fence first before charge it as guilty/hang is incorrect looks to me because why you not check it twice, triple, and even more loops ? You check it one time and you found it just signaled that’s great and lucky(really lucky…), But what if it didn’t signaled (like most usual case) , why not check it again and again ? do you have a theoretic to support on how much time you need to check before finally consider it hang ? No I don’t think you have so please just cut this unnecessary checking, we already use amdgpu_job_timeout to give the deadline of each job. So I refuse to check if @job is just signaled in gpu_reset, because this action is vague (and no one can guarantee the job won’t signal during gpu_reset, we should not argue on this event …), I prefer clean and restrict rules. >Force completion is not so much of the issue, but rather in which order you do >things. >See the original code first stops the scheduler and removes the connection >between hardware fence and job in an atomic manner. And THEN
[PATCH xf86-video-amdgpu] Don't enable DRI3 without glamor
From: Michel DänzerCan't work currently. Fixes crash when trying to run a DRI3 client when glamor isn't enabled. Bugzilla: https://bugs.freedesktop.org/100968 Signed-off-by: Michel Dänzer --- src/amdgpu_kms.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index 0182cbe0a..4df81f993 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -1741,7 +1741,10 @@ Bool AMDGPUScreenInit_KMS(SCREEN_INIT_ARGS_DECL) #endif if (!amdgpu_is_gpu_screen(pScreen)) { - value = xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0); + if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0)) + value = info->use_glamor; + else + value = FALSE; from = X_DEFAULT; if (info->use_glamor) { -- 2.11.0 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 3/3] drm/amdgpu: id reset count only is updated when used end v2
before that, we have function to check if reset happens by using reset count. v2: always update reset count after vm flush Change-Id: I2e941dd35295d4210d57a9593d39b5ee9021be9f Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 0d3136a..84aba1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -450,7 +450,6 @@ static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm, id->flushed_updates = fence_get(updates); } id->pd_gpu_addr = job->vm_pd_addr; - id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); atomic64_set(>owner, vm->client_id); job->vm_needs_flush = needs_flush; if (needs_flush) { @@ -598,7 +597,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, id->pd_gpu_addr = job->vm_pd_addr; fence_put(id->flushed_updates); id->flushed_updates = fence_get(updates); - id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); atomic64_set(>owner, vm->client_id); needs_flush: @@ -781,6 +779,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job) mutex_lock(_mgr->lock); fence_put(id->last_flush); id->last_flush = fence; + id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); mutex_unlock(_mgr->lock); } -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH xf86-video-amdgpu] Remove unused struct members from drmmode_display.h
From: Michel DänzerSigned-off-by: Michel Dänzer --- src/drmmode_display.c | 1 - src/drmmode_display.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 5b2431495..9996d2f70 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2370,7 +2370,6 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) xf86CrtcConfigInit(pScrn, _xf86crtc_config_funcs); drmmode->scrn = pScrn; - drmmode->cpp = cpp; mode_res = drmModeGetResources(pAMDGPUEnt->fd); if (!mode_res) return FALSE; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index fa15a4f72..2d5698f61 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -38,8 +38,6 @@ typedef struct { unsigned fb_id; - drmModeFBPtr mode_fb; - int cpp; ScrnInfoPtr scrn; #ifdef HAVE_LIBUDEV struct udev_monitor *uevent_monitor; @@ -55,7 +53,6 @@ typedef struct { } drmmode_rec, *drmmode_ptr; typedef struct { - int fd; unsigned old_fb_id; int flip_count; void *event_data; -- 2.11.0 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH xf86-video-ati] Simplify tracking of PRIME scanout pixmap
From: Michel DänzerRemember the shared pixmap passed to drmmode_set_scanout_pixmap for each CRTC, and just compare against that. Fixes leaving stale entries in ScreenRec::pixmap_dirty_list under some circumstances, which would usually result in use-after-free and a crash down the line. Signed-off-by: Michel Dänzer --- src/drmmode_display.c | 21 +++-- src/drmmode_display.h | 3 +++ src/radeon_kms.c | 7 ++- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ec3072621..e2899cf50 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -732,9 +732,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, xorg_list_for_each_entry(dirty, >pixmap_dirty_list, ent) { - if (dirty->src == crtc->randr_crtc->scanout_pixmap && - dirty->slave_dst == - drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) { + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { dirty->slave_dst = drmmode_crtc->scanout[scanout_id].pixmap; break; @@ -887,7 +885,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, drmmode_ConvertToKMode(crtc->scrn, , mode); #ifdef RADEON_PIXMAP_SHARING - if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) { + if (drmmode_crtc->prime_scanout_pixmap) { drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id, , , ); } else @@ -1278,14 +1276,15 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) PixmapDirtyUpdatePtr dirty; xorg_list_for_each_entry(dirty, >pixmap_dirty_list, ent) { - if (dirty->slave_dst != drmmode_crtc->scanout[scanout_id].pixmap) - continue; - - PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); - drmmode_crtc_scanout_free(drmmode_crtc); - break; + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { + PixmapStopDirtyTracking(dirty->src, dirty->slave_dst); + break; + } } + drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc->prime_scanout_pixmap = NULL; + if (!ppix) return TRUE; @@ -1302,6 +1301,8 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) return FALSE; } + drmmode_crtc->prime_scanout_pixmap = ppix; + #ifdef HAS_DIRTYTRACKING_ROTATION PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap, 0, 0, 0, 0, RR_Rotate_0); diff --git a/src/drmmode_display.h b/src/drmmode_display.h index 14d1cb034..df2c4b7bb 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -92,6 +92,9 @@ typedef struct { unsigned scanout_id; Bool scanout_update_pending; Bool tear_free; + +PixmapPtr prime_scanout_pixmap; + int dpms_mode; /* For when a flip is pending when DPMS off requested */ int pending_dpms_mode; diff --git a/src/radeon_kms.c b/src/radeon_kms.c index 2b410eb3d..c4bdfcfac 100644 --- a/src/radeon_kms.c +++ b/src/radeon_kms.c @@ -657,8 +657,7 @@ radeon_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty) xf86CrtcPtr xf86_crtc = xf86_config->crtc[c]; drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; - if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst || - drmmode_crtc->scanout[1].pixmap == dirty->slave_dst) + if (drmmode_crtc->prime_scanout_pixmap == dirty->src) return xf86_crtc; } @@ -671,13 +670,11 @@ radeon_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id) ScrnInfoPtr scrn = crtc->scrn; ScreenPtr screen = scrn->pScreen; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; -PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap; PixmapDirtyUpdatePtr dirty; Bool ret = FALSE; xorg_list_for_each_entry(dirty, >pixmap_dirty_list, ent) { - if (dirty->src == scanoutpix && dirty->slave_dst == - drmmode_crtc->scanout[scanout_id ^ drmmode_crtc->tear_free].pixmap) { + if (dirty->src == drmmode_crtc->prime_scanout_pixmap) { RegionPtr region; if (master_has_sync_shared_pixmap(scrn, dirty)) -- 2.11.0 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH xf86-video-ati 2/2] Use reference counting for tracking KMS framebuffer lifetimes
From: Michel DänzerReferences are held by the pixmaps corresponding to the FBs (so the same KMS FB can be reused as long as the pixmap exists) and by the CRTCs scanning out from them (so a KMS FB is only destroyed once it's not being scanned out anymore, preventing intermittent black screens and worse issues due to a CRTC turning off when it should be on). v2: * Only increase reference count in drmmode_fb_reference if it was sane before * Make drmmode_fb_reference's indentation match the rest of drmmode_display.h Reviewed-by: Alex Deucher # v1 Signed-off-by: Michel Dänzer --- src/drmmode_display.c | 147 + src/drmmode_display.h | 39 +++-- src/radeon.h | 73 src/radeon_bo_helper.h | 3 - src/radeon_exa.c | 2 + src/radeon_kms.c | 64 ++--- src/radeon_present.c | 8 --- 7 files changed, 226 insertions(+), 110 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index a101ac233..ec3072621 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -375,6 +375,7 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, NULL, 0, NULL); + drmmode_fb_reference(drmmode->fd, _crtc->fb, NULL); } else if (drmmode_crtc->dpms_mode != DPMSModeOn) crtc->funcs->set_mode_major(crtc, >mode, crtc->rotation, crtc->x, crtc->y); @@ -447,8 +448,9 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); RADEONInfoPtr info = RADEONPTR(pScrn); - PixmapPtr src, dst; ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr src, dst = pScreen->GetScreenPixmap(pScreen); + struct drmmode_fb *fb = radeon_pixmap_get_fb(dst); int fbcon_id = 0; Bool force; GCPtr gc; @@ -464,7 +466,7 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) if (!fbcon_id) return; - if (fbcon_id == drmmode->fb_id) { + if (fbcon_id == fb->handle) { /* in some rare case there might be no fbcon and we might already * be the one with the current fb to avoid a false deadlck in * kernel ttm code just do nothing as anyway there is nothing @@ -477,8 +479,6 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode) if (!src) return; - dst = pScreen->GetScreenPixmap(pScreen); - gc = GetScratchGC(pScrn->depth, pScreen); ValidateGC(>drawable, gc); @@ -505,8 +505,6 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, } if (scanout->bo) { - drmModeRmFB(drmmode->fd, scanout->fb_id); - scanout->fb_id = 0; radeon_bo_unmap(scanout->bo); radeon_bo_unref(scanout->bo); scanout->bo = NULL; @@ -571,15 +569,9 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, scanout->bo = radeon_alloc_pixmap_bo(pScrn, width, height, pScrn->depth, tiling, pScrn->bitsPerPixel, , , ); - if (scanout->bo == NULL) - goto error; - - if (drmModeAddFB(drmmode->fd, width, height, pScrn->depth, - pScrn->bitsPerPixel, pitch, - scanout->bo->handle, - >fb_id) != 0) { - ErrorF("failed to add scanout fb\n"); - goto error; + if (!scanout->bo) { + ErrorF("failed to create CRTC scanout BO\n"); + return NULL; } scanout->pixmap = drmmode_create_bo_pixmap(pScrn, @@ -587,13 +579,17 @@ drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, pScrn->depth, pScrn->bitsPerPixel, pitch, scanout->bo, NULL); - if (scanout->pixmap) { + if (!scanout->pixmap) { + ErrorF("failed to create CRTC scanout pixmap\n"); + goto error; + } + + if (radeon_pixmap_get_fb(scanout->pixmap)) { scanout->width = width; scanout->height = height; } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate scanout pixmap for CRTC\n"); -error: + ErrorF("failed to create CRTC scanout FB\n"); +error: drmmode_crtc_scanout_destroy(drmmode, scanout); } @@ -706,8 +702,8 @@
[PATCH xf86-video-ati 1/2] Pass pixmap instead of handle to radeon_do_pageflip
From: Michel DänzerThis brings us in line with amdgpu and prepares for the following change, no functional change intended. (Ported from amdgpu commit e463b849f3e9d7b69e64a65619a22e00e78d297b) v2: * Be more consistent with the amdgpu code, which should make porting the following change to amdgpu easier Reviewed-by: Alex Deucher # v1 Signed-off-by: Michel Dänzer --- src/drmmode_display.c | 26 +- src/drmmode_display.h | 2 +- src/radeon_dri2.c | 5 + src/radeon_present.c | 15 ++- 4 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 0b823754b..a101ac233 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -2950,36 +2950,27 @@ void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) } Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, - uint32_t new_front_handle, uint64_t id, void *data, + PixmapPtr new_front, uint64_t id, void *data, int ref_crtc_hw_id, radeon_drm_handler_proc handler, radeon_drm_abort_proc abort, enum drmmode_flip_sync flip_sync, uint32_t target_msc) { RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn); - RADEONInfoPtr info = RADEONPTR(scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcPtr crtc = NULL; drmmode_crtc_private_ptr drmmode_crtc = config->crtc[0]->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; - unsigned int pitch; int i; - uint32_t tiling_flags = 0; uint32_t flip_flags = flip_sync == FLIP_ASYNC ? DRM_MODE_PAGE_FLIP_ASYNC : 0; drmmode_flipdata_ptr flipdata; uintptr_t drm_queue_seq = 0; + uint32_t new_front_handle; - if (info->allowColorTiling) { - if (info->ChipFamily >= CHIP_FAMILY_R600) - tiling_flags |= RADEON_TILING_MICRO; - else - tiling_flags |= RADEON_TILING_MACRO; - } - - pitch = RADEON_ALIGN(scrn->displayWidth, drmmode_get_pitch_align(scrn, info->pixel_bytes, tiling_flags)) * - info->pixel_bytes; - if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) { - pitch = info->front_surface.level[0].pitch_bytes; + if (!radeon_get_pixmap_handle(new_front, _front_handle)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "flip queue: failed to get new front handle\n"); + return FALSE; } flipdata = calloc(1, sizeof(drmmode_flipdata_rec)); @@ -2993,8 +2984,9 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, * Create a new handle for the back buffer */ flipdata->old_fb_id = drmmode->fb_id; - if (drmModeAddFB(drmmode->fd, scrn->virtualX, scrn->virtualY, -scrn->depth, scrn->bitsPerPixel, pitch, + if (drmModeAddFB(drmmode->fd, new_front->drawable.width, +new_front->drawable.height, scrn->depth, +scrn->bitsPerPixel, new_front->devKind, new_front_handle, >fb_id)) goto error; diff --git a/src/drmmode_display.h b/src/drmmode_display.h index bd3f5f987..35d64179d 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -168,7 +168,7 @@ extern int drmmode_get_base_align(ScrnInfoPtr scrn, int bpe, uint32_t tiling); extern void drmmode_clear_pending_flip(xf86CrtcPtr crtc); Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client, - uint32_t new_front_handle, uint64_t id, void *data, + PixmapPtr new_front, uint64_t id, void *data, int ref_crtc_hw_id, radeon_drm_handler_proc handler, radeon_drm_abort_proc abort, enum drmmode_flip_sync flip_sync, diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index c108ceab2..cc72bd52d 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -652,7 +652,6 @@ radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, ScrnInfoPtr scrn = crtc->scrn; RADEONInfoPtr info = RADEONPTR(scrn); struct dri2_buffer_priv *back_priv; -struct radeon_bo *bo; DRI2FrameEventPtr flip_info; int ref_crtc_hw_id = drmmode_get_crtc_id(crtc); @@ -673,9 +672,7 @@ radeon_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, /* Page flip the full screen buffer */ back_priv = back->driverPrivate; -bo = radeon_get_pixmap_bo(back_priv->pixmap); - -if (radeon_do_pageflip(scrn, client, bo->handle, +if (radeon_do_pageflip(scrn, client, back_priv->pixmap, RADEON_DRM_QUEUE_ID_DEFAULT, flip_info,
Re: [PATCH 1/4] drm/amdgpu: add sched sync for amdgpu job
On 2017年05月10日 16:50, Christian König wrote: Am 10.05.2017 um 10:38 schrieb zhoucm1: On 2017年05月10日 16:26, Christian König wrote: Am 10.05.2017 um 09:31 schrieb Chunming Zhou: this is an improvement for previous patch, the sched_sync is to store fence that could be skipped as scheduled, when job is executed, we didn't need pipeline_sync if all fences in sched_sync are signalled, otherwise insert pipeline_sync still. Change-Id: I26d3a2794272ba94b25753d4bf367326d12f6939 Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 5 - 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 787acd7..ef018bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1162,6 +1162,7 @@ struct amdgpu_job { struct amdgpu_vm*vm; struct amdgpu_ring*ring; struct amdgpu_syncsync; +struct amdgpu_syncsched_sync; struct amdgpu_ib*ibs; struct fence*fence; /* the hw fence */ uint32_tpreamble_status; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 2c6624d..86ad507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -121,6 +121,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, { struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = [0]; +struct fence *tmp; bool skip_preamble, need_ctx_switch; unsigned patch_offset = ~0; struct amdgpu_vm *vm; @@ -167,8 +168,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, return r; } -if (ring->funcs->emit_pipeline_sync && job && job->need_pipeline_sync) +if (ring->funcs->emit_pipeline_sync && job && +(tmp = amdgpu_sync_get_fence(>sched_sync))) { +job->need_pipeline_sync = true; amdgpu_ring_emit_pipeline_sync(ring); +fence_put(tmp); +} if (vm) { amdgpu_ring_insert_nop(ring, extra_nop); /* prevent CE go too fast than DE */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index cfa97ab..fa0c8b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -60,6 +60,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->need_pipeline_sync = false; amdgpu_sync_create(&(*job)->sync); +amdgpu_sync_create(&(*job)->sched_sync); return 0; } @@ -98,6 +99,7 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job) fence_put(job->fence); amdgpu_sync_free(>sync); +amdgpu_sync_free(>sched_sync); kfree(job); } @@ -107,6 +109,7 @@ void amdgpu_job_free(struct amdgpu_job *job) fence_put(job->fence); amdgpu_sync_free(>sync); +amdgpu_sync_free(>sched_sync); kfree(job); } @@ -154,7 +157,7 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) } if (amd_sched_dependency_optimized(fence, sched_job->s_entity)) -job->need_pipeline_sync = true; +amdgpu_sync_fence(job->adev, >sched_sync, fence); This can result in an -ENOMEM will handle it. and additional to that we only need to remember the last fence optimized like this, not all of them. So just keep the last one found here in job->sched_fence instead. I guess this isn't enough. The dependency is not in order when calling, so the last one is not always the last scheduled fence. And they could be sched fence not hw fence, although they are handled by same hw ring, but the sched fence context isn't same. so we still need sched_sync here, right? No, amdgpu_job_dependency is only called again when the returned fence is signaled (or scheduled on the same ring). Let use give an example for it: Assume job->sync has two fences(fenceA and fenceB) which could be scheduled. fenceA is from entity1, fenceB is from entity2, but both for gfx engine, but fenceA could be submitted to hw ring behind fenceB. the order in job->sync list is: others>fenceA>fenceB--->others. when calling amdgpu_job_dependency, fenceA will be checked first, and then fenceB. If following your proposal, we only store fenceB, but fenceA is the later. Which isn't expected. Regards, David Zhou So when this is called and you find that you need to wait for another fence the order is guaranteed. Regards, Christian. Regards, David zhou Regards, Christian. return fence; } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/4] drm/amdgpu: add sched sync for amdgpu job
Am 10.05.2017 um 10:38 schrieb zhoucm1: On 2017年05月10日 16:26, Christian König wrote: Am 10.05.2017 um 09:31 schrieb Chunming Zhou: this is an improvement for previous patch, the sched_sync is to store fence that could be skipped as scheduled, when job is executed, we didn't need pipeline_sync if all fences in sched_sync are signalled, otherwise insert pipeline_sync still. Change-Id: I26d3a2794272ba94b25753d4bf367326d12f6939 Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 5 - 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 787acd7..ef018bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1162,6 +1162,7 @@ struct amdgpu_job { struct amdgpu_vm*vm; struct amdgpu_ring*ring; struct amdgpu_syncsync; +struct amdgpu_syncsched_sync; struct amdgpu_ib*ibs; struct fence*fence; /* the hw fence */ uint32_tpreamble_status; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 2c6624d..86ad507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -121,6 +121,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, { struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = [0]; +struct fence *tmp; bool skip_preamble, need_ctx_switch; unsigned patch_offset = ~0; struct amdgpu_vm *vm; @@ -167,8 +168,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, return r; } -if (ring->funcs->emit_pipeline_sync && job && job->need_pipeline_sync) +if (ring->funcs->emit_pipeline_sync && job && +(tmp = amdgpu_sync_get_fence(>sched_sync))) { +job->need_pipeline_sync = true; amdgpu_ring_emit_pipeline_sync(ring); +fence_put(tmp); +} if (vm) { amdgpu_ring_insert_nop(ring, extra_nop); /* prevent CE go too fast than DE */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index cfa97ab..fa0c8b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -60,6 +60,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->need_pipeline_sync = false; amdgpu_sync_create(&(*job)->sync); +amdgpu_sync_create(&(*job)->sched_sync); return 0; } @@ -98,6 +99,7 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job) fence_put(job->fence); amdgpu_sync_free(>sync); +amdgpu_sync_free(>sched_sync); kfree(job); } @@ -107,6 +109,7 @@ void amdgpu_job_free(struct amdgpu_job *job) fence_put(job->fence); amdgpu_sync_free(>sync); +amdgpu_sync_free(>sched_sync); kfree(job); } @@ -154,7 +157,7 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) } if (amd_sched_dependency_optimized(fence, sched_job->s_entity)) -job->need_pipeline_sync = true; +amdgpu_sync_fence(job->adev, >sched_sync, fence); This can result in an -ENOMEM will handle it. and additional to that we only need to remember the last fence optimized like this, not all of them. So just keep the last one found here in job->sched_fence instead. I guess this isn't enough. The dependency is not in order when calling, so the last one is not always the last scheduled fence. And they could be sched fence not hw fence, although they are handled by same hw ring, but the sched fence context isn't same. so we still need sched_sync here, right? No, amdgpu_job_dependency is only called again when the returned fence is signaled (or scheduled on the same ring). So when this is called and you find that you need to wait for another fence the order is guaranteed. Regards, Christian. Regards, David zhou Regards, Christian. return fence; } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/4] drm/amdgpu: add sched sync for amdgpu job
On 2017年05月10日 16:26, Christian König wrote: Am 10.05.2017 um 09:31 schrieb Chunming Zhou: this is an improvement for previous patch, the sched_sync is to store fence that could be skipped as scheduled, when job is executed, we didn't need pipeline_sync if all fences in sched_sync are signalled, otherwise insert pipeline_sync still. Change-Id: I26d3a2794272ba94b25753d4bf367326d12f6939 Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 5 - 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 787acd7..ef018bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1162,6 +1162,7 @@ struct amdgpu_job { struct amdgpu_vm*vm; struct amdgpu_ring*ring; struct amdgpu_syncsync; +struct amdgpu_syncsched_sync; struct amdgpu_ib*ibs; struct fence*fence; /* the hw fence */ uint32_tpreamble_status; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 2c6624d..86ad507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -121,6 +121,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, { struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = [0]; +struct fence *tmp; bool skip_preamble, need_ctx_switch; unsigned patch_offset = ~0; struct amdgpu_vm *vm; @@ -167,8 +168,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, return r; } -if (ring->funcs->emit_pipeline_sync && job && job->need_pipeline_sync) +if (ring->funcs->emit_pipeline_sync && job && +(tmp = amdgpu_sync_get_fence(>sched_sync))) { +job->need_pipeline_sync = true; amdgpu_ring_emit_pipeline_sync(ring); +fence_put(tmp); +} if (vm) { amdgpu_ring_insert_nop(ring, extra_nop); /* prevent CE go too fast than DE */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index cfa97ab..fa0c8b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -60,6 +60,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->need_pipeline_sync = false; amdgpu_sync_create(&(*job)->sync); +amdgpu_sync_create(&(*job)->sched_sync); return 0; } @@ -98,6 +99,7 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job) fence_put(job->fence); amdgpu_sync_free(>sync); +amdgpu_sync_free(>sched_sync); kfree(job); } @@ -107,6 +109,7 @@ void amdgpu_job_free(struct amdgpu_job *job) fence_put(job->fence); amdgpu_sync_free(>sync); +amdgpu_sync_free(>sched_sync); kfree(job); } @@ -154,7 +157,7 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) } if (amd_sched_dependency_optimized(fence, sched_job->s_entity)) -job->need_pipeline_sync = true; +amdgpu_sync_fence(job->adev, >sched_sync, fence); This can result in an -ENOMEM will handle it. and additional to that we only need to remember the last fence optimized like this, not all of them. So just keep the last one found here in job->sched_fence instead. I guess this isn't enough. The dependency is not in order when calling, so the last one is not always the last scheduled fence. And they could be sched fence not hw fence, although they are handled by same hw ring, but the sched fence context isn't same. so we still need sched_sync here, right? Regards, David zhou Regards, Christian. return fence; } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 2/4] drm/amdgpu: make pipeline sync be in same place
Am 10.05.2017 um 09:31 schrieb Chunming Zhou: Change-Id: I0ccfa0e6de0cddbcca8dd85f2862240bc5ca02b3 Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 34 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 2 ++ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index ef018bf..a583aab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1170,7 +1170,6 @@ struct amdgpu_job { void*owner; uint64_tfence_ctx; /* the fence_context this job uses */ boolvm_needs_flush; - boolneed_pipeline_sync; unsignedvm_id; uint64_tvm_pd_addr; uint32_tgds_base, gds_size; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 86ad507..dc250d6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -121,7 +121,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, { struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = [0]; - struct fence *tmp; + struct fence *tmp = NULL; bool skip_preamble, need_ctx_switch; unsigned patch_offset = ~0; struct amdgpu_vm *vm; @@ -169,8 +169,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, } if (ring->funcs->emit_pipeline_sync && job && - (tmp = amdgpu_sync_get_fence(>sched_sync))) { - job->need_pipeline_sync = true; + ((tmp = amdgpu_sync_get_fence(>sched_sync)) || +amdgpu_vm_need_pipeline_sync(ring, job))) { amdgpu_ring_emit_pipeline_sync(ring); fence_put(tmp); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index fa0c8b1..adb7901 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -57,7 +57,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->vm = vm; (*job)->ibs = (void *)&(*job)[1]; (*job)->num_ibs = num_ibs; - (*job)->need_pipeline_sync = false; amdgpu_sync_create(&(*job)->sync); amdgpu_sync_create(&(*job)->sched_sync); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b4f83fc..58cde30 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -700,6 +700,37 @@ static u64 amdgpu_vm_adjust_mc_addr(struct amdgpu_device *adev, u64 mc_addr) return addr; } +bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring, + struct amdgpu_job *job) +{ + struct amdgpu_device *adev = ring->adev; + unsigned vmhub = ring->funcs->vmhub; + struct amdgpu_vm_id_manager *id_mgr = >vm_manager.id_mgr[vmhub]; + struct amdgpu_vm_id *id; + bool gds_switch_needed; + bool vm_flush_needed = job->vm_needs_flush || + amdgpu_vm_ring_has_compute_vm_bug(ring); + + if (job->vm_id == 0) + return false; + id = _mgr->ids[job->vm_id]; + gds_switch_needed = ring->funcs->emit_gds_switch && ( + id->gds_base != job->gds_base || + id->gds_size != job->gds_size || + id->gws_base != job->gws_base || + id->gws_size != job->gws_size || + id->oa_base != job->oa_base || + id->oa_size != job->oa_size); + + if (amdgpu_vm_had_gpu_reset(adev, id)) { + gds_switch_needed = true; + vm_flush_needed = true; You can shortcut here, e.g. just return true. Same above if you use an "if". Apart from that looks good to me. Christian. + } + if (!vm_flush_needed && !gds_switch_needed) + return false; + return true; +} + /** * amdgpu_vm_flush - hardware flush the vm * @@ -738,9 +769,6 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job) if (ring->funcs->init_cond_exec) patch_offset = amdgpu_ring_init_cond_exec(ring); - if (ring->funcs->emit_pipeline_sync && !job->need_pipeline_sync) - amdgpu_ring_emit_pipeline_sync(ring); - if (ring->funcs->emit_vm_flush && vm_flush_needed) { u64 pd_addr = amdgpu_vm_adjust_mc_addr(adev, job->vm_pd_addr); struct fence *fence; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 9828fcd..3d16169 100644 ---
Re: [PATCH 1/4] drm/amdgpu: add sched sync for amdgpu job
Am 10.05.2017 um 09:31 schrieb Chunming Zhou: this is an improvement for previous patch, the sched_sync is to store fence that could be skipped as scheduled, when job is executed, we didn't need pipeline_sync if all fences in sched_sync are signalled, otherwise insert pipeline_sync still. Change-Id: I26d3a2794272ba94b25753d4bf367326d12f6939 Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 7 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 5 - 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 787acd7..ef018bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1162,6 +1162,7 @@ struct amdgpu_job { struct amdgpu_vm*vm; struct amdgpu_ring *ring; struct amdgpu_sync sync; + struct amdgpu_sync sched_sync; struct amdgpu_ib*ibs; struct fence*fence; /* the hw fence */ uint32_tpreamble_status; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 2c6624d..86ad507 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -121,6 +121,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, { struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = [0]; + struct fence *tmp; bool skip_preamble, need_ctx_switch; unsigned patch_offset = ~0; struct amdgpu_vm *vm; @@ -167,8 +168,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, return r; } - if (ring->funcs->emit_pipeline_sync && job && job->need_pipeline_sync) + if (ring->funcs->emit_pipeline_sync && job && + (tmp = amdgpu_sync_get_fence(>sched_sync))) { + job->need_pipeline_sync = true; amdgpu_ring_emit_pipeline_sync(ring); + fence_put(tmp); + } if (vm) { amdgpu_ring_insert_nop(ring, extra_nop); /* prevent CE go too fast than DE */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index cfa97ab..fa0c8b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -60,6 +60,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->need_pipeline_sync = false; amdgpu_sync_create(&(*job)->sync); + amdgpu_sync_create(&(*job)->sched_sync); return 0; } @@ -98,6 +99,7 @@ static void amdgpu_job_free_cb(struct amd_sched_job *s_job) fence_put(job->fence); amdgpu_sync_free(>sync); + amdgpu_sync_free(>sched_sync); kfree(job); } @@ -107,6 +109,7 @@ void amdgpu_job_free(struct amdgpu_job *job) fence_put(job->fence); amdgpu_sync_free(>sync); + amdgpu_sync_free(>sched_sync); kfree(job); } @@ -154,7 +157,7 @@ static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) } if (amd_sched_dependency_optimized(fence, sched_job->s_entity)) - job->need_pipeline_sync = true; + amdgpu_sync_fence(job->adev, >sched_sync, fence); This can result in an -ENOMEM and additional to that we only need to remember the last fence optimized like this, not all of them. So just keep the last one found here in job->sched_fence instead. Regards, Christian. return fence; } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH xf86-video-ati] Apply gamma correction to HW cursor
From: Michel DänzerThe display hardware CLUT we're currently using for gamma correction doesn't affect the HW cursor, so we have to apply it manually when uploading the HW cursor data. This currently only works in depth 24/32. (Ported from amdgpu commit 82fa615f38137add75f9cd4bb49c48dd88de916f) Signed-off-by: Michel Dänzer --- src/drmmode_display.c | 66 --- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 84e7ef967..0b823754b 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -812,6 +812,17 @@ drmmode_crtc_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode, } } +static void +drmmode_crtc_gamma_do_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, + uint16_t *blue, int size) +{ + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + drmModeCrtcSetGamma(drmmode_crtc->drmmode->fd, + drmmode_crtc->mode_crtc->crtc_id, size, red, green, + blue); +} + static Bool drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y) @@ -873,8 +884,8 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (drmmode_crtc->tear_free) scanout_id = drmmode_crtc->scanout_id; - crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, - crtc->gamma_blue, crtc->gamma_size); + drmmode_crtc_gamma_do_set(crtc, crtc->gamma_red, crtc->gamma_green, + crtc->gamma_blue, crtc->gamma_size); drmmode_ConvertToKMode(crtc->scrn, , mode); @@ -1043,6 +1054,31 @@ drmmode_cursor_src_offset(Rotation rotation, int width, int height, #endif +static uint32_t +drmmode_cursor_gamma(xf86CrtcPtr crtc, uint32_t argb) +{ + uint32_t alpha = argb >> 24; + uint32_t rgb[3]; + int i; + + if (!alpha) + return 0; + + if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32) + return argb; + + /* Un-premultiply alpha */ + for (i = 0; i < 3; i++) + rgb[i] = ((argb >> (i * 8)) & 0xff) * 0xff / alpha; + + /* Apply gamma correction and pre-multiply alpha */ + rgb[0] = (crtc->gamma_blue[rgb[0]] >> 8) * alpha / 0xff; + rgb[1] = (crtc->gamma_green[rgb[1]] >> 8) * alpha / 0xff; + rgb[2] = (crtc->gamma_red[rgb[2]] >> 8) * alpha / 0xff; + + return alpha << 24 | rgb[2] << 16 | rgb[1] << 8 | rgb[0]; +} + static void drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) { @@ -1068,7 +1104,8 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) dstx, dsty); ptr[dsty * info->cursor_w + dstx] = - cpu_to_le32(image[srcoffset]); + cpu_to_le32(drmmode_cursor_gamma(crtc, + image[srcoffset])); } } } else @@ -1078,7 +1115,7 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) int i; for (i = 0; i < cursor_size; i++) - ptr[i] = cpu_to_le32(image[i]); + ptr[i] = cpu_to_le32(drmmode_cursor_gamma(crtc, image[i])); } } @@ -1209,11 +1246,24 @@ static void drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t *red, uint16_t *green, uint16_t *blue, int size) { - drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; - drmmode_ptr drmmode = drmmode_crtc->drmmode; + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); + RADEONInfoPtr info = RADEONPTR(scrn); + int i; - drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - size, red, green, blue); + drmmode_crtc_gamma_do_set(crtc, red, green, blue, size); + + /* Compute index of this CRTC into xf86_config->crtc */ + for (i = 0; xf86_config->crtc[i] != crtc; i++) {} + + if (info->hwcursor_disabled & (1 << i)) + return; + +#ifdef HAVE_XF86_CURSOR_RESET_CURSOR + xf86CursorResetCursor(scrn->pScreen); +#else + xf86_reload_cursors(scrn->pScreen); +#endif } #ifdef RADEON_PIXMAP_SHARING -- 2.11.0 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 3/4] drm/amdgpu: id reset count only is updated when used end
Am 10.05.2017 um 09:31 schrieb Chunming Zhou: before that, we have function to check if reset happens by using reset count. Change-Id: I2e941dd35295d4210d57a9593d39b5ee9021be9f Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 58cde30..bbb3587 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -450,7 +450,6 @@ static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm, id->flushed_updates = fence_get(updates); } id->pd_gpu_addr = job->vm_pd_addr; - id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); atomic64_set(>owner, vm->client_id); job->vm_needs_flush = needs_flush; if (needs_flush) { @@ -598,7 +597,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, id->pd_gpu_addr = job->vm_pd_addr; fence_put(id->flushed_updates); id->flushed_updates = fence_get(updates); - id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); atomic64_set(>owner, vm->client_id); needs_flush: @@ -783,6 +781,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job) mutex_lock(_mgr->lock); fence_put(id->last_flush); id->last_flush = fence; + if (amdgpu_vm_had_gpu_reset(adev, id)) + id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); Just drop the "if", checking the memory location first to avoid the write is rather pointless with an atomic. With that fixed the patch is Reviewed-by: Christian König . Regards, Christian. mutex_unlock(_mgr->lock); } ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 4/4] drm/amdgpu: check whether the vmid can be reused first
NAK, it is intentionally done like this to avoid starvation of processes. In other words we assign a VMID only when there is at least one free. Regards, Christian. Am 10.05.2017 um 09:31 schrieb Chunming Zhou: Change-Id: If24a62b9c3097c9b040225ab0e768145b7a3db1e Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 92 +- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index bbb3587..6259608 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -492,51 +492,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, mutex_unlock(_mgr->lock); return r; } - fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL); - if (!fences) { - mutex_unlock(_mgr->lock); - return -ENOMEM; - } - /* Check if we have an idle VMID */ - i = 0; - list_for_each_entry(idle, _mgr->ids_lru, list) { - fences[i] = amdgpu_sync_peek_fence(>active, ring); - if (!fences[i]) - break; - ++i; - } - - /* If we can't find a idle VMID to use, wait till one becomes available */ - if (>list == _mgr->ids_lru) { - u64 fence_context = adev->vm_manager.fence_context + ring->idx; - unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; - struct fence_array *array; - unsigned j; - - for (j = 0; j < i; ++j) - fence_get(fences[j]); - - array = fence_array_create(i, fences, fence_context, - seqno, true); - if (!array) { - for (j = 0; j < i; ++j) - fence_put(fences[j]); - kfree(fences); - r = -ENOMEM; - goto error; - } - - - r = amdgpu_sync_fence(ring->adev, sync, >base); - fence_put(>base); - if (r) - goto error; - - mutex_unlock(_mgr->lock); - return 0; - - } - kfree(fences); job->vm_needs_flush = false; /* Check if we can use a VMID already assigned to this VM */ @@ -586,6 +541,53 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, }; + fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL); + if (!fences) { + mutex_unlock(_mgr->lock); + return -ENOMEM; + } + /* Check if we have an idle VMID */ + i = 0; + list_for_each_entry(idle, _mgr->ids_lru, list) { + fences[i] = amdgpu_sync_peek_fence(>active, ring); + if (!fences[i]) + break; + ++i; + } + + /* If we can't find a idle VMID to use, wait till one becomes available */ + if (>list == _mgr->ids_lru) { + u64 fence_context = adev->vm_manager.fence_context + ring->idx; + unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; + struct fence_array *array; + unsigned j; + + for (j = 0; j < i; ++j) + fence_get(fences[j]); + + array = fence_array_create(i, fences, fence_context, + seqno, true); + if (!array) { + for (j = 0; j < i; ++j) + fence_put(fences[j]); + kfree(fences); + r = -ENOMEM; + goto error; + } + + + r = amdgpu_sync_fence(ring->adev, sync, >base); + fence_put(>base); + if (r) + goto error; + + mutex_unlock(_mgr->lock); + return 0; + + } + kfree(fences); + + /* Still no ID to use? Then use the idle one found earlier */ id = idle; ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 4/4] drm/amdgpu: check whether the vmid can be reused first
On 05/10/2017 03:31 PM, Chunming Zhou wrote: Change-Id: If24a62b9c3097c9b040225ab0e768145b7a3db1e Signed-off-by: Chunming ZhouI had same idea when read this code before. Reviewed-by: Junwei Zhang --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 92 +- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index bbb3587..6259608 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -492,51 +492,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, mutex_unlock(_mgr->lock); return r; } - fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL); - if (!fences) { - mutex_unlock(_mgr->lock); - return -ENOMEM; - } - /* Check if we have an idle VMID */ - i = 0; - list_for_each_entry(idle, _mgr->ids_lru, list) { - fences[i] = amdgpu_sync_peek_fence(>active, ring); - if (!fences[i]) - break; - ++i; - } - - /* If we can't find a idle VMID to use, wait till one becomes available */ - if (>list == _mgr->ids_lru) { - u64 fence_context = adev->vm_manager.fence_context + ring->idx; - unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; - struct fence_array *array; - unsigned j; - - for (j = 0; j < i; ++j) - fence_get(fences[j]); - - array = fence_array_create(i, fences, fence_context, - seqno, true); - if (!array) { - for (j = 0; j < i; ++j) - fence_put(fences[j]); - kfree(fences); - r = -ENOMEM; - goto error; - } - - - r = amdgpu_sync_fence(ring->adev, sync, >base); - fence_put(>base); - if (r) - goto error; - - mutex_unlock(_mgr->lock); - return 0; - - } - kfree(fences); job->vm_needs_flush = false; /* Check if we can use a VMID already assigned to this VM */ @@ -586,6 +541,53 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, }; + fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL); + if (!fences) { + mutex_unlock(_mgr->lock); + return -ENOMEM; + } + /* Check if we have an idle VMID */ + i = 0; + list_for_each_entry(idle, _mgr->ids_lru, list) { + fences[i] = amdgpu_sync_peek_fence(>active, ring); + if (!fences[i]) + break; + ++i; + } + + /* If we can't find a idle VMID to use, wait till one becomes available */ + if (>list == _mgr->ids_lru) { + u64 fence_context = adev->vm_manager.fence_context + ring->idx; + unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; + struct fence_array *array; + unsigned j; + + for (j = 0; j < i; ++j) + fence_get(fences[j]); + + array = fence_array_create(i, fences, fence_context, + seqno, true); + if (!array) { + for (j = 0; j < i; ++j) + fence_put(fences[j]); + kfree(fences); + r = -ENOMEM; + goto error; + } + + + r = amdgpu_sync_fence(ring->adev, sync, >base); + fence_put(>base); + if (r) + goto error; + + mutex_unlock(_mgr->lock); + return 0; + + } + kfree(fences); + + /* Still no ID to use? Then use the idle one found earlier */ id = idle; ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 4/4] drm/amdgpu: check whether the vmid can be reused first
Change-Id: If24a62b9c3097c9b040225ab0e768145b7a3db1e Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 92 +- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index bbb3587..6259608 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -492,51 +492,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, mutex_unlock(_mgr->lock); return r; } - fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL); - if (!fences) { - mutex_unlock(_mgr->lock); - return -ENOMEM; - } - /* Check if we have an idle VMID */ - i = 0; - list_for_each_entry(idle, _mgr->ids_lru, list) { - fences[i] = amdgpu_sync_peek_fence(>active, ring); - if (!fences[i]) - break; - ++i; - } - - /* If we can't find a idle VMID to use, wait till one becomes available */ - if (>list == _mgr->ids_lru) { - u64 fence_context = adev->vm_manager.fence_context + ring->idx; - unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; - struct fence_array *array; - unsigned j; - - for (j = 0; j < i; ++j) - fence_get(fences[j]); - - array = fence_array_create(i, fences, fence_context, - seqno, true); - if (!array) { - for (j = 0; j < i; ++j) - fence_put(fences[j]); - kfree(fences); - r = -ENOMEM; - goto error; - } - - - r = amdgpu_sync_fence(ring->adev, sync, >base); - fence_put(>base); - if (r) - goto error; - - mutex_unlock(_mgr->lock); - return 0; - - } - kfree(fences); job->vm_needs_flush = false; /* Check if we can use a VMID already assigned to this VM */ @@ -586,6 +541,53 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, }; + fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL); + if (!fences) { + mutex_unlock(_mgr->lock); + return -ENOMEM; + } + /* Check if we have an idle VMID */ + i = 0; + list_for_each_entry(idle, _mgr->ids_lru, list) { + fences[i] = amdgpu_sync_peek_fence(>active, ring); + if (!fences[i]) + break; + ++i; + } + + /* If we can't find a idle VMID to use, wait till one becomes available */ + if (>list == _mgr->ids_lru) { + u64 fence_context = adev->vm_manager.fence_context + ring->idx; + unsigned seqno = ++adev->vm_manager.seqno[ring->idx]; + struct fence_array *array; + unsigned j; + + for (j = 0; j < i; ++j) + fence_get(fences[j]); + + array = fence_array_create(i, fences, fence_context, + seqno, true); + if (!array) { + for (j = 0; j < i; ++j) + fence_put(fences[j]); + kfree(fences); + r = -ENOMEM; + goto error; + } + + + r = amdgpu_sync_fence(ring->adev, sync, >base); + fence_put(>base); + if (r) + goto error; + + mutex_unlock(_mgr->lock); + return 0; + + } + kfree(fences); + + /* Still no ID to use? Then use the idle one found earlier */ id = idle; -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 3/4] drm/amdgpu: id reset count only is updated when used end
before that, we have function to check if reset happens by using reset count. Change-Id: I2e941dd35295d4210d57a9593d39b5ee9021be9f Signed-off-by: Chunming Zhou--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 58cde30..bbb3587 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -450,7 +450,6 @@ static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm, id->flushed_updates = fence_get(updates); } id->pd_gpu_addr = job->vm_pd_addr; - id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); atomic64_set(>owner, vm->client_id); job->vm_needs_flush = needs_flush; if (needs_flush) { @@ -598,7 +597,6 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, id->pd_gpu_addr = job->vm_pd_addr; fence_put(id->flushed_updates); id->flushed_updates = fence_get(updates); - id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); atomic64_set(>owner, vm->client_id); needs_flush: @@ -783,6 +781,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job) mutex_lock(_mgr->lock); fence_put(id->last_flush); id->last_flush = fence; + if (amdgpu_vm_had_gpu_reset(adev, id)) + id->current_gpu_reset_count = atomic_read(>gpu_reset_counter); mutex_unlock(_mgr->lock); } -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx