From 2c7f9a4df9def07867087a520bc32169e2eec9f8 Mon Sep 17 00:00:00 2001 From: Colin Xu Date: Thu, 14 Feb 2019 12:56:33 +0800 Subject: drm/i915/gvt: Use consist max display pipe numbers as i915 definition GVT implements a homogeneous vGPU as host GPU so max vGPU display pipes can't exceed HW. The inconsistency definition has potential risks which could cause array indexing overflow. Remove the unnecessary define of INTEL_GVT_MAX_PIPE and align with i915. Reviewed-by: Zhenyu Wang Signed-off-by: Colin Xu Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gvt.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 0ba4b42e3bb0..db82a420efcc 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -111,11 +111,9 @@ struct intel_vgpu_cfg_space { #define vgpu_cfg_space(vgpu) ((vgpu)->cfg_space.virtual_cfg_space) -#define INTEL_GVT_MAX_PIPE 4 - struct intel_vgpu_irq { bool irq_warn_once[INTEL_GVT_EVENT_MAX]; - DECLARE_BITMAP(flip_done_event[INTEL_GVT_MAX_PIPE], + DECLARE_BITMAP(flip_done_event[I915_MAX_PIPES], INTEL_GVT_EVENT_MAX); }; -- cgit v1.2.3 From f74a6d9a2c427b6656bc93eacfa6d329ba54d611 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 20 Feb 2019 12:07:44 +0800 Subject: drm/i915/gvt: Refine the snapshort range of I915 MCHBAR to optimize gvt-g boot time Currently it will take the snapshot of the MCHBAR registers for gvt-g initialization so that it can be used for guest vgpu. And it will cover from 0x140000 to 0x17ffff. In fact based on the HW spec most of them are meanlingless and some time is wasted to read these register. Only the range of 0x144000 to 0x147fff contains the valid definition. So the range of capturing I915 MCHBAR register is refined, which helps to optimize the gvt-g boot time. V1->V2: Move the register definition into reg.h Signed-off-by: Zhao Yakui Acked-by: Zhenyu Wang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/handlers.c | 2 +- drivers/gpu/drm/i915/gvt/reg.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 9c106e47e640..65ee8ed0e206 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -3264,7 +3264,7 @@ void intel_gvt_clean_mmio_info(struct intel_gvt *gvt) /* Special MMIO blocks. */ static struct gvt_mmio_block mmio_blocks[] = { {D_SKL_PLUS, _MMIO(CSR_MMIO_START_RANGE), 0x3000, NULL, NULL}, - {D_ALL, _MMIO(MCHBAR_MIRROR_BASE_SNB), 0x40000, NULL, NULL}, + {D_ALL, MCHBAR_MIRROR_REG_BASE, 0x4000, NULL, NULL}, {D_ALL, _MMIO(VGT_PVINFO_PAGE), VGT_PVINFO_SIZE, pvinfo_mmio_read, pvinfo_mmio_write}, {D_ALL, LGC_PALETTE(PIPE_A, 0), 1024, NULL, NULL}, diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h index 428d252344f1..56cff20eba44 100644 --- a/drivers/gpu/drm/i915/gvt/reg.h +++ b/drivers/gpu/drm/i915/gvt/reg.h @@ -95,4 +95,7 @@ #define RING_GFX_MODE(base) _MMIO((base) + 0x29c) #define VF_GUARDBAND _MMIO(0x83a4) +/* define the effective range of MCHBAR register on Sandybridge+ */ +#define MCHBAR_MIRROR_REG_BASE _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x4000) + #endif -- cgit v1.2.3 From ed47c5cb8ee638b1c60fbb65c82c8784bf68539d Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 20 Feb 2019 12:07:45 +0800 Subject: drm/i915/gvt: Refine the combined intel_vgpu_oos_page struct to save memory The intel_vgpu_oos_page uses the combined structure, which embeds the tracked page. As it is allocated by kmalloc, the size(4140) is aligned to 8192. The 8192 oos_pages will waste about 32M memory. So the tracked page is split from the intel_vgpu_oos_page. And this will help to assure that the access of tracked page is cache aligned. Another minor change is that it doesn't need to be cleared to zero as it is writen firstly when one page is added to oos_page list. Signed-off-by: Zhao Yakui Reviewed-by: Zhenyu Wang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 7 +++++++ drivers/gpu/drm/i915/gvt/gtt.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 58e166effa45..115dc6829c26 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -2488,6 +2488,7 @@ static void clean_spt_oos(struct intel_gvt *gvt) list_for_each_safe(pos, n, >t->oos_page_free_list_head) { oos_page = container_of(pos, struct intel_vgpu_oos_page, list); list_del(&oos_page->list); + free_page((unsigned long)oos_page->mem); kfree(oos_page); } } @@ -2508,6 +2509,12 @@ static int setup_spt_oos(struct intel_gvt *gvt) ret = -ENOMEM; goto fail; } + oos_page->mem = (void *)__get_free_pages(GFP_KERNEL, 0); + if (!oos_page->mem) { + ret = -ENOMEM; + kfree(oos_page); + goto fail; + } INIT_LIST_HEAD(&oos_page->list); INIT_LIST_HEAD(&oos_page->vm_list); diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index d8cb04cc946d..e9f72a659014 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h @@ -221,7 +221,7 @@ struct intel_vgpu_oos_page { struct list_head list; struct list_head vm_list; int id; - unsigned char mem[I915_GTT_PAGE_SIZE]; + void *mem; }; #define GTT_ENTRY_NUM_IN_ONE_PAGE 512 -- cgit v1.2.3 From 13bcb80b7ee79431fce361e060611134cb19e209 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Wed, 20 Feb 2019 16:25:04 +0800 Subject: drm/i915/gvt: Fix MI_FLUSH_DW parsing with correct index check When MI_FLUSH_DW post write hw status page in index mode, the index value is in dword step and turned into address offset in cmd dword1. As status page size is 4K, so can't exceed that. This fixed upper bound check in cmd parser code which incorrectly stopped VM for reason of invalid MI_FLUSH_DW write index. v2: - Fix upper bound as 4K page size because index value is address offset. Fixes: be1da7070aea ("drm/i915/gvt: vGPU command scanner") Cc: stable@vger.kernel.org # v4.10+ Cc: "Zhao, Yan Y" Reviewed-by: Yan Zhao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 77ae634eb11c..bd95fd6b4ac8 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -1446,7 +1446,7 @@ static inline int cmd_address_audit(struct parser_exec_state *s, } if (index_mode) { - if (guest_gma >= I915_GTT_PAGE_SIZE / sizeof(u64)) { + if (guest_gma >= I915_GTT_PAGE_SIZE) { ret = -EFAULT; goto err; } -- cgit v1.2.3 From 1e8b15a1988ed3c7429402017d589422628cdf47 Mon Sep 17 00:00:00 2001 From: Colin Xu Date: Fri, 22 Feb 2019 14:13:42 +0800 Subject: drm/i915/gvt: Add in context mmio 0x20D8 to gen9 mmio list Depends on GEN family and I915_PARAM_HAS_CONTEXT_ISOLATION, Mesa driver will decide whether constant buffer 0 address is relative or absolute, and load GPU initial state by lri to context mmio INSTPM (GEN8) or 0x20D8 (>=GEN9). Mesa Commit fa8a764b62 ("i965: Use absolute addressing for constant buffer 0 on Kernel 4.16+.") INSTPM is already added to gen8_engine_mmio_list, but 0x20D8 is missed in gen9_engine_mmio_list. From GVT point of view, different guest could have different context so should switch those mmio accordingly. v2: Update fixes commit ID. Fixes: 178657139307 ("drm/i915/gvt: vGPU context switch") Reviewed-by: Zhenyu Wang Signed-off-by: Colin Xu Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/mmio_context.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index d6e02c15ef97..38492450552a 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c @@ -132,6 +132,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = { {RCS, GEN9_GAMT_ECO_REG_RW_IA, 0x0, false}, /* 0x4ab0 */ {RCS, GEN9_CSFE_CHICKEN1_RCS, 0xffff, false}, /* 0x20d4 */ + {RCS, _MMIO(0x20D8), 0xffff, true}, /* 0x20d8 */ {RCS, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */ {RCS, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */ -- cgit v1.2.3 From 9f4984773240cf004cbffb99316af3269bbb5e26 Mon Sep 17 00:00:00 2001 From: Weinan Li Date: Wed, 27 Feb 2019 15:36:58 +0800 Subject: drm/i915/gvt: stop scheduling workload when vgpu is inactive There is one corner case that workload_thread may pick and dispatch one workload of vgpu after it's already deactivated. Below is the scenario: 1. deactive_vgpu got the vgpu_lock, it found pending workload was submitted, then it released the vgpu_lock and wait for vgpu idle. 2. before deactive_vgpu got the vgpu_lock back, workload_thread might pick one new valid workload, then it was blocked by the vgpu_lock. 3. deactive_vgpu got the vgpu_lock again, finished the last processes of deactivating, then release the vgpu_lock. 4. workload_thread got the vgpu_lock, then it will try to dispatch the fetched workload. It's not expected one workload of deactivated vgpu is dispatched. The solution is to add condition check of the vgpu's active flag and stop to schedule when it's inactive. Reviewed-by: Zhenyu Wang Signed-off-by: Weinan Li Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/scheduler.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 55bb7885e228..af97df10495e 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -738,7 +738,8 @@ static struct intel_vgpu_workload *pick_next_workload( goto out; } - if (list_empty(workload_q_head(scheduler->current_vgpu, ring_id))) + if (!scheduler->current_vgpu->active || + list_empty(workload_q_head(scheduler->current_vgpu, ring_id))) goto out; /* -- cgit v1.2.3 From f552e7bd028f93157b206bd1c7e3e195e919e8c2 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 1 Mar 2019 15:55:04 +0800 Subject: drm/i915/gvt: Don't submit request for error workload dispatch As vGPU shadow ctx is loaded with guest context state, arbitrarily submitting request in error workload dispatch path would cause trouble. So don't try to submit in error path now like in previous code. This is to fix VM failure when GPU hang happens. Fixes: f0e994372518 ("drm/i915/gvt: Fix workload request allocation before request add") Reviewed-by: Xiong Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/scheduler.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index af97df10495e..817d46f25f09 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -677,6 +677,7 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) { struct intel_vgpu *vgpu = workload->vgpu; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + struct i915_request *rq; int ring_id = workload->ring_id; int ret; @@ -702,6 +703,14 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) ret = prepare_workload(workload); out: + if (ret) { + /* We might still need to add request with + * clean ctx to retire it properly.. + */ + rq = fetch_and_zero(&workload->req); + i915_request_put(rq); + } + if (!IS_ERR_OR_NULL(workload->req)) { gvt_dbg_sched("ring id %d submit workload to i915 %p\n", ring_id, workload->req); -- cgit v1.2.3 From 1e18d5e6731d674fee0bb4b66f5ea61e504452a3 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 1 Mar 2019 15:04:12 +0800 Subject: drm/i915/gvt: Only assign ppgtt root at dispatch time This moves ppgtt root hook out of scan and shadow function, as it's only required at dispatch time. Also make sure this checks against shadow mm to be ready, otherwise bail to fail earlier. Reviewed-by: Xiong Zhang Cc: Xiong Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/scheduler.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 817d46f25f09..0f2f2c43c0e0 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -345,7 +345,7 @@ static int set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload, int i = 0; if (mm->type != INTEL_GVT_MM_PPGTT || !mm->ppgtt_mm.shadowed) - return -1; + return -EINVAL; if (mm->ppgtt_mm.root_entry_type == GTT_TYPE_PPGTT_ROOT_L4_ENTRY) { px_dma(&ppgtt->pml4) = mm->ppgtt_mm.shadow_pdps[0]; @@ -409,12 +409,6 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload) if (workload->shadow) return 0; - ret = set_context_ppgtt_from_shadow(workload, shadow_ctx); - if (ret < 0) { - gvt_vgpu_err("workload shadow ppgtt isn't ready\n"); - return ret; - } - /* pin shadow context by gvt even the shadow context will be pinned * when i915 alloc request. That is because gvt will update the guest * context from shadow context when workload is completed, and at that @@ -677,6 +671,8 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) { struct intel_vgpu *vgpu = workload->vgpu; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + struct intel_vgpu_submission *s = &vgpu->submission; + struct i915_gem_context *shadow_ctx = s->shadow_ctx; struct i915_request *rq; int ring_id = workload->ring_id; int ret; @@ -687,6 +683,12 @@ static int dispatch_workload(struct intel_vgpu_workload *workload) mutex_lock(&vgpu->vgpu_lock); mutex_lock(&dev_priv->drm.struct_mutex); + ret = set_context_ppgtt_from_shadow(workload, shadow_ctx); + if (ret < 0) { + gvt_vgpu_err("workload shadow ppgtt isn't ready\n"); + goto err_req; + } + ret = intel_gvt_workload_req_alloc(workload); if (ret) goto err_req; -- cgit v1.2.3 From 72aabfb862e40ee83c136c4f87877c207e6859b7 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 1 Mar 2019 15:04:13 +0800 Subject: drm/i915/gvt: Add mutual lock for ppgtt mm LRU list This adds mutex to guard against update of global ppgtt mm LRU list. To resolve error found as below warning. [73130.012162] ------------[ cut here ]------------ [73130.012168] list_add corruption. prev->next should be next (ffff995f970cca50), but was 0000000000000000. (prev=ffff995f0dc5bdf8). [73130.012181] WARNING: CPU: 3 PID: 82 at lib/list_debug.c:28 __list_add_valid+0x4d/0x70 [73130.012183] Modules linked in: btrfs(E) xor(E) zstd_decompress(E) zstd_compress(E) raid6_pq(E) dm_mod(E) kvmgt(E) fuse(E) xt_addrtype(E) nft_compat(E) xt_conntrack(E) nf_nat(E) nf_conntrack(E) nf_defrag_ipv6(E) nf_defrag_ipv4(E) libcrc32c(E) br_netfilter(E) bridge(E) stp(E) llc(E) overlay(E) devlink(E) nf_tables(E) nfnetlink(E) loop(E) x86_pkg_temp_thermal(E) intel_powerclamp(E) coretemp(E) crct10dif_pclmul(E) crc32_pclmul(E) ghash_clmulni_intel(E) mei_me(E) aesni_intel(E) aes_x86_64(E) crypto_simd(E) cryptd(E) glue_helper(E) intel_cstate(E) intel_uncore(E) mei(E) intel_pch_thermal(E) intel_rapl_perf(E) pcspkr(E) iTCO_wdt(E) iTCO_vendor_support(E) idma64(E) sg(E) virt_dma(E) acpi_pad(E) evdev(E) binfmt_misc(E) ip_tables(E) x_tables(E) ipv6(E) autofs4(E) hid_generic(E) usbhid(E) hid(E) ext4(E) crc32c_generic(E) crc16(E) mbcache(E) jbd2(E) fscrypto(E) xhci_pci(E) sdhci_pci(E) cqhci(E) intel_lpss_pci(E) intel_lpss(E) crc32c_intel(E) xhci_hcd(E) sdhci(E) i2c_i801(E) e1000e(E) mmc_core(E) [73130.012218] ptp(E) pps_core(E) usbcore(E) mfd_core(E) sd_mod(E) fan(E) thermal(E) [73130.012227] CPU: 3 PID: 82 Comm: gvt workload 0 Tainted: G W E 5.0.0-rc7-staging-190226+ #282 [73130.012228] Hardware name: /NUC6i5SYB, BIOS SYSKLi35.86A.0039.2016.0316.1747 03/16/2016 [73130.012232] RIP: 0010:__list_add_valid+0x4d/0x70 [73130.012234] Code: c3 48 89 d1 48 c7 c7 e0 82 91 bb 48 89 c2 e8 44 8a cc ff 0f 0b 31 c0 c3 48 89 c1 4c 89 c6 48 c7 c7 30 83 91 bb e8 2d 8a cc ff <0f> 0b 31 c0 c3 48 89 f2 4c 89 c1 48 89 fe 48 c7 c7 80 83 91 bb e8 [73130.012236] RSP: 0018:ffffa4924107fdd0 EFLAGS: 00010286 [73130.012238] RAX: 0000000000000000 RBX: ffff995d8a5ccf00 RCX: 0000000000000006 [73130.012240] RDX: 0000000000000007 RSI: 0000000000000086 RDI: ffff995faad96680 [73130.012241] RBP: 0000000000000000 R08: 0000000000213a28 R09: 0000000000000084 [73130.012243] R10: 0000000000000000 R11: ffffa4924107fc70 R12: ffff995d8a5ccf78 [73130.012245] R13: ffff995f970c8000 R14: ffff995f0dc5bdf8 R15: ffff995f970cca50 [73130.012247] FS: 0000000000000000(0000) GS:ffff995faad80000(0000) knlGS:0000000000000000 [73130.012249] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [73130.012250] CR2: 00000222e1891000 CR3: 0000000116848002 CR4: 00000000003626e0 [73130.012252] Call Trace: [73130.012258] intel_vgpu_pin_mm+0x7a/0xa0 [73130.012262] workload_thread+0x683/0x12a0 [73130.012266] ? do_wait_intr_irq+0xb0/0xb0 [73130.012269] ? finish_wait+0x80/0x80 [73130.012271] ? intel_vgpu_clean_workloads+0x110/0x110 [73130.012274] kthread+0x116/0x130 [73130.012276] ? kthread_bind+0x30/0x30 [73130.012280] ret_from_fork+0x35/0x40 [73130.012285] WARNING: CPU: 3 PID: 82 at lib/list_debug.c:28 __list_add_valid+0x4d/0x70 [73130.012286] ---[ end trace 458a2e792eec21c0 ]--- v2: - simplify lock handling Reviewed-by: Xiong Zhang Cc: Xiong Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 14 +++++++++++++- drivers/gpu/drm/i915/gvt/gtt.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index c7103dd2d8d5..d7052ab7908c 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1882,7 +1882,11 @@ struct intel_vgpu_mm *intel_vgpu_create_ppgtt_mm(struct intel_vgpu *vgpu, } list_add_tail(&mm->ppgtt_mm.list, &vgpu->gtt.ppgtt_mm_list_head); + + mutex_lock(&gvt->gtt.ppgtt_mm_lock); list_add_tail(&mm->ppgtt_mm.lru_list, &gvt->gtt.ppgtt_mm_lru_list_head); + mutex_unlock(&gvt->gtt.ppgtt_mm_lock); + return mm; } @@ -1967,9 +1971,10 @@ int intel_vgpu_pin_mm(struct intel_vgpu_mm *mm) if (ret) return ret; + mutex_lock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock); list_move_tail(&mm->ppgtt_mm.lru_list, &mm->vgpu->gvt->gtt.ppgtt_mm_lru_list_head); - + mutex_unlock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock); } return 0; @@ -1980,6 +1985,8 @@ static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt) struct intel_vgpu_mm *mm; struct list_head *pos, *n; + mutex_lock(&gvt->gtt.ppgtt_mm_lock); + list_for_each_safe(pos, n, &gvt->gtt.ppgtt_mm_lru_list_head) { mm = container_of(pos, struct intel_vgpu_mm, ppgtt_mm.lru_list); @@ -1987,9 +1994,11 @@ static int reclaim_one_ppgtt_mm(struct intel_gvt *gvt) continue; list_del_init(&mm->ppgtt_mm.lru_list); + mutex_unlock(&gvt->gtt.ppgtt_mm_lock); invalidate_ppgtt_mm(mm); return 1; } + mutex_unlock(&gvt->gtt.ppgtt_mm_lock); return 0; } @@ -2659,6 +2668,7 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt) } } INIT_LIST_HEAD(&gvt->gtt.ppgtt_mm_lru_list_head); + mutex_init(&gvt->gtt.ppgtt_mm_lock); return 0; } @@ -2699,7 +2709,9 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu) list_for_each_safe(pos, n, &vgpu->gtt.ppgtt_mm_list_head) { mm = container_of(pos, struct intel_vgpu_mm, ppgtt_mm.list); if (mm->type == INTEL_GVT_MM_PPGTT) { + mutex_lock(&vgpu->gvt->gtt.ppgtt_mm_lock); list_del_init(&mm->ppgtt_mm.lru_list); + mutex_unlock(&vgpu->gvt->gtt.ppgtt_mm_lock); if (mm->ppgtt_mm.shadowed) invalidate_ppgtt_mm(mm); } diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h index d8cb04cc946d..edb610dc5d86 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.h +++ b/drivers/gpu/drm/i915/gvt/gtt.h @@ -88,6 +88,7 @@ struct intel_gvt_gtt { void (*mm_free_page_table)(struct intel_vgpu_mm *mm); struct list_head oos_page_use_list_head; struct list_head oos_page_free_list_head; + struct mutex ppgtt_mm_lock; struct list_head ppgtt_mm_lru_list_head; struct page *scratch_page; -- cgit v1.2.3 From 9c1c8416fc3759d52e6e173d4059149d5d2c6c00 Mon Sep 17 00:00:00 2001 From: Yan Zhao Date: Sun, 10 Mar 2019 21:40:45 -0400 Subject: drm/i915/gvt: remove the unused sreg code cleanup. sreg is not used now. remove it for code cleanness. v3: remove unnecessary array_size in vreg's memory allocation (min he) v2: do not allocate memory for sreg. (min he) Reviewed-by: He, Min Signed-off-by: Yan Zhao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gvt.h | 5 ----- drivers/gpu/drm/i915/gvt/handlers.c | 5 +---- drivers/gpu/drm/i915/gvt/mmio.c | 8 ++------ 3 files changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index db82a420efcc..05e9c2dd6183 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -94,7 +94,6 @@ struct intel_vgpu_fence { struct intel_vgpu_mmio { void *vreg; - void *sreg; }; #define INTEL_GVT_MAX_BAR_NUM 4 @@ -447,10 +446,6 @@ void intel_vgpu_write_fence(struct intel_vgpu *vgpu, (*(u64 *)(vgpu->mmio.vreg + i915_mmio_reg_offset(reg))) #define vgpu_vreg64(vgpu, offset) \ (*(u64 *)(vgpu->mmio.vreg + (offset))) -#define vgpu_sreg_t(vgpu, reg) \ - (*(u32 *)(vgpu->mmio.sreg + i915_mmio_reg_offset(reg))) -#define vgpu_sreg(vgpu, offset) \ - (*(u32 *)(vgpu->mmio.sreg + (offset))) #define for_each_active_vgpu(gvt, vgpu, id) \ idr_for_each_entry((&(gvt)->vgpu_idr), (vgpu), (id)) \ diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 65ee8ed0e206..6f9763fbf4f5 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -3488,12 +3488,11 @@ int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset, return mmio_info->read(vgpu, offset, pdata, bytes); else { u64 ro_mask = mmio_info->ro_mask; - u32 old_vreg = 0, old_sreg = 0; + u32 old_vreg = 0; u64 data = 0; if (intel_gvt_mmio_has_mode_mask(gvt, mmio_info->offset)) { old_vreg = vgpu_vreg(vgpu, offset); - old_sreg = vgpu_sreg(vgpu, offset); } if (likely(!ro_mask)) @@ -3515,8 +3514,6 @@ int intel_vgpu_mmio_reg_rw(struct intel_vgpu *vgpu, unsigned int offset, vgpu_vreg(vgpu, offset) = (old_vreg & ~mask) | (vgpu_vreg(vgpu, offset) & mask); - vgpu_sreg(vgpu, offset) = (old_sreg & ~mask) - | (vgpu_sreg(vgpu, offset) & mask); } } diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c index ed4df2f6d60b..a55178884d67 100644 --- a/drivers/gpu/drm/i915/gvt/mmio.c +++ b/drivers/gpu/drm/i915/gvt/mmio.c @@ -239,7 +239,6 @@ void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr) if (dmlr) { memcpy(vgpu->mmio.vreg, mmio, info->mmio_size); - memcpy(vgpu->mmio.sreg, mmio, info->mmio_size); vgpu_vreg_t(vgpu, GEN6_GT_THREAD_STATUS_REG) = 0; @@ -280,7 +279,6 @@ void intel_vgpu_reset_mmio(struct intel_vgpu *vgpu, bool dmlr) * touched */ memcpy(vgpu->mmio.vreg, mmio, GVT_GEN8_MMIO_RESET_OFFSET); - memcpy(vgpu->mmio.sreg, mmio, GVT_GEN8_MMIO_RESET_OFFSET); } } @@ -296,12 +294,10 @@ int intel_vgpu_init_mmio(struct intel_vgpu *vgpu) { const struct intel_gvt_device_info *info = &vgpu->gvt->device_info; - vgpu->mmio.vreg = vzalloc(array_size(info->mmio_size, 2)); + vgpu->mmio.vreg = vzalloc(info->mmio_size); if (!vgpu->mmio.vreg) return -ENOMEM; - vgpu->mmio.sreg = vgpu->mmio.vreg + info->mmio_size; - intel_vgpu_reset_mmio(vgpu, true); return 0; @@ -315,5 +311,5 @@ int intel_vgpu_init_mmio(struct intel_vgpu *vgpu) void intel_vgpu_clean_mmio(struct intel_vgpu *vgpu) { vfree(vgpu->mmio.vreg); - vgpu->mmio.vreg = vgpu->mmio.sreg = NULL; + vgpu->mmio.vreg = NULL; } -- cgit v1.2.3 From 21d2b122732318b48c10b7262e15595ce54511d3 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 26 Feb 2019 13:44:51 -0800 Subject: drm/vgem: fix use-after-free when drm_gem_handle_create() fails If drm_gem_handle_create() fails in vgem_gem_create(), then the drm_vgem_gem_object is freed twice: once when the reference is dropped by drm_gem_object_put_unlocked(), and again by __vgem_gem_destroy(). This was hit by syzkaller using fault injection. Fix it by skipping the second free. Reported-by: syzbot+e73f2fb5ed5a5df36d33@syzkaller.appspotmail.com Fixes: af33a9190d02 ("drm/vgem: Enable dmabuf import interfaces") Reviewed-by: Chris Wilson Cc: Laura Abbott Cc: Daniel Vetter Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers Acked-by: Laura Abbott Signed-off-by: Rodrigo Siqueira Link: https://patchwork.freedesktop.org/patch/msgid/20190226214451.195123-1-ebiggers@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vgem/vgem_drv.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index 5930facd6d2d..11a8f99ba18c 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -191,13 +191,9 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, ret = drm_gem_handle_create(file, &obj->base, handle); drm_gem_object_put_unlocked(&obj->base); if (ret) - goto err; + return ERR_PTR(ret); return &obj->base; - -err: - __vgem_gem_destroy(obj); - return ERR_PTR(ret); } static int vgem_gem_dumb_create(struct drm_file *file, struct drm_device *dev, -- cgit v1.2.3 From 36b6c9ed45afe89045973e8dee1b004dd5372d40 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 26 Feb 2019 14:08:58 -0800 Subject: drm/vkms: fix use-after-free when drm_gem_handle_create() fails If drm_gem_handle_create() fails in vkms_gem_create(), then the vkms_gem_object is freed twice: once when the reference is dropped by drm_gem_object_put_unlocked(), and again by the extra calls to drm_gem_object_release() and kfree(). Fix it by skipping the second release and free. This bug was originally found in the vgem driver by syzkaller using fault injection, but I noticed it's also present in the vkms driver. Fixes: 559e50fd34d1 ("drm/vkms: Add dumb operations") Cc: Rodrigo Siqueira Cc: Haneen Mohammed Cc: Daniel Vetter Cc: Chris Wilson Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers Reviewed-by: Chris Wilson Reviewed-by: Rodrigo Siqueira Signed-off-by: Rodrigo Siqueira Link: https://patchwork.freedesktop.org/patch/msgid/20190226220858.214438-1-ebiggers@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vkms/vkms_gem.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vkms/vkms_gem.c b/drivers/gpu/drm/vkms/vkms_gem.c index 138b0bb325cf..69048e73377d 100644 --- a/drivers/gpu/drm/vkms/vkms_gem.c +++ b/drivers/gpu/drm/vkms/vkms_gem.c @@ -111,11 +111,8 @@ struct drm_gem_object *vkms_gem_create(struct drm_device *dev, ret = drm_gem_handle_create(file, &obj->gem, handle); drm_gem_object_put_unlocked(&obj->gem); - if (ret) { - drm_gem_object_release(&obj->gem); - kfree(obj); + if (ret) return ERR_PTR(ret); - } return &obj->gem; } -- cgit v1.2.3 From e9abc611a941d4051cde1d94b2ab7473fdb50102 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Wed, 20 Feb 2019 22:40:06 +0000 Subject: drm/rockchip: vop: reset scale mode when win is disabled NV12 framebuffers produced by the VPU shows distorted on RK3288 after win has been disabled when scaling is active. This issue can be reproduced using a 1080p modeset by: - Scale a 1280x720 NV12 framebuffer to 1920x1080 on win0 - Disable win0 - Display a 1920x1080 NV12 framebuffer without scaling on win0 - Output will now show the framebuffer distorted And by: - Scale a 1280x720 NV12 framebuffer to 1920x1080 - Change to a 720p modeset (win gets disabled and scaling reset to none) - Output will now show the framebuffer distorted Fix this by setting scale mode to none when win is disabled. Fixes: 4c156c21c794 ("drm/rockchip: vop: support plane scale") Cc: stable@vger.kernel.org Signed-off-by: Jonas Karlman Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/AM3PR03MB0966DE3E19BACE07328CD637AC7D0@AM3PR03MB0966.eurprd03.prod.outlook.com --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c7d4c6073ea5..0d4ade9d4722 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -541,6 +541,18 @@ static void vop_core_clks_disable(struct vop *vop) clk_disable(vop->hclk); } +static void vop_win_disable(struct vop *vop, const struct vop_win_data *win) +{ + if (win->phy->scl && win->phy->scl->ext) { + VOP_SCL_SET_EXT(vop, win, yrgb_hor_scl_mode, SCALE_NONE); + VOP_SCL_SET_EXT(vop, win, yrgb_ver_scl_mode, SCALE_NONE); + VOP_SCL_SET_EXT(vop, win, cbcr_hor_scl_mode, SCALE_NONE); + VOP_SCL_SET_EXT(vop, win, cbcr_ver_scl_mode, SCALE_NONE); + } + + VOP_WIN_SET(vop, win, enable, 0); +} + static int vop_enable(struct drm_crtc *crtc) { struct vop *vop = to_vop(crtc); @@ -586,7 +598,7 @@ static int vop_enable(struct drm_crtc *crtc) struct vop_win *vop_win = &vop->win[i]; const struct vop_win_data *win = vop_win->data; - VOP_WIN_SET(vop, win, enable, 0); + vop_win_disable(vop, win); } spin_unlock(&vop->reg_lock); @@ -735,7 +747,7 @@ static void vop_plane_atomic_disable(struct drm_plane *plane, spin_lock(&vop->reg_lock); - VOP_WIN_SET(vop, win, enable, 0); + vop_win_disable(vop, win); spin_unlock(&vop->reg_lock); } @@ -1622,7 +1634,7 @@ static int vop_initial(struct vop *vop) int channel = i * 2 + 1; VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel); - VOP_WIN_SET(vop, win, enable, 0); + vop_win_disable(vop, win); VOP_WIN_SET(vop, win, gate, 1); } -- cgit v1.2.3 From 3df64d7b0a4f70f1797f23cfd4cca5c4d48131fe Mon Sep 17 00:00:00 2001 From: CK Hu Date: Mon, 14 Jan 2019 17:36:48 +0800 Subject: drm/mediatek: Implement gem prime vmap/vunmap function For some application which need kernel virtual address, such as fbcon, implement these function to map/unmap kernel virtual address of prime buffer. Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++ drivers/gpu/drm/mediatek/mtk_drm_gem.c | 46 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/mediatek/mtk_drm_gem.h | 3 +++ 3 files changed, 51 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index cf59ea9bccfd..4c3375cfb68f 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -341,6 +341,8 @@ static struct drm_driver mtk_drm_driver = { .gem_prime_get_sg_table = mtk_gem_prime_get_sg_table, .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, .gem_prime_mmap = mtk_drm_gem_mmap_buf, + .gem_prime_vmap = mtk_drm_gem_prime_vmap, + .gem_prime_vunmap = mtk_drm_gem_prime_vunmap, .fops = &mtk_drm_fops, .name = DRIVER_NAME, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c b/drivers/gpu/drm/mediatek/mtk_drm_gem.c index 259b7b0de1d2..38483e9ee071 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -241,3 +241,49 @@ err_gem_free: kfree(mtk_gem); return ERR_PTR(ret); } + +void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj) +{ + struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj); + struct sg_table *sgt; + struct sg_page_iter iter; + unsigned int npages; + unsigned int i = 0; + + if (mtk_gem->kvaddr) + return mtk_gem->kvaddr; + + sgt = mtk_gem_prime_get_sg_table(obj); + if (IS_ERR(sgt)) + return NULL; + + npages = obj->size >> PAGE_SHIFT; + mtk_gem->pages = kcalloc(npages, sizeof(*mtk_gem->pages), GFP_KERNEL); + if (!mtk_gem->pages) + goto out; + + for_each_sg_page(sgt->sgl, &iter, sgt->orig_nents, 0) { + mtk_gem->pages[i++] = sg_page_iter_page(&iter); + if (i > npages) + break; + } + mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); + +out: + kfree((void *)sgt); + + return mtk_gem->kvaddr; +} + +void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) +{ + struct mtk_drm_gem_obj *mtk_gem = to_mtk_gem_obj(obj); + + if (!mtk_gem->pages) + return; + + vunmap(vaddr); + mtk_gem->kvaddr = 0; + kfree((void *)mtk_gem->pages); +} diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.h b/drivers/gpu/drm/mediatek/mtk_drm_gem.h index 534639b43a1c..c047a7ef294f 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_gem.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.h @@ -37,6 +37,7 @@ struct mtk_drm_gem_obj { dma_addr_t dma_addr; unsigned long dma_attrs; struct sg_table *sg; + struct page **pages; }; #define to_mtk_gem_obj(x) container_of(x, struct mtk_drm_gem_obj, base) @@ -52,5 +53,7 @@ int mtk_drm_gem_mmap_buf(struct drm_gem_object *obj, struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj); struct drm_gem_object *mtk_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg); +void *mtk_drm_gem_prime_vmap(struct drm_gem_object *obj); +void mtk_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); #endif -- cgit v1.2.3 From d6db988a44294d7a91f60ecb87914694ba106305 Mon Sep 17 00:00:00 2001 From: CK Hu Date: Mon, 14 Jan 2019 17:44:44 +0800 Subject: drm/mediatek: Add Mediatek framebuffer device For Mediatek drm driver, use fbdev emulation to create a framebuffer device. Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 4c3375cfb68f..57ce4708ef1b 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -378,6 +379,10 @@ static int mtk_drm_bind(struct device *dev) if (ret < 0) goto err_deinit; + ret = drm_fbdev_generic_setup(drm, 32); + if (ret) + DRM_ERROR("Failed to initialize fbdev: %d\n", ret); + return 0; err_deinit: -- cgit v1.2.3 From 0ab925d3690614aa44cd29fb84cdcef03eab97dc Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 21 Mar 2019 11:53:45 -0400 Subject: drm/amd/display: Only allow VRR when vrefresh is within supported range [Why] Black screens or artifacting can occur when enabling FreeSync outside of the supported range of the monitor. This can happen since the supported range isn't always the min/max vrefresh range available for the monitor. [How] There was previously a fix that prevented this from happening in the low range but it didn't cover the upper range. Expand the condition to include both. Cc: Sun peng Li Cc: Harry Wentland Signed-off-by: Nicholas Kazlauskas Acked-by: Alex Deucher Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fb27783d7a54..81127f7d6ed1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5429,9 +5429,11 @@ static void get_freesync_config_for_crtc( struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(new_con_state->base.connector); struct drm_display_mode *mode = &new_crtc_state->base.mode; + int vrefresh = drm_mode_vrefresh(mode); new_crtc_state->vrr_supported = new_con_state->freesync_capable && - aconnector->min_vfreq <= drm_mode_vrefresh(mode); + vrefresh >= aconnector->min_vfreq && + vrefresh <= aconnector->max_vfreq; if (new_crtc_state->vrr_supported) { new_crtc_state->stream->ignore_msa_timing_param = true; -- cgit v1.2.3 From 69903dfae0310afe8a15f5cd4e376ebb7c6da1d2 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Tue, 19 Mar 2019 15:18:47 -0700 Subject: drm/i915/icl: Fix the TRANS_DDI_FUNC_CTL2 bitfield macro This patch fixes the PORT_SYNC_MODE_MASTER_SELECT macro to correctly do the left shifting to set the port sync master select correctly. I have tested this fix on ICL. Fixes: 49edbd49786e ("drm/i915/icl: Define TRANS_DDI_FUNC_CTL DSI registers") Cc: Madhav Chauhan Cc: Jani Nikula Cc: # v5.0+ Signed-off-by: Manasi Navare Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190319221847.21311-1-manasi.d.navare@intel.com (cherry picked from commit 7264aebb81d15aa6bbed650c816bba90f026bc35) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 638a586469f9..684589acc368 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -9243,7 +9243,7 @@ enum skl_power_gate { #define TRANS_DDI_FUNC_CTL2(tran) _MMIO_TRANS2(tran, \ _TRANS_DDI_FUNC_CTL2_A) #define PORT_SYNC_MODE_ENABLE (1 << 4) -#define PORT_SYNC_MODE_MASTER_SELECT(x) ((x) < 0) +#define PORT_SYNC_MODE_MASTER_SELECT(x) ((x) << 0) #define PORT_SYNC_MODE_MASTER_SELECT_MASK (0x7 << 0) #define PORT_SYNC_MODE_MASTER_SELECT_SHIFT 0 -- cgit v1.2.3 From 7cf77b273a8fc51e7de622fa6691abd4436a9a6b Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 11 Feb 2019 11:51:20 +0100 Subject: drm/tegra: hub: Fix dereference before check Reported-by: Dan Carpenter Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/hub.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index ba9b3cfb8c3d..b3436c2aed68 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -378,14 +378,16 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane, static void tegra_shared_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct tegra_dc *dc = to_tegra_dc(old_state->crtc); struct tegra_plane *p = to_tegra_plane(plane); + struct tegra_dc *dc; u32 value; /* rien ne va plus */ if (!old_state || !old_state->crtc) return; + dc = to_tegra_dc(old_state->crtc); + /* * XXX Legacy helpers seem to sometimes call ->atomic_disable() even * on planes that are already disabled. Make sure we fallback to the -- cgit v1.2.3 From 509869a2fec36ecb2b841180915995f41d5a0219 Mon Sep 17 00:00:00 2001 From: Anders Roxell Date: Mon, 18 Feb 2019 12:00:50 +0100 Subject: drm/tegra: vic: Fix implicit function declaration warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CONFIG_IOMMU_API isn't set the following warnings pops up: drivers/gpu/drm/tegra/vic.c: In function ‘vic_boot’: drivers/gpu/drm/tegra/vic.c:110:31: error: implicit declaration of function ‘dev_iommu_fwspec_get’; did you mean ‘iommu_fwspec_free’? [-Werror=implicit-function-declaration] struct iommu_fwspec *spec = dev_iommu_fwspec_get(vic->dev); ^~~~~~~~~~~~~~~~~~~~ iommu_fwspec_free drivers/gpu/drm/tegra/vic.c:110:31: warning: initialization of ‘struct iommu_fwspec *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion] drivers/gpu/drm/tegra/vic.c:117:19: error: ‘struct iommu_fwspec’ has no member named ‘num_ids’ if (spec && spec->num_ids > 0) { ^~ drivers/gpu/drm/tegra/vic.c:118:16: error: ‘struct iommu_fwspec’ has no member named ‘ids’ value = spec->ids[0] & 0xffff; ^~ Rework so that its inside a '#ifdef CONFIG_IOMMU_API' block. Fixes: f3779cb190a5 ("drm/tegra: vic: Support stream ID register programming") Signed-off-by: Anders Roxell Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/vic.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 39bfed9623de..982ce37ecde1 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -106,6 +106,7 @@ static int vic_boot(struct vic *vic) if (vic->booted) return 0; +#ifdef CONFIG_IOMMU_API if (vic->config->supports_sid) { struct iommu_fwspec *spec = dev_iommu_fwspec_get(vic->dev); u32 value; @@ -121,6 +122,7 @@ static int vic_boot(struct vic *vic) vic_writel(vic, value, VIC_THI_STREAMID1); } } +#endif /* setup clockgating registers */ vic_writel(vic, CG_IDLE_CG_DLY_CNT(4) | -- cgit v1.2.3 From 11c632e1cfd3dcb49f2d04625d31c818a4c3b426 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 18 Feb 2019 17:01:54 +0100 Subject: drm/tegra: sor: Implement acquire/release for reset By implementing the acquire/release protocol, the SOR reset can be shared with other drivers that also adhere to this protocol, such as the PMC driver that uses the same reset as part of the powergate and -ungate implementation using generic power domains. Runtime PM makes sure that the operations are executed in the right order, and the reset core has error handling and WARNs in place to make sure the acquire/release protocol is followed. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/sor.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 40057106f5f3..5be5a0817dfe 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -2871,6 +2871,13 @@ static int tegra_sor_init(struct host1x_client *client) * kernel is possible. */ if (sor->rst) { + err = reset_control_acquire(sor->rst); + if (err < 0) { + dev_err(sor->dev, "failed to acquire SOR reset: %d\n", + err); + return err; + } + err = reset_control_assert(sor->rst); if (err < 0) { dev_err(sor->dev, "failed to assert SOR reset: %d\n", @@ -2894,6 +2901,8 @@ static int tegra_sor_init(struct host1x_client *client) err); return err; } + + reset_control_release(sor->rst); } err = clk_prepare_enable(sor->clk_safe); @@ -3331,7 +3340,7 @@ static int tegra_sor_probe(struct platform_device *pdev) goto remove; } - sor->rst = devm_reset_control_get(&pdev->dev, "sor"); + sor->rst = devm_reset_control_get_exclusive_released(&pdev->dev, "sor"); if (IS_ERR(sor->rst)) { err = PTR_ERR(sor->rst); @@ -3519,6 +3528,8 @@ static int tegra_sor_suspend(struct device *dev) dev_err(dev, "failed to assert reset: %d\n", err); return err; } + + reset_control_release(sor->rst); } usleep_range(1000, 2000); @@ -3542,9 +3553,17 @@ static int tegra_sor_resume(struct device *dev) usleep_range(1000, 2000); if (sor->rst) { + err = reset_control_acquire(sor->rst); + if (err < 0) { + dev_err(dev, "failed to acquire reset: %d\n", err); + clk_disable_unprepare(sor->clk); + return err; + } + err = reset_control_deassert(sor->rst); if (err < 0) { dev_err(dev, "failed to deassert reset: %d\n", err); + reset_control_release(sor->rst); clk_disable_unprepare(sor->clk); return err; } -- cgit v1.2.3 From b6a36e5ddf8496ec83a14589f32f58bbaf022046 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 15 Mar 2019 11:46:21 +1000 Subject: drm/fb: avoid setting 0 depth. If the downscaling fails and we end up with a best_depth of 0, then ignore it. This actually works around a cascade of failure, but it the simplest fix for now. The scaling patch broke the udl driver, as the udl driver doesn't expose planes at all, so gets the two default 32-bit formats, but the udl driver then ask for 16bpp fbdev, and the scaling code falls over. This fixes the udl driver since the scaled depth support was added. Fixes: f4bd542bcaee ("drm/fb-helper: Scale back depth to supported maximum") Cc: Daniel Vetter Reviewed-by: Linus Walleij Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190315014621.21816-2-airlied@gmail.com --- drivers/gpu/drm/drm_fb_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 0e9349ff2d16..af2ab640cadb 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1963,7 +1963,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, best_depth = fmt->depth; } } - if (sizes.surface_depth != best_depth) { + if (sizes.surface_depth != best_depth && best_depth) { DRM_INFO("requested bpp %d, scaled depth down to %d", sizes.surface_bpp, best_depth); sizes.surface_depth = best_depth; -- cgit v1.2.3 From 3f04e0a6cfebf48152ac64502346cdc258811f79 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Fri, 8 Feb 2019 15:01:02 +0100 Subject: drm: Fix drm_release() and device unplug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If userspace has open fd(s) when drm_dev_unplug() is run, it will result in drm_dev_unregister() being called twice. First in drm_dev_unplug() and then later in drm_release() through the call to drm_put_dev(). Since userspace already holds a ref on drm_device through the drm_minor, it's not necessary to add extra ref counting based on no open file handles. Instead just drm_dev_put() unconditionally in drm_dev_unplug(). We now have this: - Userpace holds a ref on drm_device as long as there's open fd(s) - The driver holds a ref on drm_device as long as it's bound to the struct device When both sides are done with drm_device, it is released. Signed-off-by: Noralf Trønnes Reviewed-by: Oleksandr Andrushchenko Reviewed-by: Daniel Vetter Reviewed-by: Sean Paul Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190208140103.28919-2-noralf@tronnes.org --- drivers/gpu/drm/drm_drv.c | 6 +----- drivers/gpu/drm/drm_file.c | 6 ++---- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 381581b01d48..05bbc2b622fc 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -376,11 +376,7 @@ void drm_dev_unplug(struct drm_device *dev) synchronize_srcu(&drm_unplug_srcu); drm_dev_unregister(dev); - - mutex_lock(&drm_global_mutex); - if (dev->open_count == 0) - drm_dev_put(dev); - mutex_unlock(&drm_global_mutex); + drm_dev_put(dev); } EXPORT_SYMBOL(drm_dev_unplug); diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 83a5bbca6e7e..7caa3c7ed978 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -489,11 +489,9 @@ int drm_release(struct inode *inode, struct file *filp) drm_close_helper(filp); - if (!--dev->open_count) { + if (!--dev->open_count) drm_lastclose(dev); - if (drm_dev_is_unplugged(dev)) - drm_put_dev(dev); - } + mutex_unlock(&drm_global_mutex); drm_minor_release(minor); -- cgit v1.2.3 From a51143001d9e0683ab6f7968a516fc9243527e44 Mon Sep 17 00:00:00 2001 From: Robert Tarasov Date: Thu, 14 Mar 2019 15:53:39 -0700 Subject: drm/udl: Refactor edid retrieving in UDL driver (v2) Now drm/udl driver uses drm_do_get_edid() function to retrieve and validate all blocks of EDID data. Old approach had insufficient validation routine and had problems with retrieving of extra blocks Signed-off-by: Robert Tarasov Reviewed-by: Jani Nikula Signed-off-by: Dave Airlie [airlied: Fix spelling mistakes] Link: https://patchwork.freedesktop.org/patch/msgid/20190314225339.162386-1-tutankhamen@chromium.org --- drivers/gpu/drm/udl/udl_connector.c | 72 ++++++------------------------------- 1 file changed, 11 insertions(+), 61 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index 66885c24590f..c1bd5e3d9e4a 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -18,18 +18,19 @@ #include "udl_connector.h" #include "udl_drv.h" -static bool udl_get_edid_block(struct udl_device *udl, int block_idx, - u8 *buff) +static int udl_get_edid_block(void *data, u8 *buf, unsigned int block, + size_t len) { int ret, i; u8 *read_buff; + struct udl_device *udl = data; read_buff = kmalloc(2, GFP_KERNEL); if (!read_buff) - return false; + return -1; - for (i = 0; i < EDID_LENGTH; i++) { - int bval = (i + block_idx * EDID_LENGTH) << 8; + for (i = 0; i < len; i++) { + int bval = (i + block * EDID_LENGTH) << 8; ret = usb_control_msg(udl->udev, usb_rcvctrlpipe(udl->udev, 0), (0x02), (0x80 | (0x02 << 5)), bval, @@ -37,60 +38,13 @@ static bool udl_get_edid_block(struct udl_device *udl, int block_idx, if (ret < 1) { DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret); kfree(read_buff); - return false; + return -1; } - buff[i] = read_buff[1]; + buf[i] = read_buff[1]; } kfree(read_buff); - return true; -} - -static bool udl_get_edid(struct udl_device *udl, u8 **result_buff, - int *result_buff_size) -{ - int i, extensions; - u8 *block_buff = NULL, *buff_ptr; - - block_buff = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (block_buff == NULL) - return false; - - if (udl_get_edid_block(udl, 0, block_buff) && - memchr_inv(block_buff, 0, EDID_LENGTH)) { - extensions = ((struct edid *)block_buff)->extensions; - if (extensions > 0) { - /* we have to read all extensions one by one */ - *result_buff_size = EDID_LENGTH * (extensions + 1); - *result_buff = kmalloc(*result_buff_size, GFP_KERNEL); - buff_ptr = *result_buff; - if (buff_ptr == NULL) { - kfree(block_buff); - return false; - } - memcpy(buff_ptr, block_buff, EDID_LENGTH); - kfree(block_buff); - buff_ptr += EDID_LENGTH; - for (i = 1; i < extensions; ++i) { - if (udl_get_edid_block(udl, i, buff_ptr)) { - buff_ptr += EDID_LENGTH; - } else { - kfree(*result_buff); - *result_buff = NULL; - return false; - } - } - return true; - } - /* we have only base edid block */ - *result_buff = block_buff; - *result_buff_size = EDID_LENGTH; - return true; - } - - kfree(block_buff); - - return false; + return 0; } static int udl_get_modes(struct drm_connector *connector) @@ -122,8 +76,6 @@ static enum drm_mode_status udl_mode_valid(struct drm_connector *connector, static enum drm_connector_status udl_detect(struct drm_connector *connector, bool force) { - u8 *edid_buff = NULL; - int edid_buff_size = 0; struct udl_device *udl = connector->dev->dev_private; struct udl_drm_connector *udl_connector = container_of(connector, @@ -136,12 +88,10 @@ udl_detect(struct drm_connector *connector, bool force) udl_connector->edid = NULL; } - - if (!udl_get_edid(udl, &edid_buff, &edid_buff_size)) + udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, udl); + if (!udl_connector->edid) return connector_status_disconnected; - udl_connector->edid = (struct edid *)edid_buff; - return connector_status_connected; } -- cgit v1.2.3 From 776e78677f514ecddd12dba48b9040958999bd5a Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Fri, 22 Mar 2019 15:26:56 +0000 Subject: drm/meson: Fix invalid pointer in meson_drv_unbind() meson_drv_bind() registers a meson_drm struct as the device's privdata, but meson_drv_unbind() tries to retrieve a drm_device. This may cause a segfault on shutdown: [ 5194.593429] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000197 ... [ 5194.788850] Call trace: [ 5194.791349] drm_dev_unregister+0x1c/0x118 [drm] [ 5194.795848] meson_drv_unbind+0x50/0x78 [meson_drm] Retrieve the right pointer in meson_drv_unbind(). Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller") Signed-off-by: Jean-Philippe Brucker Acked-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20190322152657.13752-1-jean-philippe.brucker@arm.com --- drivers/gpu/drm/meson/meson_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 2281ed3eb774..7e85802c5398 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -356,8 +356,8 @@ static int meson_drv_bind(struct device *dev) static void meson_drv_unbind(struct device *dev) { - struct drm_device *drm = dev_get_drvdata(dev); - struct meson_drm *priv = drm->dev_private; + struct meson_drm *priv = dev_get_drvdata(dev); + struct drm_device *drm = priv->drm; if (priv->canvas) { meson_canvas_free(priv->canvas, priv->canvas_id_osd1); -- cgit v1.2.3 From 2d8f92897ad816f5dda54b2ed2fd9f2d7cb1abde Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Fri, 22 Mar 2019 15:26:57 +0000 Subject: drm/meson: Uninstall IRQ handler meson_drv_unbind() doesn't unregister the IRQ handler, which can lead to use-after-free if the IRQ fires after unbind: [ 64.656876] Unable to handle kernel paging request at virtual address ffff000011706dbc ... [ 64.662001] pc : meson_irq+0x18/0x30 [meson_drm] I'm assuming that a similar problem could happen on the error path of bind(), so uninstall the IRQ handler there as well. Fixes: bbbe775ec5b5 ("drm: Add support for Amlogic Meson Graphic Controller") Signed-off-by: Jean-Philippe Brucker Acked-by: Neil Armstrong Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20190322152657.13752-2-jean-philippe.brucker@arm.com --- drivers/gpu/drm/meson/meson_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 7e85802c5398..8a4ebcb6405c 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -337,12 +337,14 @@ static int meson_drv_bind_master(struct device *dev, bool has_components) ret = drm_dev_register(drm, 0); if (ret) - goto free_drm; + goto uninstall_irq; drm_fbdev_generic_setup(drm, 32); return 0; +uninstall_irq: + drm_irq_uninstall(drm); free_drm: drm_dev_put(drm); @@ -367,6 +369,7 @@ static void meson_drv_unbind(struct device *dev) } drm_dev_unregister(drm); + drm_irq_uninstall(drm); drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); drm_dev_put(drm); -- cgit v1.2.3 From 3d565a21f2ce1f37479e91914734478c39b5c6fc Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Wed, 20 Mar 2019 09:11:10 +0100 Subject: drm/meson: fix TMDS clock filtering for DMT monitors DMT monitors does not necessarely report a maximum TMDS clock in a VSDB EDID extension. In this case, all modes are wrongly rejected, including the DRM fallback EDID. This patch only rejects modes whith clock > max_tmds_clock if the max_tmds_clock is specified. This will only reject 4:2:0 HDMI2.0 modes, who reports a clock > max_tmds_clock. Reported-by: Maxime Jourdan Fixes: d7d8fb7046b6 ("drm/meson: add HDMI div40 TMDS mode") Signed-off-by: Neil Armstrong Tested-by: Maxime Jourdan Reviewed-by: Maxime Jourdan Link: https://patchwork.freedesktop.org/patch/msgid/20190320081110.1718-1-narmstrong@baylibre.com --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index e28814f4ea6c..563953ec6ad0 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -569,7 +569,8 @@ dw_hdmi_mode_valid(struct drm_connector *connector, DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); /* If sink max TMDS clock, we reject the mode */ - if (mode->clock > connector->display_info.max_tmds_clock) + if (connector->display_info.max_tmds_clock && + mode->clock > connector->display_info.max_tmds_clock) return MODE_BAD; /* Check against non-VIC supported modes */ -- cgit v1.2.3 From 836f90f9e2d11263f9c6d7610c82f3bc7335d9a6 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Fri, 15 Mar 2019 10:54:14 +0100 Subject: drm/bridge: dw-hdmi: disable SCDC configuration for invalid setups This patch is an attempt to limit HDMI 2.0 SCDC setup when : - the SoC embeds an HDMI 1.4 only controller - the EDID supports SCDC but not scrambling - the EDID supports SCDC scrambling but not for low TMDS bit rates, while only supporting low TMDS bit rates This to avoid communicating with the SCDC DDC slave uncessary, and setting the DW-HDMI TMDS Scrambler setup when not supported by the underlying hardware. Reported-by: Rob Herring Fixes: 264fce6cc2c1 ("drm/bridge: dw-hdmi: Add SCDC and TMDS Scrambling support") Signed-off-by: Neil Armstrong Tested-by: Rob Herring Reviewed-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/20190315095414.28520-1-narmstrong@baylibre.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 34 +++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index a63e5f0dae56..db761329a1e3 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -1037,6 +1037,31 @@ void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, } EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); +/* Filter out invalid setups to avoid configuring SCDC and scrambling */ +static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi) +{ + struct drm_display_info *display = &hdmi->connector.display_info; + + /* Completely disable SCDC support for older controllers */ + if (hdmi->version < 0x200a) + return false; + + /* Disable if SCDC is not supported, or if an HF-VSDB block is absent */ + if (!display->hdmi.scdc.supported || + !display->hdmi.scdc.scrambling.supported) + return false; + + /* + * Disable if display only support low TMDS rates and scrambling + * for low rates is not supported either + */ + if (!display->hdmi.scdc.scrambling.low_rates && + display->max_tmds_clock <= 340000) + return false; + + return true; +} + /* * HDMI2.0 Specifies the following procedure for High TMDS Bit Rates: * - The Source shall suspend transmission of the TMDS clock and data @@ -1055,7 +1080,7 @@ void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi) unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock; /* Control for TMDS Bit Period/TMDS Clock-Period Ratio */ - if (hdmi->connector.display_info.hdmi.scdc.supported) { + if (dw_hdmi_support_scdc(hdmi)) { if (mtmdsclock > HDMI14_MAX_TMDSCLK) drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1); else @@ -1579,8 +1604,9 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, /* Set up HDMI_FC_INVIDCONF */ inv_val = (hdmi->hdmi_data.hdcp_enable || - vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || - hdmi_info->scdc.scrambling.low_rates ? + (dw_hdmi_support_scdc(hdmi) && + (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || + hdmi_info->scdc.scrambling.low_rates)) ? HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); @@ -1646,7 +1672,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi, } /* Scrambling Control */ - if (hdmi_info->scdc.supported) { + if (dw_hdmi_support_scdc(hdmi)) { if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK || hdmi_info->scdc.scrambling.low_rates) { /* -- cgit v1.2.3 From 4b9a3932e7ba929baa231231e61874c7a56f8959 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 22 Mar 2019 22:49:44 +0200 Subject: drm/i915: Mark AML 0x87CA as ULX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If I'm reading the spec right AML 0x87CA is a Y SKU, so it should be marked as ULX in our old style terminology. Cc: stable@vger.kernel.org Cc: José Roberto de Souza Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Fixes: c0c46ca461f1 ("drm/i915/aml: Add new Amber Lake PCI ID") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190322204944.23613-1-ville.syrjala@linux.intel.com Reviewed-by: José Roberto de Souza (cherry picked from commit 57b1c4460dc46a00f6ec439f3f11d670736b0209) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9adc7bb9e69c..a67a63b5aa84 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2346,7 +2346,8 @@ static inline unsigned int i915_sg_segment_size(void) INTEL_DEVID(dev_priv) == 0x5915 || \ INTEL_DEVID(dev_priv) == 0x591E) #define IS_AML_ULX(dev_priv) (INTEL_DEVID(dev_priv) == 0x591C || \ - INTEL_DEVID(dev_priv) == 0x87C0) + INTEL_DEVID(dev_priv) == 0x87C0 || \ + INTEL_DEVID(dev_priv) == 0x87CA) #define IS_SKL_GT2(dev_priv) (IS_SKYLAKE(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 2) #define IS_SKL_GT3(dev_priv) (IS_SKYLAKE(dev_priv) && \ -- cgit v1.2.3 From 71cd6cb234876e2232635bb2fdcfde5146f7fffd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 26 Mar 2019 08:08:43 +0300 Subject: drm/i915/selftests: Fix an IS_ERR() vs NULL check The live_context() function returns error pointers. It never returns NULL. Fixes: 9c1477e83e62 ("drm/i915/selftests: Exercise adding requests to a full GGTT") Signed-off-by: Dan Carpenter Reviewed-by: Mika Kuoppala Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190326050843.GA20038@kadam (cherry picked from commit 602cbe8efc523ba56e1f41e8f74c7aa835672593) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/selftests/i915_gem_evict.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index 32dce7176f63..b9b0ea4e2404 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -455,7 +455,7 @@ static int igt_evict_contexts(void *arg) struct i915_gem_context *ctx; ctx = live_context(i915, file); - if (!ctx) + if (IS_ERR(ctx)) break; /* We will need some GGTT space for the rq's context */ -- cgit v1.2.3 From 14bc29646639650e38f061fca6f644706cc25034 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Mon, 7 Jan 2019 14:09:34 +0100 Subject: drm/omap: fix typo Fix spelling mistake: "lenght" -> "length" Signed-off-by: Matteo Croce Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20190107130934.9997-1-mcroce@redhat.com --- drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c index 813ba42f2753..e384b95ad857 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c @@ -708,7 +708,7 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, else acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; /* - * The I2S input word length is twice the lenght given in the IEC-60958 + * The I2S input word length is twice the length given in the IEC-60958 * status word. If the word size is greater than * 20 bits, increment by one. */ -- cgit v1.2.3 From 36a1da15b5df493241b0011d2185fdd724ac1ed1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 26 Mar 2019 08:14:37 -0700 Subject: drm/omap: hdmi4_cec: Fix CEC clock handling for PM If CONFIG_OMAP4_DSS_HDMI_CEC is enabled in .config, deeper SoC idle states are blocked because the CEC clock gets always enabled on init. Let's fix the issue by moving the CEC clock handling to happen later in hdmi_cec_adap_enable() as suggested by Hans Verkuil . This way the CEC clock gets only enabled when needed. This can be tested by doing cec-ctl --playback to enable the CEC, and doing cec-ctl --clear to disable it. Let's also fix the typo for "divider" in the comments while at it. Fixes: 8d7f934df8d8 ("omapdrm: hdmi4_cec: add OMAP4 HDMI CEC support") Suggested-by: Hans Verkuil Cc: Hans Verkuil Cc: Jyri Sarha Cc: Laurent Pinchart Signed-off-by: Tony Lindgren Reviewed-by: Hans Verkuil Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20190326151438.32414-1-tony@atomide.com --- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c index 340383150fb9..ebf9c96d43ee 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c @@ -175,6 +175,7 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0, 3, 3); hdmi_wp_clear_irqenable(core->wp, HDMI_IRQ_CORE); hdmi_wp_set_irqstatus(core->wp, HDMI_IRQ_CORE); + REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); hdmi4_core_disable(core); return 0; } @@ -182,16 +183,24 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) if (err) return err; + /* + * Initialize CEC clock divider: CEC needs 2MHz clock hence + * set the divider to 24 to get 48/24=2MHz clock + */ + REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0); + /* Clear TX FIFO */ if (!hdmi_cec_clear_tx_fifo(adap)) { pr_err("cec-%s: could not clear TX FIFO\n", adap->name); - return -EIO; + err = -EIO; + goto err_disable_clk; } /* Clear RX FIFO */ if (!hdmi_cec_clear_rx_fifo(adap)) { pr_err("cec-%s: could not clear RX FIFO\n", adap->name); - return -EIO; + err = -EIO; + goto err_disable_clk; } /* Clear CEC interrupts */ @@ -236,6 +245,12 @@ static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, temp); } return 0; + +err_disable_clk: + REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); + hdmi4_core_disable(core); + + return err; } static int hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) @@ -333,11 +348,8 @@ int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core, return ret; core->wp = wp; - /* - * Initialize CEC clock divider: CEC needs 2MHz clock hence - * set the devider to 24 to get 48/24=2MHz clock - */ - REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0); + /* Disable clock initially, hdmi_cec_adap_enable() manages it */ + REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0, 5, 0); ret = cec_register_adapter(core->adap, &pdev->dev); if (ret < 0) { -- cgit v1.2.3 From ad51c46eec739c18be24178a30b47801b10e0357 Mon Sep 17 00:00:00 2001 From: Chengming Gui Date: Thu, 21 Mar 2019 13:26:28 +0800 Subject: drm/amd/amdgpu: fix PCIe dpm feature issue (v3) use pcie_bandwidth_available to get real link state to update pcie table. v2: fix incorrect initialized return value v3: expand the fetching method about the link width to all asics. Signed-off-by: Chengming Gui Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 4f8fb4ecde34..ac0d646a7b74 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3625,6 +3625,7 @@ static void amdgpu_device_get_min_pci_speed_width(struct amdgpu_device *adev, struct pci_dev *pdev = adev->pdev; enum pci_bus_speed cur_speed; enum pcie_link_width cur_width; + u32 ret = 1; *speed = PCI_SPEED_UNKNOWN; *width = PCIE_LNK_WIDTH_UNKNOWN; @@ -3632,6 +3633,10 @@ static void amdgpu_device_get_min_pci_speed_width(struct amdgpu_device *adev, while (pdev) { cur_speed = pcie_get_speed_cap(pdev); cur_width = pcie_get_width_cap(pdev); + ret = pcie_bandwidth_available(adev->pdev, NULL, + NULL, &cur_width); + if (!ret) + cur_width = PCIE_LNK_WIDTH_RESRV; if (cur_speed != PCI_SPEED_UNKNOWN) { if (*speed == PCI_SPEED_UNKNOWN) -- cgit v1.2.3 From 6f5d29ff1a643d52128efb4b6c4f4d4074e32e10 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Sat, 23 Mar 2019 01:02:44 +0800 Subject: drm/amd/powerplay: add ECC feature bit It's OK to have this feature bit with old SMU firmwares. But the feature should be disabled on them. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 10 +++++++++- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h | 1 + drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 9aa7bec1b5fe..5e3ffcc5b14a 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -91,6 +91,12 @@ static void vega20_set_default_registry_data(struct pp_hwmgr *hwmgr) * MP0CLK DS */ data->registry_data.disallowed_features = 0xE0041C00; + /* ECC feature should be disabled on old SMUs */ + smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion); + hwmgr->smu_version = smum_get_argument(hwmgr); + if (hwmgr->smu_version < 0x282100) + data->registry_data.disallowed_features |= FEATURE_ECC_MASK; + data->registry_data.od_state_in_dc_support = 0; data->registry_data.thermal_support = 1; data->registry_data.skip_baco_hardware = 0; @@ -357,6 +363,7 @@ static void vega20_init_dpm_defaults(struct pp_hwmgr *hwmgr) data->smu_features[GNLD_DS_MP1CLK].smu_feature_id = FEATURE_DS_MP1CLK_BIT; data->smu_features[GNLD_DS_MP0CLK].smu_feature_id = FEATURE_DS_MP0CLK_BIT; data->smu_features[GNLD_XGMI].smu_feature_id = FEATURE_XGMI_BIT; + data->smu_features[GNLD_ECC].smu_feature_id = FEATURE_ECC_BIT; for (i = 0; i < GNLD_FEATURES_MAX; i++) { data->smu_features[i].smu_feature_bitmap = @@ -3020,7 +3027,8 @@ static int vega20_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf) "FCLK_DS", "MP1CLK_DS", "MP0CLK_DS", - "XGMI"}; + "XGMI", + "ECC"}; static const char *output_title[] = { "FEATURES", "BITMASK", diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h index a5bc758ae097..ac2a3118a0ae 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h @@ -80,6 +80,7 @@ enum { GNLD_DS_MP1CLK, GNLD_DS_MP0CLK, GNLD_XGMI, + GNLD_ECC, GNLD_FEATURES_MAX }; diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h index 63d5cf691549..b90089a4fb6a 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h @@ -99,7 +99,7 @@ #define FEATURE_DS_MP1CLK_BIT 30 #define FEATURE_DS_MP0CLK_BIT 31 #define FEATURE_XGMI_BIT 32 -#define FEATURE_SPARE_33_BIT 33 +#define FEATURE_ECC_BIT 33 #define FEATURE_SPARE_34_BIT 34 #define FEATURE_SPARE_35_BIT 35 #define FEATURE_SPARE_36_BIT 36 @@ -166,6 +166,7 @@ #define FEATURE_DS_MP1CLK_MASK (1 << FEATURE_DS_MP1CLK_BIT ) #define FEATURE_DS_MP0CLK_MASK (1 << FEATURE_DS_MP0CLK_BIT ) #define FEATURE_XGMI_MASK (1 << FEATURE_XGMI_BIT ) +#define FEATURE_ECC_MASK (1ULL << FEATURE_ECC_BIT ) #define DPM_OVERRIDE_DISABLE_SOCCLK_PID 0x00000001 #define DPM_OVERRIDE_DISABLE_UCLK_PID 0x00000002 -- cgit v1.2.3 From aaaba51bf1618958c91728607c63264655c545ef Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Sat, 23 Mar 2019 02:02:24 +0800 Subject: drm/amd/powerplay: correct data type to avoid overflow Avoid left shift overflow. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h index b90089a4fb6a..195c4ae67058 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu11_driver_if.h @@ -165,7 +165,7 @@ #define FEATURE_DS_FCLK_MASK (1 << FEATURE_DS_FCLK_BIT ) #define FEATURE_DS_MP1CLK_MASK (1 << FEATURE_DS_MP1CLK_BIT ) #define FEATURE_DS_MP0CLK_MASK (1 << FEATURE_DS_MP0CLK_BIT ) -#define FEATURE_XGMI_MASK (1 << FEATURE_XGMI_BIT ) +#define FEATURE_XGMI_MASK (1ULL << FEATURE_XGMI_BIT ) #define FEATURE_ECC_MASK (1ULL << FEATURE_ECC_BIT ) #define DPM_OVERRIDE_DISABLE_SOCCLK_PID 0x00000001 -- cgit v1.2.3 From db64a2f43c1bc22c5ff2d22606000b8c3587d0ec Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Tue, 26 Mar 2019 17:57:53 +0800 Subject: drm/amd/powerplay: fix possible hang with 3+ 4K monitors If DAL requires to force MCLK high, the FCLK will be forced to high also. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 5e3ffcc5b14a..23b5b94a4939 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -3470,6 +3470,7 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr) struct vega20_single_dpm_table *dpm_table; bool vblank_too_short = false; bool disable_mclk_switching; + bool disable_fclk_switching; uint32_t i, latency; disable_mclk_switching = ((1 < hwmgr->display_config->num_display) && @@ -3545,13 +3546,20 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr) if (hwmgr->display_config->nb_pstate_switch_disable) dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; + if ((disable_mclk_switching && + (dpm_table->dpm_state.hard_min_level == dpm_table->dpm_levels[dpm_table->count - 1].value)) || + hwmgr->display_config->min_mem_set_clock / 100 >= dpm_table->dpm_levels[dpm_table->count - 1].value) + disable_fclk_switching = true; + else + disable_fclk_switching = false; + /* fclk */ dpm_table = &(data->dpm_table.fclk_table); dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.soft_max_level = VG20_CLOCK_MAX_DEFAULT; dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[0].value; dpm_table->dpm_state.hard_max_level = VG20_CLOCK_MAX_DEFAULT; - if (hwmgr->display_config->nb_pstate_switch_disable) + if (hwmgr->display_config->nb_pstate_switch_disable || disable_fclk_switching) dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; /* vclk */ -- cgit v1.2.3 From ab0cb022c8fd6f465f40f1cbee7d71c6280b6c74 Mon Sep 17 00:00:00 2001 From: Paul Hsieh Date: Mon, 18 Mar 2019 18:04:05 +0800 Subject: drm/amd/display: VBIOS can't be light up HDMI when restart system [Why] VBIOS will not post pixel rate > 340MHz. If driver set pixel rate > 340MHz and do restart bottom, VBIOS can't post HDMI monitor due to monitor is stay in HDMI2.0 state. [How] Program Scrambling_Enable and TMDS_Bit_Clock_Ratio when disable stream. Signed-off-by: Paul Hsieh Reviewed-by: Charlene Liu Acked-by: Bhawanpreet Lakha Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 4eba3c4800b6..ea18e9c2d8ce 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2660,12 +2660,18 @@ void core_link_enable_stream( void core_link_disable_stream(struct pipe_ctx *pipe_ctx, int option) { struct dc *core_dc = pipe_ctx->stream->ctx->dc; + struct dc_stream_state *stream = pipe_ctx->stream; core_dc->hwss.blank_stream(pipe_ctx); if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) deallocate_mst_payload(pipe_ctx); + if (dc_is_hdmi_signal(pipe_ctx->stream->signal)) + dal_ddc_service_write_scdc_data( + stream->link->ddc, 0, + stream->timing.flags.LTE_340MCSC_SCRAMBLE); + core_dc->hwss.disable_stream(pipe_ctx, option); disable_link(pipe_ctx->stream->link, pipe_ctx->stream->signal); -- cgit v1.2.3 From 26cdaac4793c49357d2c731f2190632cefb7efb1 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 26 Mar 2019 16:02:23 -0700 Subject: drm/i915/icl: Fix VEBOX mismatch BUG_ON() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GT VEBOX DISABLE is only 4 bits wide but it was using a 8 bits wide mask, the remaning reserved bits is set to 0 causing 4 more nonexistent VEBOX engines being detected as enabled, triggering the BUG_ON() because of mismatch between vebox_mask and newly added VEBOX_MASK(). [ 64.081621] [drm:intel_device_info_init_mmio [i915]] vdbox enable: 0005, instances: 0005 [ 64.081763] [drm:intel_device_info_init_mmio [i915]] vebox enable: 00f1, instances: 0001 [ 64.081825] intel_device_info_init_mmio:925 GEM_BUG_ON(vebox_mask != ({ unsigned int first__ = (VECS0); unsigned int count__ = (2); ((&(dev_priv)->__info)->engine_mask & (((~0UL) - (1UL << (first__)) + 1) & (~0UL >> (64 - 1 - (first__ + count__ - 1))))) >> first__; })) [ 64.082047] ------------[ cut here ]------------ [ 64.082054] kernel BUG at drivers/gpu/drm/i915/intel_device_info.c:925! BSpec: 20680 Fixes: 26376a7e74d2 ("drm/i915/icl: Check for fused-off VDBOX and VEBOX instances") Cc: Chris Wilson Cc: Tvrtko Ursulin Cc: Oscar Mateo Signed-off-by: José Roberto de Souza Reviewed-by: Tvrtko Ursulin Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190326230223.26336-1-jose.souza@intel.com (cherry picked from commit 547fcf9b1c608cf5c43c156a8773a94c6a38dc44) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 684589acc368..047855dd8c6b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2863,7 +2863,7 @@ enum i915_power_well_id { #define GEN11_GT_VEBOX_VDBOX_DISABLE _MMIO(0x9140) #define GEN11_GT_VDBOX_DISABLE_MASK 0xff #define GEN11_GT_VEBOX_DISABLE_SHIFT 16 -#define GEN11_GT_VEBOX_DISABLE_MASK (0xff << GEN11_GT_VEBOX_DISABLE_SHIFT) +#define GEN11_GT_VEBOX_DISABLE_MASK (0x0f << GEN11_GT_VEBOX_DISABLE_SHIFT) #define GEN11_EU_DISABLE _MMIO(0x9134) #define GEN11_EU_DIS_MASK 0xFF -- cgit v1.2.3 From e0510da051920e6edbfdff1305b85d6c1e209a1b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:36 +0200 Subject: drm/i915: Extract check_luts() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In prepartion for per-platform color_check() functions extract the common code into a separate function. v2: Improve the C8 comment (Matt) Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 68 ++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 28 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 467fd1a1630c..5d1bf68646b4 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -771,6 +771,38 @@ static int check_lut_size(const struct drm_property_blob *lut, int expected) return 0; } +static int check_luts(const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); + const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; + const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut; + int gamma_length, degamma_length; + u32 gamma_tests, degamma_tests; + + /* Always allow legacy gamma LUT with no further checking. */ + if (crtc_state_is_legacy_gamma(crtc_state)) + return 0; + + /* C8 relies on its palette being stored in the legacy LUT */ + if (crtc_state->c8_planes) + return -EINVAL; + + degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size; + gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size; + degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests; + gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests; + + if (check_lut_size(degamma_lut, degamma_length) || + check_lut_size(gamma_lut, gamma_length)) + return -EINVAL; + + if (drm_color_lut_check(degamma_lut, degamma_tests) || + drm_color_lut_check(gamma_lut, gamma_tests)) + return -EINVAL; + + return 0; +} + static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state) { u32 cgm_mode = 0; @@ -794,19 +826,11 @@ int intel_color_check(struct intel_crtc_state *crtc_state) const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut; bool limited_color_range = false; - int gamma_length, degamma_length; - u32 gamma_tests, degamma_tests; int ret; - degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size; - gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size; - degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests; - gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests; - - /* C8 needs the legacy LUT all to itself */ - if (crtc_state->c8_planes && - !crtc_state_is_legacy_gamma(crtc_state)) - return -EINVAL; + ret = check_luts(crtc_state); + if (ret) + return ret; crtc_state->gamma_enable = (gamma_lut || degamma_lut) && !crtc_state->c8_planes; @@ -828,25 +852,10 @@ int intel_color_check(struct intel_crtc_state *crtc_state) if (IS_CHERRYVIEW(dev_priv)) crtc_state->cgm_mode = chv_cgm_mode(crtc_state); - /* Always allow legacy gamma LUT with no further checking. */ if (!crtc_state->gamma_enable || - crtc_state_is_legacy_gamma(crtc_state)) { + crtc_state_is_legacy_gamma(crtc_state)) crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; - if (INTEL_GEN(dev_priv) >= 11 && - crtc_state->gamma_enable) - crtc_state->gamma_mode |= POST_CSC_GAMMA_ENABLE; - return 0; - } - - if (check_lut_size(degamma_lut, degamma_length) || - check_lut_size(gamma_lut, gamma_length)) - return -EINVAL; - - if (drm_color_lut_check(degamma_lut, degamma_tests) || - drm_color_lut_check(gamma_lut, gamma_tests)) - return -EINVAL; - - if (INTEL_GEN(dev_priv) >= 11) + else if (INTEL_GEN(dev_priv) >= 11) crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT | PRE_CSC_GAMMA_ENABLE | POST_CSC_GAMMA_ENABLE; @@ -858,6 +867,9 @@ int intel_color_check(struct intel_crtc_state *crtc_state) crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; if (INTEL_GEN(dev_priv) >= 11) { + if (crtc_state->gamma_enable) + crtc_state->gamma_mode |= POST_CSC_GAMMA_ENABLE; + if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || crtc_state->limited_color_range) crtc_state->csc_mode |= ICL_OUTPUT_CSC_ENABLE; -- cgit v1.2.3 From 9d9cb9c18c7019a6e740af3b29eb19610733d763 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:37 +0200 Subject: drm/i915: Turn intel_color_check() into a vfunc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current intel_color_check() is a mess, and worse yet it is in fact incorrect for several platforms. The hardware has evolved quite a bit over the years, so let's just go for a clean split between the platforms by turning this into a vfunc. The actual work to split it up will follow. v2: Assign the vfuncs in the order they appear in the struct (Matt) Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_color.c | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 25c264e55d3c..a32bfc7ec5ea 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -325,6 +325,7 @@ struct drm_i915_display_funcs { /* display clock increase/decrease */ /* pll clock increase/decrease */ + int (*color_check)(struct intel_crtc_state *crtc_state); /* * Program double buffered color management registers during * vblank evasion. The registers should then latch during the diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 5d1bf68646b4..c6eb7eb323a0 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -704,6 +704,13 @@ void intel_color_commit(const struct intel_crtc_state *crtc_state) dev_priv->display.color_commit(crtc_state); } +int intel_color_check(struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); + + return dev_priv->display.color_check(crtc_state); +} + static bool need_plane_update(struct intel_plane *plane, const struct intel_crtc_state *crtc_state) { @@ -820,7 +827,7 @@ static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state) return cgm_mode; } -int intel_color_check(struct intel_crtc_state *crtc_state) +static int _intel_color_check(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; @@ -888,13 +895,23 @@ void intel_color_init(struct intel_crtc *crtc) drm_mode_crtc_set_gamma_size(&crtc->base, 256); if (HAS_GMCH(dev_priv)) { + dev_priv->display.color_check = _intel_color_check; + dev_priv->display.color_commit = i9xx_color_commit; + if (IS_CHERRYVIEW(dev_priv)) dev_priv->display.load_luts = cherryview_load_luts; else dev_priv->display.load_luts = i9xx_load_luts; - - dev_priv->display.color_commit = i9xx_color_commit; } else { + dev_priv->display.color_check = _intel_color_check; + + if (INTEL_GEN(dev_priv) >= 9) + dev_priv->display.color_commit = skl_color_commit; + else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + dev_priv->display.color_commit = hsw_color_commit; + else + dev_priv->display.color_commit = ilk_color_commit; + if (INTEL_GEN(dev_priv) >= 11) dev_priv->display.load_luts = icl_load_luts; else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) @@ -903,13 +920,6 @@ void intel_color_init(struct intel_crtc *crtc) dev_priv->display.load_luts = broadwell_load_luts; else dev_priv->display.load_luts = i9xx_load_luts; - - if (INTEL_GEN(dev_priv) >= 9) - dev_priv->display.color_commit = skl_color_commit; - else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - dev_priv->display.color_commit = hsw_color_commit; - else - dev_priv->display.color_commit = ilk_color_commit; } /* Enable color management support when we have degamma & gamma LUTs. */ -- cgit v1.2.3 From e98f35624ca4a477c9f526196c1338e46c18abd1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:38 +0200 Subject: drm/i915: Extract i9xx_color_check() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apart from CHV the other gmch platforms don't currently require much work in .color_check(). So let's start by extracting i9xx_color_check(). Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-4-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index c6eb7eb323a0..cdd5eccb767b 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -810,6 +810,27 @@ static int check_luts(const struct intel_crtc_state *crtc_state) return 0; } +static int i9xx_color_check(struct intel_crtc_state *crtc_state) +{ + int ret; + + ret = check_luts(crtc_state); + if (ret) + return ret; + + crtc_state->gamma_enable = + crtc_state->base.gamma_lut && + !crtc_state->c8_planes; + + crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; + + ret = intel_color_add_affected_planes(crtc_state); + if (ret) + return ret; + + return 0; +} + static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state) { u32 cgm_mode = 0; @@ -895,13 +916,15 @@ void intel_color_init(struct intel_crtc *crtc) drm_mode_crtc_set_gamma_size(&crtc->base, 256); if (HAS_GMCH(dev_priv)) { - dev_priv->display.color_check = _intel_color_check; - dev_priv->display.color_commit = i9xx_color_commit; - - if (IS_CHERRYVIEW(dev_priv)) + if (IS_CHERRYVIEW(dev_priv)) { + dev_priv->display.color_check = _intel_color_check; + dev_priv->display.color_commit = i9xx_color_commit; dev_priv->display.load_luts = cherryview_load_luts; - else + } else { + dev_priv->display.color_check = i9xx_color_check; + dev_priv->display.color_commit = i9xx_color_commit; dev_priv->display.load_luts = i9xx_load_luts; + } } else { dev_priv->display.color_check = _intel_color_check; -- cgit v1.2.3 From 3cdd5174cfc6d5ddc73913d507a08b14cb947764 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:39 +0200 Subject: drm/i915: Extract chv_color_check() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since CHV has the CGM unit we require a custom implementation of .color_check(). This fixes the computation of gamma_enable as previously we left it enabled even when were using the CGM gamma instead. Now we turn off the legacy LUT unless it's actually required. v2: Add some comment explaining the color pipeline (Matt) Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-5-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 40 ++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index cdd5eccb767b..87cc204a1dbf 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -848,6 +848,41 @@ static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state) return cgm_mode; } +/* + * CHV color pipeline: + * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma -> + * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10 + * + * We always bypass the WGC csc and use the CGM csc + * instead since it has degamma and better precision. + */ +static int chv_color_check(struct intel_crtc_state *crtc_state) +{ + int ret; + + ret = check_luts(crtc_state); + if (ret) + return ret; + + /* + * Pipe gamma will be used only for the legacy LUT. + * Otherwise we bypass it and use the CGM gamma instead. + */ + crtc_state->gamma_enable = + crtc_state_is_legacy_gamma(crtc_state) && + !crtc_state->c8_planes; + + crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; + + crtc_state->cgm_mode = chv_cgm_mode(crtc_state); + + ret = intel_color_add_affected_planes(crtc_state); + if (ret) + return ret; + + return 0; +} + static int _intel_color_check(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); @@ -877,9 +912,6 @@ static int _intel_color_check(struct intel_crtc_state *crtc_state) crtc_state->csc_mode = 0; - if (IS_CHERRYVIEW(dev_priv)) - crtc_state->cgm_mode = chv_cgm_mode(crtc_state); - if (!crtc_state->gamma_enable || crtc_state_is_legacy_gamma(crtc_state)) crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; @@ -917,7 +949,7 @@ void intel_color_init(struct intel_crtc *crtc) if (HAS_GMCH(dev_priv)) { if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.color_check = _intel_color_check; + dev_priv->display.color_check = chv_color_check; dev_priv->display.color_commit = i9xx_color_commit; dev_priv->display.load_luts = cherryview_load_luts; } else { -- cgit v1.2.3 From 1b386cf84931a75676d3d14c4868929c0296d6c1 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:40 +0200 Subject: drm/i915: Extract icl_color_check() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ICL is rather easy when it comes to .color_check() as it finally provides us with a full color pipeline with individual knobs for each stage. We'll also start bypassing each LUT individually when it is not needed. Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-6-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 70 +++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 17 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 87cc204a1dbf..cb40c89da038 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -883,6 +883,55 @@ static int chv_color_check(struct intel_crtc_state *crtc_state) return 0; } +static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state) +{ + u32 gamma_mode = 0; + + if (crtc_state->base.degamma_lut) + gamma_mode |= PRE_CSC_GAMMA_ENABLE; + + if (crtc_state->base.gamma_lut && + !crtc_state->c8_planes) + gamma_mode |= POST_CSC_GAMMA_ENABLE; + + if (!crtc_state->base.gamma_lut || + crtc_state_is_legacy_gamma(crtc_state)) + gamma_mode |= GAMMA_MODE_MODE_8BIT; + else + gamma_mode |= GAMMA_MODE_MODE_10BIT; + + return gamma_mode; +} + +static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state) +{ + u32 csc_mode = 0; + + if (crtc_state->base.ctm) + csc_mode |= ICL_CSC_ENABLE; + + if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || + crtc_state->limited_color_range) + csc_mode |= ICL_OUTPUT_CSC_ENABLE; + + return csc_mode; +} + +static int icl_color_check(struct intel_crtc_state *crtc_state) +{ + int ret; + + ret = check_luts(crtc_state); + if (ret) + return ret; + + crtc_state->gamma_mode = icl_gamma_mode(crtc_state); + + crtc_state->csc_mode = icl_csc_mode(crtc_state); + + return 0; +} + static int _intel_color_check(struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); @@ -915,10 +964,6 @@ static int _intel_color_check(struct intel_crtc_state *crtc_state) if (!crtc_state->gamma_enable || crtc_state_is_legacy_gamma(crtc_state)) crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; - else if (INTEL_GEN(dev_priv) >= 11) - crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT | - PRE_CSC_GAMMA_ENABLE | - POST_CSC_GAMMA_ENABLE; else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT; else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) @@ -926,18 +971,6 @@ static int _intel_color_check(struct intel_crtc_state *crtc_state) else crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; - if (INTEL_GEN(dev_priv) >= 11) { - if (crtc_state->gamma_enable) - crtc_state->gamma_mode |= POST_CSC_GAMMA_ENABLE; - - if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || - crtc_state->limited_color_range) - crtc_state->csc_mode |= ICL_OUTPUT_CSC_ENABLE; - - if (crtc_state->base.ctm) - crtc_state->csc_mode |= ICL_CSC_ENABLE; - } - return 0; } @@ -958,7 +991,10 @@ void intel_color_init(struct intel_crtc *crtc) dev_priv->display.load_luts = i9xx_load_luts; } } else { - dev_priv->display.color_check = _intel_color_check; + if (INTEL_GEN(dev_priv) >= 11) + dev_priv->display.color_check = icl_color_check; + else + dev_priv->display.color_check = _intel_color_check; if (INTEL_GEN(dev_priv) >= 9) dev_priv->display.color_commit = skl_color_commit; -- cgit v1.2.3 From fbeb4f36221358f01c9608b959b8d542e7becae6 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:41 +0200 Subject: drm/i915: Extract glk_color_check() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlike the earlier platforms GLK has dedicated degamma and gamma LUTs. And quite curiously the degamma LUT is actually controlled via the PLANE_COLOR_CTL CSC enable bit. Hence we must compute gamma_enable and csc_enable differently to pre-GLK platforms. Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-7-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index cb40c89da038..90ebcf7bef82 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -883,6 +883,44 @@ static int chv_color_check(struct intel_crtc_state *crtc_state) return 0; } +static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state) +{ + if (!crtc_state->gamma_enable || + crtc_state_is_legacy_gamma(crtc_state)) + return GAMMA_MODE_MODE_8BIT; + else + return GAMMA_MODE_MODE_10BIT; +} + +static int glk_color_check(struct intel_crtc_state *crtc_state) +{ + int ret; + + ret = check_luts(crtc_state); + if (ret) + return ret; + + crtc_state->gamma_enable = + crtc_state->base.gamma_lut && + !crtc_state->c8_planes; + + /* On GLK+ degamma LUT is controlled by csc_enable */ + crtc_state->csc_enable = + crtc_state->base.degamma_lut || + crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || + crtc_state->base.ctm || crtc_state->limited_color_range; + + crtc_state->gamma_mode = glk_gamma_mode(crtc_state); + + crtc_state->csc_mode = 0; + + ret = intel_color_add_affected_planes(crtc_state); + if (ret) + return ret; + + return 0; +} + static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state) { u32 gamma_mode = 0; @@ -993,6 +1031,8 @@ void intel_color_init(struct intel_crtc *crtc) } else { if (INTEL_GEN(dev_priv) >= 11) dev_priv->display.color_check = icl_color_check; + else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) + dev_priv->display.color_check = glk_color_check; else dev_priv->display.color_check = _intel_color_check; -- cgit v1.2.3 From 1eb6315611209dbb81c626a0d8e6fa32a6b42609 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:42 +0200 Subject: drm/i915: Extract bdw_color_check() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide a separate .color_check() for BDW+ where we currently provide the split gamma mode etc. Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-8-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 90ebcf7bef82..d9be011ae49a 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -883,6 +883,43 @@ static int chv_color_check(struct intel_crtc_state *crtc_state) return 0; } +static u32 bdw_gamma_mode(const struct intel_crtc_state *crtc_state) +{ + if (!crtc_state->gamma_enable || + crtc_state_is_legacy_gamma(crtc_state)) + return GAMMA_MODE_MODE_8BIT; + else + return GAMMA_MODE_MODE_SPLIT; +} + +static int bdw_color_check(struct intel_crtc_state *crtc_state) +{ + int ret; + + ret = check_luts(crtc_state); + if (ret) + return ret; + + crtc_state->gamma_enable = + (crtc_state->base.gamma_lut || + crtc_state->base.degamma_lut) && + !crtc_state->c8_planes; + + crtc_state->csc_enable = + crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || + crtc_state->base.ctm || crtc_state->limited_color_range; + + crtc_state->gamma_mode = bdw_gamma_mode(crtc_state); + + crtc_state->csc_mode = 0; + + ret = intel_color_add_affected_planes(crtc_state); + if (ret) + return ret; + + return 0; +} + static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state) { if (!crtc_state->gamma_enable || @@ -1033,6 +1070,8 @@ void intel_color_init(struct intel_crtc *crtc) dev_priv->display.color_check = icl_color_check; else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) dev_priv->display.color_check = glk_color_check; + else if (INTEL_GEN(dev_priv) >= 8) + dev_priv->display.color_check = bdw_color_check; else dev_priv->display.color_check = _intel_color_check; -- cgit v1.2.3 From f65d5528c023752d058c6cdce6e656740c858c42 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:43 +0200 Subject: drm/i915: Extract ilk_color_check() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With everything else moved out of the way only ilk+ remains using _intel_color_check(). Streamline the logic into ilk_color_check(). v2: Add some comments explaining we that we don't expose the full hardware capabilities currently (Matt) Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-9-ville.syrjala@linux.intel.com Reviewed-by: Matt Roper --- drivers/gpu/drm/i915/intel_color.c | 76 +++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 43 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index d9be011ae49a..66e2b7d48410 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -883,6 +883,38 @@ static int chv_color_check(struct intel_crtc_state *crtc_state) return 0; } +static int ilk_color_check(struct intel_crtc_state *crtc_state) +{ + int ret; + + ret = check_luts(crtc_state); + if (ret) + return ret; + + crtc_state->gamma_enable = + crtc_state->base.gamma_lut && + !crtc_state->c8_planes; + + /* + * We don't expose the ctm on ilk-hsw currently, + * nor do we enable YCbCr output. Only hsw uses + * the csc for RGB limited range output. + */ + crtc_state->csc_enable = + ilk_csc_limited_range(crtc_state); + + /* We don't expose fancy gamma modes on ilk-hsw currently */ + crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; + + crtc_state->csc_mode = 0; + + ret = intel_color_add_affected_planes(crtc_state); + if (ret) + return ret; + + return 0; +} + static u32 bdw_gamma_mode(const struct intel_crtc_state *crtc_state) { if (!crtc_state->gamma_enable || @@ -1007,48 +1039,6 @@ static int icl_color_check(struct intel_crtc_state *crtc_state) return 0; } -static int _intel_color_check(struct intel_crtc_state *crtc_state) -{ - struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev); - const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; - const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut; - bool limited_color_range = false; - int ret; - - ret = check_luts(crtc_state); - if (ret) - return ret; - - crtc_state->gamma_enable = (gamma_lut || degamma_lut) && - !crtc_state->c8_planes; - - if (INTEL_GEN(dev_priv) >= 9 || - IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - limited_color_range = crtc_state->limited_color_range; - - crtc_state->csc_enable = - crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || - crtc_state->base.ctm || limited_color_range; - - ret = intel_color_add_affected_planes(crtc_state); - if (ret) - return ret; - - crtc_state->csc_mode = 0; - - if (!crtc_state->gamma_enable || - crtc_state_is_legacy_gamma(crtc_state)) - crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; - else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) - crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT; - else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) - crtc_state->gamma_mode = GAMMA_MODE_MODE_SPLIT; - else - crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; - - return 0; -} - void intel_color_init(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -1073,7 +1063,7 @@ void intel_color_init(struct intel_crtc *crtc) else if (INTEL_GEN(dev_priv) >= 8) dev_priv->display.color_check = bdw_color_check; else - dev_priv->display.color_check = _intel_color_check; + dev_priv->display.color_check = ilk_color_check; if (INTEL_GEN(dev_priv) >= 9) dev_priv->display.color_commit = skl_color_commit; -- cgit v1.2.3 From c25abff511ad058e473c663286463a41bfc968f5 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:44 +0200 Subject: drm/i915: Drop the pointless linear legacy LUT load on CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now bypass the legacy LUT when it's not needed, so no point in filling it up with a linear LUT. Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-10-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 66e2b7d48410..8d8fca7b5d65 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -376,15 +376,6 @@ static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state, (drm_color_lut_extract(lut[i].green, 8) << 8) | drm_color_lut_extract(lut[i].blue, 8); - if (HAS_GMCH(dev_priv)) - I915_WRITE(PALETTE(pipe, i), word); - else - I915_WRITE(LGC_PALETTE(pipe, i), word); - } - } else { - for (i = 0; i < 256; i++) { - u32 word = (i << 16) | (i << 8) | i; - if (HAS_GMCH(dev_priv)) I915_WRITE(PALETTE(pipe, i), word); else @@ -643,7 +634,7 @@ static void cherryview_load_luts(const struct intel_crtc_state *crtc_state) cherryview_load_csc_matrix(crtc_state); if (crtc_state_is_legacy_gamma(crtc_state)) { - i9xx_load_luts_internal(crtc_state, gamma_lut); + i9xx_load_luts(crtc_state); return; } @@ -682,12 +673,6 @@ static void cherryview_load_luts(const struct intel_crtc_state *crtc_state) I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1), word1); } } - - /* - * Also program a linear LUT in the legacy block (behind the - * CGM block). - */ - i9xx_load_luts_internal(crtc_state, NULL); } void intel_color_load_luts(const struct intel_crtc_state *crtc_state) -- cgit v1.2.3 From c4128ce7d59e811e3b229ac17bc67a6699cc525b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 17:50:45 +0200 Subject: drm/i915: Skip the linear degamma LUT load on ICL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't load the linear degamma LUT on ICL. The hardware no longer has any silly linkages between the CSC enable and degamma LUT enable so the degamma LUT is only needed when it's actually enabled. Also add comments to explain the situation on GLK. v2: Drop useless parens around 1<<16 v3: Add missing const Signed-off-by: Ville Syrjälä Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20190327155045.28446-11-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_color.c | 91 +++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 27 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 8d8fca7b5d65..ff910ed08468 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -273,6 +273,14 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state) ilk_csc_coeff_limited_range, ilk_csc_postoff_limited_range); } else if (crtc_state->csc_enable) { + /* + * On GLK+ both pipe CSC and degamma LUT are controlled + * by csc_enable. Hence for the cases where the degama + * LUT is needed but CSC is not we need to load an + * identity matrix. + */ + WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv)); + ilk_update_pipe_csc(crtc, ilk_csc_off_zero, ilk_csc_coeff_identity, ilk_csc_off_zero); @@ -559,6 +567,7 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state) struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size; + const struct drm_color_lut *lut = crtc_state->base.degamma_lut->data; u32 i; /* @@ -569,42 +578,69 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state) I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0); I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT); - if (crtc_state->base.degamma_lut) { - struct drm_color_lut *lut = crtc_state->base.degamma_lut->data; + for (i = 0; i < lut_size; i++) { + /* + * First 33 entries represent range from 0 to 1.0 + * 34th and 35th entry will represent extended range + * inputs 3.0 and 7.0 respectively, currently clamped + * at 1.0. Since the precision is 16bit, the user + * value can be directly filled to register. + * The pipe degamma table in GLK+ onwards doesn't + * support different values per channel, so this just + * programs green value which will be equal to Red and + * Blue into the lut registers. + * ToDo: Extend to max 7.0. Enable 32 bit input value + * as compared to just 16 to achieve this. + */ + I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green); + } - for (i = 0; i < lut_size; i++) { - /* - * First 33 entries represent range from 0 to 1.0 - * 34th and 35th entry will represent extended range - * inputs 3.0 and 7.0 respectively, currently clamped - * at 1.0. Since the precision is 16bit, the user - * value can be directly filled to register. - * The pipe degamma table in GLK+ onwards doesn't - * support different values per channel, so this just - * programs green value which will be equal to Red and - * Blue into the lut registers. - * ToDo: Extend to max 7.0. Enable 32 bit input value - * as compared to just 16 to achieve this. - */ - I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green); - } - } else { - /* load a linear table. */ - for (i = 0; i < lut_size; i++) { - u32 v = (i * (1 << 16)) / (lut_size - 1); + /* Clamp values > 1.0. */ + while (i++ < 35) + I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16); +} - I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v); - } +static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum pipe pipe = crtc->pipe; + const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size; + u32 i; + + /* + * When setting the auto-increment bit, the hardware seems to + * ignore the index bits, so we need to reset it to index 0 + * separately. + */ + I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0); + I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT); + + for (i = 0; i < lut_size; i++) { + u32 v = (i << 16) / (lut_size - 1); + + I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v); } /* Clamp values > 1.0. */ while (i++ < 35) - I915_WRITE(PRE_CSC_GAMC_DATA(pipe), (1 << 16)); + I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16); } static void glk_load_luts(const struct intel_crtc_state *crtc_state) { - glk_load_degamma_lut(crtc_state); + /* + * On GLK+ both pipe CSC and degamma LUT are controlled + * by csc_enable. Hence for the cases where the CSC is + * needed but degamma LUT is not we need to load a + * linear degamma LUT. In fact we'll just always load + * the degama LUT so that we don't have to reload + * it every time the pipe CSC is being enabled. + */ + if (crtc_state->base.degamma_lut) + glk_load_degamma_lut(crtc_state); + else + glk_load_degamma_lut_linear(crtc_state); if (crtc_state_is_legacy_gamma(crtc_state)) i9xx_load_luts(crtc_state); @@ -614,7 +650,8 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) static void icl_load_luts(const struct intel_crtc_state *crtc_state) { - glk_load_degamma_lut(crtc_state); + if (crtc_state->base.degamma_lut) + glk_load_degamma_lut(crtc_state); if (crtc_state_is_legacy_gamma(crtc_state)) i9xx_load_luts(crtc_state); -- cgit v1.2.3 From dade58ed5af6365ac50ff4259c2a0bf31219e285 Mon Sep 17 00:00:00 2001 From: Yan Zhao Date: Wed, 27 Mar 2019 00:54:51 -0400 Subject: drm/i915/gvt: do not deliver a workload if its creation fails in workload creation routine, if any failure occurs, do not queue this workload for delivery. if this failure is fatal, enter into failsafe mode. Fixes: 6d76303553ba ("drm/i915/gvt: Move common vGPU workload creation into scheduler.c") Cc: stable@vger.kernel.org #4.19+ Cc: zhenyuw@linux.intel.com Signed-off-by: Yan Zhao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/scheduler.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 159192c097cc..05b953793316 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -1486,8 +1486,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, intel_runtime_pm_put_unchecked(dev_priv); } - if (ret && (vgpu_is_vm_unhealthy(ret))) { - enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR); + if (ret) { + if (vgpu_is_vm_unhealthy(ret)) + enter_failsafe_mode(vgpu, GVT_FAILSAFE_GUEST_ERR); intel_vgpu_destroy_workload(workload); return ERR_PTR(ret); } -- cgit v1.2.3 From 663a50ceac75c2208d2ad95365bc8382fd42f44d Mon Sep 17 00:00:00 2001 From: Yan Zhao Date: Wed, 27 Mar 2019 00:55:45 -0400 Subject: drm/i915/gvt: do not let pin count of shadow mm go negative shadow mm's pin count got increased in workload preparation phase, which is after workload scanning. it will get decreased in complete_current_workload() anyway after workload completion. Sometimes, if a workload meets a scanning error, its shadow mm pin count will not get increased but will get decreased in the end. This patch lets shadow mm's pin count not go below 0. Fixes: 2707e4446688 ("drm/i915/gvt: vGPU graphics memory virtualization") Cc: zhenyuw@linux.intel.com Cc: stable@vger.kernel.org #4.14+ Signed-off-by: Yan Zhao Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index d7052ab7908c..cf133ef03873 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -1946,7 +1946,7 @@ void _intel_vgpu_mm_release(struct kref *mm_ref) */ void intel_vgpu_unpin_mm(struct intel_vgpu_mm *mm) { - atomic_dec(&mm->pincount); + atomic_dec_if_positive(&mm->pincount); } /** -- cgit v1.2.3 From 43226e6fe798b7ede55027a25f97fd73b940ce7d Mon Sep 17 00:00:00 2001 From: Xiaolin Zhang Date: Wed, 20 Mar 2019 13:14:03 -0400 Subject: drm/i915/gvt: replaced register address with name in init_skil_mmio_info, replaced register address with the known name from i915_reg.h definition to improve code readbility. Reviewed-by: Zhenyu Wang Signed-off-by: Xiaolin Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/handlers.c | 79 +++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 6f9763fbf4f5..de7fb67b5fa7 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -2826,26 +2826,26 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_DH(DBUF_CTL, D_SKL_PLUS, NULL, gen9_dbuf_ctl_mmio_write); - MMIO_D(_MMIO(0xa210), D_SKL_PLUS); + MMIO_D(GEN9_PG_ENABLE, D_SKL_PLUS); MMIO_D(GEN9_MEDIA_PG_IDLE_HYSTERESIS, D_SKL_PLUS); MMIO_D(GEN9_RENDER_PG_IDLE_HYSTERESIS, D_SKL_PLUS); MMIO_DFH(GEN9_GAMT_ECO_REG_RW_IA, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); - MMIO_DH(_MMIO(0x4ddc), D_SKL_PLUS, NULL, NULL); - MMIO_DH(_MMIO(0x42080), D_SKL_PLUS, NULL, NULL); - MMIO_D(_MMIO(0x45504), D_SKL_PLUS); - MMIO_D(_MMIO(0x45520), D_SKL_PLUS); - MMIO_D(_MMIO(0x46000), D_SKL_PLUS); - MMIO_DH(_MMIO(0x46010), D_SKL_PLUS, NULL, skl_lcpll_write); - MMIO_DH(_MMIO(0x46014), D_SKL_PLUS, NULL, skl_lcpll_write); - MMIO_D(_MMIO(0x6C040), D_SKL_PLUS); - MMIO_D(_MMIO(0x6C048), D_SKL_PLUS); - MMIO_D(_MMIO(0x6C050), D_SKL_PLUS); - MMIO_D(_MMIO(0x6C044), D_SKL_PLUS); - MMIO_D(_MMIO(0x6C04C), D_SKL_PLUS); - MMIO_D(_MMIO(0x6C054), D_SKL_PLUS); - MMIO_D(_MMIO(0x6c058), D_SKL_PLUS); - MMIO_D(_MMIO(0x6c05c), D_SKL_PLUS); - MMIO_DH(_MMIO(0x6c060), D_SKL_PLUS, dpll_status_read, NULL); + MMIO_DH(MMCD_MISC_CTRL, D_SKL_PLUS, NULL, NULL); + MMIO_DH(CHICKEN_PAR1_1, D_SKL_PLUS, NULL, NULL); + MMIO_D(DC_STATE_EN, D_SKL_PLUS); + MMIO_D(DC_STATE_DEBUG, D_SKL_PLUS); + MMIO_D(CDCLK_CTL, D_SKL_PLUS); + MMIO_DH(LCPLL1_CTL, D_SKL_PLUS, NULL, skl_lcpll_write); + MMIO_DH(LCPLL2_CTL, D_SKL_PLUS, NULL, skl_lcpll_write); + MMIO_D(_MMIO(_DPLL1_CFGCR1), D_SKL_PLUS); + MMIO_D(_MMIO(_DPLL2_CFGCR1), D_SKL_PLUS); + MMIO_D(_MMIO(_DPLL3_CFGCR1), D_SKL_PLUS); + MMIO_D(_MMIO(_DPLL1_CFGCR2), D_SKL_PLUS); + MMIO_D(_MMIO(_DPLL2_CFGCR2), D_SKL_PLUS); + MMIO_D(_MMIO(_DPLL3_CFGCR2), D_SKL_PLUS); + MMIO_D(DPLL_CTRL1, D_SKL_PLUS); + MMIO_D(DPLL_CTRL2, D_SKL_PLUS); + MMIO_DH(DPLL_STATUS, D_SKL_PLUS, dpll_status_read, NULL); MMIO_DH(SKL_PS_WIN_POS(PIPE_A, 0), D_SKL_PLUS, NULL, pf_write); MMIO_DH(SKL_PS_WIN_POS(PIPE_A, 1), D_SKL_PLUS, NULL, pf_write); @@ -2964,40 +2964,41 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_DH(_MMIO(_REG_701C4(PIPE_C, 3)), D_SKL_PLUS, NULL, NULL); MMIO_DH(_MMIO(_REG_701C4(PIPE_C, 4)), D_SKL_PLUS, NULL, NULL); - MMIO_D(_MMIO(0x70380), D_SKL_PLUS); - MMIO_D(_MMIO(0x71380), D_SKL_PLUS); + MMIO_D(_MMIO(_PLANE_CTL_3_A), D_SKL_PLUS); + MMIO_D(_MMIO(_PLANE_CTL_3_B), D_SKL_PLUS); MMIO_D(_MMIO(0x72380), D_SKL_PLUS); MMIO_D(_MMIO(0x7239c), D_SKL_PLUS); - MMIO_D(_MMIO(0x7039c), D_SKL_PLUS); + MMIO_D(_MMIO(_PLANE_SURF_3_A), D_SKL_PLUS); - MMIO_D(_MMIO(0x8f074), D_SKL_PLUS); - MMIO_D(_MMIO(0x8f004), D_SKL_PLUS); - MMIO_D(_MMIO(0x8f034), D_SKL_PLUS); + MMIO_D(CSR_SSP_BASE, D_SKL_PLUS); + MMIO_D(CSR_HTP_SKL, D_SKL_PLUS); + MMIO_D(CSR_LAST_WRITE, D_SKL_PLUS); - MMIO_D(_MMIO(0xb11c), D_SKL_PLUS); + MMIO_D(BDW_SCRATCH1, D_SKL_PLUS); - MMIO_D(_MMIO(0x51000), D_SKL_PLUS); - MMIO_D(_MMIO(0x6c00c), D_SKL_PLUS); + MMIO_D(SKL_DFSM, D_SKL_PLUS); + MMIO_D(DISPIO_CR_TX_BMU_CR0, D_SKL_PLUS); - MMIO_F(_MMIO(0xc800), 0x7f8, F_CMD_ACCESS, 0, 0, D_SKL_PLUS, + MMIO_F(GEN9_GFX_MOCS(0), 0x7f8, F_CMD_ACCESS, 0, 0, D_SKL_PLUS, NULL, NULL); - MMIO_F(_MMIO(0xb020), 0x80, F_CMD_ACCESS, 0, 0, D_SKL_PLUS, + MMIO_F(GEN7_L3CNTLREG2, 0x80, F_CMD_ACCESS, 0, 0, D_SKL_PLUS, NULL, NULL); MMIO_D(RPM_CONFIG0, D_SKL_PLUS); MMIO_D(_MMIO(0xd08), D_SKL_PLUS); MMIO_D(RC6_LOCATION, D_SKL_PLUS); - MMIO_DFH(_MMIO(0x20e0), D_SKL_PLUS, F_MODE_MASK, NULL, NULL); - MMIO_DFH(_MMIO(0x20ec), D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, + MMIO_DFH(GEN7_FF_SLICE_CS_CHICKEN1, D_SKL_PLUS, F_MODE_MASK, + NULL, NULL); + MMIO_DFH(GEN9_CS_DEBUG_MODE1, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); /* TRTT */ - MMIO_DFH(_MMIO(0x4de0), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(_MMIO(0x4de4), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(_MMIO(0x4de8), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(_MMIO(0x4dec), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(_MMIO(0x4df0), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); - MMIO_DFH(_MMIO(0x4df4), D_SKL_PLUS, F_CMD_ACCESS, + MMIO_DFH(TRVATTL3PTRDW(0), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(TRVATTL3PTRDW(1), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(TRVATTL3PTRDW(2), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(TRVATTL3PTRDW(3), D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(TRVADR, D_SKL_PLUS, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(TRTTE, D_SKL_PLUS, F_CMD_ACCESS, NULL, gen9_trtte_write); MMIO_DH(_MMIO(0x4dfc), D_SKL_PLUS, NULL, gen9_trtt_chicken_write); @@ -3010,7 +3011,7 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_DH(DMA_CTRL, D_SKL_PLUS, NULL, dma_ctrl_write); MMIO_D(_MMIO(0x65900), D_SKL_PLUS); - MMIO_D(_MMIO(0x1082c0), D_SKL_PLUS); + MMIO_D(GEN6_STOLEN_RESERVED, D_SKL_PLUS); MMIO_D(_MMIO(0x4068), D_SKL_PLUS); MMIO_D(_MMIO(0x67054), D_SKL_PLUS); MMIO_D(_MMIO(0x6e560), D_SKL_PLUS); @@ -3041,8 +3042,8 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_DFH(GEN9_WM_CHICKEN3, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); - MMIO_D(_MMIO(0x4ab8), D_KBL | D_CFL); - MMIO_D(_MMIO(0x2248), D_SKL_PLUS); + MMIO_D(GAMT_CHKN_BIT_REG, D_KBL); + MMIO_D(GEN9_CTX_PREEMPT_REG, D_KBL | D_SKL); return 0; } -- cgit v1.2.3 From aee183baaa3aadbf0d013d647b2e4cdaba66f872 Mon Sep 17 00:00:00 2001 From: Colin Xu Date: Mon, 25 Mar 2019 09:52:15 +0800 Subject: drm/i915/gvt: Add macro define for mmio 0x50080 and gvt flip event Add SKL_FLIP_EVENT to address into intel_gvt_event_type for primary and sprite0 plane flip event. Add macro to address REG_50080 offset. v2: Add bit operation definition for flip mode. (zhenyu) Reviewed-by: Zhenyu Wang Signed-off-by: Colin Xu Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/reg.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h index 56cff20eba44..3de5b643b266 100644 --- a/drivers/gpu/drm/i915/gvt/reg.h +++ b/drivers/gpu/drm/i915/gvt/reg.h @@ -60,6 +60,37 @@ #define _REG_701C0(pipe, plane) (0x701c0 + pipe * 0x1000 + (plane - 1) * 0x100) #define _REG_701C4(pipe, plane) (0x701c4 + pipe * 0x1000 + (plane - 1) * 0x100) +#define SKL_FLIP_EVENT(pipe, plane) (PRIMARY_A_FLIP_DONE + (plane) * 3 + (pipe)) + +#define PLANE_CTL_ASYNC_FLIP (1 << 9) +#define REG50080_FLIP_TYPE_MASK 0x3 +#define REG50080_FLIP_TYPE_ASYNC 0x1 + +#define REG_50080(_pipe, _plane) ({ \ + typeof(_pipe) (p) = (_pipe); \ + typeof(_plane) (q) = (_plane); \ + (((p) == PIPE_A) ? (((q) == PLANE_PRIMARY) ? (_MMIO(0x50080)) : \ + (_MMIO(0x50090))) : \ + (((p) == PIPE_B) ? (((q) == PLANE_PRIMARY) ? (_MMIO(0x50088)) : \ + (_MMIO(0x50098))) : \ + (((p) == PIPE_C) ? (((q) == PLANE_PRIMARY) ? (_MMIO(0x5008C)) : \ + (_MMIO(0x5009C))) : \ + (_MMIO(0x50080))))); }) + +#define REG_50080_TO_PIPE(_reg) ({ \ + typeof(_reg) (reg) = (_reg); \ + (((reg) == 0x50080 || (reg) == 0x50090) ? (PIPE_A) : \ + (((reg) == 0x50088 || (reg) == 0x50098) ? (PIPE_B) : \ + (((reg) == 0x5008C || (reg) == 0x5009C) ? (PIPE_C) : \ + (INVALID_PIPE)))); }) + +#define REG_50080_TO_PLANE(_reg) ({ \ + typeof(_reg) (reg) = (_reg); \ + (((reg) == 0x50080 || (reg) == 0x50088 || (reg) == 0x5008C) ? \ + (PLANE_PRIMARY) : \ + (((reg) == 0x50090 || (reg) == 0x50098 || (reg) == 0x5009C) ? \ + (PLANE_SPRITE0) : (I915_MAX_PLANES))); }) + #define GFX_MODE_BIT_SET_IN_MASK(val, bit) \ ((((bit) & 0xffff0000) == 0) && !!((val) & (((bit) << 16)))) -- cgit v1.2.3 From d39af942822feaccc8559b18f0ca8215c739492e Mon Sep 17 00:00:00 2001 From: Colin Xu Date: Mon, 25 Mar 2019 09:52:16 +0800 Subject: drm/i915/gvt: Enable synchronous flip on handling MI_DISPLAY_FLIP According to Intel GFX PRM on 01.org, the MI_DISPLAY_FLIP command can either request display plane flip synchronously or asynchronously. In synchronous flip, flip will be hold until next vsync, which is not implemented yet in GVT. In asynchronous flip, flip will happen immediately, which is current implementation. The patch enables the sync flip on handling MI_DISPLAY_FLIP, and increment flip count correctly by only increment on primary plane. v2: Use bit operation definition for flip mode. (zhenyu) Reviewed-by: Zhenyu Wang Signed-off-by: Colin Xu Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 35b4ec3f7618..c53dbdbfeaa7 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -1321,8 +1321,14 @@ static int gen8_update_plane_mmio_from_mi_display_flip( info->tile_val << 10); } - vgpu_vreg_t(vgpu, PIPE_FRMCOUNT_G4X(info->pipe))++; - intel_vgpu_trigger_virtual_event(vgpu, info->event); + if (info->plane == PLANE_PRIMARY) + vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(info->pipe))++; + + if (info->async_flip) + intel_vgpu_trigger_virtual_event(vgpu, info->event); + else + set_bit(info->event, vgpu->irq.flip_done_event[info->pipe]); + return 0; } -- cgit v1.2.3 From d57b39e3ee3cdb4b00452090e386d197980cefc9 Mon Sep 17 00:00:00 2001 From: Colin Xu Date: Mon, 25 Mar 2019 09:52:17 +0800 Subject: drm/i915/gvt: Enable async flip on plane surface mmio writes According to Intel GFX PRM on 01.org, plane surface address can be updated synchronously or asynchronously. Synchronous flip will hold plane surface address update to start of next vsync, which is current implementation. Asynchronous flip will update the address as soon as possible. Without async flip, some 3D application could not reach better performance and the maximum performance is no higher than vsync frequency. The patch enables the async flip on plane surface address mmio update, and increment flip count correctly. With async flip enabled, some 3D applications have significant performance improvement. i.e. 3DMark Ice Storm has a 300%~400% increment on score. v2: Use bit operation definition for flip mode. (zhenyu) Reviewed-by: Zhenyu Wang Signed-off-by: Colin Xu Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/display.c | 1 - drivers/gpu/drm/i915/gvt/handlers.c | 73 ++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 19 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 035479e273be..d7536e41aff9 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -407,7 +407,6 @@ static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe) if (!pipe_is_enabled(vgpu, pipe)) continue; - vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++; intel_vgpu_trigger_virtual_event(vgpu, event); } diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index de7fb67b5fa7..1a343f99b3b4 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -750,18 +750,19 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; - unsigned int index = DSPSURF_TO_PIPE(offset); - i915_reg_t surflive_reg = DSPSURFLIVE(index); - int flip_event[] = { - [PIPE_A] = PRIMARY_A_FLIP_DONE, - [PIPE_B] = PRIMARY_B_FLIP_DONE, - [PIPE_C] = PRIMARY_C_FLIP_DONE, - }; + u32 pipe = DSPSURF_TO_PIPE(offset); + int event = SKL_FLIP_EVENT(pipe, PLANE_PRIMARY); write_vreg(vgpu, offset, p_data, bytes); - vgpu_vreg_t(vgpu, surflive_reg) = vgpu_vreg(vgpu, offset); + vgpu_vreg_t(vgpu, DSPSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset); + + vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++; + + if (vgpu_vreg_t(vgpu, DSPCNTR(pipe)) & PLANE_CTL_ASYNC_FLIP) + intel_vgpu_trigger_virtual_event(vgpu, event); + else + set_bit(event, vgpu->irq.flip_done_event[pipe]); - set_bit(flip_event[index], vgpu->irq.flip_done_event[index]); return 0; } @@ -771,18 +772,42 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, static int spr_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { - unsigned int index = SPRSURF_TO_PIPE(offset); - i915_reg_t surflive_reg = SPRSURFLIVE(index); - int flip_event[] = { - [PIPE_A] = SPRITE_A_FLIP_DONE, - [PIPE_B] = SPRITE_B_FLIP_DONE, - [PIPE_C] = SPRITE_C_FLIP_DONE, - }; + u32 pipe = SPRSURF_TO_PIPE(offset); + int event = SKL_FLIP_EVENT(pipe, PLANE_SPRITE0); write_vreg(vgpu, offset, p_data, bytes); - vgpu_vreg_t(vgpu, surflive_reg) = vgpu_vreg(vgpu, offset); + vgpu_vreg_t(vgpu, SPRSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset); + + if (vgpu_vreg_t(vgpu, SPRCTL(pipe)) & PLANE_CTL_ASYNC_FLIP) + intel_vgpu_trigger_virtual_event(vgpu, event); + else + set_bit(event, vgpu->irq.flip_done_event[pipe]); + + return 0; +} + +static int reg50080_mmio_write(struct intel_vgpu *vgpu, + unsigned int offset, void *p_data, + unsigned int bytes) +{ + struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; + enum pipe pipe = REG_50080_TO_PIPE(offset); + enum plane_id plane = REG_50080_TO_PLANE(offset); + int event = SKL_FLIP_EVENT(pipe, plane); + + write_vreg(vgpu, offset, p_data, bytes); + if (plane == PLANE_PRIMARY) { + vgpu_vreg_t(vgpu, DSPSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset); + vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++; + } else { + vgpu_vreg_t(vgpu, SPRSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset); + } + + if ((vgpu_vreg(vgpu, offset) & REG50080_FLIP_TYPE_MASK) == REG50080_FLIP_TYPE_ASYNC) + intel_vgpu_trigger_virtual_event(vgpu, event); + else + set_bit(event, vgpu->irq.flip_done_event[pipe]); - set_bit(flip_event[index], vgpu->irq.flip_done_event[index]); return 0; } @@ -1969,6 +1994,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_DH(DSPSURF(PIPE_A), D_ALL, NULL, pri_surf_mmio_write); MMIO_D(DSPOFFSET(PIPE_A), D_ALL); MMIO_D(DSPSURFLIVE(PIPE_A), D_ALL); + MMIO_DH(REG_50080(PIPE_A, PLANE_PRIMARY), D_ALL, NULL, + reg50080_mmio_write); MMIO_D(DSPCNTR(PIPE_B), D_ALL); MMIO_D(DSPADDR(PIPE_B), D_ALL); @@ -1978,6 +2005,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_DH(DSPSURF(PIPE_B), D_ALL, NULL, pri_surf_mmio_write); MMIO_D(DSPOFFSET(PIPE_B), D_ALL); MMIO_D(DSPSURFLIVE(PIPE_B), D_ALL); + MMIO_DH(REG_50080(PIPE_B, PLANE_PRIMARY), D_ALL, NULL, + reg50080_mmio_write); MMIO_D(DSPCNTR(PIPE_C), D_ALL); MMIO_D(DSPADDR(PIPE_C), D_ALL); @@ -1987,6 +2016,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_DH(DSPSURF(PIPE_C), D_ALL, NULL, pri_surf_mmio_write); MMIO_D(DSPOFFSET(PIPE_C), D_ALL); MMIO_D(DSPSURFLIVE(PIPE_C), D_ALL); + MMIO_DH(REG_50080(PIPE_C, PLANE_PRIMARY), D_ALL, NULL, + reg50080_mmio_write); MMIO_D(SPRCTL(PIPE_A), D_ALL); MMIO_D(SPRLINOFF(PIPE_A), D_ALL); @@ -2000,6 +2031,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(SPROFFSET(PIPE_A), D_ALL); MMIO_D(SPRSCALE(PIPE_A), D_ALL); MMIO_D(SPRSURFLIVE(PIPE_A), D_ALL); + MMIO_DH(REG_50080(PIPE_A, PLANE_SPRITE0), D_ALL, NULL, + reg50080_mmio_write); MMIO_D(SPRCTL(PIPE_B), D_ALL); MMIO_D(SPRLINOFF(PIPE_B), D_ALL); @@ -2013,6 +2046,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(SPROFFSET(PIPE_B), D_ALL); MMIO_D(SPRSCALE(PIPE_B), D_ALL); MMIO_D(SPRSURFLIVE(PIPE_B), D_ALL); + MMIO_DH(REG_50080(PIPE_B, PLANE_SPRITE0), D_ALL, NULL, + reg50080_mmio_write); MMIO_D(SPRCTL(PIPE_C), D_ALL); MMIO_D(SPRLINOFF(PIPE_C), D_ALL); @@ -2026,6 +2061,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(SPROFFSET(PIPE_C), D_ALL); MMIO_D(SPRSCALE(PIPE_C), D_ALL); MMIO_D(SPRSURFLIVE(PIPE_C), D_ALL); + MMIO_DH(REG_50080(PIPE_C, PLANE_SPRITE0), D_ALL, NULL, + reg50080_mmio_write); MMIO_D(HTOTAL(TRANSCODER_A), D_ALL); MMIO_D(HBLANK(TRANSCODER_A), D_ALL); -- cgit v1.2.3 From fe61692886669bbcc260f980903eacb4ddebaf59 Mon Sep 17 00:00:00 2001 From: Rodrigo Siqueira Date: Thu, 14 Mar 2019 15:48:45 -0300 Subject: drm/atomic-helper: Make atomic_enable/disable crtc callbacks optional Allow atomic_enable and atomic_disable operations from drm_crtc_helper_funcs struct optional. With this, the target display drivers don't need to define a dummy function if they don't need one. Changes since v2: * Don't make funcs optional * Update kerneldoc for atomic_enable/disable * Replace "if (funcs->atomic_enable)" by "if (funcs->commit)" * Improve commit message Signed-off-by: Rodrigo Siqueira Reviewed-by: Daniel Vetter Link: http://patchwork.freedesktop.org/patch/msgid/20190314184845.gjmvkamobj4dilyp@smtp.gmail.com Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/drm_atomic_helper.c | 5 ++--- include/drm/drm_modeset_helper_vtables.h | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 40ac19848034..fbb76332cc9f 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -1034,7 +1034,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) funcs->atomic_disable(crtc, old_crtc_state); else if (funcs->disable) funcs->disable(crtc); - else + else if (funcs->dpms) funcs->dpms(crtc, DRM_MODE_DPMS_OFF); if (!(dev->irq_enabled && dev->num_crtcs)) @@ -1277,10 +1277,9 @@ void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev, if (new_crtc_state->enable) { DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n", crtc->base.id, crtc->name); - if (funcs->atomic_enable) funcs->atomic_enable(crtc, old_crtc_state); - else + else if (funcs->commit) funcs->commit(crtc); } } diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index cfb7be40bed7..ce4de6b1e444 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -418,6 +418,8 @@ struct drm_crtc_helper_funcs { * Drivers can use the @old_crtc_state input parameter if the operations * needed to enable the CRTC don't depend solely on the new state but * also on the transition between the old state and the new state. + * + * This function is optional. */ void (*atomic_enable)(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); @@ -441,6 +443,8 @@ struct drm_crtc_helper_funcs { * parameter @old_crtc_state which could be used to access the old * state. Atomic drivers should consider to use this one instead * of @disable. + * + * This function is optional. */ void (*atomic_disable)(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state); -- cgit v1.2.3 From f6ac993fb0ca5d8c0233ac17a71aacb22f84ac54 Mon Sep 17 00:00:00 2001 From: Daniele Ceraolo Spurio Date: Thu, 28 Mar 2019 10:45:32 -0700 Subject: drm/i915: move the edram detection out of uncore init edram is not part of uncore and there is no requirement for the detection to be done before we initialize the uncore functions. The first check on HAS_EDRAM is in the ggtt_init path, so move it to i915_driver_init_hw, where other dram-related detection happens. While at it, save the size in MB instead of the capabilities because the size is the only thing we look at outside of the init function. Signed-off-by: Daniele Ceraolo Spurio Cc: Paulo Zanoni Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190328174533.31532-1-daniele.ceraolospurio@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.c | 42 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 9 +++++--- drivers/gpu/drm/i915/intel_uncore.c | 46 ------------------------------------- drivers/gpu/drm/i915/intel_uncore.h | 1 - 5 files changed, 50 insertions(+), 52 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index bb2c16c439ea..84c0c2a50f78 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2087,8 +2087,8 @@ static int i915_llc(struct seq_file *m, void *data) const bool edram = INTEL_GEN(dev_priv) > 8; seq_printf(m, "LLC: %s\n", yesno(HAS_LLC(dev_priv))); - seq_printf(m, "%s: %lluMB\n", edram ? "eDRAM" : "eLLC", - intel_uncore_edram_size(dev_priv)/1024/1024); + seq_printf(m, "%s: %uMB\n", edram ? "eDRAM" : "eLLC", + dev_priv->edram_size_mb); return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index bbe1a5d56480..4d5f3f2d94ee 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1441,6 +1441,45 @@ intel_get_dram_info(struct drm_i915_private *dev_priv) dram_info->ranks, yesno(dram_info->is_16gb_dimm)); } +static u32 gen9_edram_size_mb(struct drm_i915_private *dev_priv, u32 cap) +{ + const unsigned int ways[8] = { 4, 8, 12, 16, 16, 16, 16, 16 }; + const unsigned int sets[4] = { 1, 1, 2, 2 }; + + return EDRAM_NUM_BANKS(cap) * + ways[EDRAM_WAYS_IDX(cap)] * + sets[EDRAM_SETS_IDX(cap)]; +} + +static void edram_detect(struct drm_i915_private *dev_priv) +{ + u32 edram_cap = 0; + + if (!(IS_HASWELL(dev_priv) || + IS_BROADWELL(dev_priv) || + INTEL_GEN(dev_priv) >= 9)) + return; + + edram_cap = __raw_uncore_read32(&dev_priv->uncore, HSW_EDRAM_CAP); + + /* NB: We can't write IDICR yet because we don't have gt funcs set up */ + + if (!(edram_cap & EDRAM_ENABLED)) + return; + + /* + * The needed capability bits for size calculation are not there with + * pre gen9 so return 128MB always. + */ + if (INTEL_GEN(dev_priv) < 9) + dev_priv->edram_size_mb = 128; + else + dev_priv->edram_size_mb = + gen9_edram_size_mb(dev_priv, edram_cap); + + DRM_INFO("Found %uMB of eDRAM\n", dev_priv->edram_size_mb); +} + /** * i915_driver_init_hw - setup state requiring device access * @dev_priv: device private @@ -1483,6 +1522,9 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) intel_sanitize_options(dev_priv); + /* needs to be done before ggtt probe */ + edram_detect(dev_priv); + i915_perf_init(dev_priv); ret = i915_ggtt_probe_hw(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a32bfc7ec5ea..f75600fa77c6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1707,8 +1707,11 @@ struct drm_i915_private { struct intel_l3_parity l3_parity; - /* Cannot be determined by PCIID. You must always read a register. */ - u32 edram_cap; + /* + * edram size in MB. + * Cannot be determined by PCIID. You must always read a register. + */ + u32 edram_size_mb; /* * Protects RPS/RC6 register access and PCU communication. @@ -2468,7 +2471,7 @@ static inline unsigned int i915_sg_segment_size(void) #define HAS_LLC(dev_priv) (INTEL_INFO(dev_priv)->has_llc) #define HAS_SNOOP(dev_priv) (INTEL_INFO(dev_priv)->has_snoop) -#define HAS_EDRAM(dev_priv) (!!((dev_priv)->edram_cap & EDRAM_ENABLED)) +#define HAS_EDRAM(dev_priv) ((dev_priv)->edram_size_mb) #define HAS_WT(dev_priv) ((IS_HASWELL(dev_priv) || \ IS_BROADWELL(dev_priv)) && HAS_EDRAM(dev_priv)) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 5c80704bf283..106df24f20a5 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -420,51 +420,6 @@ intel_uncore_forcewake_reset(struct intel_uncore *uncore) return fw; /* track the lost user forcewake domains */ } -static u64 gen9_edram_size(struct drm_i915_private *dev_priv) -{ - const unsigned int ways[8] = { 4, 8, 12, 16, 16, 16, 16, 16 }; - const unsigned int sets[4] = { 1, 1, 2, 2 }; - const u32 cap = dev_priv->edram_cap; - - return EDRAM_NUM_BANKS(cap) * - ways[EDRAM_WAYS_IDX(cap)] * - sets[EDRAM_SETS_IDX(cap)] * - 1024 * 1024; -} - -u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv) -{ - if (!HAS_EDRAM(dev_priv)) - return 0; - - /* The needed capability bits for size calculation - * are not there with pre gen9 so return 128MB always. - */ - if (INTEL_GEN(dev_priv) < 9) - return 128 * 1024 * 1024; - - return gen9_edram_size(dev_priv); -} - -static void intel_uncore_edram_detect(struct drm_i915_private *dev_priv) -{ - if (IS_HASWELL(dev_priv) || - IS_BROADWELL(dev_priv) || - INTEL_GEN(dev_priv) >= 9) { - dev_priv->edram_cap = __raw_uncore_read32(&dev_priv->uncore, - HSW_EDRAM_CAP); - - /* NB: We can't write IDICR yet because we do not have gt funcs - * set up */ - } else { - dev_priv->edram_cap = 0; - } - - if (HAS_EDRAM(dev_priv)) - DRM_INFO("Found %lluMB of eDRAM\n", - intel_uncore_edram_size(dev_priv) / (1024 * 1024)); -} - static bool fpga_check_for_unclaimed_mmio(struct intel_uncore *uncore) { @@ -1584,7 +1539,6 @@ int intel_uncore_init(struct intel_uncore *uncore) if (INTEL_GEN(i915) > 5 && !intel_vgpu_active(i915)) uncore->flags |= UNCORE_HAS_FORCEWAKE; - intel_uncore_edram_detect(i915); intel_uncore_fw_domains_init(uncore); __intel_uncore_early_sanitize(uncore, 0); diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 50d226f68753..896585a1c2dd 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -187,7 +187,6 @@ void intel_uncore_suspend(struct intel_uncore *uncore); void intel_uncore_resume_early(struct intel_uncore *uncore); void intel_uncore_runtime_resume(struct intel_uncore *uncore); -u64 intel_uncore_edram_size(struct drm_i915_private *dev_priv); void assert_forcewakes_inactive(struct intel_uncore *uncore); void assert_forcewakes_active(struct intel_uncore *uncore, enum forcewake_domains fw_domains); -- cgit v1.2.3 From e15be4298f3570366d40dbec06e5b0d6e0626eb4 Mon Sep 17 00:00:00 2001 From: Daniele Ceraolo Spurio Date: Fri, 29 Mar 2019 09:50:18 -0700 Subject: drm/i915: fix i9xx irq enable/disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those functions are used on gen4 as well and gen4 does have a non-RCS engine, so remove the BUG_ON and flip back the logic to what it was before the ENGINE_READ/WRITE update v2: update the posting read as well (Chris, Ville). Fixes: baba6e572b38 ("drm/i915: take a reference to uncore in the engine and use it") Signed-off-by: Daniele Ceraolo Spurio Cc: Chris Wilson Cc: Paulo Zanoni Cc: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190329165018.32953-1-daniele.ceraolospurio@intel.com --- drivers/gpu/drm/i915/intel_ringbuffer.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 48ba4d61a4ae..8a19eee9c5d4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -976,20 +976,16 @@ gen5_irq_disable(struct intel_engine_cs *engine) static void i9xx_irq_enable(struct intel_engine_cs *engine) { - GEM_BUG_ON(engine->id != RCS0); - engine->i915->irq_mask &= ~engine->irq_enable_mask; - ENGINE_WRITE(engine, RING_IMR, engine->i915->irq_mask); - ENGINE_POSTING_READ(engine, RING_IMR); + intel_uncore_write(engine->uncore, IMR, engine->i915->irq_mask); + intel_uncore_posting_read_fw(engine->uncore, IMR); } static void i9xx_irq_disable(struct intel_engine_cs *engine) { - GEM_BUG_ON(engine->id != RCS0); - engine->i915->irq_mask |= engine->irq_enable_mask; - ENGINE_WRITE(engine, RING_IMR, engine->i915->irq_mask); + intel_uncore_write(engine->uncore, IMR, engine->i915->irq_mask); } static void -- cgit v1.2.3 From 61eae851c92b0b5b089a3f5da92219500dc99d59 Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Fri, 29 Mar 2019 19:59:15 +0530 Subject: drm/i915: Fix GCMAX color register programming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GC MAX register is used to program values from 1.0 to less than 3.0. A different register was used instead of the intended one. Fixed the same. Currently limiting it to 1.0 due to ABI limitations. v2: Updated the 1.0 programming and aligned as per GLK, based on Ville's feedback. Reported-by: Ville Syrjälä Signed-off-by: Uma Shankar Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1553869756-4546-2-git-send-email-uma.shankar@intel.com --- drivers/gpu/drm/i915/intel_color.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index ff910ed08468..c7761591ba7c 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -518,14 +518,14 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of I915_WRITE(PREC_PAL_DATA(pipe), word); } - /* Program the max register to clamp values > 1.0. */ - i = lut_size - 1; - I915_WRITE(PREC_PAL_GC_MAX(pipe, 0), - drm_color_lut_extract(lut[i].red, 16)); - I915_WRITE(PREC_PAL_GC_MAX(pipe, 1), - drm_color_lut_extract(lut[i].green, 16)); - I915_WRITE(PREC_PAL_GC_MAX(pipe, 2), - drm_color_lut_extract(lut[i].blue, 16)); + /* + * Program the max register to clamp values > 1.0. + * ToDo: Extend the ABI to be able to program values + * from 1.0 to 3.0 + */ + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), (1 << 16)); + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), (1 << 16)); + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), (1 << 16)); } else { for (i = 0; i < lut_size; i++) { u32 v = (i * ((1 << 10) - 1)) / (lut_size - 1); @@ -534,9 +534,9 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of (v << 20) | (v << 10) | v); } - I915_WRITE(PREC_PAL_GC_MAX(pipe, 0), (1 << 16) - 1); - I915_WRITE(PREC_PAL_GC_MAX(pipe, 1), (1 << 16) - 1); - I915_WRITE(PREC_PAL_GC_MAX(pipe, 2), (1 << 16) - 1); + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), (1 << 16)); + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), (1 << 16)); + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), (1 << 16)); } /* -- cgit v1.2.3 From 502da13a72dad49690f5ac1c4d1a182ab7810eaa Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Fri, 29 Mar 2019 19:59:16 +0530 Subject: drm/i915: Program EXT2 GC MAX registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EXT2 GC MAX registers are introduced from Gen10+ to program values from 3.0 to 7.0. Enabled the same, but currently limiting it to 1.0 as userspace ABI is limited at that currently. v2: Updated the 1.0 programming and aligned as per GLK, also added GLK along with GEN10+ check, as per Ville's feedback. Signed-off-by: Uma Shankar Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/1553869756-4546-3-git-send-email-uma.shankar@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_color.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c866379a521b..341f03e00536 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10144,6 +10144,7 @@ enum skl_power_gate { #define PREC_PAL_DATA(pipe) _MMIO_PIPE(pipe, _PAL_PREC_DATA_A, _PAL_PREC_DATA_B) #define PREC_PAL_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4) #define PREC_PAL_EXT_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4) +#define PREC_PAL_EXT2_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT2_GC_MAX_A, _PAL_PREC_EXT2_GC_MAX_B) + (i) * 4) #define _PRE_CSC_GAMC_INDEX_A 0x4A484 #define _PRE_CSC_GAMC_INDEX_B 0x4AC84 diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index c7761591ba7c..f2907cfd116a 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -526,6 +526,17 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), (1 << 16)); I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), (1 << 16)); I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), (1 << 16)); + + /* + * Program the gc max 2 register to clamp values > 1.0. + * ToDo: Extend the ABI to be able to program values + * from 3.0 to 7.0 + */ + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), (1 << 16)); + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), (1 << 16)); + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), (1 << 16)); + } } else { for (i = 0; i < lut_size; i++) { u32 v = (i * ((1 << 10) - 1)) / (lut_size - 1); @@ -537,6 +548,17 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), (1 << 16)); I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), (1 << 16)); I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), (1 << 16)); + + /* + * Program the gc max 2 register to clamp values > 1.0. + * ToDo: Extend the ABI to be able to program values + * from 3.0 to 7.0 + */ + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), (1 << 16)); + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), (1 << 16)); + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), (1 << 16)); + } } /* -- cgit v1.2.3 From ee6df5694a9a2e30566ae05e9c145a0f6d5e087f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Mar 2019 16:51:52 +0000 Subject: drm/i915: Always backoff after a drm_modeset_lock() deadlock If drm_modeset_lock() reports a deadlock it sets the ctx->contexted field and insists that the caller calls drm_modeset_backoff() or else it generates a WARN on cleanup. <4> [1601.870376] WARNING: CPU: 3 PID: 8445 at drivers/gpu/drm/drm_modeset_lock.c:228 drm_modeset_drop_locks+0x35/0x40 <4> [1601.870395] Modules linked in: vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal i915 coretemp crct10dif_pclmul <6> [1601.870403] Console: switching <4> [1601.870403] snd_hda_intel <4> [1601.870406] to colour frame buffer device 320x90 <4> [1601.870406] crc32_pclmul snd_hda_codec snd_hwdep ghash_clmulni_intel e1000e snd_hda_core cdc_ether ptp usbnet mii pps_core snd_pcm i2c_i801 mei_me mei prime_numbers <4> [1601.870422] CPU: 3 PID: 8445 Comm: cat Tainted: G U 5.0.0-rc7-CI-CI_DRM_5650+ #1 <4> [1601.870424] Hardware name: Intel Corporation Ice Lake Client Platform/IceLake U DDR4 SODIMM PD RVP TLC, BIOS ICLSFWR1.R00.2402.AD3.1810170014 10/17/2018 <4> [1601.870427] RIP: 0010:drm_modeset_drop_locks+0x35/0x40 <4> [1601.870430] Code: 29 48 8b 43 60 48 8d 6b 60 48 39 c5 74 19 48 8b 43 60 48 8d b8 70 ff ff ff e8 87 ff ff ff 48 8b 43 60 48 39 c5 75 e7 5b 5d c3 <0f> 0b eb d3 0f 1f 80 00 00 00 00 41 56 41 55 41 54 55 53 48 8b 6f <4> [1601.870432] RSP: 0018:ffffc90000d67ce8 EFLAGS: 00010282 <4> [1601.870435] RAX: 00000000ffffffdd RBX: ffffc90000d67d00 RCX: 5dbbe23d00000000 <4> [1601.870437] RDX: 0000000000000000 RSI: 0000000093e6194a RDI: ffffc90000d67d00 <4> [1601.870439] RBP: ffff88849e62e678 R08: 0000000003b7329a R09: 0000000000000001 <4> [1601.870441] R10: 0000000000000000 R11: 0000000000000000 R12: ffff888492100410 <4> [1601.870442] R13: ffff88849ea50958 R14: ffff8884a67eb028 R15: ffff8884a67eb028 <4> [1601.870445] FS: 00007fa7a27745c0(0000) GS:ffff8884aff80000(0000) knlGS:0000000000000000 <4> [1601.870447] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4> [1601.870449] CR2: 000055af07e66000 CR3: 00000004a8cc2006 CR4: 0000000000760ee0 <4> [1601.870451] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 <4> [1601.870453] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 <4> [1601.870454] PKRU: 55555554 <4> [1601.870456] Call Trace: <4> [1601.870505] i915_dsc_fec_support_show+0x91/0x190 [i915] <4> [1601.870522] seq_read+0xdb/0x3c0 <4> [1601.870531] full_proxy_read+0x51/0x80 <4> [1601.870538] __vfs_read+0x31/0x190 <4> [1601.870546] ? __se_sys_newfstat+0x3c/0x60 <4> [1601.870552] vfs_read+0x9e/0x150 <4> [1601.870557] ksys_read+0x50/0xc0 <4> [1601.870564] do_syscall_64+0x55/0x190 <4> [1601.870569] entry_SYSCALL_64_after_hwframe+0x49/0xbe <4> [1601.870572] RIP: 0033:0x7fa7a226d081 <4> [1601.870574] Code: fe ff ff 48 8d 3d 67 9c 0a 00 48 83 ec 08 e8 a6 4c 02 00 66 0f 1f 44 00 00 48 8d 05 81 08 2e 00 8b 00 85 c0 75 13 31 c0 0f 05 <48> 3d 00 f0 ff ff 77 57 f3 c3 0f 1f 44 00 00 41 54 55 49 89 d4 53 <4> [1601.870576] RSP: 002b:00007ffcc05140c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 <4> [1601.870579] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fa7a226d081 <4> [1601.870581] RDX: 0000000000020000 RSI: 000055af07e63000 RDI: 0000000000000007 <4> [1601.870583] RBP: 0000000000020000 R08: 000000000000007b R09: 0000000000000000 <4> [1601.870585] R10: 000055af07e60010 R11: 0000000000000246 R12: 000055af07e63000 <4> [1601.870587] R13: 0000000000000007 R14: 000055af07e634bf R15: 0000000000020000 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109745 Fixes: e845f099f1c6 ("drm/i915/dsc: Add Per connector debugfs node for DSC support/enable") Signed-off-by: Chris Wilson Cc: Rodrigo Vivi Cc: Ville Syrjala Cc: Anusha Srivatsa Cc: Lyude Paul Cc: Manasi Navare Reviewed-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20190329165152.29259-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_debugfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 84c0c2a50f78..3aef121067e4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4787,7 +4787,10 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data) ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); if (ret) { - ret = -EINTR; + if (ret == -EDEADLK && !drm_modeset_backoff(&ctx)) { + try_again = true; + continue; + } break; } crtc = connector->state->crtc; -- cgit v1.2.3 From 52b832606038c5b3cb1070e7653e4115b7942606 Mon Sep 17 00:00:00 2001 From: "Robert M. Fosha" Date: Fri, 29 Mar 2019 16:17:46 -0700 Subject: drm/i915/guc: Retry GuC load for all load failures Currently we only retry to load GuC firmware if the load fails due to timeout. On Gen9 GuC loading may fail for different reasons, not just hang/timeout. Direction from the GuC team is to retry for all cases of GuC load failure on Gen9, not just for timeout. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108593 Signed-off-by: Robert M. Fosha Cc: Daniele Ceraolo Spurio Cc: Michal Wajdeczko Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190329231746.9129-1-robert.m.fosha@intel.com --- drivers/gpu/drm/i915/intel_uc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 2d360d53757f..25b80ffe71ad 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -375,7 +375,7 @@ int intel_uc_init_hw(struct drm_i915_private *i915) intel_guc_init_params(guc); ret = intel_guc_fw_upload(guc); - if (ret == 0 || ret != -ETIMEDOUT) + if (ret == 0) break; DRM_DEBUG_DRIVER("GuC fw load failed: %d; will reset and " -- cgit v1.2.3 From cde5f7edd511b190c175ab817f3f02c5f0897895 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 30 Mar 2019 10:03:49 +0000 Subject: drm/i915: Avoid using ctx->file_priv during construction As we only set ctx->file_priv on registering the GEM context after construction, it is invalid to try and use it in the middle for setting various parameters. Indeed, we put the file_priv into struct create_ext so that we have the right file_private available without having to look at ctx->file_priv. However, it helps to use it! Reported-by: Jordan Justen Fixes: b91715417244 ("drm/i915: Extend CONTEXT_CREATE to set parameters upon construction") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Jordan Justen Reviewed-by: Jordan Justen Tested-by: Jordan Justen Link: https://patchwork.freedesktop.org/patch/msgid/20190330100349.30642-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_context.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 662da485e15f..141da4e71e46 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -969,10 +969,10 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915, return 0; } -static int get_ppgtt(struct i915_gem_context *ctx, +static int get_ppgtt(struct drm_i915_file_private *file_priv, + struct i915_gem_context *ctx, struct drm_i915_gem_context_param *args) { - struct drm_i915_file_private *file_priv = ctx->file_priv; struct i915_hw_ppgtt *ppgtt; int ret; @@ -1071,10 +1071,10 @@ static int emit_ppgtt_update(struct i915_request *rq, void *data) return 0; } -static int set_ppgtt(struct i915_gem_context *ctx, +static int set_ppgtt(struct drm_i915_file_private *file_priv, + struct i915_gem_context *ctx, struct drm_i915_gem_context_param *args) { - struct drm_i915_file_private *file_priv = ctx->file_priv; struct i915_hw_ppgtt *ppgtt, *old; int err; @@ -1416,7 +1416,8 @@ static int set_sseu(struct i915_gem_context *ctx, return 0; } -static int ctx_setparam(struct i915_gem_context *ctx, +static int ctx_setparam(struct drm_i915_file_private *fpriv, + struct i915_gem_context *ctx, struct drm_i915_gem_context_param *args) { int ret = 0; @@ -1485,7 +1486,7 @@ static int ctx_setparam(struct i915_gem_context *ctx, break; case I915_CONTEXT_PARAM_VM: - ret = set_ppgtt(ctx, args); + ret = set_ppgtt(fpriv, ctx, args); break; case I915_CONTEXT_PARAM_BAN_PERIOD: @@ -1513,7 +1514,7 @@ static int create_setparam(struct i915_user_extension __user *ext, void *data) if (local.param.ctx_id) return -EINVAL; - return ctx_setparam(arg->ctx, &local.param); + return ctx_setparam(arg->fpriv, arg->ctx, &local.param); } static const i915_user_extension_fn create_extensions[] = { @@ -1712,7 +1713,7 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, break; case I915_CONTEXT_PARAM_VM: - ret = get_ppgtt(ctx, args); + ret = get_ppgtt(file_priv, ctx, args); break; case I915_CONTEXT_PARAM_BAN_PERIOD: @@ -1737,7 +1738,7 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, if (!ctx) return -ENOENT; - ret = ctx_setparam(ctx, args); + ret = ctx_setparam(file_priv, ctx, args); i915_gem_context_put(ctx); return ret; -- cgit v1.2.3 From ee8efa80799f0f7d84c87bec6c4def7fa3556b95 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 31 Mar 2019 10:46:20 +0100 Subject: drm/i915: Check domains for userptr on release When we return pages to the system, we release control over them and should defensively return them to the CPU write domain so that we catch any external writes on reacquiring them (e.g. to transparently swapout/swapin). While we did this defensive clflushing for ordinary shmem pages, it was forgotten for userptr. Fortunately, userptr objects are normally cache coherent and so oblivious to the forgotten domain tracking. References: a679f58d0510 ("drm/i915: Flush pages on acquisition") References: 754a25442705 ("drm/i915: Skip object locking around a no-op set-domain ioctl") Signed-off-by: Chris Wilson Cc: Matthew Auld Cc: Tvrtko Ursulin Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20190331094620.15185-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 3 +-- drivers/gpu/drm/i915/i915_gem_object.h | 4 ++++ drivers/gpu/drm/i915/i915_gem_userptr.c | 4 +--- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e506e43cfade..c3b4ec52e1b7 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -308,7 +308,7 @@ static void __start_cpu_write(struct drm_i915_gem_object *obj) obj->cache_dirty = true; } -static void +void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, struct sg_table *pages, bool needs_clflush) @@ -2202,7 +2202,6 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj, struct page *page; __i915_gem_object_release_shmem(obj, pages, true); - i915_gem_gtt_finish_pages(obj, pages); if (i915_gem_object_needs_bit17_swizzle(obj)) diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h index 1a24dc97e4fd..ca93a40c0c87 100644 --- a/drivers/gpu/drm/i915/i915_gem_object.h +++ b/drivers/gpu/drm/i915/i915_gem_object.h @@ -502,4 +502,8 @@ void i915_gem_object_set_cache_coherency(struct drm_i915_gem_object *obj, unsigned int cache_level); void i915_gem_object_flush_if_display(struct drm_i915_gem_object *obj); +void __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, + struct sg_table *pages, + bool needs_clflush); + #endif diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index ad0087127144..215bf3fef10c 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -673,9 +673,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj, if (!pages) return; - if (obj->mm.madv != I915_MADV_WILLNEED) - obj->mm.dirty = false; - + __i915_gem_object_release_shmem(obj, pages, true); i915_gem_gtt_finish_pages(obj, pages); for_each_sgt_page(page, sgt_iter, pages) { -- cgit v1.2.3 From 86d35d4e7625f7c056d81316da107bd3a7564fb3 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 26 Mar 2019 07:40:54 +0000 Subject: drm/i915: Split Pineview device info into desktop and mobile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows the IS_PINEVIEW_ macros to be removed and avoid duplication of device ids already defined in i915_pciids.h. !IS_MOBILE check can be used in place of existing IS_PINEVIEW_G call sites. Signed-off-by: Tvrtko Ursulin Suggested-by: Ville Syrjälä Cc: Ville Syrjälä Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190326074057.27833-2-tvrtko.ursulin@linux.intel.com --- arch/x86/kernel/early-quirks.c | 3 ++- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_pci.c | 12 ++++++++++-- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- include/drm/i915_pciids.h | 6 ++++-- 5 files changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 50d5848bf22e..f91d3ed2df62 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -525,7 +525,8 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_I945G_IDS(&gen3_early_ops), INTEL_I945GM_IDS(&gen3_early_ops), INTEL_VLV_IDS(&gen6_early_ops), - INTEL_PINEVIEW_IDS(&gen3_early_ops), + INTEL_PINEVIEW_G_IDS(&gen3_early_ops), + INTEL_PINEVIEW_M_IDS(&gen3_early_ops), INTEL_I965G_IDS(&gen3_early_ops), INTEL_G33_IDS(&gen3_early_ops), INTEL_I965GM_IDS(&gen3_early_ops), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f75600fa77c6..d1fd8f7d6f8a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2317,8 +2317,6 @@ static inline unsigned int i915_sg_segment_size(void) #define IS_G45(dev_priv) IS_PLATFORM(dev_priv, INTEL_G45) #define IS_GM45(dev_priv) IS_PLATFORM(dev_priv, INTEL_GM45) #define IS_G4X(dev_priv) (IS_G45(dev_priv) || IS_GM45(dev_priv)) -#define IS_PINEVIEW_G(dev_priv) (INTEL_DEVID(dev_priv) == 0xa001) -#define IS_PINEVIEW_M(dev_priv) (INTEL_DEVID(dev_priv) == 0xa011) #define IS_PINEVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_PINEVIEW) #define IS_G33(dev_priv) IS_PLATFORM(dev_priv, INTEL_G33) #define IS_IRONLAKE_M(dev_priv) (INTEL_DEVID(dev_priv) == 0x0046) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index a7e1611af26d..716f2f95c57d 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -257,7 +257,14 @@ static const struct intel_device_info intel_g33_info = { .display.has_overlay = 1, }; -static const struct intel_device_info intel_pineview_info = { +static const struct intel_device_info intel_pineview_g_info = { + GEN3_FEATURES, + PLATFORM(INTEL_PINEVIEW), + .display.has_hotplug = 1, + .display.has_overlay = 1, +}; + +static const struct intel_device_info intel_pineview_m_info = { GEN3_FEATURES, PLATFORM(INTEL_PINEVIEW), .is_mobile = 1, @@ -761,7 +768,8 @@ static const struct pci_device_id pciidlist[] = { INTEL_I965GM_IDS(&intel_i965gm_info), INTEL_GM45_IDS(&intel_gm45_info), INTEL_G45_IDS(&intel_g45_info), - INTEL_PINEVIEW_IDS(&intel_pineview_info), + INTEL_PINEVIEW_G_IDS(&intel_pineview_g_info), + INTEL_PINEVIEW_M_IDS(&intel_pineview_m_info), INTEL_IRONLAKE_D_IDS(&intel_ironlake_d_info), INTEL_IRONLAKE_M_IDS(&intel_ironlake_m_info), INTEL_SNB_D_GT1_IDS(&intel_sandybridge_d_gt1_info), diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9a6eb2ef5f48..0e05ee1f3ea0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -850,7 +850,7 @@ static void pineview_update_wm(struct intel_crtc *unused_crtc) u32 reg; unsigned int wm; - latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev_priv), + latency = intel_get_cxsr_latency(!IS_MOBILE(dev_priv), dev_priv->is_ddr3, dev_priv->fsb_freq, dev_priv->mem_freq); @@ -9589,7 +9589,7 @@ void intel_init_pm(struct drm_i915_private *dev_priv) dev_priv->display.initial_watermarks = g4x_initial_watermarks; dev_priv->display.optimize_watermarks = g4x_optimize_watermarks; } else if (IS_PINEVIEW(dev_priv)) { - if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev_priv), + if (!intel_get_cxsr_latency(!IS_MOBILE(dev_priv), dev_priv->is_ddr3, dev_priv->fsb_freq, dev_priv->mem_freq)) { diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index c7cdbfc4d033..cb9b5b35aa2c 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -108,8 +108,10 @@ INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \ INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */ -#define INTEL_PINEVIEW_IDS(info) \ - INTEL_VGA_DEVICE(0xa001, info), \ +#define INTEL_PINEVIEW_G_IDS(info) \ + INTEL_VGA_DEVICE(0xa001, info) + +#define INTEL_PINEVIEW_M_IDS(info) \ INTEL_VGA_DEVICE(0xa011, info) #define INTEL_IRONLAKE_D_IDS(info) \ -- cgit v1.2.3 From e08891a5b7e6d8b66c09bd6b0a1d3544083461c4 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 26 Mar 2019 07:40:55 +0000 Subject: drm/i915: Remove redundant device id from IS_IRONLAKE_M macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IS_IRONLAKE_M can use the already defined intel_device_info.is_mobile for this platform, so remove the instance of Ironlake's mobile device id from the header file and replace it with an IS_MOBILE check. v2: * Improved commit text. (Chris) v3: * Rebased for EHL. Signed-off-by: Tvrtko Ursulin Suggested-by: Ville Syrjälä Cc: Ville Syrjälä Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190326074057.27833-3-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d1fd8f7d6f8a..b2a9955b39ae 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2304,6 +2304,8 @@ static inline unsigned int i915_sg_segment_size(void) #define IS_PLATFORM(dev_priv, p) (INTEL_INFO(dev_priv)->platform_mask & BIT(p)) +#define IS_MOBILE(dev_priv) (INTEL_INFO(dev_priv)->is_mobile) + #define IS_I830(dev_priv) IS_PLATFORM(dev_priv, INTEL_I830) #define IS_I845G(dev_priv) IS_PLATFORM(dev_priv, INTEL_I845G) #define IS_I85X(dev_priv) IS_PLATFORM(dev_priv, INTEL_I85X) @@ -2319,7 +2321,9 @@ static inline unsigned int i915_sg_segment_size(void) #define IS_G4X(dev_priv) (IS_G45(dev_priv) || IS_GM45(dev_priv)) #define IS_PINEVIEW(dev_priv) IS_PLATFORM(dev_priv, INTEL_PINEVIEW) #define IS_G33(dev_priv) IS_PLATFORM(dev_priv, INTEL_G33) -#define IS_IRONLAKE_M(dev_priv) (INTEL_DEVID(dev_priv) == 0x0046) +#define IS_IRONLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_IRONLAKE) +#define IS_IRONLAKE_M(dev_priv) \ + (IS_PLATFORM(dev_priv, INTEL_IRONLAKE) && IS_MOBILE(dev_priv)) #define IS_IVYBRIDGE(dev_priv) IS_PLATFORM(dev_priv, INTEL_IVYBRIDGE) #define IS_IVB_GT1(dev_priv) (IS_IVYBRIDGE(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 1) @@ -2335,7 +2339,6 @@ static inline unsigned int i915_sg_segment_size(void) #define IS_CANNONLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_CANNONLAKE) #define IS_ICELAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_ICELAKE) #define IS_ELKHARTLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE) -#define IS_MOBILE(dev_priv) (INTEL_INFO(dev_priv)->is_mobile) #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) #define IS_BDW_ULT(dev_priv) (IS_BROADWELL(dev_priv) && \ -- cgit v1.2.3 From 805446c8347c9e743912cb7acf795683d9af7972 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 27 Mar 2019 14:23:28 +0000 Subject: drm/i915: Introduce concept of a sub-platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Concept of a sub-platform already exist in our code (like ULX and ULT platform variants and similar),implemented via the macros which check a list of device ids to determine a match. With this patch we consolidate device ids checking into a single function called during early driver load. A few low bits in the platform mask are reserved for sub-platform identification and defined as a per-platform namespace. At the same time it future proofs the platform_mask handling by preparing the code for easy extending, and tidies the very verbose WARN strings generated when IS_PLATFORM macros are embedded into a WARN type statements. v2: Fixed IS_SUBPLATFORM. Updated commit msg. v3: Chris was right, there is an ordering problem. v4: * Catch-up with new sub-platforms. * Rebase for RUNTIME_INFO. * Drop subplatform mask union tricks and convert platform_mask to an array for extensibility. v5: * Fix subplatform check. * Protect against forgetting to expand subplatform bits. * Remove platform enum tallying. * Add subplatform to error state. (Chris) * Drop macros and just use static inlines. * Remove redundant IRONLAKE_M. (Ville) v6: * Split out Ironlake change. * Optimize subplatform check. * Use __always_inline. (Lucas) * Add platform_mask comment. (Paulo) * Pass stored runtime info in error capture. (Chris) v7: * Rebased for new AML ULX device id. * Bump platform mask array size for EHL. * Stop mentioning device ids in intel_device_subplatform_init by using the trick of splitting macros i915_pciids.h. (Jani) * AML seems to be either a subplatform of KBL or CFL so express it like that. v8: * Use one device id table per subplatform. (Jani) Signed-off-by: Tvrtko Ursulin Suggested-by: Chris Wilson Cc: Chris Wilson Cc: Jani Nikula Cc: Lucas De Marchi Cc: Jose Souza Cc: Ville Syrjälä Cc: Paulo Zanoni Reviewed-by: Chris Wilson Acked-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190327142328.31780-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.c | 8 +- drivers/gpu/drm/i915/i915_drv.h | 123 +++++++++++++++++++++---------- drivers/gpu/drm/i915/i915_gpu_error.c | 3 + drivers/gpu/drm/i915/i915_pci.c | 2 +- drivers/gpu/drm/i915/intel_device_info.c | 93 +++++++++++++++++++++++ drivers/gpu/drm/i915/intel_device_info.h | 27 ++++++- 6 files changed, 214 insertions(+), 42 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4d5f3f2d94ee..0ca57dc5da5c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -868,6 +868,8 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv) if (i915_inject_load_failure()) return -ENODEV; + intel_device_info_subplatform_init(dev_priv); + spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->gpu_error.lock); mutex_init(&dev_priv->backlight_lock); @@ -1760,10 +1762,12 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) if (drm_debug & DRM_UT_DRIVER) { struct drm_printer p = drm_debug_printer("i915 device info:"); - drm_printf(&p, "pciid=0x%04x rev=0x%02x platform=%s gen=%i\n", + drm_printf(&p, "pciid=0x%04x rev=0x%02x platform=%s (subplatform=0x%x) gen=%i\n", INTEL_DEVID(dev_priv), INTEL_REVID(dev_priv), intel_platform_name(INTEL_INFO(dev_priv)->platform), + intel_subplatform(RUNTIME_INFO(dev_priv), + INTEL_INFO(dev_priv)->platform), INTEL_GEN(dev_priv)); intel_device_info_dump_flags(INTEL_INFO(dev_priv), &p); @@ -1806,8 +1810,6 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) memcpy(device_info, match_info, sizeof(*device_info)); RUNTIME_INFO(i915)->device_id = pdev->device; - BUILD_BUG_ON(INTEL_MAX_PLATFORMS > - BITS_PER_TYPE(device_info->platform_mask)); BUG_ON(device_info->gen > BITS_PER_TYPE(device_info->gen_mask)); return i915; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b2a9955b39ae..5a94c7430e62 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2302,7 +2302,67 @@ static inline unsigned int i915_sg_segment_size(void) #define IS_REVID(p, since, until) \ (INTEL_REVID(p) >= (since) && INTEL_REVID(p) <= (until)) -#define IS_PLATFORM(dev_priv, p) (INTEL_INFO(dev_priv)->platform_mask & BIT(p)) +static __always_inline unsigned int +__platform_mask_index(const struct intel_runtime_info *info, + enum intel_platform p) +{ + const unsigned int pbits = + BITS_PER_TYPE(info->platform_mask[0]) - INTEL_SUBPLATFORM_BITS; + + /* Expand the platform_mask array if this fails. */ + BUILD_BUG_ON(INTEL_MAX_PLATFORMS > + pbits * ARRAY_SIZE(info->platform_mask)); + + return p / pbits; +} + +static __always_inline unsigned int +__platform_mask_bit(const struct intel_runtime_info *info, + enum intel_platform p) +{ + const unsigned int pbits = + BITS_PER_TYPE(info->platform_mask[0]) - INTEL_SUBPLATFORM_BITS; + + return p % pbits + INTEL_SUBPLATFORM_BITS; +} + +static inline u32 +intel_subplatform(const struct intel_runtime_info *info, enum intel_platform p) +{ + const unsigned int pi = __platform_mask_index(info, p); + + return info->platform_mask[pi] & INTEL_SUBPLATFORM_BITS; +} + +static __always_inline bool +IS_PLATFORM(const struct drm_i915_private *i915, enum intel_platform p) +{ + const struct intel_runtime_info *info = RUNTIME_INFO(i915); + const unsigned int pi = __platform_mask_index(info, p); + const unsigned int pb = __platform_mask_bit(info, p); + + BUILD_BUG_ON(!__builtin_constant_p(p)); + + return info->platform_mask[pi] & BIT(pb); +} + +static __always_inline bool +IS_SUBPLATFORM(const struct drm_i915_private *i915, + enum intel_platform p, unsigned int s) +{ + const struct intel_runtime_info *info = RUNTIME_INFO(i915); + const unsigned int pi = __platform_mask_index(info, p); + const unsigned int pb = __platform_mask_bit(info, p); + const unsigned int msb = BITS_PER_TYPE(info->platform_mask[0]) - 1; + const u32 mask = info->platform_mask[pi]; + + BUILD_BUG_ON(!__builtin_constant_p(p)); + BUILD_BUG_ON(!__builtin_constant_p(s)); + BUILD_BUG_ON((s) >= INTEL_SUBPLATFORM_BITS); + + /* Shift and test on the MSB position so sign flag can be used. */ + return ((mask << (msb - pb)) & (mask << (msb - s))) & BIT(msb); +} #define IS_MOBILE(dev_priv) (INTEL_INFO(dev_priv)->is_mobile) @@ -2341,43 +2401,32 @@ static inline unsigned int i915_sg_segment_size(void) #define IS_ELKHARTLAKE(dev_priv) IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE) #define IS_HSW_EARLY_SDV(dev_priv) (IS_HASWELL(dev_priv) && \ (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0C00) -#define IS_BDW_ULT(dev_priv) (IS_BROADWELL(dev_priv) && \ - ((INTEL_DEVID(dev_priv) & 0xf) == 0x6 || \ - (INTEL_DEVID(dev_priv) & 0xf) == 0xb || \ - (INTEL_DEVID(dev_priv) & 0xf) == 0xe)) -/* ULX machines are also considered ULT. */ -#define IS_BDW_ULX(dev_priv) (IS_BROADWELL(dev_priv) && \ - (INTEL_DEVID(dev_priv) & 0xf) == 0xe) +#define IS_BDW_ULT(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_BROADWELL, INTEL_SUBPLATFORM_ULT) +#define IS_BDW_ULX(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_BROADWELL, INTEL_SUBPLATFORM_ULX) #define IS_BDW_GT3(dev_priv) (IS_BROADWELL(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 3) -#define IS_HSW_ULT(dev_priv) (IS_HASWELL(dev_priv) && \ - (INTEL_DEVID(dev_priv) & 0xFF00) == 0x0A00) +#define IS_HSW_ULT(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_HASWELL, INTEL_SUBPLATFORM_ULT) #define IS_HSW_GT3(dev_priv) (IS_HASWELL(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 3) #define IS_HSW_GT1(dev_priv) (IS_HASWELL(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 1) /* ULX machines are also considered ULT. */ -#define IS_HSW_ULX(dev_priv) (INTEL_DEVID(dev_priv) == 0x0A0E || \ - INTEL_DEVID(dev_priv) == 0x0A1E) -#define IS_SKL_ULT(dev_priv) (INTEL_DEVID(dev_priv) == 0x1906 || \ - INTEL_DEVID(dev_priv) == 0x1913 || \ - INTEL_DEVID(dev_priv) == 0x1916 || \ - INTEL_DEVID(dev_priv) == 0x1921 || \ - INTEL_DEVID(dev_priv) == 0x1926) -#define IS_SKL_ULX(dev_priv) (INTEL_DEVID(dev_priv) == 0x190E || \ - INTEL_DEVID(dev_priv) == 0x1915 || \ - INTEL_DEVID(dev_priv) == 0x191E) -#define IS_KBL_ULT(dev_priv) (INTEL_DEVID(dev_priv) == 0x5906 || \ - INTEL_DEVID(dev_priv) == 0x5913 || \ - INTEL_DEVID(dev_priv) == 0x5916 || \ - INTEL_DEVID(dev_priv) == 0x5921 || \ - INTEL_DEVID(dev_priv) == 0x5926) -#define IS_KBL_ULX(dev_priv) (INTEL_DEVID(dev_priv) == 0x590E || \ - INTEL_DEVID(dev_priv) == 0x5915 || \ - INTEL_DEVID(dev_priv) == 0x591E) -#define IS_AML_ULX(dev_priv) (INTEL_DEVID(dev_priv) == 0x591C || \ - INTEL_DEVID(dev_priv) == 0x87C0 || \ - INTEL_DEVID(dev_priv) == 0x87CA) +#define IS_HSW_ULX(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_HASWELL, INTEL_SUBPLATFORM_ULX) +#define IS_SKL_ULT(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_SKYLAKE, INTEL_SUBPLATFORM_ULT) +#define IS_SKL_ULX(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_SKYLAKE, INTEL_SUBPLATFORM_ULX) +#define IS_KBL_ULT(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_KABYLAKE, INTEL_SUBPLATFORM_ULT) +#define IS_KBL_ULX(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_KABYLAKE, INTEL_SUBPLATFORM_ULX) +#define IS_AML_ULX(dev_priv) \ + (IS_SUBPLATFORM(dev_priv, INTEL_KABYLAKE, INTEL_SUBPLATFORM_AML) || \ + IS_SUBPLATFORM(dev_priv, INTEL_COFFEELAKE, INTEL_SUBPLATFORM_AML)) #define IS_SKL_GT2(dev_priv) (IS_SKYLAKE(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 2) #define IS_SKL_GT3(dev_priv) (IS_SKYLAKE(dev_priv) && \ @@ -2388,16 +2437,16 @@ static inline unsigned int i915_sg_segment_size(void) INTEL_INFO(dev_priv)->gt == 2) #define IS_KBL_GT3(dev_priv) (IS_KABYLAKE(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 3) -#define IS_CFL_ULT(dev_priv) (IS_COFFEELAKE(dev_priv) && \ - (INTEL_DEVID(dev_priv) & 0x00F0) == 0x00A0) +#define IS_CFL_ULT(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_COFFEELAKE, INTEL_SUBPLATFORM_ULT) #define IS_CFL_GT2(dev_priv) (IS_COFFEELAKE(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 2) #define IS_CFL_GT3(dev_priv) (IS_COFFEELAKE(dev_priv) && \ INTEL_INFO(dev_priv)->gt == 3) -#define IS_CNL_WITH_PORT_F(dev_priv) (IS_CANNONLAKE(dev_priv) && \ - (INTEL_DEVID(dev_priv) & 0x0004) == 0x0004) -#define IS_ICL_WITH_PORT_F(dev_priv) (IS_ICELAKE(dev_priv) && \ - INTEL_DEVID(dev_priv) != 0x8A51) +#define IS_CNL_WITH_PORT_F(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_CANNONLAKE, INTEL_SUBPLATFORM_PORTF) +#define IS_ICL_WITH_PORT_F(dev_priv) \ + IS_SUBPLATFORM(dev_priv, INTEL_ICELAKE, INTEL_SUBPLATFORM_PORTF) #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support) diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a2a98ccda421..81a27b808273 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -677,6 +677,9 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m, err_printf(m, "Reset count: %u\n", error->reset_count); err_printf(m, "Suspend count: %u\n", error->suspend_count); err_printf(m, "Platform: %s\n", intel_platform_name(error->device_info.platform)); + err_printf(m, "Subplatform: 0x%x\n", + intel_subplatform(&error->runtime_info, + error->device_info.platform)); err_print_pciid(m, m->i915); err_printf(m, "IOMMU enabled?: %d\n", error->iommu); diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 716f2f95c57d..39251586349a 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -32,7 +32,7 @@ #include "i915_globals.h" #include "i915_selftest.h" -#define PLATFORM(x) .platform = (x), .platform_mask = BIT(x) +#define PLATFORM(x) .platform = (x) #define GEN(x) .gen = (x), .gen_mask = BIT((x) - 1) #define I845_PIPE_OFFSETS \ diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index e0f5e0231d04..0ed49d032c00 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -714,6 +714,99 @@ static u32 read_timestamp_frequency(struct drm_i915_private *dev_priv) return 0; } +#undef INTEL_VGA_DEVICE +#define INTEL_VGA_DEVICE(id, info) (id) + +static const u16 subplatform_ult_ids[] = { + INTEL_HSW_ULT_GT1_IDS(0), + INTEL_HSW_ULT_GT2_IDS(0), + INTEL_HSW_ULT_GT3_IDS(0), + INTEL_BDW_ULT_GT1_IDS(0), + INTEL_BDW_ULT_GT2_IDS(0), + INTEL_BDW_ULT_GT3_IDS(0), + INTEL_BDW_ULT_RSVD_IDS(0), + INTEL_SKL_ULT_GT1_IDS(0), + INTEL_SKL_ULT_GT2_IDS(0), + INTEL_SKL_ULT_GT3_IDS(0), + INTEL_KBL_ULT_GT1_IDS(0), + INTEL_KBL_ULT_GT2_IDS(0), + INTEL_KBL_ULT_GT3_IDS(0), + INTEL_CFL_U_GT2_IDS(0), + INTEL_CFL_U_GT3_IDS(0), + INTEL_WHL_U_GT1_IDS(0), + INTEL_WHL_U_GT2_IDS(0), + INTEL_WHL_U_GT3_IDS(0) +}; + +static const u16 subplatform_ulx_ids[] = { + INTEL_HSW_ULX_GT1_IDS(0), + INTEL_HSW_ULX_GT2_IDS(0), + INTEL_BDW_ULX_GT1_IDS(0), + INTEL_BDW_ULX_GT2_IDS(0), + INTEL_BDW_ULX_GT3_IDS(0), + INTEL_BDW_ULX_RSVD_IDS(0), + INTEL_SKL_ULX_GT1_IDS(0), + INTEL_SKL_ULX_GT2_IDS(0), + INTEL_KBL_ULX_GT1_IDS(0), + INTEL_KBL_ULX_GT2_IDS(0) +}; + +static const u16 subplatform_aml_ids[] = { + INTEL_AML_KBL_GT2_IDS(0), + INTEL_AML_CFL_GT2_IDS(0) +}; + +static const u16 subplatform_portf_ids[] = { + INTEL_CNL_PORT_F_IDS(0), + INTEL_ICL_PORT_F_IDS(0) +}; + +static bool find_devid(u16 id, const u16 *p, unsigned int num) +{ + for (; num; num--, p++) { + if (*p == id) + return true; + } + + return false; +} + +void intel_device_info_subplatform_init(struct drm_i915_private *i915) +{ + const struct intel_device_info *info = INTEL_INFO(i915); + const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915); + const unsigned int pi = __platform_mask_index(rinfo, info->platform); + const unsigned int pb = __platform_mask_bit(rinfo, info->platform); + u16 devid = INTEL_DEVID(i915); + u32 mask; + + /* Make sure IS_ checks are working. */ + RUNTIME_INFO(i915)->platform_mask[pi] = BIT(pb); + + /* Find and mark subplatform bits based on the PCI device id. */ + if (find_devid(devid, subplatform_ult_ids, + ARRAY_SIZE(subplatform_ult_ids))) { + mask = BIT(INTEL_SUBPLATFORM_ULT); + } else if (find_devid(devid, subplatform_ulx_ids, + ARRAY_SIZE(subplatform_ulx_ids))) { + mask = BIT(INTEL_SUBPLATFORM_ULX); + if (IS_HASWELL(i915) || IS_BROADWELL(i915)) { + /* ULX machines are also considered ULT. */ + mask |= BIT(INTEL_SUBPLATFORM_ULT); + } + } else if (find_devid(devid, subplatform_aml_ids, + ARRAY_SIZE(subplatform_aml_ids))) { + mask = BIT(INTEL_SUBPLATFORM_AML); + } else if (find_devid(devid, subplatform_portf_ids, + ARRAY_SIZE(subplatform_portf_ids))) { + mask = BIT(INTEL_SUBPLATFORM_PORTF); + } + + GEM_BUG_ON(mask & ~INTEL_SUBPLATFORM_BITS); + + RUNTIME_INFO(i915)->platform_mask[pi] |= mask; +} + /** * intel_device_info_runtime_init - initialize runtime info * @dev_priv: the i915 device diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 7e04b4829aba..616e9f707877 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -77,6 +77,21 @@ enum intel_platform { INTEL_MAX_PLATFORMS }; +/* + * Subplatform bits share the same namespace per parent platform. In other words + * it is fine for the same bit to be used on multiple parent platforms. + */ + +#define INTEL_SUBPLATFORM_BITS (3) + +/* HSW/BDW/SKL/KBL/CFL */ +#define INTEL_SUBPLATFORM_ULT (0) +#define INTEL_SUBPLATFORM_ULX (1) +#define INTEL_SUBPLATFORM_AML (2) + +/* CNL/ICL */ +#define INTEL_SUBPLATFORM_PORTF (0) + enum intel_ppgtt_type { INTEL_PPGTT_NONE = I915_GEM_PPGTT_NONE, INTEL_PPGTT_ALIASING = I915_GEM_PPGTT_ALIASING, @@ -160,7 +175,6 @@ struct intel_device_info { intel_engine_mask_t engine_mask; /* Engines supported by the HW */ enum intel_platform platform; - u32 platform_mask; enum intel_ppgtt_type ppgtt_type; unsigned int ppgtt_size; /* log2, e.g. 31/32/48 bits */ @@ -197,6 +211,16 @@ struct intel_device_info { }; struct intel_runtime_info { + /* + * Platform mask is used for optimizing or-ed IS_PLATFORM calls into + * into single runtime conditionals, and also to provide groundwork + * for future per platform, or per SKU build optimizations. + * + * Array can be extended when necessary if the corresponding + * BUILD_BUG_ON is hit. + */ + u32 platform_mask[2]; + u16 device_id; u8 num_sprites[I915_MAX_PIPES]; @@ -267,6 +291,7 @@ static inline void sseu_set_eus(struct sseu_dev_info *sseu, const char *intel_platform_name(enum intel_platform platform); +void intel_device_info_subplatform_init(struct drm_i915_private *dev_priv); void intel_device_info_runtime_init(struct drm_i915_private *dev_priv); void intel_device_info_dump_flags(const struct intel_device_info *info, struct drm_printer *p); -- cgit v1.2.3 From a145b5b0e48783d0cd3ee605ed00b133d5c8ffed Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Mar 2019 16:51:52 +0000 Subject: drm/i915: Always backoff after a drm_modeset_lock() deadlock If drm_modeset_lock() reports a deadlock it sets the ctx->contexted field and insists that the caller calls drm_modeset_backoff() or else it generates a WARN on cleanup. <4> [1601.870376] WARNING: CPU: 3 PID: 8445 at drivers/gpu/drm/drm_modeset_lock.c:228 drm_modeset_drop_locks+0x35/0x40 <4> [1601.870395] Modules linked in: vgem snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal i915 coretemp crct10dif_pclmul <6> [1601.870403] Console: switching <4> [1601.870403] snd_hda_intel <4> [1601.870406] to colour frame buffer device 320x90 <4> [1601.870406] crc32_pclmul snd_hda_codec snd_hwdep ghash_clmulni_intel e1000e snd_hda_core cdc_ether ptp usbnet mii pps_core snd_pcm i2c_i801 mei_me mei prime_numbers <4> [1601.870422] CPU: 3 PID: 8445 Comm: cat Tainted: G U 5.0.0-rc7-CI-CI_DRM_5650+ #1 <4> [1601.870424] Hardware name: Intel Corporation Ice Lake Client Platform/IceLake U DDR4 SODIMM PD RVP TLC, BIOS ICLSFWR1.R00.2402.AD3.1810170014 10/17/2018 <4> [1601.870427] RIP: 0010:drm_modeset_drop_locks+0x35/0x40 <4> [1601.870430] Code: 29 48 8b 43 60 48 8d 6b 60 48 39 c5 74 19 48 8b 43 60 48 8d b8 70 ff ff ff e8 87 ff ff ff 48 8b 43 60 48 39 c5 75 e7 5b 5d c3 <0f> 0b eb d3 0f 1f 80 00 00 00 00 41 56 41 55 41 54 55 53 48 8b 6f <4> [1601.870432] RSP: 0018:ffffc90000d67ce8 EFLAGS: 00010282 <4> [1601.870435] RAX: 00000000ffffffdd RBX: ffffc90000d67d00 RCX: 5dbbe23d00000000 <4> [1601.870437] RDX: 0000000000000000 RSI: 0000000093e6194a RDI: ffffc90000d67d00 <4> [1601.870439] RBP: ffff88849e62e678 R08: 0000000003b7329a R09: 0000000000000001 <4> [1601.870441] R10: 0000000000000000 R11: 0000000000000000 R12: ffff888492100410 <4> [1601.870442] R13: ffff88849ea50958 R14: ffff8884a67eb028 R15: ffff8884a67eb028 <4> [1601.870445] FS: 00007fa7a27745c0(0000) GS:ffff8884aff80000(0000) knlGS:0000000000000000 <4> [1601.870447] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 <4> [1601.870449] CR2: 000055af07e66000 CR3: 00000004a8cc2006 CR4: 0000000000760ee0 <4> [1601.870451] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 <4> [1601.870453] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 <4> [1601.870454] PKRU: 55555554 <4> [1601.870456] Call Trace: <4> [1601.870505] i915_dsc_fec_support_show+0x91/0x190 [i915] <4> [1601.870522] seq_read+0xdb/0x3c0 <4> [1601.870531] full_proxy_read+0x51/0x80 <4> [1601.870538] __vfs_read+0x31/0x190 <4> [1601.870546] ? __se_sys_newfstat+0x3c/0x60 <4> [1601.870552] vfs_read+0x9e/0x150 <4> [1601.870557] ksys_read+0x50/0xc0 <4> [1601.870564] do_syscall_64+0x55/0x190 <4> [1601.870569] entry_SYSCALL_64_after_hwframe+0x49/0xbe <4> [1601.870572] RIP: 0033:0x7fa7a226d081 <4> [1601.870574] Code: fe ff ff 48 8d 3d 67 9c 0a 00 48 83 ec 08 e8 a6 4c 02 00 66 0f 1f 44 00 00 48 8d 05 81 08 2e 00 8b 00 85 c0 75 13 31 c0 0f 05 <48> 3d 00 f0 ff ff 77 57 f3 c3 0f 1f 44 00 00 41 54 55 49 89 d4 53 <4> [1601.870576] RSP: 002b:00007ffcc05140c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 <4> [1601.870579] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fa7a226d081 <4> [1601.870581] RDX: 0000000000020000 RSI: 000055af07e63000 RDI: 0000000000000007 <4> [1601.870583] RBP: 0000000000020000 R08: 000000000000007b R09: 0000000000000000 <4> [1601.870585] R10: 000055af07e60010 R11: 0000000000000246 R12: 000055af07e63000 <4> [1601.870587] R13: 0000000000000007 R14: 000055af07e634bf R15: 0000000000020000 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109745 Fixes: e845f099f1c6 ("drm/i915/dsc: Add Per connector debugfs node for DSC support/enable") Signed-off-by: Chris Wilson Cc: Rodrigo Vivi Cc: Ville Syrjala Cc: Anusha Srivatsa Cc: Lyude Paul Cc: Manasi Navare Reviewed-by: Manasi Navare Link: https://patchwork.freedesktop.org/patch/msgid/20190329165152.29259-1-chris@chris-wilson.co.uk (cherry picked from commit ee6df5694a9a2e30566ae05e9c145a0f6d5e087f) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_debugfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0bd890c04fe4..f6f6e5b78e97 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4830,7 +4830,10 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data) ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); if (ret) { - ret = -EINTR; + if (ret == -EDEADLK && !drm_modeset_backoff(&ctx)) { + try_again = true; + continue; + } break; } crtc = connector->state->crtc; -- cgit v1.2.3 From 2d85978341e6a32e7443d9f28639da254d53f400 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Mar 2019 17:31:30 +0300 Subject: drm/mediatek: Fix an error code in mtk_hdmi_dt_parse_pdata() We don't want to overwrite "ret", it already holds the correct error code. The "regmap" variable might be a valid pointer as this point. Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support") Signed-off-by: Dan Carpenter Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 915cc84621ae..543a25e5765e 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1480,7 +1480,6 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, if (IS_ERR(regmap)) ret = PTR_ERR(regmap); if (ret) { - ret = PTR_ERR(regmap); dev_err(dev, "Failed to get system configuration registers: %d\n", ret); -- cgit v1.2.3 From b01720bfcdf9d4410a2968fac0769246ea3de81b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Apr 2019 14:39:09 +0100 Subject: drm/i915: Prefault before locking pages in shmem_pwrite If the user passes in a pointer to a GGTT mmaping of the same buffer being written to, we can hit a deadlock in acquiring the shmemfs page (once as the write destination and then as the read source). [<0>] io_schedule+0xd/0x30 [<0>] __lock_page+0x105/0x1b0 [<0>] find_lock_entry+0x55/0x90 [<0>] shmem_getpage_gfp+0xbb/0x800 [<0>] shmem_read_mapping_page_gfp+0x2d/0x50 [<0>] shmem_get_pages+0x158/0x5d0 [i915] [<0>] ____i915_gem_object_get_pages+0x17/0x90 [i915] [<0>] __i915_gem_object_get_pages+0x57/0x70 [i915] [<0>] i915_gem_fault+0x1b4/0x5c0 [i915] [<0>] __do_fault+0x2d/0x80 [<0>] __handle_mm_fault+0xad4/0xfb0 [<0>] handle_mm_fault+0xe6/0x1f0 [<0>] __do_page_fault+0x18f/0x3f0 [<0>] page_fault+0x1b/0x20 [<0>] copy_user_enhanced_fast_string+0x7/0x10 [<0>] _copy_from_user+0x37/0x60 [<0>] shmem_pwrite+0xf0/0x160 [i915] [<0>] i915_gem_pwrite_ioctl+0x14e/0x520 [i915] [<0>] drm_ioctl_kernel+0x81/0xd0 [<0>] drm_ioctl+0x1a7/0x310 [<0>] do_vfs_ioctl+0x88/0x5d0 [<0>] ksys_ioctl+0x35/0x70 [<0>] __x64_sys_ioctl+0x11/0x20 [<0>] do_syscall_64+0x39/0xe0 [<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 We can reduce (but not eliminate!) the chance of this happening by faulting the user_data before we take the page lock in pagecache_write_begin(). One way to eliminate the potential recursion here is by disabling pagefaults for the copy, and handling the fallback to use an alternative method -- so convert to use kmap_atomic (which should disable preemption and pagefaulting for the copy) and report ENODEV instead of EFAULT so that our caller tries again with a different copy mechanism -- we already check that the page should have been faultable so a false negative should be rare. Testcase: igt/gem_pwrite/self Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Matthew Auld Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20190401133909.31203-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c3b4ec52e1b7..bf594a5e88bc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2788,7 +2788,11 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, u64 remain, offset; unsigned int pg; - /* Before we instantiate/pin the backing store for our use, we + /* Caller already validated user args */ + GEM_BUG_ON(!access_ok(user_data, arg->size)); + + /* + * Before we instantiate/pin the backing store for our use, we * can prepopulate the shmemfs filp efficiently using a write into * the pagecache. We avoid the penalty of instantiating all the * pages, important if the user is just writing to a few and never @@ -2802,7 +2806,8 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, if (obj->mm.madv != I915_MADV_WILLNEED) return -EFAULT; - /* Before the pages are instantiated the object is treated as being + /* + * Before the pages are instantiated the object is treated as being * in the CPU domain. The pages will be clflushed as required before * use, and we can freely write into the pages directly. If userspace * races pwrite with any other operation; corruption will ensue - @@ -2818,20 +2823,32 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, struct page *page; void *data, *vaddr; int err; + char c; len = PAGE_SIZE - pg; if (len > remain) len = remain; + /* Prefault the user page to reduce potential recursion */ + err = __get_user(c, user_data); + if (err) + return err; + + err = __get_user(c, user_data + len - 1); + if (err) + return err; + err = pagecache_write_begin(obj->base.filp, mapping, offset, len, 0, &page, &data); if (err < 0) return err; - vaddr = kmap(page); - unwritten = copy_from_user(vaddr + pg, user_data, len); - kunmap(page); + vaddr = kmap_atomic(page); + unwritten = __copy_from_user_inatomic(vaddr + pg, + user_data, + len); + kunmap_atomic(vaddr); err = pagecache_write_end(obj->base.filp, mapping, offset, len, len - unwritten, @@ -2839,8 +2856,9 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj, if (err < 0) return err; + /* We don't handle -EFAULT, leave it to the caller to check */ if (unwritten) - return -EFAULT; + return -ENODEV; remain -= len; user_data += len; -- cgit v1.2.3 From 3a891a62679424e5625a551b9af9c33af6ea59b3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Apr 2019 17:26:39 +0100 Subject: drm/i915: Move intel_engine_mask_t around for use by i915_request_types.h We want to use intel_engine_mask_t inside i915_request.h, which means extracting it from the general header file mess and placing it inside a types.h. A knock on effect is that the compiler wants to warn about type-contraction of ALL_ENGINES into intel_engine_maskt_t, so prepare for the worst. v2: Use intel_engine_mask_t consistently v3: Move I915_NUM_ENGINES to its natural home at the end of the enum Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala Cc: John Harrison Link: https://patchwork.freedesktop.org/patch/msgid/20190401162641.10963-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/gvt/execlist.c | 11 +-- drivers/gpu/drm/i915/gvt/execlist.h | 2 +- drivers/gpu/drm/i915/gvt/gvt.h | 8 +- drivers/gpu/drm/i915/gvt/handlers.c | 2 +- drivers/gpu/drm/i915/gvt/scheduler.c | 8 +- drivers/gpu/drm/i915/gvt/scheduler.h | 6 +- drivers/gpu/drm/i915/gvt/vgpu.c | 4 +- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_gem.h | 2 - drivers/gpu/drm/i915/i915_gem_context.c | 6 +- drivers/gpu/drm/i915/i915_gem_context.h | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.h | 2 +- drivers/gpu/drm/i915/i915_gpu_error.c | 9 +- drivers/gpu/drm/i915/i915_gpu_error.h | 2 +- drivers/gpu/drm/i915/i915_reset.c | 43 +++++----- drivers/gpu/drm/i915/i915_reset.h | 9 +- drivers/gpu/drm/i915/i915_scheduler.h | 86 +------------------ drivers/gpu/drm/i915/i915_scheduler_types.h | 98 ++++++++++++++++++++++ drivers/gpu/drm/i915/i915_timeline.h | 1 + drivers/gpu/drm/i915/i915_timeline_types.h | 3 +- drivers/gpu/drm/i915/intel_device_info.h | 3 +- drivers/gpu/drm/i915/intel_engine_types.h | 11 ++- drivers/gpu/drm/i915/intel_guc_submission.h | 1 + drivers/gpu/drm/i915/intel_hangcheck.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_context.c | 8 +- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 3 +- .../i915/test_i915_scheduler_types_standalone.c | 7 ++ 29 files changed, 191 insertions(+), 152 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_scheduler_types.h create mode 100644 drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 60de05f3fa60..1f3e8b145fc0 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -61,6 +61,7 @@ i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o i915-$(CONFIG_DRM_I915_WERROR) += \ test_i915_active_types_standalone.o \ test_i915_gem_context_types_standalone.o \ + test_i915_scheduler_types_standalone.o \ test_i915_timeline_types_standalone.o \ test_intel_context_types_standalone.o \ test_intel_engine_types_standalone.o \ diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c index 1a93472cb34e..f21b8fb5b37e 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.c +++ b/drivers/gpu/drm/i915/gvt/execlist.c @@ -526,12 +526,13 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id) vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw; } -static void clean_execlist(struct intel_vgpu *vgpu, unsigned long engine_mask) +static void clean_execlist(struct intel_vgpu *vgpu, + intel_engine_mask_t engine_mask) { - unsigned int tmp; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct intel_engine_cs *engine; struct intel_vgpu_submission *s = &vgpu->submission; + intel_engine_mask_t tmp; for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { kfree(s->ring_scan_buffer[engine->id]); @@ -541,18 +542,18 @@ static void clean_execlist(struct intel_vgpu *vgpu, unsigned long engine_mask) } static void reset_execlist(struct intel_vgpu *vgpu, - unsigned long engine_mask) + intel_engine_mask_t engine_mask) { struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct intel_engine_cs *engine; - unsigned int tmp; + intel_engine_mask_t tmp; for_each_engine_masked(engine, dev_priv, engine_mask, tmp) init_vgpu_execlist(vgpu, engine->id); } static int init_execlist(struct intel_vgpu *vgpu, - unsigned long engine_mask) + intel_engine_mask_t engine_mask) { reset_execlist(vgpu, engine_mask); return 0; diff --git a/drivers/gpu/drm/i915/gvt/execlist.h b/drivers/gpu/drm/i915/gvt/execlist.h index 714d709829a2..5ccc2c695848 100644 --- a/drivers/gpu/drm/i915/gvt/execlist.h +++ b/drivers/gpu/drm/i915/gvt/execlist.h @@ -180,6 +180,6 @@ int intel_vgpu_init_execlist(struct intel_vgpu *vgpu); int intel_vgpu_submit_execlist(struct intel_vgpu *vgpu, int ring_id); void intel_vgpu_reset_execlist(struct intel_vgpu *vgpu, - unsigned long engine_mask); + intel_engine_mask_t engine_mask); #endif /*_GVT_EXECLIST_H_*/ diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 8bce09de4b82..7a4e1a6387e5 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -144,9 +144,9 @@ enum { struct intel_vgpu_submission_ops { const char *name; - int (*init)(struct intel_vgpu *vgpu, unsigned long engine_mask); - void (*clean)(struct intel_vgpu *vgpu, unsigned long engine_mask); - void (*reset)(struct intel_vgpu *vgpu, unsigned long engine_mask); + int (*init)(struct intel_vgpu *vgpu, intel_engine_mask_t engine_mask); + void (*clean)(struct intel_vgpu *vgpu, intel_engine_mask_t engine_mask); + void (*reset)(struct intel_vgpu *vgpu, intel_engine_mask_t engine_mask); }; struct intel_vgpu_submission { @@ -488,7 +488,7 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt, void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu); void intel_gvt_release_vgpu(struct intel_vgpu *vgpu); void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, - unsigned int engine_mask); + intel_engine_mask_t engine_mask); void intel_gvt_reset_vgpu(struct intel_vgpu *vgpu); void intel_gvt_activate_vgpu(struct intel_vgpu *vgpu); void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu); diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index dbc749617922..86761b1def1e 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -311,7 +311,7 @@ static int mul_force_wake_write(struct intel_vgpu *vgpu, static int gdrst_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { - unsigned int engine_mask = 0; + intel_engine_mask_t engine_mask = 0; u32 data; write_vreg(vgpu, offset, p_data, bytes); diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c index 3faf2438b9bc..b385edbeaa30 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.c +++ b/drivers/gpu/drm/i915/gvt/scheduler.c @@ -838,13 +838,13 @@ static void update_guest_context(struct intel_vgpu_workload *workload) } void intel_vgpu_clean_workloads(struct intel_vgpu *vgpu, - unsigned long engine_mask) + intel_engine_mask_t engine_mask) { struct intel_vgpu_submission *s = &vgpu->submission; struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; struct intel_engine_cs *engine; struct intel_vgpu_workload *pos, *n; - unsigned int tmp; + intel_engine_mask_t tmp; /* free the unsubmited workloads in the queues. */ for_each_engine_masked(engine, dev_priv, engine_mask, tmp) { @@ -1137,7 +1137,7 @@ void intel_vgpu_clean_submission(struct intel_vgpu *vgpu) * */ void intel_vgpu_reset_submission(struct intel_vgpu *vgpu, - unsigned long engine_mask) + intel_engine_mask_t engine_mask) { struct intel_vgpu_submission *s = &vgpu->submission; @@ -1227,7 +1227,7 @@ out_shadow_ctx: * */ int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu, - unsigned long engine_mask, + intel_engine_mask_t engine_mask, unsigned int interface) { struct intel_vgpu_submission *s = &vgpu->submission; diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h index 0635b2c4bed7..90c6756f5453 100644 --- a/drivers/gpu/drm/i915/gvt/scheduler.h +++ b/drivers/gpu/drm/i915/gvt/scheduler.h @@ -142,12 +142,12 @@ void intel_gvt_wait_vgpu_idle(struct intel_vgpu *vgpu); int intel_vgpu_setup_submission(struct intel_vgpu *vgpu); void intel_vgpu_reset_submission(struct intel_vgpu *vgpu, - unsigned long engine_mask); + intel_engine_mask_t engine_mask); void intel_vgpu_clean_submission(struct intel_vgpu *vgpu); int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu, - unsigned long engine_mask, + intel_engine_mask_t engine_mask, unsigned int interface); extern const struct intel_vgpu_submission_ops @@ -160,6 +160,6 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id, void intel_vgpu_destroy_workload(struct intel_vgpu_workload *workload); void intel_vgpu_clean_workloads(struct intel_vgpu *vgpu, - unsigned long engine_mask); + intel_engine_mask_t engine_mask); #endif diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 314e40121e47..44ce3c2b9ac1 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -526,11 +526,11 @@ struct intel_vgpu *intel_gvt_create_vgpu(struct intel_gvt *gvt, * GPU engines. For FLR, engine_mask is ignored. */ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, - unsigned int engine_mask) + intel_engine_mask_t engine_mask) { struct intel_gvt *gvt = vgpu->gvt; struct intel_gvt_workload_scheduler *scheduler = &gvt->scheduler; - unsigned int resetting_eng = dmlr ? ALL_ENGINES : engine_mask; + intel_engine_mask_t resetting_eng = dmlr ? ALL_ENGINES : engine_mask; gvt_dbg_core("------------------------------------------\n"); gvt_dbg_core("resseting vgpu%d, dmlr %d, engine_mask %08x\n", diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3aef121067e4..4dd2d9ae3202 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2245,7 +2245,7 @@ static int i915_guc_stage_pool(struct seq_file *m, void *data) const struct intel_guc *guc = &dev_priv->guc; struct guc_stage_desc *desc = guc->stage_desc_pool_vaddr; struct intel_guc_client *client = guc->execbuf_client; - unsigned int tmp; + intel_engine_mask_t tmp; int index; if (!USES_GUC_SUBMISSION(dev_priv)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5a94c7430e62..0ab4826921f7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2505,7 +2505,6 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define IS_GEN9_LP(dev_priv) (IS_GEN(dev_priv, 9) && IS_LP(dev_priv)) #define IS_GEN9_BC(dev_priv) (IS_GEN(dev_priv, 9) && !IS_LP(dev_priv)) -#define ALL_ENGINES (~0u) #define HAS_ENGINE(dev_priv, id) (INTEL_INFO(dev_priv)->engine_mask & BIT(id)) #define ENGINE_INSTANCES_MASK(dev_priv, first, count) ({ \ diff --git a/drivers/gpu/drm/i915/i915_gem.h b/drivers/gpu/drm/i915/i915_gem.h index 5c073fe73664..9074eb1e843f 100644 --- a/drivers/gpu/drm/i915/i915_gem.h +++ b/drivers/gpu/drm/i915/i915_gem.h @@ -73,8 +73,6 @@ struct drm_i915_private; #define GEM_TRACE_DUMP_ON(expr) BUILD_BUG_ON_INVALID(expr) #endif -#define I915_NUM_ENGINES 8 - #define I915_GEM_IDLE_TIMEOUT (HZ / 5) void i915_gem_park(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 141da4e71e46..fe7ddb1f59e1 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -858,9 +858,9 @@ static void cb_retire(struct i915_active *base) kfree(cb); } -I915_SELFTEST_DECLARE(static unsigned long context_barrier_inject_fault); +I915_SELFTEST_DECLARE(static intel_engine_mask_t context_barrier_inject_fault); static int context_barrier_task(struct i915_gem_context *ctx, - unsigned long engines, + intel_engine_mask_t engines, int (*emit)(struct i915_request *rq, void *data), void (*task)(void *data), void *data) @@ -922,7 +922,7 @@ static int context_barrier_task(struct i915_gem_context *ctx, } int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915, - unsigned long mask) + intel_engine_mask_t mask) { struct intel_engine_cs *engine; diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index edc6ba3f0288..23dcb01bfd82 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h @@ -142,7 +142,7 @@ void i915_gem_context_close(struct drm_file *file); int i915_switch_context(struct i915_request *rq); int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915, - unsigned long engine_mask); + intel_engine_mask_t engine_mask); void i915_gem_context_release(struct kref *ctx_ref); struct i915_gem_context * diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 83ded9fc761a..f597f35b109b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -390,7 +390,7 @@ struct i915_hw_ppgtt { struct i915_address_space vm; struct kref ref; - unsigned long pd_dirty_engines; + intel_engine_mask_t pd_dirty_engines; union { struct i915_pml4 pml4; /* GEN8+ & 48b PPGTT */ struct i915_page_directory_pointer pdp; /* GEN8+ */ diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 81a27b808273..c65d45bc63ee 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1096,7 +1096,7 @@ static u32 capture_error_bo(struct drm_i915_error_buffer *err, * It's only a small step better than a random number in its current form. */ static u32 i915_error_generate_code(struct i915_gpu_state *error, - unsigned long engine_mask) + intel_engine_mask_t engine_mask) { /* * IPEHR would be an ideal way to detect errors, as it's the gross @@ -1641,7 +1641,8 @@ static void capture_reg_state(struct i915_gpu_state *error) } static const char * -error_msg(struct i915_gpu_state *error, unsigned long engines, const char *msg) +error_msg(struct i915_gpu_state *error, + intel_engine_mask_t engines, const char *msg) { int len; int i; @@ -1651,7 +1652,7 @@ error_msg(struct i915_gpu_state *error, unsigned long engines, const char *msg) engines &= ~BIT(i); len = scnprintf(error->error_msg, sizeof(error->error_msg), - "GPU HANG: ecode %d:%lx:0x%08x", + "GPU HANG: ecode %d:%x:0x%08x", INTEL_GEN(error->i915), engines, i915_error_generate_code(error, engines)); if (engines) { @@ -1790,7 +1791,7 @@ i915_capture_gpu_state(struct drm_i915_private *i915) * to pick up. */ void i915_capture_error_state(struct drm_i915_private *i915, - unsigned long engine_mask, + intel_engine_mask_t engine_mask, const char *msg) { static bool warned; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h index 302a14240b45..5dc761e85d9d 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.h +++ b/drivers/gpu/drm/i915/i915_gpu_error.h @@ -263,7 +263,7 @@ void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...); struct i915_gpu_state *i915_capture_gpu_state(struct drm_i915_private *i915); void i915_capture_error_state(struct drm_i915_private *dev_priv, - unsigned long engine_mask, + intel_engine_mask_t engine_mask, const char *error_msg); static inline struct i915_gpu_state * diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c index 2f25ed702ba0..ddc403ee8855 100644 --- a/drivers/gpu/drm/i915/i915_reset.c +++ b/drivers/gpu/drm/i915/i915_reset.c @@ -144,15 +144,15 @@ static void gen3_stop_engine(struct intel_engine_cs *engine) } static void i915_stop_engines(struct drm_i915_private *i915, - unsigned int engine_mask) + intel_engine_mask_t engine_mask) { struct intel_engine_cs *engine; - enum intel_engine_id id; + intel_engine_mask_t tmp; if (INTEL_GEN(i915) < 3) return; - for_each_engine_masked(engine, i915, engine_mask, id) + for_each_engine_masked(engine, i915, engine_mask, tmp) gen3_stop_engine(engine); } @@ -165,7 +165,7 @@ static bool i915_in_reset(struct pci_dev *pdev) } static int i915_do_reset(struct drm_i915_private *i915, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry) { struct pci_dev *pdev = i915->drm.pdev; @@ -194,7 +194,7 @@ static bool g4x_reset_complete(struct pci_dev *pdev) } static int g33_do_reset(struct drm_i915_private *i915, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry) { struct pci_dev *pdev = i915->drm.pdev; @@ -204,7 +204,7 @@ static int g33_do_reset(struct drm_i915_private *i915, } static int g4x_do_reset(struct drm_i915_private *dev_priv, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry) { struct pci_dev *pdev = dev_priv->drm.pdev; @@ -242,7 +242,7 @@ out: } static int ironlake_do_reset(struct drm_i915_private *dev_priv, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry) { struct intel_uncore *uncore = &dev_priv->uncore; @@ -303,7 +303,7 @@ static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv, } static int gen6_reset_engines(struct drm_i915_private *i915, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry) { struct intel_engine_cs *engine; @@ -319,7 +319,7 @@ static int gen6_reset_engines(struct drm_i915_private *i915, if (engine_mask == ALL_ENGINES) { hw_mask = GEN6_GRDOM_FULL; } else { - unsigned int tmp; + intel_engine_mask_t tmp; hw_mask = 0; for_each_engine_masked(engine, i915, engine_mask, tmp) { @@ -429,7 +429,7 @@ static void gen11_unlock_sfc(struct drm_i915_private *dev_priv, } static int gen11_reset_engines(struct drm_i915_private *i915, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry) { const u32 hw_engine_mask[] = { @@ -443,7 +443,7 @@ static int gen11_reset_engines(struct drm_i915_private *i915, [VECS1] = GEN11_GRDOM_VECS2, }; struct intel_engine_cs *engine; - unsigned int tmp; + intel_engine_mask_t tmp; u32 hw_mask; int ret; @@ -496,12 +496,12 @@ static void gen8_engine_reset_cancel(struct intel_engine_cs *engine) } static int gen8_reset_engines(struct drm_i915_private *i915, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry) { struct intel_engine_cs *engine; const bool reset_non_ready = retry >= 1; - unsigned int tmp; + intel_engine_mask_t tmp; int ret; for_each_engine_masked(engine, i915, engine_mask, tmp) { @@ -537,7 +537,7 @@ skip_reset: } typedef int (*reset_func)(struct drm_i915_private *, - unsigned int engine_mask, + intel_engine_mask_t engine_mask, unsigned int retry); static reset_func intel_get_gpu_reset(struct drm_i915_private *i915) @@ -558,7 +558,8 @@ static reset_func intel_get_gpu_reset(struct drm_i915_private *i915) return NULL; } -int intel_gpu_reset(struct drm_i915_private *i915, unsigned int engine_mask) +int intel_gpu_reset(struct drm_i915_private *i915, + intel_engine_mask_t engine_mask) { const int retries = engine_mask == ALL_ENGINES ? RESET_MAX_RETRIES : 1; reset_func reset; @@ -692,7 +693,8 @@ static void gt_revoke(struct drm_i915_private *i915) revoke_mmaps(i915); } -static int gt_reset(struct drm_i915_private *i915, unsigned int stalled_mask) +static int gt_reset(struct drm_i915_private *i915, + intel_engine_mask_t stalled_mask) { struct intel_engine_cs *engine; enum intel_engine_id id; @@ -951,7 +953,8 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915) return result; } -static int do_reset(struct drm_i915_private *i915, unsigned int stalled_mask) +static int do_reset(struct drm_i915_private *i915, + intel_engine_mask_t stalled_mask) { int err, i; @@ -986,7 +989,7 @@ static int do_reset(struct drm_i915_private *i915, unsigned int stalled_mask) * - re-init display */ void i915_reset(struct drm_i915_private *i915, - unsigned int stalled_mask, + intel_engine_mask_t stalled_mask, const char *reason) { struct i915_gpu_error *error = &i915->gpu_error; @@ -1233,14 +1236,14 @@ void i915_clear_error_registers(struct drm_i915_private *dev_priv) * of a ring dump etc.). */ void i915_handle_error(struct drm_i915_private *i915, - u32 engine_mask, + intel_engine_mask_t engine_mask, unsigned long flags, const char *fmt, ...) { struct i915_gpu_error *error = &i915->gpu_error; struct intel_engine_cs *engine; intel_wakeref_t wakeref; - unsigned int tmp; + intel_engine_mask_t tmp; char error_msg[80]; char *msg = NULL; diff --git a/drivers/gpu/drm/i915/i915_reset.h b/drivers/gpu/drm/i915/i915_reset.h index 16f2389f656f..86b1ac8116ce 100644 --- a/drivers/gpu/drm/i915/i915_reset.h +++ b/drivers/gpu/drm/i915/i915_reset.h @@ -11,13 +11,15 @@ #include #include +#include "intel_engine_types.h" + struct drm_i915_private; struct intel_engine_cs; struct intel_guc; __printf(4, 5) void i915_handle_error(struct drm_i915_private *i915, - u32 engine_mask, + intel_engine_mask_t engine_mask, unsigned long flags, const char *fmt, ...); #define I915_ERROR_CAPTURE BIT(0) @@ -25,7 +27,7 @@ void i915_handle_error(struct drm_i915_private *i915, void i915_clear_error_registers(struct drm_i915_private *i915); void i915_reset(struct drm_i915_private *i915, - unsigned int stalled_mask, + intel_engine_mask_t stalled_mask, const char *reason); int i915_reset_engine(struct intel_engine_cs *engine, const char *reason); @@ -41,7 +43,8 @@ int i915_terminally_wedged(struct drm_i915_private *i915); bool intel_has_gpu_reset(struct drm_i915_private *i915); bool intel_has_reset_engine(struct drm_i915_private *i915); -int intel_gpu_reset(struct drm_i915_private *i915, u32 engine_mask); +int intel_gpu_reset(struct drm_i915_private *i915, + intel_engine_mask_t engine_mask); int intel_reset_guc(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h index 9a1d257f3d6e..07d243acf553 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.h +++ b/drivers/gpu/drm/i915/i915_scheduler.h @@ -8,92 +8,10 @@ #define _I915_SCHEDULER_H_ #include +#include #include -#include - -struct drm_i915_private; -struct i915_request; -struct intel_engine_cs; - -enum { - I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1, - I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY, - I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1, - - I915_PRIORITY_INVALID = INT_MIN -}; - -#define I915_USER_PRIORITY_SHIFT 3 -#define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT) - -#define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT) -#define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1) - -#define I915_PRIORITY_WAIT ((u8)BIT(0)) -#define I915_PRIORITY_NEWCLIENT ((u8)BIT(1)) -#define I915_PRIORITY_NOSEMAPHORE ((u8)BIT(2)) - -#define __NO_PREEMPTION (I915_PRIORITY_WAIT) - -struct i915_sched_attr { - /** - * @priority: execution and service priority - * - * All clients are equal, but some are more equal than others! - * - * Requests from a context with a greater (more positive) value of - * @priority will be executed before those with a lower @priority - * value, forming a simple QoS. - * - * The &drm_i915_private.kernel_context is assigned the lowest priority. - */ - int priority; -}; - -/* - * "People assume that time is a strict progression of cause to effect, but - * actually, from a nonlinear, non-subjective viewpoint, it's more like a big - * ball of wibbly-wobbly, timey-wimey ... stuff." -The Doctor, 2015 - * - * Requests exist in a complex web of interdependencies. Each request - * has to wait for some other request to complete before it is ready to be run - * (e.g. we have to wait until the pixels have been rendering into a texture - * before we can copy from it). We track the readiness of a request in terms - * of fences, but we also need to keep the dependency tree for the lifetime - * of the request (beyond the life of an individual fence). We use the tree - * at various points to reorder the requests whilst keeping the requests - * in order with respect to their various dependencies. - * - * There is no active component to the "scheduler". As we know the dependency - * DAG of each request, we are able to insert it into a sorted queue when it - * is ready, and are able to reorder its portion of the graph to accommodate - * dynamic priority changes. - */ -struct i915_sched_node { - struct list_head signalers_list; /* those before us, we depend upon */ - struct list_head waiters_list; /* those after us, they depend upon us */ - struct list_head link; - struct i915_sched_attr attr; - unsigned int flags; -#define I915_SCHED_HAS_SEMAPHORE BIT(0) -}; - -struct i915_dependency { - struct i915_sched_node *signaler; - struct list_head signal_link; - struct list_head wait_link; - struct list_head dfs_link; - unsigned long flags; -#define I915_DEPENDENCY_ALLOC BIT(0) -}; - -struct i915_priolist { - struct list_head requests[I915_PRIORITY_COUNT]; - struct rb_node node; - unsigned long used; - int priority; -}; +#include "i915_scheduler_types.h" #define priolist_for_each_request(it, plist, idx) \ for (idx = 0; idx < ARRAY_SIZE((plist)->requests); idx++) \ diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h new file mode 100644 index 000000000000..5c94b3eb5c81 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h @@ -0,0 +1,98 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2018 Intel Corporation + */ + +#ifndef _I915_SCHEDULER_TYPES_H_ +#define _I915_SCHEDULER_TYPES_H_ + +#include +#include + +#include + +struct drm_i915_private; +struct i915_request; +struct intel_engine_cs; + +enum { + I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1, + I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY, + I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1, + + I915_PRIORITY_INVALID = INT_MIN +}; + +#define I915_USER_PRIORITY_SHIFT 3 +#define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT) + +#define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT) +#define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1) + +#define I915_PRIORITY_WAIT ((u8)BIT(0)) +#define I915_PRIORITY_NEWCLIENT ((u8)BIT(1)) +#define I915_PRIORITY_NOSEMAPHORE ((u8)BIT(2)) + +#define __NO_PREEMPTION (I915_PRIORITY_WAIT) + +struct i915_sched_attr { + /** + * @priority: execution and service priority + * + * All clients are equal, but some are more equal than others! + * + * Requests from a context with a greater (more positive) value of + * @priority will be executed before those with a lower @priority + * value, forming a simple QoS. + * + * The &drm_i915_private.kernel_context is assigned the lowest priority. + */ + int priority; +}; + +/* + * "People assume that time is a strict progression of cause to effect, but + * actually, from a nonlinear, non-subjective viewpoint, it's more like a big + * ball of wibbly-wobbly, timey-wimey ... stuff." -The Doctor, 2015 + * + * Requests exist in a complex web of interdependencies. Each request + * has to wait for some other request to complete before it is ready to be run + * (e.g. we have to wait until the pixels have been rendering into a texture + * before we can copy from it). We track the readiness of a request in terms + * of fences, but we also need to keep the dependency tree for the lifetime + * of the request (beyond the life of an individual fence). We use the tree + * at various points to reorder the requests whilst keeping the requests + * in order with respect to their various dependencies. + * + * There is no active component to the "scheduler". As we know the dependency + * DAG of each request, we are able to insert it into a sorted queue when it + * is ready, and are able to reorder its portion of the graph to accommodate + * dynamic priority changes. + */ +struct i915_sched_node { + struct list_head signalers_list; /* those before us, we depend upon */ + struct list_head waiters_list; /* those after us, they depend upon us */ + struct list_head link; + struct i915_sched_attr attr; + unsigned int flags; +#define I915_SCHED_HAS_SEMAPHORE BIT(0) +}; + +struct i915_dependency { + struct i915_sched_node *signaler; + struct list_head signal_link; + struct list_head wait_link; + struct list_head dfs_link; + unsigned long flags; +#define I915_DEPENDENCY_ALLOC BIT(0) +}; + +struct i915_priolist { + struct list_head requests[I915_PRIORITY_COUNT]; + struct rb_node node; + unsigned long used; + int priority; +}; + +#endif /* _I915_SCHEDULER_TYPES_H_ */ diff --git a/drivers/gpu/drm/i915/i915_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h index c1e47a423d85..4ca7f80bdf6d 100644 --- a/drivers/gpu/drm/i915/i915_timeline.h +++ b/drivers/gpu/drm/i915/i915_timeline.h @@ -27,6 +27,7 @@ #include +#include "i915_active.h" #include "i915_syncmap.h" #include "i915_timeline_types.h" diff --git a/drivers/gpu/drm/i915/i915_timeline_types.h b/drivers/gpu/drm/i915/i915_timeline_types.h index 12ba3c573aa0..1f5b55d9ffb5 100644 --- a/drivers/gpu/drm/i915/i915_timeline_types.h +++ b/drivers/gpu/drm/i915/i915_timeline_types.h @@ -9,9 +9,10 @@ #include #include +#include #include -#include "i915_active.h" +#include "i915_active_types.h" struct drm_i915_private; struct i915_vma; diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 616e9f707877..0e579f158016 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -27,6 +27,7 @@ #include +#include "intel_engine_types.h" #include "intel_display.h" struct drm_printer; @@ -165,8 +166,6 @@ struct sseu_dev_info { u8 eu_mask[GEN_MAX_SLICES * GEN_MAX_SUBSLICES]; }; -typedef u8 intel_engine_mask_t; - struct intel_device_info { u16 gen_mask; diff --git a/drivers/gpu/drm/i915/intel_engine_types.h b/drivers/gpu/drm/i915/intel_engine_types.h index b3249bf6a65f..232e37c1f312 100644 --- a/drivers/gpu/drm/i915/intel_engine_types.h +++ b/drivers/gpu/drm/i915/intel_engine_types.h @@ -13,8 +13,10 @@ #include #include +#include "i915_gem.h" +#include "i915_scheduler_types.h" +#include "i915_selftest.h" #include "i915_timeline_types.h" -#include "intel_device_info.h" #include "intel_workarounds_types.h" #include "i915_gem_batch_pool.h" @@ -25,12 +27,16 @@ #define I915_CMD_HASH_ORDER 9 +struct dma_fence; struct drm_i915_reg_table; struct i915_gem_context; struct i915_request; struct i915_sched_attr; struct intel_uncore; +typedef u8 intel_engine_mask_t; +#define ALL_ENGINES ((intel_engine_mask_t)~0ul) + struct intel_hw_status_page { struct i915_vma *vma; u32 *addr; @@ -105,8 +111,9 @@ enum intel_engine_id { VCS3, #define _VCS(n) (VCS0 + (n)) VECS0, - VECS1 + VECS1, #define _VECS(n) (VECS0 + (n)) + I915_NUM_ENGINES }; struct st_preempt_hang { diff --git a/drivers/gpu/drm/i915/intel_guc_submission.h b/drivers/gpu/drm/i915/intel_guc_submission.h index 169c54568340..aa5e6749c925 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.h +++ b/drivers/gpu/drm/i915/intel_guc_submission.h @@ -29,6 +29,7 @@ #include "i915_gem.h" #include "i915_selftest.h" +#include "intel_engine_types.h" struct drm_i915_private; diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c index 59232df11ada..3d51ed1428d4 100644 --- a/drivers/gpu/drm/i915/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/intel_hangcheck.c @@ -221,8 +221,8 @@ static void hangcheck_declare_hang(struct drm_i915_private *i915, unsigned int stuck) { struct intel_engine_cs *engine; + intel_engine_mask_t tmp; char msg[80]; - unsigned int tmp; int len; /* If some rings hung but others were still busy, only diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c index 45f73b8b4e6d..4e1b6efc6b22 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c @@ -1594,10 +1594,10 @@ out_unlock: } static __maybe_unused const char * -__engine_name(struct drm_i915_private *i915, unsigned int engines) +__engine_name(struct drm_i915_private *i915, intel_engine_mask_t engines) { struct intel_engine_cs *engine; - unsigned int tmp; + intel_engine_mask_t tmp; if (engines == ALL_ENGINES) return "all"; @@ -1610,10 +1610,10 @@ __engine_name(struct drm_i915_private *i915, unsigned int engines) static int __igt_switch_to_kernel_context(struct drm_i915_private *i915, struct i915_gem_context *ctx, - unsigned int engines) + intel_engine_mask_t engines) { struct intel_engine_cs *engine; - unsigned int tmp; + intel_engine_mask_t tmp; int pass; GEM_TRACE("Testing %s\n", __engine_name(i915, engines)); diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index 76b4fa150f2e..050bd1e19e02 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -1124,7 +1124,8 @@ static int igt_reset_engines(void *arg) return 0; } -static u32 fake_hangcheck(struct drm_i915_private *i915, u32 mask) +static u32 fake_hangcheck(struct drm_i915_private *i915, + intel_engine_mask_t mask) { u32 count = i915_reset_count(&i915->gpu_error); diff --git a/drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c b/drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c new file mode 100644 index 000000000000..8afa2c3719fb --- /dev/null +++ b/drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c @@ -0,0 +1,7 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2019 Intel Corporation + */ + +#include "i915_scheduler_types.h" -- cgit v1.2.3 From 8b74594aa45506ea6de9f827cfb2865718fa210e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Apr 2019 17:26:40 +0100 Subject: drm/i915: Split out i915_priolist_types into its own header For more intel_engine_mask_t detangling. This time so that we can use intel_engine_mask_t inside the scheduling structs. Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190401162641.10963-2-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_priolist_types.h | 42 ++++++++++++++++++++++ drivers/gpu/drm/i915/i915_scheduler_types.h | 30 +--------------- drivers/gpu/drm/i915/intel_engine_types.h | 2 +- .../drm/i915/test_i915_priolist_types_standalone.c | 7 ++++ 5 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_priolist_types.h create mode 100644 drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 1f3e8b145fc0..30bf3301ea24 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -61,6 +61,7 @@ i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o i915-$(CONFIG_DRM_I915_WERROR) += \ test_i915_active_types_standalone.o \ test_i915_gem_context_types_standalone.o \ + test_i915_priolist_types_standalone.o \ test_i915_scheduler_types_standalone.o \ test_i915_timeline_types_standalone.o \ test_intel_context_types_standalone.o \ diff --git a/drivers/gpu/drm/i915/i915_priolist_types.h b/drivers/gpu/drm/i915/i915_priolist_types.h new file mode 100644 index 000000000000..cc44ebd3b553 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_priolist_types.h @@ -0,0 +1,42 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2018 Intel Corporation + */ + +#ifndef _I915_PRIOLIST_TYPES_H_ +#define _I915_PRIOLIST_TYPES_H_ + +#include +#include + +#include + +enum { + I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1, + I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY, + I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1, + + I915_PRIORITY_INVALID = INT_MIN +}; + +#define I915_USER_PRIORITY_SHIFT 3 +#define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT) + +#define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT) +#define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1) + +#define I915_PRIORITY_WAIT ((u8)BIT(0)) +#define I915_PRIORITY_NEWCLIENT ((u8)BIT(1)) +#define I915_PRIORITY_NOSEMAPHORE ((u8)BIT(2)) + +#define __NO_PREEMPTION (I915_PRIORITY_WAIT) + +struct i915_priolist { + struct list_head requests[I915_PRIORITY_COUNT]; + struct rb_node node; + unsigned long used; + int priority; +}; + +#endif /* _I915_PRIOLIST_TYPES_H_ */ diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h index 5c94b3eb5c81..76a004a17b2e 100644 --- a/drivers/gpu/drm/i915/i915_scheduler_types.h +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h @@ -8,34 +8,13 @@ #define _I915_SCHEDULER_TYPES_H_ #include -#include -#include +#include "i915_priolist_types.h" struct drm_i915_private; struct i915_request; struct intel_engine_cs; -enum { - I915_PRIORITY_MIN = I915_CONTEXT_MIN_USER_PRIORITY - 1, - I915_PRIORITY_NORMAL = I915_CONTEXT_DEFAULT_PRIORITY, - I915_PRIORITY_MAX = I915_CONTEXT_MAX_USER_PRIORITY + 1, - - I915_PRIORITY_INVALID = INT_MIN -}; - -#define I915_USER_PRIORITY_SHIFT 3 -#define I915_USER_PRIORITY(x) ((x) << I915_USER_PRIORITY_SHIFT) - -#define I915_PRIORITY_COUNT BIT(I915_USER_PRIORITY_SHIFT) -#define I915_PRIORITY_MASK (I915_PRIORITY_COUNT - 1) - -#define I915_PRIORITY_WAIT ((u8)BIT(0)) -#define I915_PRIORITY_NEWCLIENT ((u8)BIT(1)) -#define I915_PRIORITY_NOSEMAPHORE ((u8)BIT(2)) - -#define __NO_PREEMPTION (I915_PRIORITY_WAIT) - struct i915_sched_attr { /** * @priority: execution and service priority @@ -88,11 +67,4 @@ struct i915_dependency { #define I915_DEPENDENCY_ALLOC BIT(0) }; -struct i915_priolist { - struct list_head requests[I915_PRIORITY_COUNT]; - struct rb_node node; - unsigned long used; - int priority; -}; - #endif /* _I915_SCHEDULER_TYPES_H_ */ diff --git a/drivers/gpu/drm/i915/intel_engine_types.h b/drivers/gpu/drm/i915/intel_engine_types.h index 232e37c1f312..14ad5263ea1e 100644 --- a/drivers/gpu/drm/i915/intel_engine_types.h +++ b/drivers/gpu/drm/i915/intel_engine_types.h @@ -14,7 +14,7 @@ #include #include "i915_gem.h" -#include "i915_scheduler_types.h" +#include "i915_priolist_types.h" #include "i915_selftest.h" #include "i915_timeline_types.h" #include "intel_workarounds_types.h" diff --git a/drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c b/drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c new file mode 100644 index 000000000000..f465eb99bb47 --- /dev/null +++ b/drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c @@ -0,0 +1,7 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2019 Intel Corporation + */ + +#include "i915_priolist_types.h" -- cgit v1.2.3 From 7881e6057586b0bdaaffef13d9f88c95a86ba484 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Apr 2019 17:26:41 +0100 Subject: drm/i915: Only emit one semaphore per request Ideally we only need one semaphore per ring to accommodate waiting on multiple engines in parallel. However, since we do not know which fences we will finally be waiting on, we emit a semaphore for every fence. It turns out to be quite easy to trick ourselves into exhausting our ringbuffer causing an error, just by feeding in a batch that depends on several thousand contexts. Since we never can be waiting on more than one semaphore in parallel (other than perhaps the desire to busywait on multiple engines), just pick the first fence for our semaphore. If we pick the wrong fence to busywait on, we just miss an opportunity to reduce latency. An adaption might be to use sched.flags as either a semaphore counter, or to track the first busywait on each engine, converting it back to a single use bit prior to closing the request. v2: Track first semaphore used per-engine (this caters for our basic igt that semaphores are working). Reported-by: Mika Kuoppala Testcase: igt/gem_exec_fence/long-history Fixes: e88619646971 ("drm/i915: Use HW semaphores for inter-engine synchronisation on gen8+") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20190401162641.10963-3-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_request.c | 11 +++++++++-- drivers/gpu/drm/i915/i915_scheduler.c | 5 +++-- drivers/gpu/drm/i915/i915_scheduler_types.h | 4 +++- 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index e9c2094ab8ea..82094b9f5ba7 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -783,6 +783,12 @@ emit_semaphore_wait(struct i915_request *to, GEM_BUG_ON(!from->timeline->has_initial_breadcrumb); GEM_BUG_ON(INTEL_GEN(to->i915) < 8); + /* Just emit the first semaphore we see as request space is limited. */ + if (to->sched.semaphores & from->engine->mask) + return i915_sw_fence_await_dma_fence(&to->submit, + &from->fence, 0, + I915_FENCE_GFP); + /* We need to pin the signaler's HWSP until we are finished reading. */ err = i915_timeline_read_hwsp(from, to, &hwsp_offset); if (err) @@ -814,7 +820,8 @@ emit_semaphore_wait(struct i915_request *to, *cs++ = 0; intel_ring_advance(to, cs); - to->sched.flags |= I915_SCHED_HAS_SEMAPHORE; + to->sched.semaphores |= from->engine->mask; + to->sched.flags |= I915_SCHED_HAS_SEMAPHORE_CHAIN; return 0; } @@ -1126,7 +1133,7 @@ void i915_request_add(struct i915_request *request) * far in the distance past over useful work, we keep a history * of any semaphore use along our dependency chain. */ - if (!(request->sched.flags & I915_SCHED_HAS_SEMAPHORE)) + if (!(request->sched.flags & I915_SCHED_HAS_SEMAPHORE_CHAIN)) attr.priority |= I915_PRIORITY_NOSEMAPHORE; /* diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index e0f609d01564..77dbf7d74e12 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -41,6 +41,7 @@ void i915_sched_node_init(struct i915_sched_node *node) INIT_LIST_HEAD(&node->waiters_list); INIT_LIST_HEAD(&node->link); node->attr.priority = I915_PRIORITY_INVALID; + node->semaphores = 0; node->flags = 0; } @@ -73,9 +74,9 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node, dep->flags = flags; /* Keep track of whether anyone on this chain has a semaphore */ - if (signal->flags & I915_SCHED_HAS_SEMAPHORE && + if (signal->flags & I915_SCHED_HAS_SEMAPHORE_CHAIN && !node_started(signal)) - node->flags |= I915_SCHED_HAS_SEMAPHORE; + node->flags |= I915_SCHED_HAS_SEMAPHORE_CHAIN; ret = true; } diff --git a/drivers/gpu/drm/i915/i915_scheduler_types.h b/drivers/gpu/drm/i915/i915_scheduler_types.h index 76a004a17b2e..f1af3916a808 100644 --- a/drivers/gpu/drm/i915/i915_scheduler_types.h +++ b/drivers/gpu/drm/i915/i915_scheduler_types.h @@ -10,6 +10,7 @@ #include #include "i915_priolist_types.h" +#include "intel_engine_types.h" struct drm_i915_private; struct i915_request; @@ -55,7 +56,8 @@ struct i915_sched_node { struct list_head link; struct i915_sched_attr attr; unsigned int flags; -#define I915_SCHED_HAS_SEMAPHORE BIT(0) +#define I915_SCHED_HAS_SEMAPHORE_CHAIN BIT(0) + intel_engine_mask_t semaphores; }; struct i915_dependency { -- cgit v1.2.3 From f722b8c1e2a2a85add58a8ffd9cb794d4d6287ff Mon Sep 17 00:00:00 2001 From: Bob Paauwe Date: Wed, 20 Mar 2019 14:15:46 -0700 Subject: drm/i915/ehl: All EHL ports are combo phys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlike ICL, all of the output ports are combo phys so just return true in intel_port_is_combophy for all EHL ports to indicate that. v2: Return false in intel_port_is_tc since no EHL ports are TC. (Jose) Cc: Jose Souza Signed-off-by: Bob Paauwe Signed-off-by: Rodrigo Vivi Reviewed-by: José Roberto de Souza Signed-off-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20190320211547.519266-1-bob.j.paauwe@intel.com --- drivers/gpu/drm/i915/intel_display.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8576a7f799f2..6facfba79a41 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6180,6 +6180,9 @@ bool intel_port_is_combophy(struct drm_i915_private *dev_priv, enum port port) if (port == PORT_NONE) return false; + if (IS_ELKHARTLAKE(dev_priv)) + return port <= PORT_C; + if (INTEL_GEN(dev_priv) >= 11) return port <= PORT_B; @@ -6188,7 +6191,7 @@ bool intel_port_is_combophy(struct drm_i915_private *dev_priv, enum port port) bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port) { - if (INTEL_GEN(dev_priv) >= 11) + if (INTEL_GEN(dev_priv) >= 11 && !IS_ELKHARTLAKE(dev_priv)) return port >= PORT_C && port <= PORT_F; return false; -- cgit v1.2.3 From d939f44d4a7f910755165458da20407d2139f581 Mon Sep 17 00:00:00 2001 From: Le Ma Date: Mon, 1 Apr 2019 18:08:30 +0800 Subject: drm/amdgpu: remove unnecessary rlc reset function on gfx9 The rlc reset function is not necessary during gfx9 initialization/resume phase. And this function would even cause rlc fw loading failed on some gfx9 ASIC. Remove this function safely with verification well on Vega/Raven platform. Signed-off-by: Le Ma Reviewed-by: Feifei Xu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index d0309e8c9d12..a11db2b1a63f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -2405,8 +2405,6 @@ static int gfx_v9_0_rlc_resume(struct amdgpu_device *adev) /* disable CG */ WREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL, 0); - adev->gfx.rlc.funcs->reset(adev); - gfx_v9_0_init_pg(adev); if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { -- cgit v1.2.3 From 6cbe88303621b79ceba4cb00062312030f51d18e Mon Sep 17 00:00:00 2001 From: Daniele Ceraolo Spurio Date: Tue, 2 Apr 2019 13:10:31 -0700 Subject: drm/i915: add intel_uncore_init_early Encapsulate the uncore early init and be consistent with the "_early" naming. Signed-off-by: Daniele Ceraolo Spurio Cc: Chris Wilson Cc: Paulo Zanoni Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190402201032.15841-1-daniele.ceraolospurio@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 3 ++- drivers/gpu/drm/i915/intel_uncore.c | 4 ++++ drivers/gpu/drm/i915/intel_uncore.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0ca57dc5da5c..5bfacf353fa4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -870,10 +870,11 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv) intel_device_info_subplatform_init(dev_priv); + intel_uncore_init_early(&dev_priv->uncore); + spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->gpu_error.lock); mutex_init(&dev_priv->backlight_lock); - spin_lock_init(&dev_priv->uncore.lock); mutex_init(&dev_priv->sb_lock); mutex_init(&dev_priv->av_mutex); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 106df24f20a5..3ccda8b7b783 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1524,6 +1524,10 @@ static void uncore_mmio_cleanup(struct intel_uncore *uncore) pci_iounmap(pdev, uncore->regs); } +void intel_uncore_init_early(struct intel_uncore *uncore) +{ + spin_lock_init(&uncore->lock); +} int intel_uncore_init(struct intel_uncore *uncore) { diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 896585a1c2dd..78de1af59334 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -178,6 +178,7 @@ intel_uncore_has_fifo(const struct intel_uncore *uncore) } void intel_uncore_sanitize(struct drm_i915_private *dev_priv); +void intel_uncore_init_early(struct intel_uncore *uncore); int intel_uncore_init(struct intel_uncore *uncore); void intel_uncore_prune(struct intel_uncore *uncore); bool intel_uncore_unclaimed_mmio(struct intel_uncore *uncore); -- cgit v1.2.3 From 3de6f8529461706dcea78044dd4ccf1290a62e50 Mon Sep 17 00:00:00 2001 From: Daniele Ceraolo Spurio Date: Tue, 2 Apr 2019 13:10:32 -0700 Subject: drm/i915: rename init/fini/prune uncore functions Add "_mmio" postfix to be consistent from the init/fini phase they're called from. Signed-off-by: Daniele Ceraolo Spurio Suggested-by: Chris Wilson Cc: Chris Wilson Cc: Paulo Zanoni Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190402201032.15841-2-daniele.ceraolospurio@intel.com --- drivers/gpu/drm/i915/i915_drv.c | 8 ++++---- drivers/gpu/drm/i915/intel_uncore.c | 6 +++--- drivers/gpu/drm/i915/intel_uncore.h | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5bfacf353fa4..0bbf3f5db5fc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -957,7 +957,7 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) if (i915_get_bridge_dev(dev_priv)) return -EIO; - ret = intel_uncore_init(&dev_priv->uncore); + ret = intel_uncore_init_mmio(&dev_priv->uncore); if (ret < 0) goto err_bridge; @@ -966,7 +966,7 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) intel_device_info_init_mmio(dev_priv); - intel_uncore_prune(&dev_priv->uncore); + intel_uncore_prune_mmio_domains(&dev_priv->uncore); intel_uc_init_mmio(dev_priv); @@ -980,7 +980,7 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) err_uncore: intel_teardown_mchbar(dev_priv); - intel_uncore_fini(&dev_priv->uncore); + intel_uncore_fini_mmio(&dev_priv->uncore); err_bridge: pci_dev_put(dev_priv->bridge_dev); @@ -994,7 +994,7 @@ err_bridge: static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) { intel_teardown_mchbar(dev_priv); - intel_uncore_fini(&dev_priv->uncore); + intel_uncore_fini_mmio(&dev_priv->uncore); pci_dev_put(dev_priv->bridge_dev); } diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 3ccda8b7b783..a01d1b352a7c 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -1529,7 +1529,7 @@ void intel_uncore_init_early(struct intel_uncore *uncore) spin_lock_init(&uncore->lock); } -int intel_uncore_init(struct intel_uncore *uncore) +int intel_uncore_init_mmio(struct intel_uncore *uncore) { struct drm_i915_private *i915 = uncore_to_i915(uncore); int ret; @@ -1608,7 +1608,7 @@ int intel_uncore_init(struct intel_uncore *uncore) * the forcewake domains. Prune them, to make sure they only reference existing * engines. */ -void intel_uncore_prune(struct intel_uncore *uncore) +void intel_uncore_prune_mmio_domains(struct intel_uncore *uncore) { struct drm_i915_private *i915 = uncore_to_i915(uncore); @@ -1639,7 +1639,7 @@ void intel_uncore_prune(struct intel_uncore *uncore) } } -void intel_uncore_fini(struct intel_uncore *uncore) +void intel_uncore_fini_mmio(struct intel_uncore *uncore) { /* Paranoia: make sure we have disabled everything before we exit. */ intel_uncore_sanitize(uncore_to_i915(uncore)); diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 78de1af59334..a64d3dc0db4d 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -179,11 +179,11 @@ intel_uncore_has_fifo(const struct intel_uncore *uncore) void intel_uncore_sanitize(struct drm_i915_private *dev_priv); void intel_uncore_init_early(struct intel_uncore *uncore); -int intel_uncore_init(struct intel_uncore *uncore); -void intel_uncore_prune(struct intel_uncore *uncore); +int intel_uncore_init_mmio(struct intel_uncore *uncore); +void intel_uncore_prune_mmio_domains(struct intel_uncore *uncore); bool intel_uncore_unclaimed_mmio(struct intel_uncore *uncore); bool intel_uncore_arm_unclaimed_mmio_detection(struct intel_uncore *uncore); -void intel_uncore_fini(struct intel_uncore *uncore); +void intel_uncore_fini_mmio(struct intel_uncore *uncore); void intel_uncore_suspend(struct intel_uncore *uncore); void intel_uncore_resume_early(struct intel_uncore *uncore); void intel_uncore_runtime_resume(struct intel_uncore *uncore); -- cgit v1.2.3 From 640cde65b48ae6c773f00cbbdece7e67945b3f34 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 3 Apr 2019 07:44:07 +0100 Subject: drm/i915: Fix uninitialized mask in intel_device_info_subplatform_init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mask need to be initialized to zero since device id checks may not match. Signed-off-by: Tvrtko Ursulin Reported-by: Dan Carpenter Fixes: 805446c8347c ("drm/i915: Introduce concept of a sub-platform") Cc: Tvrtko Ursulin Cc: Chris Wilson Cc: Jani Nikula Cc: Lucas De Marchi Cc: Jose Souza Cc: Ville Syrjälä Cc: Paulo Zanoni Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Dan Carpenter Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190403064407.25646-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_device_info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 0ed49d032c00..6af480b95bc6 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -778,7 +778,7 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915) const unsigned int pi = __platform_mask_index(rinfo, info->platform); const unsigned int pb = __platform_mask_bit(rinfo, info->platform); u16 devid = INTEL_DEVID(i915); - u32 mask; + u32 mask = 0; /* Make sure IS_ checks are working. */ RUNTIME_INFO(i915)->platform_mask[pi] = BIT(pb); -- cgit v1.2.3 From 4c6ce5c99084411391ba892a821f61cf42c79157 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Mar 2019 15:49:12 +0000 Subject: drm/i915: Move the decision to use the breadcrumb tasklet to the backend Use the engine->flags to store whether we want to kick the submission tasklet on receipt of a breadcrumb interrupt, so that this decision can be made by the submission backend and not dependent on a limited feature test within the interrupt handler. This should make it easier to adapt to different submission backends. Signed-off-by: Chris Wilson Cc: Michal Wajdeczko Cc: Xiaolin Zhang Cc: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190329154912.13781-1-chris@chris-wilson.co.uk Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_engine_types.h | 7 +++++++ drivers/gpu/drm/i915/intel_guc_submission.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 455b2bf691b5..aa107a78cb36 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1470,7 +1470,7 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir) if (iir & GT_RENDER_USER_INTERRUPT) { intel_engine_breadcrumbs_irq(engine); - tasklet |= USES_GUC_SUBMISSION(engine->i915); + tasklet |= intel_engine_needs_breadcrumb_tasklet(engine); } if (tasklet) diff --git a/drivers/gpu/drm/i915/intel_engine_types.h b/drivers/gpu/drm/i915/intel_engine_types.h index 14ad5263ea1e..6c6d8a9aca94 100644 --- a/drivers/gpu/drm/i915/intel_engine_types.h +++ b/drivers/gpu/drm/i915/intel_engine_types.h @@ -432,6 +432,7 @@ struct intel_engine_cs { #define I915_ENGINE_SUPPORTS_STATS BIT(1) #define I915_ENGINE_HAS_PREEMPTION BIT(2) #define I915_ENGINE_HAS_SEMAPHORES BIT(3) +#define I915_ENGINE_NEEDS_BREADCRUMB_TASKLET BIT(4) unsigned int flags; /* @@ -515,6 +516,12 @@ intel_engine_has_semaphores(const struct intel_engine_cs *engine) return engine->flags & I915_ENGINE_HAS_SEMAPHORES; } +static inline bool +intel_engine_needs_breadcrumb_tasklet(const struct intel_engine_cs *engine) +{ + return engine->flags & I915_ENGINE_NEEDS_BREADCRUMB_TASKLET; +} + #define instdone_slice_mask(dev_priv__) \ (IS_GEN(dev_priv__, 7) ? \ 1 : RUNTIME_INFO(dev_priv__)->sseu.slice_mask) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index c4ad73980988..c58922226d47 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -1262,10 +1262,12 @@ static void guc_interrupts_release(struct drm_i915_private *dev_priv) static void guc_submission_park(struct intel_engine_cs *engine) { intel_engine_unpin_breadcrumbs_irq(engine); + engine->flags &= ~I915_ENGINE_NEEDS_BREADCRUMB_TASKLET; } static void guc_submission_unpark(struct intel_engine_cs *engine) { + engine->flags |= I915_ENGINE_NEEDS_BREADCRUMB_TASKLET; intel_engine_pin_breadcrumbs_irq(engine); } -- cgit v1.2.3 From af67772d0a763a62b3d14e12e9d1c08c6974eac9 Mon Sep 17 00:00:00 2001 From: Emily Deng Date: Thu, 28 Mar 2019 17:29:10 +0800 Subject: drm/amdgpu: Correct the irq types' num of sdma MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the issue about TDR-2 will have "fallback timer expired on ring sdma1". It is because the wrong number of irq types setting. Signed-off-by: Emily Deng Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h | 7 ++----- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 25 ++++++++++++------------- drivers/gpu/drm/amd/amdgpu/si_dma.c | 8 ++++---- 6 files changed, 30 insertions(+), 34 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h index c17af30e758d..1ba9ba3b54f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h @@ -28,11 +28,8 @@ #define AMDGPU_MAX_SDMA_INSTANCES 2 enum amdgpu_sdma_irq { - AMDGPU_SDMA_IRQ_TRAP0 = 0, - AMDGPU_SDMA_IRQ_TRAP1, - AMDGPU_SDMA_IRQ_ECC0, - AMDGPU_SDMA_IRQ_ECC1, - + AMDGPU_SDMA_IRQ_INSTANCE0 = 0, + AMDGPU_SDMA_IRQ_INSTANCE1, AMDGPU_SDMA_IRQ_LAST }; diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 189599b694e8..d42808b05971 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -977,8 +977,8 @@ static int cik_sdma_sw_init(void *handle) r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq, (i == 0) ? - AMDGPU_SDMA_IRQ_TRAP0 : - AMDGPU_SDMA_IRQ_TRAP1); + AMDGPU_SDMA_IRQ_INSTANCE0 : + AMDGPU_SDMA_IRQ_INSTANCE1); if (r) return r; } @@ -1114,7 +1114,7 @@ static int cik_sdma_set_trap_irq_state(struct amdgpu_device *adev, u32 sdma_cntl; switch (type) { - case AMDGPU_SDMA_IRQ_TRAP0: + case AMDGPU_SDMA_IRQ_INSTANCE0: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(mmSDMA0_CNTL + SDMA0_REGISTER_OFFSET); @@ -1130,7 +1130,7 @@ static int cik_sdma_set_trap_irq_state(struct amdgpu_device *adev, break; } break; - case AMDGPU_SDMA_IRQ_TRAP1: + case AMDGPU_SDMA_IRQ_INSTANCE1: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(mmSDMA0_CNTL + SDMA1_REGISTER_OFFSET); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index cca3552b36ed..36196372e8db 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -870,8 +870,8 @@ static int sdma_v2_4_sw_init(void *handle) r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq, (i == 0) ? - AMDGPU_SDMA_IRQ_TRAP0 : - AMDGPU_SDMA_IRQ_TRAP1); + AMDGPU_SDMA_IRQ_INSTANCE0 : + AMDGPU_SDMA_IRQ_INSTANCE1); if (r) return r; } @@ -1006,7 +1006,7 @@ static int sdma_v2_4_set_trap_irq_state(struct amdgpu_device *adev, u32 sdma_cntl; switch (type) { - case AMDGPU_SDMA_IRQ_TRAP0: + case AMDGPU_SDMA_IRQ_INSTANCE0: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(mmSDMA0_CNTL + SDMA0_REGISTER_OFFSET); @@ -1022,7 +1022,7 @@ static int sdma_v2_4_set_trap_irq_state(struct amdgpu_device *adev, break; } break; - case AMDGPU_SDMA_IRQ_TRAP1: + case AMDGPU_SDMA_IRQ_INSTANCE1: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(mmSDMA0_CNTL + SDMA1_REGISTER_OFFSET); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 0ce8331baeb2..6d39544e7829 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -1154,8 +1154,8 @@ static int sdma_v3_0_sw_init(void *handle) r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq, (i == 0) ? - AMDGPU_SDMA_IRQ_TRAP0 : - AMDGPU_SDMA_IRQ_TRAP1); + AMDGPU_SDMA_IRQ_INSTANCE0 : + AMDGPU_SDMA_IRQ_INSTANCE1); if (r) return r; } @@ -1340,7 +1340,7 @@ static int sdma_v3_0_set_trap_irq_state(struct amdgpu_device *adev, u32 sdma_cntl; switch (type) { - case AMDGPU_SDMA_IRQ_TRAP0: + case AMDGPU_SDMA_IRQ_INSTANCE0: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(mmSDMA0_CNTL + SDMA0_REGISTER_OFFSET); @@ -1356,7 +1356,7 @@ static int sdma_v3_0_set_trap_irq_state(struct amdgpu_device *adev, break; } break; - case AMDGPU_SDMA_IRQ_TRAP1: + case AMDGPU_SDMA_IRQ_INSTANCE1: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(mmSDMA0_CNTL + SDMA1_REGISTER_OFFSET); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 8691b621148e..7be5228f6c6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -1551,13 +1551,13 @@ static int sdma_v4_0_late_init(void *handle) if (r) goto sysfs; resume: - r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_ECC0); + r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_INSTANCE0); if (r) goto irq; - r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_ECC1); + r = amdgpu_irq_get(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_INSTANCE1); if (r) { - amdgpu_irq_put(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_ECC0); + amdgpu_irq_put(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_INSTANCE0); goto irq; } @@ -1621,8 +1621,8 @@ static int sdma_v4_0_sw_init(void *handle) r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq, (i == 0) ? - AMDGPU_SDMA_IRQ_TRAP0 : - AMDGPU_SDMA_IRQ_TRAP1); + AMDGPU_SDMA_IRQ_INSTANCE0 : + AMDGPU_SDMA_IRQ_INSTANCE1); if (r) return r; @@ -1641,8 +1641,8 @@ static int sdma_v4_0_sw_init(void *handle) r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq, (i == 0) ? - AMDGPU_SDMA_IRQ_TRAP0 : - AMDGPU_SDMA_IRQ_TRAP1); + AMDGPU_SDMA_IRQ_INSTANCE0 : + AMDGPU_SDMA_IRQ_INSTANCE1); if (r) return r; } @@ -1709,8 +1709,8 @@ static int sdma_v4_0_hw_fini(void *handle) if (amdgpu_sriov_vf(adev)) return 0; - amdgpu_irq_put(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_ECC0); - amdgpu_irq_put(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_ECC1); + amdgpu_irq_put(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_INSTANCE0); + amdgpu_irq_put(adev, &adev->sdma.ecc_irq, AMDGPU_SDMA_IRQ_INSTANCE1); sdma_v4_0_ctx_switch_enable(adev, false); sdma_v4_0_enable(adev, false); @@ -1780,13 +1780,12 @@ static int sdma_v4_0_set_trap_irq_state(struct amdgpu_device *adev, unsigned type, enum amdgpu_interrupt_state state) { - unsigned int instance = (type == AMDGPU_SDMA_IRQ_TRAP0) ? 0 : 1; u32 sdma_cntl; - sdma_cntl = RREG32_SDMA(instance, mmSDMA0_CNTL); + sdma_cntl = RREG32_SDMA(type, mmSDMA0_CNTL); sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA0_CNTL, TRAP_ENABLE, state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0); - WREG32_SDMA(instance, mmSDMA0_CNTL, sdma_cntl); + WREG32_SDMA(type, mmSDMA0_CNTL, sdma_cntl); return 0; } @@ -1908,7 +1907,7 @@ static int sdma_v4_0_set_ecc_irq_state(struct amdgpu_device *adev, { u32 sdma_edc_config; - u32 reg_offset = (type == AMDGPU_SDMA_IRQ_ECC0) ? + u32 reg_offset = (type == AMDGPU_SDMA_IRQ_INSTANCE0) ? sdma_v4_0_get_reg_offset(adev, 0, mmSDMA0_EDC_CONFIG) : sdma_v4_0_get_reg_offset(adev, 1, mmSDMA0_EDC_CONFIG); diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c index f15f196684ba..3eeefd40dae0 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c @@ -503,8 +503,8 @@ static int si_dma_sw_init(void *handle) r = amdgpu_ring_init(adev, ring, 1024, &adev->sdma.trap_irq, (i == 0) ? - AMDGPU_SDMA_IRQ_TRAP0 : - AMDGPU_SDMA_IRQ_TRAP1); + AMDGPU_SDMA_IRQ_INSTANCE0 : + AMDGPU_SDMA_IRQ_INSTANCE1); if (r) return r; } @@ -591,7 +591,7 @@ static int si_dma_set_trap_irq_state(struct amdgpu_device *adev, u32 sdma_cntl; switch (type) { - case AMDGPU_SDMA_IRQ_TRAP0: + case AMDGPU_SDMA_IRQ_INSTANCE0: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET); @@ -607,7 +607,7 @@ static int si_dma_set_trap_irq_state(struct amdgpu_device *adev, break; } break; - case AMDGPU_SDMA_IRQ_TRAP1: + case AMDGPU_SDMA_IRQ_INSTANCE1: switch (state) { case AMDGPU_IRQ_STATE_DISABLE: sdma_cntl = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET); -- cgit v1.2.3 From 795c1b8d0730541f4bfd09921d61bb824f7070f6 Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Mon, 25 Mar 2019 16:07:23 -0400 Subject: drm/amdgpu: Adjust TMR address alignment as per HW requirement According to HW engineer, they prefer the TMR address be "naturally aligned", e.g. the start address must be an integer divide of TME size. Signed-off-by: shaoyunl Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 2206bb4b0903..905cce1814f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -187,13 +187,13 @@ static int psp_tmr_init(struct psp_context *psp) int ret; /* - * Allocate 3M memory aligned to 1M from Frame Buffer (local - * physical). + * According to HW engineer, they prefer the TMR address be "naturally + * aligned" , e.g. the start address be an integer divide of TMR size. * * Note: this memory need be reserved till the driver * uninitializes. */ - ret = amdgpu_bo_create_kernel(psp->adev, PSP_TMR_SIZE, 0x100000, + ret = amdgpu_bo_create_kernel(psp->adev, PSP_TMR_SIZE, PSP_TMR_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); -- cgit v1.2.3 From 5fa76a9dfe9fe501203d1a12a646d467db79aa90 Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 28 Mar 2019 13:53:38 +0100 Subject: drm/amdgpu: fix ATC handling for Ryzen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we don't correctly use translate further. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 21c712e34148..eb8a5064eadf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -769,14 +769,17 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, addr = 0; if (ats_entries) { - uint64_t ats_value; + uint64_t value = 0, flags; - ats_value = AMDGPU_PTE_DEFAULT_ATC; - if (level != AMDGPU_VM_PTB) - ats_value |= AMDGPU_PDE_PTE; + flags = AMDGPU_PTE_DEFAULT_ATC; + if (level != AMDGPU_VM_PTB) { + /* Handle leaf PDEs as PTEs */ + flags |= AMDGPU_PDE_PTE; + amdgpu_gmc_get_vm_pde(adev, level, &value, &flags); + } r = vm->update_funcs->update(¶ms, bo, addr, 0, ats_entries, - 0, ats_value); + value, flags); if (r) return r; -- cgit v1.2.3 From b6f3a51e0a3427fe6e737c37f911d07afb50683f Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 28 Mar 2019 13:51:23 +0100 Subject: drm/amdgpu: handle leaf PDEs as PTEs on Vega MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way we get retry faults for missing PDs. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index eb8a5064eadf..fc7236af6a41 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -787,15 +787,22 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, } if (entries) { - uint64_t value = 0; - - /* Workaround for fault priority problem on GMC9 */ - if (level == AMDGPU_VM_PTB && - adev->asic_type >= CHIP_VEGA10) - value = AMDGPU_PTE_EXECUTABLE; + uint64_t value = 0, flags = 0; + + if (adev->asic_type >= CHIP_VEGA10) { + if (level != AMDGPU_VM_PTB) { + /* Handle leaf PDEs as PTEs */ + flags |= AMDGPU_PDE_PTE; + amdgpu_gmc_get_vm_pde(adev, level, + &value, &flags); + } else { + /* Workaround for fault priority problem on GMC9 */ + flags = AMDGPU_PTE_EXECUTABLE; + } + } r = vm->update_funcs->update(¶ms, bo, addr, 0, entries, - 0, value); + value, flags); if (r) return r; } -- cgit v1.2.3 From c4229c6e37c203fd99397c1bcfe83a2bc1d30d96 Mon Sep 17 00:00:00 2001 From: Christian König Date: Mon, 25 Mar 2019 16:13:44 +0100 Subject: drm/amdgpu: provide the page fault queue to the VM code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are going to need that for recoverable page faults. Signed-off-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 1 + drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index beac15bca526..91baf95212a6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -303,6 +303,7 @@ struct amdgpu_vm_manager { const struct amdgpu_vm_pte_funcs *vm_pte_funcs; struct drm_sched_rq *vm_pte_rqs[AMDGPU_MAX_RINGS]; unsigned vm_pte_num_rqs; + struct amdgpu_ring *page_fault; /* partial resident texture handling */ spinlock_t prt_lock; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 7be5228f6c6f..e858043a3a0e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -2291,6 +2291,7 @@ static void sdma_v4_0_set_vm_pte_funcs(struct amdgpu_device *adev) &sched->sched_rq[DRM_SCHED_PRIORITY_KERNEL]; } adev->vm_manager.vm_pte_num_rqs = adev->sdma.num_instances - 1; + adev->vm_manager.page_fault = &adev->sdma.instance[0].page; } else { for (i = 0; i < adev->sdma.num_instances; i++) { sched = &adev->sdma.instance[i].ring.sched; -- cgit v1.2.3 From b4ae4fe6cdbbfedb9e71294a4d9aa2b4a37edf16 Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Tue, 26 Mar 2019 14:47:57 -0400 Subject: drm/amdgpu: Add preferred_domain check when determine XGMI state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid unnecessary XGMI hight pstate trigger when mapping none-vram memory for peer device Signed-off-by: shaoyunl Reviewed-by: Felix Kuehling Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 11 +++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 61107cfc9af6..d4fcf5475464 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -31,6 +31,7 @@ #include #include "amdgpu.h" #include "amdgpu_display.h" +#include "amdgpu_xgmi.h" void amdgpu_gem_object_free(struct drm_gem_object *gobj) { @@ -668,6 +669,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, struct amdgpu_device *adev = dev->dev_private; struct drm_amdgpu_gem_op *args = data; struct drm_gem_object *gobj; + struct amdgpu_vm_bo_base *base; struct amdgpu_bo *robj; int r; @@ -706,6 +708,15 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, amdgpu_bo_unreserve(robj); break; } + for (base = robj->vm_bo; base; base = base->next) + if (amdgpu_xgmi_same_hive(amdgpu_ttm_adev(robj->tbo.bdev), + amdgpu_ttm_adev(base->vm->root.base.bo->tbo.bdev))) { + r = -EINVAL; + amdgpu_bo_unreserve(robj); + goto out; + } + + robj->preferred_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT | AMDGPU_GEM_DOMAIN_CPU); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index fc7236af6a41..a07c85815b7a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2037,7 +2037,8 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, INIT_LIST_HEAD(&bo_va->valids); INIT_LIST_HEAD(&bo_va->invalids); - if (bo && amdgpu_xgmi_same_hive(adev, amdgpu_ttm_adev(bo->tbo.bdev))) { + if (bo && amdgpu_xgmi_same_hive(adev, amdgpu_ttm_adev(bo->tbo.bdev)) && + (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM)) { bo_va->is_xgmi = true; mutex_lock(&adev->vm_manager.lock_pstate); /* Power up XGMI if it can be potentially used */ -- cgit v1.2.3 From 233d3ee4ba3636c0215714ee9f282e08147a452b Mon Sep 17 00:00:00 2001 From: Kent Russell Date: Fri, 22 Mar 2019 09:01:26 -0400 Subject: drm/amdgpu: Allow switching to CUSTOM profile on smu7 v2 Allow changing to the CUSTOM profile without requiring the parameters being passed in each time. Store the values in the smu7_profiling table since it's defined here anyways v2: Add check that CUSTOM was previously set Signed-off-by: Kent Russell Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 32 ++++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c index 83d3d935f3ac..048757e8f494 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -77,7 +77,7 @@ #define PCIE_BUS_CLK 10000 #define TCLK (PCIE_BUS_CLK / 10) -static const struct profile_mode_setting smu7_profiling[7] = +static struct profile_mode_setting smu7_profiling[7] = {{0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 100, 30, 1, 0, 100, 10}, {1, 10, 0, 30, 0, 0, 0, 0}, @@ -4984,17 +4984,27 @@ static int smu7_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint mode = input[size]; switch (mode) { case PP_SMC_POWER_PROFILE_CUSTOM: - if (size < 8) + if (size < 8 && size != 0) return -EINVAL; - - tmp.bupdate_sclk = input[0]; - tmp.sclk_up_hyst = input[1]; - tmp.sclk_down_hyst = input[2]; - tmp.sclk_activity = input[3]; - tmp.bupdate_mclk = input[4]; - tmp.mclk_up_hyst = input[5]; - tmp.mclk_down_hyst = input[6]; - tmp.mclk_activity = input[7]; + /* If only CUSTOM is passed in, use the saved values. Check + * that we actually have a CUSTOM profile by ensuring that + * the "use sclk" or the "use mclk" bits are set + */ + tmp = smu7_profiling[PP_SMC_POWER_PROFILE_CUSTOM]; + if (size == 0) { + if (tmp.bupdate_sclk == 0 && tmp.bupdate_mclk == 0) + return -EINVAL; + } else { + tmp.bupdate_sclk = input[0]; + tmp.sclk_up_hyst = input[1]; + tmp.sclk_down_hyst = input[2]; + tmp.sclk_activity = input[3]; + tmp.bupdate_mclk = input[4]; + tmp.mclk_up_hyst = input[5]; + tmp.mclk_down_hyst = input[6]; + tmp.mclk_activity = input[7]; + smu7_profiling[PP_SMC_POWER_PROFILE_CUSTOM] = tmp; + } if (!smum_update_dpm_settings(hwmgr, &tmp)) { memcpy(&data->current_profile_setting, &tmp, sizeof(struct profile_mode_setting)); hwmgr->power_profile_mode = mode; -- cgit v1.2.3 From bbdf38cc0dce5c68658e20b777720b8611dc286c Mon Sep 17 00:00:00 2001 From: Kent Russell Date: Mon, 1 Apr 2019 06:43:39 -0400 Subject: drm/amdgpu: Allow switching to CUSTOM profile on Vega10 v2 Don't return an error if the CUSTOM profile is selected, just apply it with the values saved to the GPU. But ensure that we zero out the copy stored in adev to ensure that a valid profile has been submitted at some point first v2: Fix comment that wasn't updated from previous patch Signed-off-by: Kent Russell Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 85a536924571..476a072027a6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -1427,6 +1427,15 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) vega10_setup_default_pcie_table(hwmgr); + /* Zero out the saved copy of the CUSTOM profile + * This will be checked when trying to set the profile + * and will require that new values be passed in + */ + data->custom_profile_mode[0] = 0; + data->custom_profile_mode[1] = 0; + data->custom_profile_mode[2] = 0; + data->custom_profile_mode[3] = 0; + /* save a copy of the default DPM table */ memcpy(&(data->golden_dpm_table), &(data->dpm_table), sizeof(struct vega10_dpm_table)); @@ -4910,9 +4919,20 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui 1 << power_profile_mode); if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { - if (size == 0 || size > 4) + if (size != 0 && size != 4) return -EINVAL; + /* If size = 0 and the CUSTOM profile has been set already + * then just apply the profile. The copy stored in the hwmgr + * is zeroed out on init + */ + if (size == 0) { + if (data->custom_profile_mode[0] != 0) + goto out; + else + return -EINVAL; + } + data->custom_profile_mode[0] = busy_set_point = input[0]; data->custom_profile_mode[1] = FPS = input[1]; data->custom_profile_mode[2] = use_rlc_busy = input[2]; @@ -4923,6 +4943,7 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui use_rlc_busy << 16 | min_active_level<<24); } +out: hwmgr->power_profile_mode = power_profile_mode; return 0; -- cgit v1.2.3 From e178f10726d136e54080a43382b858020ea694a3 Mon Sep 17 00:00:00 2001 From: Kent Russell Date: Mon, 1 Apr 2019 07:19:06 -0400 Subject: drm/amdgpu: Allow switching to CUSTOM profile on Vega20 Vega20 stores a CUSTOM profile on the GPU, but it may not be valid. Add a bool to vega20_hwmgr to determine whether or not a valid CUSTOM profile has been set, and use that to check when a user requests switching to the CUSTOM profile without passing in any arguments. Then if the CUSTOM profile has been set already, we can switch to it without providing the parameters again Signed-off-by: Kent Russell Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 16 +++++++++++++++- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 3f349ada8de0..34f3782ff018 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -427,6 +427,7 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr) hwmgr->platform_descriptor.clockStep.memoryClock = 500; data->total_active_cus = adev->gfx.cu_info.number; + data->is_custom_profile_set = false; return 0; } @@ -3827,7 +3828,11 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui } if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { - if (size < 10) + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); + if (size == 0 && !data->is_custom_profile_set) + return -EINVAL; + if (size < 10 && size != 0) return -EINVAL; result = vega20_get_activity_monitor_coeff(hwmgr, @@ -3837,6 +3842,13 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui "[SetPowerProfile] Failed to get activity monitor!", return result); + /* If size==0, then we want to apply the already-configured + * CUSTOM profile again. Just apply it, since we checked its + * validity above + */ + if (size == 0) + goto out; + switch (input[0]) { case 0: /* Gfxclk */ activity_monitor.Gfx_FPS = input[1]; @@ -3887,11 +3899,13 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui result = vega20_set_activity_monitor_coeff(hwmgr, (uint8_t *)(&activity_monitor), WORKLOAD_PPLIB_CUSTOM_BIT); + data->is_custom_profile_set = true; PP_ASSERT_WITH_CODE(!result, "[SetPowerProfile] Failed to set activity monitor!", return result); } +out: /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ workload_type = conv_power_profile_to_pplib_workload(power_profile_mode); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h index a5bc758ae097..f37a28afd574 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h @@ -530,6 +530,8 @@ struct vega20_hwmgr { bool pcie_parameters_override; uint32_t pcie_gen_level1; uint32_t pcie_width_level1; + + bool is_custom_profile_set; }; #define VEGA20_DPM2_NEAR_TDP_DEC 10 -- cgit v1.2.3 From e854194c8b6e27b970f3f993909451d9cc26a21e Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 29 Mar 2019 13:00:53 +0100 Subject: drm/amd/display: Update VRR state earlier in atomic_commit_tail. We need the VRR active/inactive state info earlier in the commit sequence, so VRR related setup functions like amdgpu_dm_handle_vrr_transition() know the final VRR state when they need to do their hw setup work. Split update_freesync_state_on_stream() into an early part, that can run at the beginning of commit tail before the vrr transition handling, and a late part that must run after vrr transition handling inside the commit planes code for enabled crtc's. Suggested by Nicholas Kazlauskas. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 61 +++++++++++++++++------ 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 380a7f9bd55d..06a65712ab53 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4646,7 +4646,6 @@ static void update_freesync_state_on_stream( { struct mod_vrr_params vrr_params = new_crtc_state->vrr_params; struct dc_info_packet vrr_infopacket = {0}; - struct mod_freesync_config config = new_crtc_state->freesync_config; if (!new_stream) return; @@ -4659,20 +4658,6 @@ static void update_freesync_state_on_stream( if (!new_stream->timing.h_total || !new_stream->timing.v_total) return; - if (new_crtc_state->vrr_supported && - config.min_refresh_in_uhz && - config.max_refresh_in_uhz) { - config.state = new_crtc_state->base.vrr_enabled ? - VRR_STATE_ACTIVE_VARIABLE : - VRR_STATE_INACTIVE; - } else { - config.state = VRR_STATE_UNSUPPORTED; - } - - mod_freesync_build_vrr_params(dm->freesync_module, - new_stream, - &config, &vrr_params); - if (surface) { mod_freesync_handle_preflip( dm->freesync_module, @@ -4713,6 +4698,46 @@ static void update_freesync_state_on_stream( (int)vrr_params.state); } +static void pre_update_freesync_state_on_stream( + struct amdgpu_display_manager *dm, + struct dm_crtc_state *new_crtc_state) +{ + struct dc_stream_state *new_stream = new_crtc_state->stream; + struct mod_vrr_params vrr_params = new_crtc_state->vrr_params; + struct mod_freesync_config config = new_crtc_state->freesync_config; + + if (!new_stream) + return; + + /* + * TODO: Determine why min/max totals and vrefresh can be 0 here. + * For now it's sufficient to just guard against these conditions. + */ + if (!new_stream->timing.h_total || !new_stream->timing.v_total) + return; + + if (new_crtc_state->vrr_supported && + config.min_refresh_in_uhz && + config.max_refresh_in_uhz) { + config.state = new_crtc_state->base.vrr_enabled ? + VRR_STATE_ACTIVE_VARIABLE : + VRR_STATE_INACTIVE; + } else { + config.state = VRR_STATE_UNSUPPORTED; + } + + mod_freesync_build_vrr_params(dm->freesync_module, + new_stream, + &config, &vrr_params); + + new_crtc_state->freesync_timing_changed |= + (memcmp(&new_crtc_state->vrr_params.adjust, + &vrr_params.adjust, + sizeof(vrr_params.adjust)) != 0); + + new_crtc_state->vrr_params = vrr_params; +} + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct dc_state *dc_state, struct drm_device *dev, @@ -5234,6 +5259,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) mutex_unlock(&dm->dc_lock); } + /* Update freesync state before amdgpu_dm_handle_vrr_transition(). */ + for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); + pre_update_freesync_state_on_stream(dm, dm_new_crtc_state); + } + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { /* -- cgit v1.2.3 From 66b0c973d7f74e3f45dbe9904ad02298d1dc430f Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 29 Mar 2019 13:00:54 +0100 Subject: drm/amd/display: Prevent vblank irq disable while VRR is active. (v3) During VRR mode we can not allow vblank irq dis-/enable transitions, as an enable after a disable can happen at an arbitrary time during the video refresh cycle, e.g., with a high likelyhood inside vblank front-porch. An enable during front-porch would cause vblank timestamp updates/calculations which are completely bogus, given the code can't know when the vblank will end as long as we are in front-porch with no page flip completed. Hold a permanent vblank reference on the crtc while in active VRR mode to prevent a vblank disable, and drop the reference again when switching back to fixed refresh rate non-VRR mode. v2: Make sure transition is also handled if vrr is disabled and stream gets disabled in the same atomic commit by moving the call to the transition function outside of plane commit. Suggested by Nicholas. v3: Trivial rebase onto previous patch. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 06a65712ab53..467fa4dfda90 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -251,6 +251,12 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev, return NULL; } +static inline bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state) +{ + return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE || + dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED; +} + static void dm_pflip_high_irq(void *interrupt_params) { struct amdgpu_crtc *amdgpu_crtc; @@ -4738,6 +4744,31 @@ static void pre_update_freesync_state_on_stream( new_crtc_state->vrr_params = vrr_params; } +static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, + struct dm_crtc_state *new_state) +{ + bool old_vrr_active = amdgpu_dm_vrr_active(old_state); + bool new_vrr_active = amdgpu_dm_vrr_active(new_state); + + if (!old_vrr_active && new_vrr_active) { + /* Transition VRR inactive -> active: + * While VRR is active, we must not disable vblank irq, as a + * reenable after disable would compute bogus vblank/pflip + * timestamps if it likely happened inside display front-porch. + */ + drm_crtc_vblank_get(new_state->base.crtc); + DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", + __func__, new_state->base.crtc->base.id); + } else if (old_vrr_active && !new_vrr_active) { + /* Transition VRR active -> inactive: + * Allow vblank irq disable again for fixed refresh rate. + */ + drm_crtc_vblank_put(new_state->base.crtc); + DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", + __func__, new_state->base.crtc->base.id); + } +} + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct dc_state *dc_state, struct drm_device *dev, @@ -5278,6 +5309,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); + + /* Handle vrr on->off / off->on transitions */ + amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, + dm_new_crtc_state); + modeset_needed = modeset_required( new_crtc_state, dm_new_crtc_state->stream, -- cgit v1.2.3 From fdd1fe57c00ef96c8a8ab6e5eab03d248deecca6 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Tue, 2 Apr 2019 17:00:06 -0500 Subject: drm/amd/display: Rework vrr flip throttling for late vblank irq. For throttling to work correctly, we always need a baseline vblank count last_flip_vblank that increments at start of front-porch. This is the case for drm_crtc_vblank_count() in non-VRR mode, where the vblank irq fires at start of front-porch and triggers DRM core vblank handling, but it is no longer the case in VRR mode, where core vblank handling is done later, after end of front-porch. Therefore drm_crtc_vblank_count() is no longer useful for this. We also can't use drm_crtc_accurate_vblank_count(), as that would screw up vblank timestamps in VRR mode when called in front-porch. To solve this, use the cooked hardware vblank counter returned by amdgpu_get_vblank_counter_kms() instead, as that one is cooked to always increment at start of front-porch, independent of when vblank related irq's fire. This patch allows vblank irq handling to happen anywhere within vblank of even after it, without a negative impact on flip throttling, so followup patches can shift the vblank core handling trigger point wherever they need it. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 ++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 889e443eeee7..add238fe4b57 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -406,7 +406,7 @@ struct amdgpu_crtc { struct amdgpu_flip_work *pflip_works; enum amdgpu_flip_status pflip_status; int deferred_flip_completion; - u64 last_flip_vblank; + u32 last_flip_vblank; /* pll sharing */ struct amdgpu_atom_ss ss; bool ss_enabled; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 467fa4dfda90..4c27e68af64d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -286,7 +286,7 @@ static void dm_pflip_high_irq(void *interrupt_params) } /* Update to correct count(s) if racing with vblank irq */ - amdgpu_crtc->last_flip_vblank = drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); + drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); /* wake up userspace */ if (amdgpu_crtc->event) { @@ -298,6 +298,14 @@ static void dm_pflip_high_irq(void *interrupt_params) } else WARN_ON(1); + /* Keep track of vblank of this flip for flip throttling. We use the + * cooked hw counter, as that one incremented at start of this vblank + * of pageflip completion, so last_flip_vblank is the forbidden count + * for queueing new pageflips if vsync + VRR is enabled. + */ + amdgpu_crtc->last_flip_vblank = amdgpu_get_vblank_counter_kms(adev->ddev, + amdgpu_crtc->crtc_id); + amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; spin_unlock_irqrestore(&adev->ddev->event_lock, flags); @@ -4790,11 +4798,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, unsigned long flags; struct amdgpu_bo *abo; uint64_t tiling_flags; - uint32_t target, target_vblank; - uint64_t last_flip_vblank; - bool vrr_active = acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE; + uint32_t target_vblank, last_flip_vblank; + bool vrr_active = amdgpu_dm_vrr_active(acrtc_state); bool pflip_present = false; - struct { struct dc_surface_update surface_updates[MAX_SURFACES]; struct dc_plane_info plane_infos[MAX_SURFACES]; @@ -4936,7 +4942,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, * clients using the GLX_OML_sync_control extension or * DRI3/Present extension with defined target_msc. */ - last_flip_vblank = drm_crtc_vblank_count(pcrtc); + last_flip_vblank = amdgpu_get_vblank_counter_kms(dm->ddev, acrtc_attach->crtc_id); } else { /* For variable refresh rate mode only: @@ -4952,11 +4958,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags); } - target = (uint32_t)last_flip_vblank + wait_for_vblank; - - /* Prepare wait for target vblank early - before the fence-waits */ - target_vblank = target - (uint32_t)drm_crtc_vblank_count(pcrtc) + - amdgpu_get_vblank_counter_kms(pcrtc->dev, acrtc_attach->crtc_id); + target_vblank = last_flip_vblank + wait_for_vblank; /* * Wait until we're out of the vertical blank period before the one -- cgit v1.2.3 From d2574c33bb719575bac7a7044daed24081601804 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 29 Mar 2019 13:00:56 +0100 Subject: drm/amd/display: In VRR mode, do DRM core vblank handling at end of vblank. (v2) In VRR mode, proper vblank/pageflip timestamps can only be computed after the display scanout position has left front-porch. Therefore delay calls to drm_crtc_handle_vblank(), and thereby calls to drm_update_vblank_count() and pageflip event delivery, to after the end of front-porch when in VRR mode. We add a new vupdate irq, which triggers at the end of the vupdate interval, ie. at the end of vblank, and calls the core vblank handler function. The new irq handler is not executed in standard non-VRR mode, so vblank handling for fixed refresh rate mode is identical to the past implementation. v2: Implement feedback by Nicholas and Paul Menzel. Signed-off-by: Mario Kleiner Acked-by: Harry Wentland Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 128 ++++++++++++++++++++- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 9 ++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 22 ++++ .../amd/display/dc/irq/dce110/irq_service_dce110.c | 7 +- .../amd/display/dc/irq/dce120/irq_service_dce120.c | 7 +- .../amd/display/dc/irq/dce80/irq_service_dce80.c | 6 +- .../amd/display/dc/irq/dcn10/irq_service_dcn10.c | 40 +++++-- 8 files changed, 204 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6e71749cb3bb..6294316f24c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -827,6 +827,7 @@ struct amdgpu_device { /* For pre-DCE11. DCE11 and later are in "struct amdgpu_device->dm" */ struct work_struct hotplug_work; struct amdgpu_irq_src crtc_irq; + struct amdgpu_irq_src vupdate_irq; struct amdgpu_irq_src pageflip_irq; struct amdgpu_irq_src hpd_irq; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 4c27e68af64d..3bc3b15121e1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -315,6 +315,32 @@ static void dm_pflip_high_irq(void *interrupt_params) drm_crtc_vblank_put(&amdgpu_crtc->base); } +static void dm_vupdate_high_irq(void *interrupt_params) +{ + struct common_irq_params *irq_params = interrupt_params; + struct amdgpu_device *adev = irq_params->adev; + struct amdgpu_crtc *acrtc; + struct dm_crtc_state *acrtc_state; + + acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE); + + if (acrtc) { + acrtc_state = to_dm_crtc_state(acrtc->base.state); + + DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, + amdgpu_dm_vrr_active(acrtc_state)); + + /* Core vblank handling is done here after end of front-porch in + * vrr mode, as vblank timestamping will give valid results + * while now done after front-porch. This will also deliver + * page-flip completion events that have been queued to us + * if a pageflip happened inside front-porch. + */ + if (amdgpu_dm_vrr_active(acrtc_state)) + drm_crtc_handle_vblank(&acrtc->base); + } +} + static void dm_crtc_high_irq(void *interrupt_params) { struct common_irq_params *irq_params = interrupt_params; @@ -325,11 +351,24 @@ static void dm_crtc_high_irq(void *interrupt_params) acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); if (acrtc) { - drm_crtc_handle_vblank(&acrtc->base); - amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); - acrtc_state = to_dm_crtc_state(acrtc->base.state); + DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, + amdgpu_dm_vrr_active(acrtc_state)); + + /* Core vblank handling at start of front-porch is only possible + * in non-vrr mode, as only there vblank timestamping will give + * valid results while done in front-porch. Otherwise defer it + * to dm_vupdate_high_irq after end of front-porch. + */ + if (!amdgpu_dm_vrr_active(acrtc_state)) + drm_crtc_handle_vblank(&acrtc->base); + + /* Following stuff must happen at start of vblank, for crc + * computation and below-the-range btr support in vrr mode. + */ + amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); + if (acrtc_state->stream && acrtc_state->vrr_params.supported && acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { @@ -1447,6 +1486,27 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev) dm_crtc_high_irq, c_irq_params); } + /* Use VUPDATE interrupt */ + for (i = VISLANDS30_IV_SRCID_D1_V_UPDATE_INT; i <= VISLANDS30_IV_SRCID_D6_V_UPDATE_INT; i += 2) { + r = amdgpu_irq_add_id(adev, client_id, i, &adev->vupdate_irq); + if (r) { + DRM_ERROR("Failed to add vupdate irq id!\n"); + return r; + } + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = + dc_interrupt_to_irq_source(dc, i, 0); + + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1]; + + c_irq_params->adev = adev; + c_irq_params->irq_src = int_params.irq_source; + + amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_vupdate_high_irq, c_irq_params); + } + /* Use GRPH_PFLIP interrupt */ for (i = VISLANDS30_IV_SRCID_D1_GRPH_PFLIP; i <= VISLANDS30_IV_SRCID_D6_GRPH_PFLIP; i += 2) { @@ -1532,6 +1592,34 @@ static int dcn10_register_irq_handlers(struct amdgpu_device *adev) dm_crtc_high_irq, c_irq_params); } + /* Use VUPDATE_NO_LOCK interrupt on DCN, which seems to correspond to + * the regular VUPDATE interrupt on DCE. We want DC_IRQ_SOURCE_VUPDATEx + * to trigger at end of each vblank, regardless of state of the lock, + * matching DCE behaviour. + */ + for (i = DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT; + i <= DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT + adev->mode_info.num_crtc - 1; + i++) { + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_DCE, i, &adev->vupdate_irq); + + if (r) { + DRM_ERROR("Failed to add vupdate irq id!\n"); + return r; + } + + int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT; + int_params.irq_source = + dc_interrupt_to_irq_source(dc, i, 0); + + c_irq_params = &adev->dm.vupdate_params[int_params.irq_source - DC_IRQ_SOURCE_VUPDATE1]; + + c_irq_params->adev = adev; + c_irq_params->irq_src = int_params.irq_source; + + amdgpu_dm_irq_register_interrupt(adev, &int_params, + dm_vupdate_high_irq, c_irq_params); + } + /* Use GRPH_PFLIP interrupt */ for (i = DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT; i <= DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT + adev->mode_info.num_crtc - 1; @@ -3224,12 +3312,41 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) return &state->base; } +static inline int dm_set_vupdate_irq(struct drm_crtc *crtc, bool enable) +{ + enum dc_irq_source irq_source; + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + struct amdgpu_device *adev = crtc->dev->dev_private; + int rc; + + irq_source = IRQ_TYPE_VUPDATE + acrtc->otg_inst; + + rc = dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; + + DRM_DEBUG_DRIVER("crtc %d - vupdate irq %sabling: r=%d\n", + acrtc->crtc_id, enable ? "en" : "dis", rc); + return rc; +} static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable) { enum dc_irq_source irq_source; struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_device *adev = crtc->dev->dev_private; + struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state); + int rc = 0; + + if (enable) { + /* vblank irq on -> Only need vupdate irq in vrr mode */ + if (amdgpu_dm_vrr_active(acrtc_state)) + rc = dm_set_vupdate_irq(crtc, true); + } else { + /* vblank irq off -> vupdate irq off */ + rc = dm_set_vupdate_irq(crtc, false); + } + + if (rc) + return rc; irq_source = IRQ_TYPE_VBLANK + acrtc->otg_inst; return dc_interrupt_set(adev->dm.dc, irq_source, enable) ? 0 : -EBUSY; @@ -4763,7 +4880,11 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, * While VRR is active, we must not disable vblank irq, as a * reenable after disable would compute bogus vblank/pflip * timestamps if it likely happened inside display front-porch. + * + * We also need vupdate irq for the actual core vblank handling + * at end of vblank. */ + dm_set_vupdate_irq(new_state->base.crtc, true); drm_crtc_vblank_get(new_state->base.crtc); DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", __func__, new_state->base.crtc->base.id); @@ -4771,6 +4892,7 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, /* Transition VRR active -> inactive: * Allow vblank irq disable again for fixed refresh rate. */ + dm_set_vupdate_irq(new_state->base.crtc, false); drm_crtc_vblank_put(new_state->base.crtc); DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", __func__, new_state->base.crtc->base.id); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 773ef5ca8441..3a0b6164c755 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -182,6 +182,15 @@ struct amdgpu_display_manager { struct common_irq_params vblank_params[DC_IRQ_SOURCE_VBLANK6 - DC_IRQ_SOURCE_VBLANK1 + 1]; + /** + * @vupdate_params: + * + * Vertical update IRQ parameters, passed to registered handlers when + * triggered. + */ + struct common_irq_params + vupdate_params[DC_IRQ_SOURCE_VUPDATE6 - DC_IRQ_SOURCE_VUPDATE1 + 1]; + spinlock_t irq_handler_list_table_lock; struct backlight_device *backlight_dev; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index cd10f77cdeb0..fd22b4474dbf 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -674,11 +674,30 @@ static int amdgpu_dm_set_crtc_irq_state(struct amdgpu_device *adev, __func__); } +static int amdgpu_dm_set_vupdate_irq_state(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + unsigned int crtc_id, + enum amdgpu_interrupt_state state) +{ + return dm_irq_state( + adev, + source, + crtc_id, + state, + IRQ_TYPE_VUPDATE, + __func__); +} + static const struct amdgpu_irq_src_funcs dm_crtc_irq_funcs = { .set = amdgpu_dm_set_crtc_irq_state, .process = amdgpu_dm_irq_handler, }; +static const struct amdgpu_irq_src_funcs dm_vupdate_irq_funcs = { + .set = amdgpu_dm_set_vupdate_irq_state, + .process = amdgpu_dm_irq_handler, +}; + static const struct amdgpu_irq_src_funcs dm_pageflip_irq_funcs = { .set = amdgpu_dm_set_pflip_irq_state, .process = amdgpu_dm_irq_handler, @@ -695,6 +714,9 @@ void amdgpu_dm_set_irq_funcs(struct amdgpu_device *adev) adev->crtc_irq.num_types = adev->mode_info.num_crtc; adev->crtc_irq.funcs = &dm_crtc_irq_funcs; + adev->vupdate_irq.num_types = adev->mode_info.num_crtc; + adev->vupdate_irq.funcs = &dm_vupdate_irq_funcs; + adev->pageflip_irq.num_types = adev->mode_info.num_crtc; adev->pageflip_irq.funcs = &dm_pageflip_irq_funcs; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c index afe0876fe6f8..86987f5e8bd5 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c @@ -81,6 +81,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #define hpd_int_entry(reg_num)\ [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ .enable_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\ @@ -137,7 +142,7 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ .ack_value =\ CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ - .funcs = &vblank_irq_info_funcs\ + .funcs = &vupdate_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c index 1ea7256ec89b..750ba0ab4106 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c @@ -84,6 +84,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #define BASE_INNER(seg) \ DCE_BASE__INST0_SEG ## seg @@ -140,7 +145,7 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { IRQ_REG_ENTRY(CRTC, reg_num,\ CRTC_INTERRUPT_CONTROL, CRTC_V_UPDATE_INT_MSK,\ CRTC_V_UPDATE_INT_STATUS, CRTC_V_UPDATE_INT_CLEAR),\ - .funcs = &vblank_irq_info_funcs\ + .funcs = &vupdate_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c index 8a2066c313fe..de218fe84a43 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c @@ -84,6 +84,10 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; #define hpd_int_entry(reg_num)\ [DC_IRQ_SOURCE_INVALID + reg_num] = {\ @@ -142,7 +146,7 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ .ack_value =\ CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ - .funcs = &vblank_irq_info_funcs\ + .funcs = &vupdate_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c index e04ae49243f6..10ac6deff5ff 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c @@ -56,6 +56,18 @@ enum dc_irq_source to_dal_irq_source_dcn10( return DC_IRQ_SOURCE_VBLANK5; case DCN_1_0__SRCID__DC_D6_OTG_VSTARTUP: return DC_IRQ_SOURCE_VBLANK6; + case DCN_1_0__SRCID__OTG0_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE1; + case DCN_1_0__SRCID__OTG1_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE2; + case DCN_1_0__SRCID__OTG2_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE3; + case DCN_1_0__SRCID__OTG3_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE4; + case DCN_1_0__SRCID__OTG4_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE5; + case DCN_1_0__SRCID__OTG5_IHC_V_UPDATE_NO_LOCK_INTERRUPT: + return DC_IRQ_SOURCE_VUPDATE6; case DCN_1_0__SRCID__HUBP0_FLIP_INTERRUPT: return DC_IRQ_SOURCE_PFLIP1; case DCN_1_0__SRCID__HUBP1_FLIP_INTERRUPT: @@ -153,6 +165,11 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .ack = NULL }; +static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #define BASE_INNER(seg) \ DCE_BASE__INST0_SEG ## seg @@ -203,12 +220,15 @@ static const struct irq_source_info_funcs vblank_irq_info_funcs = { .funcs = &pflip_irq_info_funcs\ } -#define vupdate_int_entry(reg_num)\ +/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic + * of DCE's DC_IRQ_SOURCE_VUPDATEx. + */ +#define vupdate_no_lock_int_entry(reg_num)\ [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ IRQ_REG_ENTRY(OTG, reg_num,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\ - .funcs = &vblank_irq_info_funcs\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ + .funcs = &vupdate_no_lock_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ @@ -315,12 +335,12 @@ irq_source_info_dcn10[DAL_IRQ_SOURCES_NUMBER] = { dc_underflow_int_entry(6), [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(), [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(), - vupdate_int_entry(0), - vupdate_int_entry(1), - vupdate_int_entry(2), - vupdate_int_entry(3), - vupdate_int_entry(4), - vupdate_int_entry(5), + vupdate_no_lock_int_entry(0), + vupdate_no_lock_int_entry(1), + vupdate_no_lock_int_entry(2), + vupdate_no_lock_int_entry(3), + vupdate_no_lock_int_entry(4), + vupdate_no_lock_int_entry(5), vblank_int_entry(0), vblank_int_entry(1), vblank_int_entry(2), -- cgit v1.2.3 From 71bbe51a0839f77fb75b473b23485b026d74ab75 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 29 Mar 2019 13:00:57 +0100 Subject: drm/amd/display: Make pageflip event delivery compatible with VRR. We want vblank counts and timestamps of flip completion as sent in pageflip completion events to be consistent with the vblank count and timestamp of the vblank of flip completion, like in non VRR mode. In VRR mode, drm_update_vblank_count() - and thereby vblank count and timestamp updates - must be delayed until after the end of front-porch of each vblank, as it is only safe to calculate vblank timestamps outside of the front-porch, when we actually know when the vblank will end or has ended. The function drm_update_vblank_count() which updates timestamps and counts gets called by drm_crtc_accurate_vblank_count() or by drm_crtc_handle_vblank(). Therefore we must make sure that pageflip events for a completed flip are only sent out after drm_crtc_accurate_vblank_count() or drm_crtc_handle_vblank() is executed, after end of front-porch for the vblank of flip completion. Two cases: a) Pageflip irq handler executes inside front-porch: In this case we must defer sending pageflip events until drm_crtc_handle_vblank() executes after end of front-porch, and thereby calculates proper vblank count and timestamp. Iow. the pflip irq handler must just arm a pageflip event to be sent out by drm_crtc_handle_vblank() later on. b) Pageflip irq handler executes after end of front-porch, e.g., after flip completion in back-porch or due to a massively delayed handler invocation into the active scanout of the new frame. In this case we can call drm_crtc_accurate_vblank_count() to safely force calculation of a proper vblank count and timestamp, and must send the pageflip completion event ourselves from the pageflip irq handler. This is the same behaviour as needed for standard fixed refresh rate mode. To decide from within pageflip handler if we are in case a) or b), we check the current scanout position against the boundary of front-porch. In non-VRR mode we just do what we did in the past. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 68 ++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 3bc3b15121e1..65eb5611a169 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -263,6 +263,10 @@ static void dm_pflip_high_irq(void *interrupt_params) struct common_irq_params *irq_params = interrupt_params; struct amdgpu_device *adev = irq_params->adev; unsigned long flags; + struct drm_pending_vblank_event *e; + struct dm_crtc_state *acrtc_state; + uint32_t vpos, hpos, v_blank_start, v_blank_end; + bool vrr_active; amdgpu_crtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_PFLIP); @@ -285,18 +289,57 @@ static void dm_pflip_high_irq(void *interrupt_params) return; } - /* Update to correct count(s) if racing with vblank irq */ - drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); + /* page flip completed. */ + e = amdgpu_crtc->event; + amdgpu_crtc->event = NULL; - /* wake up userspace */ - if (amdgpu_crtc->event) { - drm_crtc_send_vblank_event(&amdgpu_crtc->base, amdgpu_crtc->event); + if (!e) + WARN_ON(1); - /* page flip completed. clean up */ - amdgpu_crtc->event = NULL; + acrtc_state = to_dm_crtc_state(amdgpu_crtc->base.state); + vrr_active = amdgpu_dm_vrr_active(acrtc_state); + + /* Fixed refresh rate, or VRR scanout position outside front-porch? */ + if (!vrr_active || + !dc_stream_get_scanoutpos(acrtc_state->stream, &v_blank_start, + &v_blank_end, &hpos, &vpos) || + (vpos < v_blank_start)) { + /* Update to correct count and vblank timestamp if racing with + * vblank irq. This also updates to the correct vblank timestamp + * even in VRR mode, as scanout is past the front-porch atm. + */ + drm_crtc_accurate_vblank_count(&amdgpu_crtc->base); - } else - WARN_ON(1); + /* Wake up userspace by sending the pageflip event with proper + * count and timestamp of vblank of flip completion. + */ + if (e) { + drm_crtc_send_vblank_event(&amdgpu_crtc->base, e); + + /* Event sent, so done with vblank for this flip */ + drm_crtc_vblank_put(&amdgpu_crtc->base); + } + } else if (e) { + /* VRR active and inside front-porch: vblank count and + * timestamp for pageflip event will only be up to date after + * drm_crtc_handle_vblank() has been executed from late vblank + * irq handler after start of back-porch (vline 0). We queue the + * pageflip event for send-out by drm_crtc_handle_vblank() with + * updated timestamp and count, once it runs after us. + * + * We need to open-code this instead of using the helper + * drm_crtc_arm_vblank_event(), as that helper would + * call drm_crtc_accurate_vblank_count(), which we must + * not call in VRR mode while we are in front-porch! + */ + + /* sequence will be replaced by real count during send-out. */ + e->sequence = drm_crtc_vblank_count(&amdgpu_crtc->base); + e->pipe = amdgpu_crtc->crtc_id; + + list_add_tail(&e->base.link, &adev->ddev->vblank_event_list); + e = NULL; + } /* Keep track of vblank of this flip for flip throttling. We use the * cooked hw counter, as that one incremented at start of this vblank @@ -309,10 +352,9 @@ static void dm_pflip_high_irq(void *interrupt_params) amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE; spin_unlock_irqrestore(&adev->ddev->event_lock, flags); - DRM_DEBUG_DRIVER("%s - crtc :%d[%p], pflip_stat:AMDGPU_FLIP_NONE\n", - __func__, amdgpu_crtc->crtc_id, amdgpu_crtc); - - drm_crtc_vblank_put(&amdgpu_crtc->base); + DRM_DEBUG_DRIVER("crtc:%d[%p], pflip_stat:AMDGPU_FLIP_NONE, vrr[%d]-fp %d\n", + amdgpu_crtc->crtc_id, amdgpu_crtc, + vrr_active, (int) !e); } static void dm_vupdate_high_irq(void *interrupt_params) -- cgit v1.2.3 From 905801fe72377b4dc53c6e13eea1a91c6a4aa0c4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 20 Mar 2019 15:54:36 +0200 Subject: drm/i915: Force 2*96 MHz cdclk on glk/cnl when audio power is enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CDCLK has to be at least twice the BLCK regardless of audio. Audio driver has to probe using this hook and increase the clock even in absence of any display. v2: Use atomic refcount for get_power, put_power so that we can call each once(Abhay). v3: Reset power well 2 to avoid any transaction on iDisp link during cdclk change(Abhay). v4: Remove Power well 2 reset workaround(Ville). v5: Remove unwanted Power well 2 register defined in v4(Abhay). v6: - Use a dedicated flag instead of state->modeset for min CDCLK changes - Make get/put audio power domain symmetric - Rebased on top of intel_wakeref tracking changes. Signed-off-by: Ville Syrjälä Signed-off-by: Abhay Kumar Tested-by: Abhay Kumar Signed-off-by: Imre Deak Reviewed-by: Clint Taylor Link: https://patchwork.freedesktop.org/patch/msgid/20190320135439.12201-1-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 ++ drivers/gpu/drm/i915/intel_audio.c | 64 ++++++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_cdclk.c | 30 ++++++----------- drivers/gpu/drm/i915/intel_display.c | 9 ++++- drivers/gpu/drm/i915/intel_drv.h | 3 ++ 5 files changed, 86 insertions(+), 23 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0ab4826921f7..bde4daeb20eb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1629,6 +1629,8 @@ struct drm_i915_private { struct intel_cdclk_state actual; /* The current hardware cdclk state */ struct intel_cdclk_state hw; + + int force_min_cdclk; } cdclk; /** @@ -1751,6 +1753,7 @@ struct drm_i915_private { * */ struct mutex av_mutex; + int audio_power_refcount; struct { struct mutex mutex; diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 502b57ce72ab..20324b0d34c7 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -741,18 +741,78 @@ void intel_init_audio_hooks(struct drm_i915_private *dev_priv) } } +static void glk_force_audio_cdclk(struct drm_i915_private *dev_priv, + bool enable) +{ + struct drm_modeset_acquire_ctx ctx; + struct drm_atomic_state *state; + int ret; + + drm_modeset_acquire_init(&ctx, 0); + state = drm_atomic_state_alloc(&dev_priv->drm); + if (WARN_ON(!state)) + return; + + state->acquire_ctx = &ctx; + +retry: + to_intel_atomic_state(state)->cdclk.force_min_cdclk_changed = true; + to_intel_atomic_state(state)->cdclk.force_min_cdclk = + enable ? 2 * 96000 : 0; + + /* + * Protects dev_priv->cdclk.force_min_cdclk + * Need to lock this here in case we have no active pipes + * and thus wouldn't lock it during the commit otherwise. + */ + ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, + &ctx); + if (!ret) + ret = drm_atomic_commit(state); + + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + drm_modeset_backoff(&ctx); + goto retry; + } + + WARN_ON(ret); + + drm_atomic_state_put(state); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + static unsigned long i915_audio_component_get_power(struct device *kdev) { + struct drm_i915_private *dev_priv = kdev_to_i915(kdev); + intel_wakeref_t ret; + /* Catch potential impedance mismatches before they occur! */ BUILD_BUG_ON(sizeof(intel_wakeref_t) > sizeof(unsigned long)); - return intel_display_power_get(kdev_to_i915(kdev), POWER_DOMAIN_AUDIO); + ret = intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); + + /* Force CDCLK to 2*BCLK as long as we need audio to be powered. */ + if (dev_priv->audio_power_refcount++ == 0) + if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) + glk_force_audio_cdclk(dev_priv, true); + + return ret; } static void i915_audio_component_put_power(struct device *kdev, unsigned long cookie) { - intel_display_power_put(kdev_to_i915(kdev), POWER_DOMAIN_AUDIO, cookie); + struct drm_i915_private *dev_priv = kdev_to_i915(kdev); + + /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ + if (--dev_priv->audio_power_refcount == 0) + if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) + glk_force_audio_cdclk(dev_priv, false); + + intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO, cookie); } static void i915_audio_component_codec_wake_override(struct device *kdev, diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index d40f8793718c..72074c72662d 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -2188,19 +2188,8 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) /* * According to BSpec, "The CD clock frequency must be at least twice * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default. - * - * FIXME: Check the actual, not default, BCLK being used. - * - * FIXME: This does not depend on ->has_audio because the higher CDCLK - * is required for audio probe, also when there are no audio capable - * displays connected at probe time. This leads to unnecessarily high - * CDCLK when audio is not required. - * - * FIXME: This limit is only applied when there are displays connected - * at probe time. If we probe without displays, we'll still end up using - * the platform minimum CDCLK, failing audio probe. */ - if (INTEL_GEN(dev_priv) >= 9) + if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9) min_cdclk = max(2 * 96000, min_cdclk); /* @@ -2240,7 +2229,7 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state) intel_state->min_cdclk[i] = min_cdclk; } - min_cdclk = 0; + min_cdclk = intel_state->cdclk.force_min_cdclk; for_each_pipe(dev_priv, pipe) min_cdclk = max(intel_state->min_cdclk[pipe], min_cdclk); @@ -2301,7 +2290,8 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state) vlv_calc_voltage_level(dev_priv, cdclk); if (!intel_state->active_crtcs) { - cdclk = vlv_calc_cdclk(dev_priv, 0); + cdclk = vlv_calc_cdclk(dev_priv, + intel_state->cdclk.force_min_cdclk); intel_state->cdclk.actual.cdclk = cdclk; intel_state->cdclk.actual.voltage_level = @@ -2334,7 +2324,7 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state) bdw_calc_voltage_level(cdclk); if (!intel_state->active_crtcs) { - cdclk = bdw_calc_cdclk(0); + cdclk = bdw_calc_cdclk(intel_state->cdclk.force_min_cdclk); intel_state->cdclk.actual.cdclk = cdclk; intel_state->cdclk.actual.voltage_level = @@ -2406,7 +2396,7 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) skl_calc_voltage_level(cdclk); if (!intel_state->active_crtcs) { - cdclk = skl_calc_cdclk(0, vco); + cdclk = skl_calc_cdclk(intel_state->cdclk.force_min_cdclk, vco); intel_state->cdclk.actual.vco = vco; intel_state->cdclk.actual.cdclk = cdclk; @@ -2445,10 +2435,10 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) if (!intel_state->active_crtcs) { if (IS_GEMINILAKE(dev_priv)) { - cdclk = glk_calc_cdclk(0); + cdclk = glk_calc_cdclk(intel_state->cdclk.force_min_cdclk); vco = glk_de_pll_vco(dev_priv, cdclk); } else { - cdclk = bxt_calc_cdclk(0); + cdclk = bxt_calc_cdclk(intel_state->cdclk.force_min_cdclk); vco = bxt_de_pll_vco(dev_priv, cdclk); } @@ -2484,7 +2474,7 @@ static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state) cnl_compute_min_voltage_level(intel_state)); if (!intel_state->active_crtcs) { - cdclk = cnl_calc_cdclk(0); + cdclk = cnl_calc_cdclk(intel_state->cdclk.force_min_cdclk); vco = cnl_cdclk_pll_vco(dev_priv, cdclk); intel_state->cdclk.actual.vco = vco; @@ -2520,7 +2510,7 @@ static int icl_modeset_calc_cdclk(struct drm_atomic_state *state) cnl_compute_min_voltage_level(intel_state)); if (!intel_state->active_crtcs) { - cdclk = icl_calc_cdclk(0, ref); + cdclk = icl_calc_cdclk(intel_state->cdclk.force_min_cdclk, ref); vco = icl_calc_cdclk_pll_vco(dev_priv, cdclk); intel_state->cdclk.actual.vco = vco; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6facfba79a41..cc090ab4936a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12993,6 +12993,11 @@ static int intel_modeset_checks(struct drm_atomic_state *state) return -EINVAL; } + /* keep the current setting */ + if (!intel_state->cdclk.force_min_cdclk_changed) + intel_state->cdclk.force_min_cdclk = + dev_priv->cdclk.force_min_cdclk; + intel_state->modeset = true; intel_state->active_crtcs = dev_priv->active_crtcs; intel_state->cdclk.logical = dev_priv->cdclk.logical; @@ -13088,7 +13093,7 @@ static int intel_atomic_check(struct drm_device *dev, struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state, *crtc_state; int ret, i; - bool any_ms = false; + bool any_ms = intel_state->cdclk.force_min_cdclk_changed; /* Catch I915_MODE_FLAG_INHERITED */ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, @@ -13680,6 +13685,8 @@ static int intel_atomic_commit(struct drm_device *dev, dev_priv->active_crtcs = intel_state->active_crtcs; dev_priv->cdclk.logical = intel_state->cdclk.logical; dev_priv->cdclk.actual = intel_state->cdclk.actual; + dev_priv->cdclk.force_min_cdclk = + intel_state->cdclk.force_min_cdclk; } drm_atomic_state_get(state); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f8c7b291fdc3..55ef42383c45 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -556,6 +556,9 @@ struct intel_atomic_state { * state only when all crtc's are DPMS off. */ struct intel_cdclk_state actual; + + int force_min_cdclk; + bool force_min_cdclk_changed; } cdclk; bool dpll_set, modeset; -- cgit v1.2.3 From 48d9f87ddd2108663fd866b254e05d422243cc56 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 20 Mar 2019 15:54:37 +0200 Subject: drm/i915: Save the old CDCLK atomic state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old state will be needed by an upcoming patch to determine if the commit increases or decreases CDCLK, so move the old state to the atomic state (while keeping the new one in dev_priv). cdclk.logical and cdclk.actual in the atomic state isn't used atm anywhere after the atomic check phase, so this should be safe. v2: - Use swap() instead of opencoding it. (Ville) Suggested-by: Ville Syrjälä Cc: Ville Syrjälä Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190320135439.12201-2-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_cdclk.c | 20 ++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 4 ++-- drivers/gpu/drm/i915/intel_drv.h | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 72074c72662d..2fc443468706 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -2101,6 +2101,26 @@ bool intel_cdclk_changed(const struct intel_cdclk_state *a, a->voltage_level != b->voltage_level; } +/** + * intel_cdclk_swap_state - make atomic CDCLK configuration effective + * @state: atomic state + * + * This is the CDCLK version of drm_atomic_helper_swap_state() since the + * helper does not handle driver-specific global state. + * + * Similarly to the atomic helpers this function does a complete swap, + * i.e. it also puts the old state into @state. This is used by the commit + * code to determine how CDCLK has changed (for instance did it increase or + * decrease). + */ +void intel_cdclk_swap_state(struct intel_atomic_state *state) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + + swap(state->cdclk.logical, dev_priv->cdclk.logical); + swap(state->cdclk.actual, dev_priv->cdclk.actual); +} + void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, const char *context) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cc090ab4936a..702d28459bee 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13683,10 +13683,10 @@ static int intel_atomic_commit(struct drm_device *dev, intel_state->min_voltage_level, sizeof(intel_state->min_voltage_level)); dev_priv->active_crtcs = intel_state->active_crtcs; - dev_priv->cdclk.logical = intel_state->cdclk.logical; - dev_priv->cdclk.actual = intel_state->cdclk.actual; dev_priv->cdclk.force_min_cdclk = intel_state->cdclk.force_min_cdclk; + + intel_cdclk_swap_state(intel_state); } drm_atomic_state_get(state); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 55ef42383c45..4dbe123087c9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1698,6 +1698,7 @@ bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, const struct intel_cdclk_state *b); bool intel_cdclk_changed(const struct intel_cdclk_state *a, const struct intel_cdclk_state *b); +void intel_cdclk_swap_state(struct intel_atomic_state *state); void intel_set_cdclk(struct drm_i915_private *dev_priv, const struct intel_cdclk_state *cdclk_state); void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, -- cgit v1.2.3 From 2b21dfbeee725778daed2c3dd45a3fc808176feb Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 20 Mar 2019 15:54:38 +0200 Subject: drm/i915: Remove redundant store of logical CDCLK state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We copied the original state into the atomic state already earlier in the function, so no need to do it a second time. Cc: Ville Syrjälä Signed-off-by: Imre Deak Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190320135439.12201-3-imre.deak@intel.com --- drivers/gpu/drm/i915/intel_display.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 702d28459bee..1a3d370a36b1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13051,8 +13051,6 @@ static int intel_modeset_checks(struct drm_atomic_state *state) DRM_DEBUG_KMS("New voltage level calculated to be logical %u, actual %u\n", intel_state->cdclk.logical.voltage_level, intel_state->cdclk.actual.voltage_level); - } else { - to_intel_atomic_state(state)->cdclk.logical = dev_priv->cdclk.logical; } intel_modeset_clear_plls(state); -- cgit v1.2.3 From 59f9e9cab3a1e6762fb707d0d829b982930f1349 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 27 Mar 2019 12:13:21 +0200 Subject: drm/i915: Skip modeset for cdclk changes if possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we have only a single active pipe and the cdclk change only requires the cd2x divider to be updated bxt+ can do the update with forcing a full modeset on the pipe. Try to hook that up. v2: - Wait for vblank after an optimized CDCLK change. - Avoid optimization if the pipe needs a modeset (or was disabled). - Split CDCLK change to a pre/post plane update step. v3: - Use correct version of CDCLK state as old state. (Ville) - Remove unused intel_cdclk_can_skip_modeset() v4: - For consistency call intel_set_cdclk_post_plane_update() only during modesets (and not fastsets). v5: - Remove the logic to update the CD2X divider on-the-fly on ICL, since only a divider of 1 is supported there. Clint also noticed that the pipe select bits in CDCLK_CTL are oddly defined on ICL, it's not clear yet whether that's only an error in the specification. Signed-off-by: Ville Syrjälä Signed-off-by: Abhay Kumar Tested-by: Abhay Kumar Signed-off-by: Imre Deak Reviewed-by: Clint Taylor Link: https://patchwork.freedesktop.org/patch/msgid/20190327101321.3095-1-imre.deak@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/intel_cdclk.c | 135 +++++++++++++++++++++++++++-------- drivers/gpu/drm/i915/intel_display.c | 42 ++++++++++- drivers/gpu/drm/i915/intel_drv.h | 17 ++++- 4 files changed, 163 insertions(+), 34 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bde4daeb20eb..8f38d03b1c4e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -282,7 +282,8 @@ struct drm_i915_display_funcs { void (*get_cdclk)(struct drm_i915_private *dev_priv, struct intel_cdclk_state *cdclk_state); void (*set_cdclk)(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state); + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe); int (*get_fifo_size)(struct drm_i915_private *dev_priv, enum i9xx_plane_id i9xx_plane); int (*compute_pipe_wm)(struct intel_crtc_state *cstate); diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 2fc443468706..b8cd481f5e33 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -517,7 +517,8 @@ static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv) } static void vlv_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { int cdclk = cdclk_state->cdclk; u32 val, cmd = cdclk_state->voltage_level; @@ -599,7 +600,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, } static void chv_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { int cdclk = cdclk_state->cdclk; u32 val, cmd = cdclk_state->voltage_level; @@ -698,7 +700,8 @@ static void bdw_get_cdclk(struct drm_i915_private *dev_priv, } static void bdw_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { int cdclk = cdclk_state->cdclk; u32 val; @@ -988,7 +991,8 @@ static void skl_dpll0_disable(struct drm_i915_private *dev_priv) } static void skl_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { int cdclk = cdclk_state->cdclk; int vco = cdclk_state->vco; @@ -1159,7 +1163,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv) cdclk_state.cdclk = skl_calc_cdclk(0, cdclk_state.vco); cdclk_state.voltage_level = skl_calc_voltage_level(cdclk_state.cdclk); - skl_set_cdclk(dev_priv, &cdclk_state); + skl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } /** @@ -1177,7 +1181,7 @@ void skl_uninit_cdclk(struct drm_i915_private *dev_priv) cdclk_state.vco = 0; cdclk_state.voltage_level = skl_calc_voltage_level(cdclk_state.cdclk); - skl_set_cdclk(dev_priv, &cdclk_state); + skl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } static int bxt_calc_cdclk(int min_cdclk) @@ -1356,7 +1360,8 @@ static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco) } static void bxt_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { int cdclk = cdclk_state->cdclk; int vco = cdclk_state->vco; @@ -1409,11 +1414,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, bxt_de_pll_enable(dev_priv, vco); val = divider | skl_cdclk_decimal(cdclk); - /* - * FIXME if only the cd2x divider needs changing, it could be done - * without shutting off the pipe (if only one pipe is active). - */ - val |= BXT_CDCLK_CD2X_PIPE_NONE; + if (pipe == INVALID_PIPE) + val |= BXT_CDCLK_CD2X_PIPE_NONE; + else + val |= BXT_CDCLK_CD2X_PIPE(pipe); /* * Disable SSA Precharge when CD clock frequency < 500 MHz, * enable otherwise. @@ -1422,6 +1426,9 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv, val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE; I915_WRITE(CDCLK_CTL, val); + if (pipe != INVALID_PIPE) + intel_wait_for_vblank(dev_priv, pipe); + mutex_lock(&dev_priv->pcu_lock); /* * The timeout isn't specified, the 2ms used here is based on @@ -1526,7 +1533,7 @@ void bxt_init_cdclk(struct drm_i915_private *dev_priv) } cdclk_state.voltage_level = bxt_calc_voltage_level(cdclk_state.cdclk); - bxt_set_cdclk(dev_priv, &cdclk_state); + bxt_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } /** @@ -1544,7 +1551,7 @@ void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) cdclk_state.vco = 0; cdclk_state.voltage_level = bxt_calc_voltage_level(cdclk_state.cdclk); - bxt_set_cdclk(dev_priv, &cdclk_state); + bxt_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } static int cnl_calc_cdclk(int min_cdclk) @@ -1664,7 +1671,8 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco) } static void cnl_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { int cdclk = cdclk_state->cdclk; int vco = cdclk_state->vco; @@ -1705,13 +1713,15 @@ static void cnl_set_cdclk(struct drm_i915_private *dev_priv, cnl_cdclk_pll_enable(dev_priv, vco); val = divider | skl_cdclk_decimal(cdclk); - /* - * FIXME if only the cd2x divider needs changing, it could be done - * without shutting off the pipe (if only one pipe is active). - */ - val |= BXT_CDCLK_CD2X_PIPE_NONE; + if (pipe == INVALID_PIPE) + val |= BXT_CDCLK_CD2X_PIPE_NONE; + else + val |= BXT_CDCLK_CD2X_PIPE(pipe); I915_WRITE(CDCLK_CTL, val); + if (pipe != INVALID_PIPE) + intel_wait_for_vblank(dev_priv, pipe); + /* inform PCU of the change */ mutex_lock(&dev_priv->pcu_lock); sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL, @@ -1848,7 +1858,8 @@ static int icl_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk) } static void icl_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { unsigned int cdclk = cdclk_state->cdclk; unsigned int vco = cdclk_state->vco; @@ -1873,6 +1884,11 @@ static void icl_set_cdclk(struct drm_i915_private *dev_priv, if (dev_priv->cdclk.hw.vco != vco) cnl_cdclk_pll_enable(dev_priv, vco); + /* + * On ICL CD2X_DIV can only be 1, so we'll never end up changing the + * divider here synchronized to a pipe while CDCLK is on, nor will we + * need the corresponding vblank wait. + */ I915_WRITE(CDCLK_CTL, ICL_CDCLK_CD2X_PIPE_NONE | skl_cdclk_decimal(cdclk)); @@ -2003,7 +2019,7 @@ sanitize: sanitized_state.voltage_level = icl_calc_voltage_level(sanitized_state.cdclk); - icl_set_cdclk(dev_priv, &sanitized_state); + icl_set_cdclk(dev_priv, &sanitized_state, INVALID_PIPE); } /** @@ -2021,7 +2037,7 @@ void icl_uninit_cdclk(struct drm_i915_private *dev_priv) cdclk_state.vco = 0; cdclk_state.voltage_level = icl_calc_voltage_level(cdclk_state.cdclk); - icl_set_cdclk(dev_priv, &cdclk_state); + icl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } /** @@ -2049,7 +2065,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv) cdclk_state.vco = cnl_cdclk_pll_vco(dev_priv, cdclk_state.cdclk); cdclk_state.voltage_level = cnl_calc_voltage_level(cdclk_state.cdclk); - cnl_set_cdclk(dev_priv, &cdclk_state); + cnl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } /** @@ -2067,7 +2083,7 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) cdclk_state.vco = 0; cdclk_state.voltage_level = cnl_calc_voltage_level(cdclk_state.cdclk); - cnl_set_cdclk(dev_priv, &cdclk_state); + cnl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } /** @@ -2086,6 +2102,27 @@ bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, a->ref != b->ref; } +/** + * intel_cdclk_needs_cd2x_update - Determine if two CDCLK states require a cd2x divider update + * @a: first CDCLK state + * @b: second CDCLK state + * + * Returns: + * True if the CDCLK states require just a cd2x divider update, false if not. + */ +bool intel_cdclk_needs_cd2x_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *a, + const struct intel_cdclk_state *b) +{ + /* Older hw doesn't have the capability */ + if (INTEL_GEN(dev_priv) < 10 && !IS_GEN9_LP(dev_priv)) + return false; + + return a->cdclk != b->cdclk && + a->vco == b->vco && + a->ref == b->ref; +} + /** * intel_cdclk_changed - Determine if two CDCLK states are different * @a: first CDCLK state @@ -2134,12 +2171,14 @@ void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, * intel_set_cdclk - Push the CDCLK state to the hardware * @dev_priv: i915 device * @cdclk_state: new CDCLK state + * @pipe: pipe with which to synchronize the update * * Program the hardware based on the passed in CDCLK state, * if necessary. */ -void intel_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state) +static void intel_set_cdclk(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *cdclk_state, + enum pipe pipe) { if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state)) return; @@ -2149,7 +2188,7 @@ void intel_set_cdclk(struct drm_i915_private *dev_priv, intel_dump_cdclk_state(cdclk_state, "Changing CDCLK to"); - dev_priv->display.set_cdclk(dev_priv, cdclk_state); + dev_priv->display.set_cdclk(dev_priv, cdclk_state, pipe); if (WARN(intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_state), "cdclk state doesn't match!\n")) { @@ -2158,6 +2197,46 @@ void intel_set_cdclk(struct drm_i915_private *dev_priv, } } +/** + * intel_set_cdclk_pre_plane_update - Push the CDCLK state to the hardware + * @dev_priv: i915 device + * @old_state: old CDCLK state + * @new_state: new CDCLK state + * @pipe: pipe with which to synchronize the update + * + * Program the hardware before updating the HW plane state based on the passed + * in CDCLK state, if necessary. + */ +void +intel_set_cdclk_pre_plane_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *old_state, + const struct intel_cdclk_state *new_state, + enum pipe pipe) +{ + if (pipe == INVALID_PIPE || old_state->cdclk <= new_state->cdclk) + intel_set_cdclk(dev_priv, new_state, pipe); +} + +/** + * intel_set_cdclk_post_plane_update - Push the CDCLK state to the hardware + * @dev_priv: i915 device + * @old_state: old CDCLK state + * @new_state: new CDCLK state + * @pipe: pipe with which to synchronize the update + * + * Program the hardware after updating the HW plane state based on the passed + * in CDCLK state, if necessary. + */ +void +intel_set_cdclk_post_plane_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *old_state, + const struct intel_cdclk_state *new_state, + enum pipe pipe) +{ + if (pipe != INVALID_PIPE && old_state->cdclk > new_state->cdclk) + intel_set_cdclk(dev_priv, new_state, pipe); +} + static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv, int pixel_rate) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1a3d370a36b1..7ecfb7d98839 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13002,6 +13002,7 @@ static int intel_modeset_checks(struct drm_atomic_state *state) intel_state->active_crtcs = dev_priv->active_crtcs; intel_state->cdclk.logical = dev_priv->cdclk.logical; intel_state->cdclk.actual = dev_priv->cdclk.actual; + intel_state->cdclk.pipe = INVALID_PIPE; for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (new_crtc_state->active) @@ -13021,6 +13022,8 @@ static int intel_modeset_checks(struct drm_atomic_state *state) * adjusted_mode bits in the crtc directly. */ if (dev_priv->display.modeset_calc_cdclk) { + enum pipe pipe; + ret = dev_priv->display.modeset_calc_cdclk(state); if (ret < 0) return ret; @@ -13037,12 +13040,36 @@ static int intel_modeset_checks(struct drm_atomic_state *state) return ret; } + if (is_power_of_2(intel_state->active_crtcs)) { + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + + pipe = ilog2(intel_state->active_crtcs); + crtc = &intel_get_crtc_for_pipe(dev_priv, pipe)->base; + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (crtc_state && needs_modeset(crtc_state)) + pipe = INVALID_PIPE; + } else { + pipe = INVALID_PIPE; + } + /* All pipes must be switched off while we change the cdclk. */ - if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual, - &intel_state->cdclk.actual)) { + if (pipe != INVALID_PIPE && + intel_cdclk_needs_cd2x_update(dev_priv, + &dev_priv->cdclk.actual, + &intel_state->cdclk.actual)) { + ret = intel_lock_all_pipes(state); + if (ret < 0) + return ret; + + intel_state->cdclk.pipe = pipe; + } else if (intel_cdclk_needs_modeset(&dev_priv->cdclk.actual, + &intel_state->cdclk.actual)) { ret = intel_modeset_all_pipes(state); if (ret < 0) return ret; + + intel_state->cdclk.pipe = INVALID_PIPE; } DRM_DEBUG_KMS("New cdclk calculated to be logical %u kHz, actual %u kHz\n", @@ -13451,7 +13478,10 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) if (intel_state->modeset) { drm_atomic_helper_update_legacy_modeset_state(state->dev, state); - intel_set_cdclk(dev_priv, &dev_priv->cdclk.actual); + intel_set_cdclk_pre_plane_update(dev_priv, + &intel_state->cdclk.actual, + &dev_priv->cdclk.actual, + intel_state->cdclk.pipe); /* * SKL workaround: bspec recommends we disable the SAGV when we @@ -13480,6 +13510,12 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) /* Now enable the clocks, plane, pipe, and connectors that we set up. */ dev_priv->display.update_crtcs(state); + if (intel_state->modeset) + intel_set_cdclk_post_plane_update(dev_priv, + &intel_state->cdclk.actual, + &dev_priv->cdclk.actual, + intel_state->cdclk.pipe); + /* FIXME: We should call drm_atomic_helper_commit_hw_done() here * already, but still need the state for the delayed optimization. To * fix this: diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4dbe123087c9..64544613920b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -559,6 +559,8 @@ struct intel_atomic_state { int force_min_cdclk; bool force_min_cdclk_changed; + /* pipe to which cd2x update is synchronized */ + enum pipe pipe; } cdclk; bool dpll_set, modeset; @@ -1694,13 +1696,24 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); void intel_update_max_cdclk(struct drm_i915_private *dev_priv); void intel_update_cdclk(struct drm_i915_private *dev_priv); void intel_update_rawclk(struct drm_i915_private *dev_priv); +bool intel_cdclk_needs_cd2x_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *a, + const struct intel_cdclk_state *b); bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, const struct intel_cdclk_state *b); bool intel_cdclk_changed(const struct intel_cdclk_state *a, const struct intel_cdclk_state *b); void intel_cdclk_swap_state(struct intel_atomic_state *state); -void intel_set_cdclk(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *cdclk_state); +void +intel_set_cdclk_pre_plane_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *old_state, + const struct intel_cdclk_state *new_state, + enum pipe pipe); +void +intel_set_cdclk_post_plane_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *old_state, + const struct intel_cdclk_state *new_state, + enum pipe pipe); void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, const char *context); -- cgit v1.2.3 From 813d20dccf93f84f4c16236f7c037dc34db48f10 Mon Sep 17 00:00:00 2001 From: Aidan Wood Date: Fri, 22 Feb 2019 13:37:03 -0500 Subject: drm/amd/display: Fix multi-thread writing to 1 state [Why] Multiple threads were writing back to one global VBA in DC resulting in multiple threads overwriting eachother's data [How] Add an instance of DML (which contains VBA) to each context and change all calls that used dc->dml to use context->dml. Created a seperate copy constructor for linux in a case where there is no access to DC. Signed-off-by: Aidan Wood Reviewed-by: Jun Lei Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 ++-- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 98 +++++++++++----------- drivers/gpu/drm/amd/display/dc/core/dc.c | 83 +++++++++++++----- drivers/gpu/drm/amd/display/dc/core/dc_debug.c | 24 +++--- drivers/gpu/drm/amd/display/dc/dc.h | 3 +- drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c | 30 +++---- .../drm/amd/display/dc/dce100/dce100_resource.c | 8 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 14 ++-- .../drm/amd/display/dc/dce110/dce110_resource.c | 62 +++++++------- .../drm/amd/display/dc/dce112/dce112_resource.c | 62 +++++++------- .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 8 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c | 2 +- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 24 +++--- .../display/dc/dcn10/dcn10_hw_sequencer_debug.c | 12 +-- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 10 ++- 15 files changed, 252 insertions(+), 203 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 65eb5611a169..f2312f022b46 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1773,17 +1773,16 @@ dm_atomic_duplicate_state(struct drm_private_obj *obj) __drm_atomic_helper_private_obj_duplicate_state(obj, &new_state->base); - new_state->context = dc_create_state(); + old_state = to_dm_atomic_state(obj->state); + + if (old_state && old_state->context) + new_state->context = dc_copy_state(old_state->context); + if (!new_state->context) { kfree(new_state); return NULL; } - old_state = to_dm_atomic_state(obj->state); - if (old_state && old_state->context) - dc_resource_state_copy_construct(old_state->context, - new_state->context); - return &new_state->base; } @@ -1827,7 +1826,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) if (!state) return -ENOMEM; - state->context = dc_create_state(); + state->context = dc_create_state(adev->dm.dc); if (!state->context) { kfree(state); return -ENOMEM; @@ -5287,7 +5286,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dc_state = dm_state->context; } else { /* No state changes, retain current state. */ - dc_state_temp = dc_create_state(); + dc_state_temp = dc_create_state(dm->dc); ASSERT(dc_state_temp); dc_state = dc_state_temp; dc_resource_state_copy_construct_current(dm->dc, dc_state); diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 1e23ddc7d088..8843361e842d 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -544,28 +544,28 @@ static void calc_wm_sets_and_perf_params( v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_vnom0p8; dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); - context->bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = + context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_exit_ns = v->stutter_exit_watermark * 1000; - context->bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = + context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = v->stutter_enter_plus_exit_watermark * 1000; - context->bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = + context->bw_ctx.bw.dcn.watermarks.b.cstate_pstate.pstate_change_ns = v->dram_clock_change_watermark * 1000; - context->bw.dcn.watermarks.b.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; - context->bw.dcn.watermarks.b.urgent_ns = v->urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.b.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.b.urgent_ns = v->urgent_watermark * 1000; v->dcfclk_per_state[1] = v->dcfclkv_nom0p8; v->dcfclk_per_state[0] = v->dcfclkv_nom0p8; v->dcfclk = v->dcfclkv_nom0p8; dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); - context->bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = + context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = v->stutter_exit_watermark * 1000; - context->bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = + context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = v->stutter_enter_plus_exit_watermark * 1000; - context->bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = + context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.pstate_change_ns = v->dram_clock_change_watermark * 1000; - context->bw.dcn.watermarks.c.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; - context->bw.dcn.watermarks.c.urgent_ns = v->urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.c.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = v->urgent_watermark * 1000; } if (v->voltage_level < 3) { @@ -579,14 +579,14 @@ static void calc_wm_sets_and_perf_params( v->dcfclk = v->dcfclkv_max0p9; dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); - context->bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = + context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_exit_ns = v->stutter_exit_watermark * 1000; - context->bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = + context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = v->stutter_enter_plus_exit_watermark * 1000; - context->bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = + context->bw_ctx.bw.dcn.watermarks.d.cstate_pstate.pstate_change_ns = v->dram_clock_change_watermark * 1000; - context->bw.dcn.watermarks.d.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; - context->bw.dcn.watermarks.d.urgent_ns = v->urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.d.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.d.urgent_ns = v->urgent_watermark * 1000; } v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vnom0p8; @@ -599,20 +599,20 @@ static void calc_wm_sets_and_perf_params( v->dcfclk = v->dcfclk_per_state[v->voltage_level]; dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); - context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = v->stutter_exit_watermark * 1000; - context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = v->stutter_enter_plus_exit_watermark * 1000; - context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = v->dram_clock_change_watermark * 1000; - context->bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; - context->bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000; if (v->voltage_level >= 2) { - context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a; - context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a; + context->bw_ctx.bw.dcn.watermarks.b = context->bw_ctx.bw.dcn.watermarks.a; + context->bw_ctx.bw.dcn.watermarks.c = context->bw_ctx.bw.dcn.watermarks.a; } if (v->voltage_level >= 3) - context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a; + context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a; } #endif @@ -1008,8 +1008,8 @@ bool dcn_validate_bandwidth( dc->debug.sr_enter_plus_exit_time_dpm0_ns / 1000.0f; if (dc->debug.sr_exit_time_dpm0_ns) v->sr_exit_time = dc->debug.sr_exit_time_dpm0_ns / 1000.0f; - dc->dml.soc.sr_enter_plus_exit_time_us = v->sr_enter_plus_exit_time; - dc->dml.soc.sr_exit_time_us = v->sr_exit_time; + context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = v->sr_enter_plus_exit_time; + context->bw_ctx.dml.soc.sr_exit_time_us = v->sr_exit_time; mode_support_and_system_configuration(v); } @@ -1035,54 +1035,54 @@ bool dcn_validate_bandwidth( */ dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); - context->bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_exit_ns = v->stutter_exit_watermark * 1000; - context->bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = v->stutter_enter_plus_exit_watermark * 1000; - context->bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = + context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns = v->dram_clock_change_watermark * 1000; - context->bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; - context->bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000; - context->bw.dcn.watermarks.b = context->bw.dcn.watermarks.a; - context->bw.dcn.watermarks.c = context->bw.dcn.watermarks.a; - context->bw.dcn.watermarks.d = context->bw.dcn.watermarks.a; + context->bw_ctx.bw.dcn.watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.a.urgent_ns = v->urgent_watermark * 1000; + context->bw_ctx.bw.dcn.watermarks.b = context->bw_ctx.bw.dcn.watermarks.a; + context->bw_ctx.bw.dcn.watermarks.c = context->bw_ctx.bw.dcn.watermarks.a; + context->bw_ctx.bw.dcn.watermarks.d = context->bw_ctx.bw.dcn.watermarks.a; - context->bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / + context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / (ddr4_dram_factor_single_Channel * v->number_of_channels)); if (bw_consumed == v->fabric_and_dram_bandwidth_vmin0p65) { - context->bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / 32); + context->bw_ctx.bw.dcn.clk.fclk_khz = (int)(bw_consumed * 1000000 / 32); } - context->bw.dcn.clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); - context->bw.dcn.clk.dcfclk_khz = (int)(v->dcfclk * 1000); + context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); + context->bw_ctx.bw.dcn.clk.dcfclk_khz = (int)(v->dcfclk * 1000); - context->bw.dcn.clk.dispclk_khz = (int)(v->dispclk * 1000); + context->bw_ctx.bw.dcn.clk.dispclk_khz = (int)(v->dispclk * 1000); if (dc->debug.max_disp_clk == true) - context->bw.dcn.clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000); + context->bw_ctx.bw.dcn.clk.dispclk_khz = (int)(dc->dcn_soc->max_dispclk_vmax0p9 * 1000); - if (context->bw.dcn.clk.dispclk_khz < + if (context->bw_ctx.bw.dcn.clk.dispclk_khz < dc->debug.min_disp_clk_khz) { - context->bw.dcn.clk.dispclk_khz = + context->bw_ctx.bw.dcn.clk.dispclk_khz = dc->debug.min_disp_clk_khz; } - context->bw.dcn.clk.dppclk_khz = context->bw.dcn.clk.dispclk_khz / v->dispclk_dppclk_ratio; - context->bw.dcn.clk.phyclk_khz = v->phyclk_per_state[v->voltage_level]; + context->bw_ctx.bw.dcn.clk.dppclk_khz = context->bw_ctx.bw.dcn.clk.dispclk_khz / v->dispclk_dppclk_ratio; + context->bw_ctx.bw.dcn.clk.phyclk_khz = v->phyclk_per_state[v->voltage_level]; switch (v->voltage_level) { case 0: - context->bw.dcn.clk.max_supported_dppclk_khz = + context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vmin0p65 * 1000); break; case 1: - context->bw.dcn.clk.max_supported_dppclk_khz = + context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vmid0p72 * 1000); break; case 2: - context->bw.dcn.clk.max_supported_dppclk_khz = + context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vnom0p8 * 1000); break; default: - context->bw.dcn.clk.max_supported_dppclk_khz = + context->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz = (int)(dc->dcn_soc->max_dppclk_vmax0p9 * 1000); break; } @@ -1181,9 +1181,9 @@ bool dcn_validate_bandwidth( if (v->voltage_level == 0) { - dc->dml.soc.sr_enter_plus_exit_time_us = + context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->dcn_soc->sr_enter_plus_exit_time; - dc->dml.soc.sr_exit_time_us = dc->dcn_soc->sr_exit_time; + context->bw_ctx.dml.soc.sr_exit_time_us = dc->dcn_soc->sr_exit_time; } /* diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index c7415772e280..1c1cfb513620 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -681,13 +681,6 @@ static bool construct(struct dc *dc, dc_ctx->dc_stream_id_count = 0; dc->ctx = dc_ctx; - dc->current_state = dc_create_state(); - - if (!dc->current_state) { - dm_error("%s: failed to create validate ctx\n", __func__); - goto fail; - } - /* Create logger */ dc_ctx->dce_environment = init_params->dce_environment; @@ -739,6 +732,18 @@ static bool construct(struct dc *dc, if (!dc->res_pool) goto fail; + /* Creation of current_state must occur after dc->dml + * is initialized in dc_create_resource_pool because + * on creation it copies the contents of dc->dml + */ + + dc->current_state = dc_create_state(dc); + + if (!dc->current_state) { + dm_error("%s: failed to create validate ctx\n", __func__); + goto fail; + } + dc_resource_state_construct(dc, dc->current_state); if (!create_links(dc, init_params->num_virtual_links)) @@ -755,7 +760,7 @@ fail: static void disable_dangling_plane(struct dc *dc, struct dc_state *context) { int i, j; - struct dc_state *dangling_context = dc_create_state(); + struct dc_state *dangling_context = dc_create_state(dc); struct dc_state *current_ctx; if (dangling_context == NULL) @@ -1213,18 +1218,58 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) return true; } -struct dc_state *dc_create_state(void) +struct dc_state *dc_create_state(struct dc *dc) { struct dc_state *context = kzalloc(sizeof(struct dc_state), GFP_KERNEL); if (!context) return NULL; + /* Each context must have their own instance of VBA and in order to + * initialize and obtain IP and SOC the base DML instance from DC is + * initially copied into every context + */ + memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib)); kref_init(&context->refcount); + return context; } +struct dc_state *dc_copy_state(struct dc_state *src_ctx) +{ + int i, j; + struct dc_state *new_ctx = kzalloc(sizeof(struct dc_state), + GFP_KERNEL); + + if (!new_ctx) + return NULL; + + memcpy(new_ctx, src_ctx, sizeof(struct dc_state)); + + for (i = 0; i < MAX_PIPES; i++) { + struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i]; + + if (cur_pipe->top_pipe) + cur_pipe->top_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx]; + + if (cur_pipe->bottom_pipe) + cur_pipe->bottom_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx]; + + } + + for (i = 0; i < new_ctx->stream_count; i++) { + dc_stream_retain(new_ctx->streams[i]); + for (j = 0; j < new_ctx->stream_status[i].plane_count; j++) + dc_plane_state_retain( + new_ctx->stream_status[i].plane_states[j]); + } + + kref_init(&new_ctx->refcount); + + return new_ctx; +} + void dc_retain_state(struct dc_state *context) { kref_get(&context->refcount); @@ -1824,7 +1869,7 @@ void dc_commit_updates_for_stream(struct dc *dc, if (update_type >= UPDATE_TYPE_FULL) { /* initialize scratch memory for building context */ - context = dc_create_state(); + context = dc_create_state(dc); if (context == NULL) { DC_ERROR("Failed to allocate new validate context!\n"); return; @@ -2109,13 +2154,13 @@ void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) { - info->displayClock = (unsigned int)state->bw.dcn.clk.dispclk_khz; - info->engineClock = (unsigned int)state->bw.dcn.clk.dcfclk_khz; - info->memoryClock = (unsigned int)state->bw.dcn.clk.dramclk_khz; - info->maxSupportedDppClock = (unsigned int)state->bw.dcn.clk.max_supported_dppclk_khz; - info->dppClock = (unsigned int)state->bw.dcn.clk.dppclk_khz; - info->socClock = (unsigned int)state->bw.dcn.clk.socclk_khz; - info->dcfClockDeepSleep = (unsigned int)state->bw.dcn.clk.dcfclk_deep_sleep_khz; - info->fClock = (unsigned int)state->bw.dcn.clk.fclk_khz; - info->phyClock = (unsigned int)state->bw.dcn.clk.phyclk_khz; + info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz; + info->engineClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz; + info->memoryClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz; + info->maxSupportedDppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz; + info->dppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz; + info->socClock = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz; + info->dcfClockDeepSleep = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz; + info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz; + info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c index 73d049506618..5903e7822f98 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_debug.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_debug.c @@ -351,19 +351,19 @@ void context_clock_trace( DC_LOGGER_INIT(dc->ctx->logger); CLOCK_TRACE("Current: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n", - context->bw.dcn.clk.dispclk_khz, - context->bw.dcn.clk.dppclk_khz, - context->bw.dcn.clk.dcfclk_khz, - context->bw.dcn.clk.dcfclk_deep_sleep_khz, - context->bw.dcn.clk.fclk_khz, - context->bw.dcn.clk.socclk_khz); + context->bw_ctx.bw.dcn.clk.dispclk_khz, + context->bw_ctx.bw.dcn.clk.dppclk_khz, + context->bw_ctx.bw.dcn.clk.dcfclk_khz, + context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz, + context->bw_ctx.bw.dcn.clk.fclk_khz, + context->bw_ctx.bw.dcn.clk.socclk_khz); CLOCK_TRACE("Calculated: dispclk_khz:%d max_dppclk_khz:%d dcfclk_khz:%d\n" "dcfclk_deep_sleep_khz:%d fclk_khz:%d socclk_khz:%d\n", - context->bw.dcn.clk.dispclk_khz, - context->bw.dcn.clk.dppclk_khz, - context->bw.dcn.clk.dcfclk_khz, - context->bw.dcn.clk.dcfclk_deep_sleep_khz, - context->bw.dcn.clk.fclk_khz, - context->bw.dcn.clk.socclk_khz); + context->bw_ctx.bw.dcn.clk.dispclk_khz, + context->bw_ctx.bw.dcn.clk.dppclk_khz, + context->bw_ctx.bw.dcn.clk.dcfclk_khz, + context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz, + context->bw_ctx.bw.dcn.clk.fclk_khz, + context->bw_ctx.bw.dcn.clk.socclk_khz); #endif } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c09a19046fd8..16483bf82c8f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -669,7 +669,8 @@ void dc_resource_state_destruct(struct dc_state *context); bool dc_commit_state(struct dc *dc, struct dc_state *context); -struct dc_state *dc_create_state(void); +struct dc_state *dc_create_state(struct dc *dc); +struct dc_state *dc_copy_state(struct dc_state *src_ctx); void dc_retain_state(struct dc_state *context); void dc_release_state(struct dc_state *context); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c index 6e142c2db986..963686380738 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c @@ -222,7 +222,7 @@ static enum dm_pp_clocks_state dce_get_required_clocks_state( * all required clocks */ for (i = clk_mgr_dce->max_clks_state; i >= DM_PP_CLOCKS_STATE_ULTRA_LOW; i--) - if (context->bw.dce.dispclk_khz > + if (context->bw_ctx.bw.dce.dispclk_khz > clk_mgr_dce->max_clks_by_state[i].display_clk_khz || max_pix_clk > clk_mgr_dce->max_clks_by_state[i].pixel_clk_khz) @@ -232,7 +232,7 @@ static enum dm_pp_clocks_state dce_get_required_clocks_state( if (low_req_clk > clk_mgr_dce->max_clks_state) { /* set max clock state for high phyclock, invalid on exceeding display clock */ if (clk_mgr_dce->max_clks_by_state[clk_mgr_dce->max_clks_state].display_clk_khz - < context->bw.dce.dispclk_khz) + < context->bw_ctx.bw.dce.dispclk_khz) low_req_clk = DM_PP_CLOCKS_STATE_INVALID; else low_req_clk = clk_mgr_dce->max_clks_state; @@ -610,22 +610,22 @@ static void dce11_pplib_apply_display_requirements( struct dm_pp_display_configuration *pp_display_cfg = &context->pp_display_cfg; pp_display_cfg->all_displays_in_sync = - context->bw.dce.all_displays_in_sync; + context->bw_ctx.bw.dce.all_displays_in_sync; pp_display_cfg->nb_pstate_switch_disable = - context->bw.dce.nbp_state_change_enable == false; + context->bw_ctx.bw.dce.nbp_state_change_enable == false; pp_display_cfg->cpu_cc6_disable = - context->bw.dce.cpuc_state_change_enable == false; + context->bw_ctx.bw.dce.cpuc_state_change_enable == false; pp_display_cfg->cpu_pstate_disable = - context->bw.dce.cpup_state_change_enable == false; + context->bw_ctx.bw.dce.cpup_state_change_enable == false; pp_display_cfg->cpu_pstate_separation_time = - context->bw.dce.blackout_recovery_time_us; + context->bw_ctx.bw.dce.blackout_recovery_time_us; - pp_display_cfg->min_memory_clock_khz = context->bw.dce.yclk_khz + pp_display_cfg->min_memory_clock_khz = context->bw_ctx.bw.dce.yclk_khz / MEMORY_TYPE_MULTIPLIER_CZ; pp_display_cfg->min_engine_clock_khz = determine_sclk_from_bounding_box( dc, - context->bw.dce.sclk_khz); + context->bw_ctx.bw.dce.sclk_khz); /* * As workaround for >4x4K lightup set dcfclock to min_engine_clock value. @@ -638,7 +638,7 @@ static void dce11_pplib_apply_display_requirements( pp_display_cfg->min_engine_clock_khz : 0; pp_display_cfg->min_engine_clock_deep_sleep_khz - = context->bw.dce.sclk_deep_sleep_khz; + = context->bw_ctx.bw.dce.sclk_deep_sleep_khz; pp_display_cfg->avail_mclk_switch_time_us = dce110_get_min_vblank_time_us(context); @@ -669,7 +669,7 @@ static void dce_update_clocks(struct clk_mgr *clk_mgr, { struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); struct dm_pp_power_level_change_request level_change_req; - int patched_disp_clk = context->bw.dce.dispclk_khz; + int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; /*TODO: W/A for dal3 linux, investigate why this works */ if (!clk_mgr_dce->dfs_bypass_active) @@ -696,7 +696,7 @@ static void dce11_update_clocks(struct clk_mgr *clk_mgr, { struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); struct dm_pp_power_level_change_request level_change_req; - int patched_disp_clk = context->bw.dce.dispclk_khz; + int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; /*TODO: W/A for dal3 linux, investigate why this works */ if (!clk_mgr_dce->dfs_bypass_active) @@ -711,7 +711,7 @@ static void dce11_update_clocks(struct clk_mgr *clk_mgr, } if (should_set_clock(safe_to_lower, patched_disp_clk, clk_mgr->clks.dispclk_khz)) { - context->bw.dce.dispclk_khz = dce_set_clock(clk_mgr, patched_disp_clk); + context->bw_ctx.bw.dce.dispclk_khz = dce_set_clock(clk_mgr, patched_disp_clk); clk_mgr->clks.dispclk_khz = patched_disp_clk; } dce11_pplib_apply_display_requirements(clk_mgr->ctx->dc, context); @@ -723,7 +723,7 @@ static void dce112_update_clocks(struct clk_mgr *clk_mgr, { struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); struct dm_pp_power_level_change_request level_change_req; - int patched_disp_clk = context->bw.dce.dispclk_khz; + int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; /*TODO: W/A for dal3 linux, investigate why this works */ if (!clk_mgr_dce->dfs_bypass_active) @@ -751,7 +751,7 @@ static void dce12_update_clocks(struct clk_mgr *clk_mgr, struct dce_clk_mgr *clk_mgr_dce = TO_DCE_CLK_MGR(clk_mgr); struct dm_pp_clock_for_voltage_req clock_voltage_req = {0}; int max_pix_clk = get_max_pixel_clock_for_all_paths(context); - int patched_disp_clk = context->bw.dce.dispclk_khz; + int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; /*TODO: W/A for dal3 linux, investigate why this works */ if (!clk_mgr_dce->dfs_bypass_active) diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index b733dc17db87..767d37c6d942 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -773,11 +773,11 @@ bool dce100_validate_bandwidth( if (at_least_one_pipe) { /* TODO implement when needed but for now hardcode max value*/ - context->bw.dce.dispclk_khz = 681000; - context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; + context->bw_ctx.bw.dce.dispclk_khz = 681000; + context->bw_ctx.bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; } else { - context->bw.dce.dispclk_khz = 0; - context->bw.dce.yclk_khz = 0; + context->bw_ctx.bw.dce.dispclk_khz = 0; + context->bw_ctx.bw.dce.yclk_khz = 0; } return true; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 1019c59c2e3b..a1c4d26c6747 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1630,18 +1630,18 @@ static void dce110_set_displaymarks( dc->bw_vbios->blackout_duration, pipe_ctx->stream); pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( pipe_ctx->plane_res.mi, - context->bw.dce.nbp_state_change_wm_ns[num_pipes], - context->bw.dce.stutter_exit_wm_ns[num_pipes], - context->bw.dce.stutter_entry_wm_ns[num_pipes], - context->bw.dce.urgent_wm_ns[num_pipes], + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], + context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], + context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes], + context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], total_dest_line_time_ns); if (i == underlay_idx) { num_pipes++; pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( pipe_ctx->plane_res.mi, - context->bw.dce.nbp_state_change_wm_ns[num_pipes], - context->bw.dce.stutter_exit_wm_ns[num_pipes], - context->bw.dce.urgent_wm_ns[num_pipes], + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], + context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], + context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], total_dest_line_time_ns); } num_pipes++; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 50af7e17db3b..7c4914b2b524 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -883,7 +883,7 @@ static bool dce110_validate_bandwidth( dc->bw_vbios, context->res_ctx.pipe_ctx, dc->res_pool->pipe_count, - &context->bw.dce)) + &context->bw_ctx.bw.dce)) result = true; if (!result) @@ -893,8 +893,8 @@ static bool dce110_validate_bandwidth( context->streams[0]->timing.v_addressable, context->streams[0]->timing.pix_clk_100hz / 10); - if (memcmp(&dc->current_state->bw.dce, - &context->bw.dce, sizeof(context->bw.dce))) { + if (memcmp(&dc->current_state->bw_ctx.bw.dce, + &context->bw_ctx.bw.dce, sizeof(context->bw_ctx.bw.dce))) { DC_LOG_BANDWIDTH_CALCS( "%s: finish,\n" @@ -908,34 +908,34 @@ static bool dce110_validate_bandwidth( "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n" , __func__, - context->bw.dce.nbp_state_change_wm_ns[0].b_mark, - context->bw.dce.nbp_state_change_wm_ns[0].a_mark, - context->bw.dce.urgent_wm_ns[0].b_mark, - context->bw.dce.urgent_wm_ns[0].a_mark, - context->bw.dce.stutter_exit_wm_ns[0].b_mark, - context->bw.dce.stutter_exit_wm_ns[0].a_mark, - context->bw.dce.nbp_state_change_wm_ns[1].b_mark, - context->bw.dce.nbp_state_change_wm_ns[1].a_mark, - context->bw.dce.urgent_wm_ns[1].b_mark, - context->bw.dce.urgent_wm_ns[1].a_mark, - context->bw.dce.stutter_exit_wm_ns[1].b_mark, - context->bw.dce.stutter_exit_wm_ns[1].a_mark, - context->bw.dce.nbp_state_change_wm_ns[2].b_mark, - context->bw.dce.nbp_state_change_wm_ns[2].a_mark, - context->bw.dce.urgent_wm_ns[2].b_mark, - context->bw.dce.urgent_wm_ns[2].a_mark, - context->bw.dce.stutter_exit_wm_ns[2].b_mark, - context->bw.dce.stutter_exit_wm_ns[2].a_mark, - context->bw.dce.stutter_mode_enable, - context->bw.dce.cpuc_state_change_enable, - context->bw.dce.cpup_state_change_enable, - context->bw.dce.nbp_state_change_enable, - context->bw.dce.all_displays_in_sync, - context->bw.dce.dispclk_khz, - context->bw.dce.sclk_khz, - context->bw.dce.sclk_deep_sleep_khz, - context->bw.dce.yclk_khz, - context->bw.dce.blackout_recovery_time_us); + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].b_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].a_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[0].b_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[0].a_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].b_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].a_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].b_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].a_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[1].b_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[1].a_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].b_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].a_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].b_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].a_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[2].b_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[2].a_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].b_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].a_mark, + context->bw_ctx.bw.dce.stutter_mode_enable, + context->bw_ctx.bw.dce.cpuc_state_change_enable, + context->bw_ctx.bw.dce.cpup_state_change_enable, + context->bw_ctx.bw.dce.nbp_state_change_enable, + context->bw_ctx.bw.dce.all_displays_in_sync, + context->bw_ctx.bw.dce.dispclk_khz, + context->bw_ctx.bw.dce.sclk_khz, + context->bw_ctx.bw.dce.sclk_deep_sleep_khz, + context->bw_ctx.bw.dce.yclk_khz, + context->bw_ctx.bw.dce.blackout_recovery_time_us); } return result; } diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 3d31c273f41f..2f28a74383f5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -823,7 +823,7 @@ bool dce112_validate_bandwidth( dc->bw_vbios, context->res_ctx.pipe_ctx, dc->res_pool->pipe_count, - &context->bw.dce)) + &context->bw_ctx.bw.dce)) result = true; if (!result) @@ -831,8 +831,8 @@ bool dce112_validate_bandwidth( "%s: Bandwidth validation failed!", __func__); - if (memcmp(&dc->current_state->bw.dce, - &context->bw.dce, sizeof(context->bw.dce))) { + if (memcmp(&dc->current_state->bw_ctx.bw.dce, + &context->bw_ctx.bw.dce, sizeof(context->bw_ctx.bw.dce))) { DC_LOG_BANDWIDTH_CALCS( "%s: finish,\n" @@ -846,34 +846,34 @@ bool dce112_validate_bandwidth( "sclk: %d sclk_sleep: %d yclk: %d blackout_recovery_time_us: %d\n" , __func__, - context->bw.dce.nbp_state_change_wm_ns[0].b_mark, - context->bw.dce.nbp_state_change_wm_ns[0].a_mark, - context->bw.dce.urgent_wm_ns[0].b_mark, - context->bw.dce.urgent_wm_ns[0].a_mark, - context->bw.dce.stutter_exit_wm_ns[0].b_mark, - context->bw.dce.stutter_exit_wm_ns[0].a_mark, - context->bw.dce.nbp_state_change_wm_ns[1].b_mark, - context->bw.dce.nbp_state_change_wm_ns[1].a_mark, - context->bw.dce.urgent_wm_ns[1].b_mark, - context->bw.dce.urgent_wm_ns[1].a_mark, - context->bw.dce.stutter_exit_wm_ns[1].b_mark, - context->bw.dce.stutter_exit_wm_ns[1].a_mark, - context->bw.dce.nbp_state_change_wm_ns[2].b_mark, - context->bw.dce.nbp_state_change_wm_ns[2].a_mark, - context->bw.dce.urgent_wm_ns[2].b_mark, - context->bw.dce.urgent_wm_ns[2].a_mark, - context->bw.dce.stutter_exit_wm_ns[2].b_mark, - context->bw.dce.stutter_exit_wm_ns[2].a_mark, - context->bw.dce.stutter_mode_enable, - context->bw.dce.cpuc_state_change_enable, - context->bw.dce.cpup_state_change_enable, - context->bw.dce.nbp_state_change_enable, - context->bw.dce.all_displays_in_sync, - context->bw.dce.dispclk_khz, - context->bw.dce.sclk_khz, - context->bw.dce.sclk_deep_sleep_khz, - context->bw.dce.yclk_khz, - context->bw.dce.blackout_recovery_time_us); + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].b_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[0].a_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[0].b_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[0].a_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].b_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[0].a_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].b_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[1].a_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[1].b_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[1].a_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].b_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[1].a_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].b_mark, + context->bw_ctx.bw.dce.nbp_state_change_wm_ns[2].a_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[2].b_mark, + context->bw_ctx.bw.dce.urgent_wm_ns[2].a_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].b_mark, + context->bw_ctx.bw.dce.stutter_exit_wm_ns[2].a_mark, + context->bw_ctx.bw.dce.stutter_mode_enable, + context->bw_ctx.bw.dce.cpuc_state_change_enable, + context->bw_ctx.bw.dce.cpup_state_change_enable, + context->bw_ctx.bw.dce.nbp_state_change_enable, + context->bw_ctx.bw.dce.all_displays_in_sync, + context->bw_ctx.bw.dce.dispclk_khz, + context->bw_ctx.bw.dce.sclk_khz, + context->bw_ctx.bw.dce.sclk_deep_sleep_khz, + context->bw_ctx.bw.dce.yclk_khz, + context->bw_ctx.bw.dce.blackout_recovery_time_us); } return result; } diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 066fd89747c2..c7899ec96287 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -807,11 +807,11 @@ bool dce80_validate_bandwidth( if (at_least_one_pipe) { /* TODO implement when needed but for now hardcode max value*/ - context->bw.dce.dispclk_khz = 681000; - context->bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; + context->bw_ctx.bw.dce.dispclk_khz = 681000; + context->bw_ctx.bw.dce.yclk_khz = 250000 * MEMORY_TYPE_MULTIPLIER_CZ; } else { - context->bw.dce.dispclk_khz = 0; - context->bw.dce.yclk_khz = 0; + context->bw_ctx.bw.dce.dispclk_khz = 0; + context->bw_ctx.bw.dce.yclk_khz = 0; } return true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c index 78b28c9b498b..0d9bee8d5ab9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c @@ -150,7 +150,7 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, { struct dc *dc = clk_mgr->ctx->dc; struct dc_debug_options *debug = &dc->debug; - struct dc_clocks *new_clocks = &context->bw.dcn.clk; + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; struct pp_smu_display_requirement_rv *smu_req_cur = &dc->res_pool->pp_smu_req; struct pp_smu_display_requirement_rv smu_req = *smu_req_cur; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 47653fe0bb2d..3f2ff27ff86d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -345,13 +345,13 @@ void dcn10_log_hw_state(struct dc *dc, DTN_INFO("\nCALCULATED Clocks: dcfclk_khz:%d dcfclk_deep_sleep_khz:%d dispclk_khz:%d\n" "dppclk_khz:%d max_supported_dppclk_khz:%d fclk_khz:%d socclk_khz:%d\n\n", - dc->current_state->bw.dcn.clk.dcfclk_khz, - dc->current_state->bw.dcn.clk.dcfclk_deep_sleep_khz, - dc->current_state->bw.dcn.clk.dispclk_khz, - dc->current_state->bw.dcn.clk.dppclk_khz, - dc->current_state->bw.dcn.clk.max_supported_dppclk_khz, - dc->current_state->bw.dcn.clk.fclk_khz, - dc->current_state->bw.dcn.clk.socclk_khz); + dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz, + dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.fclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz); log_mpc_crc(dc, log_ctx); @@ -2069,7 +2069,7 @@ void update_dchubp_dpp( * divided by 2 */ if (plane_state->update_flags.bits.full_update) { - bool should_divided_by_2 = context->bw.dcn.clk.dppclk_khz <= + bool should_divided_by_2 = context->bw_ctx.bw.dcn.clk.dppclk_khz <= dc->res_pool->clk_mgr->clks.dispclk_khz / 2; dpp->funcs->dpp_dppclk_control( @@ -2443,7 +2443,7 @@ static void dcn10_prepare_bandwidth( if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { if (context->stream_count == 0) - context->bw.dcn.clk.phyclk_khz = 0; + context->bw_ctx.bw.dcn.clk.phyclk_khz = 0; dc->res_pool->clk_mgr->funcs->update_clocks( dc->res_pool->clk_mgr, @@ -2452,7 +2452,7 @@ static void dcn10_prepare_bandwidth( } hubbub1_program_watermarks(dc->res_pool->hubbub, - &context->bw.dcn.watermarks, + &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, true); dcn10_stereo_hw_frame_pack_wa(dc, context); @@ -2473,7 +2473,7 @@ static void dcn10_optimize_bandwidth( if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { if (context->stream_count == 0) - context->bw.dcn.clk.phyclk_khz = 0; + context->bw_ctx.bw.dcn.clk.phyclk_khz = 0; dc->res_pool->clk_mgr->funcs->update_clocks( dc->res_pool->clk_mgr, @@ -2482,7 +2482,7 @@ static void dcn10_optimize_bandwidth( } hubbub1_program_watermarks(dc->res_pool->hubbub, - &context->bw.dcn.watermarks, + &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, true); dcn10_stereo_hw_frame_pack_wa(dc, context); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c index aa7a5163c40a..991622da9ed5 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer_debug.c @@ -472,12 +472,12 @@ static unsigned int dcn10_get_clock_states(struct dc *dc, char *pBuf, unsigned i chars_printed = snprintf_count(pBuf, bufSize, "dcfclk,dcfclk_deep_sleep,dispclk," "dppclk,fclk,socclk\n" "%d,%d,%d,%d,%d,%d\n", - dc->current_state->bw.dcn.clk.dcfclk_khz, - dc->current_state->bw.dcn.clk.dcfclk_deep_sleep_khz, - dc->current_state->bw.dcn.clk.dispclk_khz, - dc->current_state->bw.dcn.clk.dppclk_khz, - dc->current_state->bw.dcn.clk.fclk_khz, - dc->current_state->bw.dcn.clk.socclk_khz); + dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz, + dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.fclk_khz, + dc->current_state->bw_ctx.bw.dcn.clk.socclk_khz); remaining_buffer -= chars_printed; pBuf += chars_printed; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index b986c67d5b4b..c3f820cc8287 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -266,18 +266,22 @@ struct dcn_bw_output { struct dcn_watermark_set watermarks; }; -union bw_context { +union bw_output { struct dcn_bw_output dcn; struct dce_bw_output dce; }; +struct bw_context { + union bw_output bw; + struct display_mode_lib dml; +}; /** * struct dc_state - The full description of a state requested by a user * * @streams: Stream properties * @stream_status: The planes on a given stream * @res_ctx: Persistent state of resources - * @bw: The output from bandwidth and watermark calculations + * @bw_ctx: The output from bandwidth and watermark calculations and the DML * @pp_display_cfg: PowerPlay clocks and settings * @dcn_bw_vars: non-stack memory to support bandwidth calculations * @@ -289,7 +293,7 @@ struct dc_state { struct resource_context res_ctx; - union bw_context bw; + struct bw_context bw_ctx; /* Note: these are big structures, do *not* put on stack! */ struct dm_pp_display_configuration pp_display_cfg; -- cgit v1.2.3 From 805ab8f7da89c7f2a2ad39b149ac82beb62ba513 Mon Sep 17 00:00:00 2001 From: Leo Li Date: Thu, 21 Mar 2019 10:36:07 -0400 Subject: drm/amd/display: Fix "dc has no member named dml" compile error For DCN disabled builds, dc->dml is stripped out. Therefore, guard usage in dc_create_state() with CONFIG_DRM_AMD_DC_DCN1_0. It fixes the following error: drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c: In function 'dc_create_state': >> drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc.c:1237:34: error: 'struct dc' has no member named 'dml' memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib)); ^~ Signed-off-by: Leo Li Acked-by: Alex Deucher Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 1c1cfb513620..5f05e191f0ff 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1229,7 +1229,9 @@ struct dc_state *dc_create_state(struct dc *dc) * initialize and obtain IP and SOC the base DML instance from DC is * initially copied into every context */ +#ifdef CONFIG_DRM_AMD_DC_DCN1_0 memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib)); +#endif kref_init(&context->refcount); -- cgit v1.2.3 From 6752bea8b03e77c98be7d8d25b0a9d86a00b3cf7 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 11 Mar 2019 10:33:35 -0400 Subject: drm/amd/display: Prevent cursor hotspot overflow for RV overlay planes [Why] The actual position for the cursor on the screen is essentially: x_out = x - x_plane - x_hotspot y_out = y - y_plane - y_hotspot The register values for cursor position and cursor hotspot need to be greater than zero when programmed, but we also need to subtract off the plane position to display the cursor at the correct position. Since we don't want x or y to be less than zero, we add the plane position as a positive value to x_hotspot or y_hotspot. However, what this doesn't take into account is that the hotspot registers are limited by the maximum cursor size. On DCN10 the cursor hotspot regitsers are masked to 0xFF, so they have a maximum value of 0-255. Values greater this will wrap, causing the cursor to display in the wrong position. In practice this means that for sufficiently large plane positions, the cursor will be drawn twice on the screen, and can cause screen flashes or p-state WARNS depending on what the wrapped value is. So we need a way to remove the value from x_plane and y_plane without exceeding the maximum cursor size. [How] Subtract as much as x_plane/y_plane as possible from x and y and place the remainder in the cursor hotspot register. The value for x_hotspot and y_hotspot can still wrap around but it won't happen in a case where the cursor is actually enabled. The cursor plane needs to intersect at least one pixel of the plane's rectangle to be enabled, so the cursor position + hotspot provided by userspace must always be strictly less than the maximum cursor size for the cursor to actually be enabled. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Sun peng Li Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 3f2ff27ff86d..4969fa5e6f1d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2710,9 +2710,15 @@ static void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx) .rotation = pipe_ctx->plane_state->rotation, .mirror = pipe_ctx->plane_state->horizontal_mirror }; - - pos_cpy.x_hotspot += pipe_ctx->plane_state->dst_rect.x; - pos_cpy.y_hotspot += pipe_ctx->plane_state->dst_rect.y; + uint32_t x_plane = pipe_ctx->plane_state->dst_rect.x; + uint32_t y_plane = pipe_ctx->plane_state->dst_rect.y; + uint32_t x_offset = min(x_plane, pos_cpy.x); + uint32_t y_offset = min(y_plane, pos_cpy.y); + + pos_cpy.x -= x_offset; + pos_cpy.y -= y_offset; + pos_cpy.x_hotspot += (x_plane - x_offset); + pos_cpy.y_hotspot += (y_plane - y_offset); if (pipe_ctx->plane_state->address.type == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) -- cgit v1.2.3 From 320d41b33ade094f08c6a0cbb7a0bd305fceaf5f Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 1 Apr 2019 23:02:25 +0300 Subject: drm/i915: Extract ilk_lut_10() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract a helper to calculate the ILK+ 10bit gamma LUT entry. It's already duplicated twice, and soon we'll have more. v2: s/it/bit/ (Matt) Reviewed-by: Matt Roper Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-2-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/intel_color.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index f2907cfd116a..d5b3060c2645 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -359,6 +359,13 @@ static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode); } +static u32 ilk_lut_10(const struct drm_color_lut *color) +{ + return drm_color_lut_extract(color->red, 10) << 20 | + drm_color_lut_extract(color->green, 10) << 10 | + drm_color_lut_extract(color->blue, 10); +} + /* Loads the legacy palette/gamma unit for the CRTC. */ static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state, const struct drm_property_blob *blob) @@ -473,14 +480,8 @@ static void bdw_load_degamma_lut(const struct intel_crtc_state *crtc_state) if (degamma_lut) { const struct drm_color_lut *lut = degamma_lut->data; - for (i = 0; i < lut_size; i++) { - u32 word = - drm_color_lut_extract(lut[i].red, 10) << 20 | - drm_color_lut_extract(lut[i].green, 10) << 10 | - drm_color_lut_extract(lut[i].blue, 10); - - I915_WRITE(PREC_PAL_DATA(pipe), word); - } + for (i = 0; i < lut_size; i++) + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); } else { for (i = 0; i < lut_size; i++) { u32 v = (i * ((1 << 10) - 1)) / (lut_size - 1); @@ -509,14 +510,8 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of if (gamma_lut) { const struct drm_color_lut *lut = gamma_lut->data; - for (i = 0; i < lut_size; i++) { - u32 word = - (drm_color_lut_extract(lut[i].red, 10) << 20) | - (drm_color_lut_extract(lut[i].green, 10) << 10) | - drm_color_lut_extract(lut[i].blue, 10); - - I915_WRITE(PREC_PAL_DATA(pipe), word); - } + for (i = 0; i < lut_size; i++) + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); /* * Program the max register to clamp values > 1.0. -- cgit v1.2.3 From 5bda1aca5d9475ee2035d29d4855dbf97ad164ad Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 1 Apr 2019 23:02:26 +0300 Subject: drm/i915: Don't use split gamma when we don't have to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the split gamma mode when we don't have to has the annoying requirement of loading a linear LUT to the unused half. Instead let's make life simpler by switching to the 10bit gamma mode and duplicating each entry. This also allows us to load the software gamma LUT into the hardware degamma LUT, thus removing some of the buggy configurations we currently allow (YCbCr/limited range RGB + gamma LUT). We do still have other configurations that are also buggy, but those will need more complicated fixes or they just need to be rejected. Sadly GLK doesn't have this flexibility anymore and the degamma and gamma LUTs are very different so no help there. v2: Apply a mask when checking gamma_mode on icl since it contains more bits than just the gamma mode v3: Rebase due to EXT_GC_MAX/EXT2_GC_MAX changes v4: s/advertize/advertise/ (Uma) Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-3-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_color.c | 185 ++++++++++++++++++------------------- 2 files changed, 92 insertions(+), 95 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 341f03e00536..bed2c52aebd8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7214,6 +7214,7 @@ enum { #define GAMMA_MODE(pipe) _MMIO_PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B) #define PRE_CSC_GAMMA_ENABLE (1 << 31) #define POST_CSC_GAMMA_ENABLE (1 << 30) +#define GAMMA_MODE_MODE_MASK (3 << 0) #define GAMMA_MODE_MODE_8BIT (0 << 0) #define GAMMA_MODE_MODE_10BIT (1 << 0) #define GAMMA_MODE_MODE_12BIT (2 << 0) @@ -10127,6 +10128,7 @@ enum skl_power_gate { #define PAL_PREC_SPLIT_MODE (1 << 31) #define PAL_PREC_AUTO_INCREMENT (1 << 15) #define PAL_PREC_INDEX_VALUE_MASK (0x3ff << 0) +#define PAL_PREC_INDEX_VALUE(x) ((x) << 0) #define _PAL_PREC_DATA_A 0x4A404 #define _PAL_PREC_DATA_B 0x4AC04 #define _PAL_PREC_DATA_C 0x4B404 diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index d5b3060c2645..b5ee68e1759b 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -466,115 +466,83 @@ static void skl_color_commit(const struct intel_crtc_state *crtc_state) ilk_load_csc_matrix(crtc_state); } -static void bdw_load_degamma_lut(const struct intel_crtc_state *crtc_state) +static void bdw_load_lut_10(struct intel_crtc *crtc, + const struct drm_property_blob *blob, + u32 prec_index, bool duplicate) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut; - u32 i, lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size; + const struct drm_color_lut *lut = blob->data; + int i, lut_size = drm_color_lut_size(blob); enum pipe pipe = crtc->pipe; - I915_WRITE(PREC_PAL_INDEX(pipe), - PAL_PREC_SPLIT_MODE | PAL_PREC_AUTO_INCREMENT); - - if (degamma_lut) { - const struct drm_color_lut *lut = degamma_lut->data; + I915_WRITE(PREC_PAL_INDEX(pipe), prec_index | + PAL_PREC_AUTO_INCREMENT); - for (i = 0; i < lut_size; i++) - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - } else { + /* + * We advertise the split gamma sizes. When not using split + * gamma we just duplicate each entry. + * + * TODO: expose the full LUT to userspace + */ + if (duplicate) { for (i = 0; i < lut_size; i++) { - u32 v = (i * ((1 << 10) - 1)) / (lut_size - 1); - - I915_WRITE(PREC_PAL_DATA(pipe), - (v << 20) | (v << 10) | v); + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); } + } else { + for (i = 0; i < lut_size; i++) + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); } + + /* + * Reset the index, otherwise it prevents the legacy palette to be + * written properly. + */ + I915_WRITE(PREC_PAL_INDEX(pipe), 0); } -static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 offset) +static void bdw_load_lut_10_max(struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; - u32 i, lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size; enum pipe pipe = crtc->pipe; - WARN_ON(offset & ~PAL_PREC_INDEX_VALUE_MASK); - - I915_WRITE(PREC_PAL_INDEX(pipe), - (offset ? PAL_PREC_SPLIT_MODE : 0) | - PAL_PREC_AUTO_INCREMENT | - offset); - - if (gamma_lut) { - const struct drm_color_lut *lut = gamma_lut->data; - - for (i = 0; i < lut_size; i++) - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - - /* - * Program the max register to clamp values > 1.0. - * ToDo: Extend the ABI to be able to program values - * from 1.0 to 3.0 - */ - I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), (1 << 16)); - I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), (1 << 16)); - I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), (1 << 16)); - - /* - * Program the gc max 2 register to clamp values > 1.0. - * ToDo: Extend the ABI to be able to program values - * from 3.0 to 7.0 - */ - if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { - I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), (1 << 16)); - I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), (1 << 16)); - I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), (1 << 16)); - } - } else { - for (i = 0; i < lut_size; i++) { - u32 v = (i * ((1 << 10) - 1)) / (lut_size - 1); - - I915_WRITE(PREC_PAL_DATA(pipe), - (v << 20) | (v << 10) | v); - } - - I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), (1 << 16)); - I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), (1 << 16)); - I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), (1 << 16)); - - /* - * Program the gc max 2 register to clamp values > 1.0. - * ToDo: Extend the ABI to be able to program values - * from 3.0 to 7.0 - */ - if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { - I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), (1 << 16)); - I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), (1 << 16)); - I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), (1 << 16)); - } - } + /* Program the max register to clamp values > 1.0. */ + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16); + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16); + I915_WRITE(PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16); /* - * Reset the index, otherwise it prevents the legacy palette to be - * written properly. + * Program the gc max 2 register to clamp values > 1.0. + * ToDo: Extend the ABI to be able to program values + * from 3.0 to 7.0 */ - I915_WRITE(PREC_PAL_INDEX(pipe), 0); + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 0), 1 << 16); + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 1), 1 << 16); + I915_WRITE(PREC_PAL_EXT2_GC_MAX(pipe, 2), 1 << 16); + } } -/* Loads the palette/gamma unit for the CRTC on Broadwell+. */ -static void broadwell_load_luts(const struct intel_crtc_state *crtc_state) +static void bdw_load_luts(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; + const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut; - if (crtc_state_is_legacy_gamma(crtc_state)) { + if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { i9xx_load_luts(crtc_state); + } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { + bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | + PAL_PREC_INDEX_VALUE(0), false); + bdw_load_lut_10_max(crtc); + bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | + PAL_PREC_INDEX_VALUE(512), false); } else { - bdw_load_degamma_lut(crtc_state); - bdw_load_gamma_lut(crtc_state, - INTEL_INFO(dev_priv)->color.degamma_lut_size); + const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; + + bdw_load_lut_10(crtc, blob, + PAL_PREC_INDEX_VALUE(0), true); + bdw_load_lut_10_max(crtc); } } @@ -646,6 +614,9 @@ static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_stat static void glk_load_luts(const struct intel_crtc_state *crtc_state) { + const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + /* * On GLK+ both pipe CSC and degamma LUT are controlled * by csc_enable. Hence for the cases where the CSC is @@ -659,22 +630,29 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) else glk_load_degamma_lut_linear(crtc_state); - if (crtc_state_is_legacy_gamma(crtc_state)) + if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { i9xx_load_luts(crtc_state); - else - bdw_load_gamma_lut(crtc_state, 0); + } else { + bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); + bdw_load_lut_10_max(crtc); + } } static void icl_load_luts(const struct intel_crtc_state *crtc_state) { + const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + if (crtc_state->base.degamma_lut) glk_load_degamma_lut(crtc_state); - if (crtc_state_is_legacy_gamma(crtc_state)) + if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) == + GAMMA_MODE_MODE_8BIT) { i9xx_load_luts(crtc_state); - else - /* ToDo: Add support for multi segment gamma LUT */ - bdw_load_gamma_lut(crtc_state, 0); + } else { + bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); + bdw_load_lut_10_max(crtc); + } } static void cherryview_load_luts(const struct intel_crtc_state *crtc_state) @@ -959,8 +937,25 @@ static u32 bdw_gamma_mode(const struct intel_crtc_state *crtc_state) if (!crtc_state->gamma_enable || crtc_state_is_legacy_gamma(crtc_state)) return GAMMA_MODE_MODE_8BIT; - else + else if (crtc_state->base.gamma_lut && + crtc_state->base.degamma_lut) return GAMMA_MODE_MODE_SPLIT; + else + return GAMMA_MODE_MODE_10BIT; +} + +static u32 bdw_csc_mode(const struct intel_crtc_state *crtc_state) +{ + /* + * CSC comes after the LUT in degamma, RGB->YCbCr, + * and RGB full->limited range mode. + */ + if (crtc_state->base.degamma_lut || + crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || + crtc_state->limited_color_range) + return 0; + + return CSC_POSITION_BEFORE_GAMMA; } static int bdw_color_check(struct intel_crtc_state *crtc_state) @@ -982,7 +977,7 @@ static int bdw_color_check(struct intel_crtc_state *crtc_state) crtc_state->gamma_mode = bdw_gamma_mode(crtc_state); - crtc_state->csc_mode = 0; + crtc_state->csc_mode = bdw_csc_mode(crtc_state); ret = intel_color_add_affected_planes(crtc_state); if (ret) @@ -1116,7 +1111,7 @@ void intel_color_init(struct intel_crtc *crtc) else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) dev_priv->display.load_luts = glk_load_luts; else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) - dev_priv->display.load_luts = broadwell_load_luts; + dev_priv->display.load_luts = bdw_load_luts; else dev_priv->display.load_luts = i9xx_load_luts; } -- cgit v1.2.3 From c21ce2effc5278de11c5726b3fde9f39c4de17ce Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 1 Apr 2019 23:02:27 +0300 Subject: drm/i915: Implement split/10bit gamma for ivb/hsw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reuse the bdw+ code to get split/10bit gamma for ivb/hsw. The hardware is nearly identical. The only slight snag is that on ivb/hsw the precision palette auto increment mode does not work. So we must increment the index manually. We'll probably want to stick to the auto increment mode on bdw+ in the name of efficiency. Also we want to avoid using the CSC for limited range RGB output as PIPECONF will take care of that on IVB. v2: Rebase due to EXT_GC_MAX/EXT2_GC_MAX changes Reviewed-by: Matt Roper Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-4-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/i915_pci.c | 6 +- drivers/gpu/drm/i915/intel_color.c | 113 ++++++++++++++++++++++++++++++------- 2 files changed, 95 insertions(+), 24 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 39251586349a..2b0d2f4f8a46 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -116,7 +116,7 @@ [PIPE_C] = IVB_CURSOR_C_OFFSET, \ } -#define BDW_COLORS \ +#define IVB_COLORS \ .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } #define CHV_COLORS \ .color = { .degamma_lut_size = 65, .gamma_lut_size = 257, \ @@ -406,6 +406,7 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info = { .ppgtt_size = 31, \ IVB_PIPE_OFFSETS, \ IVB_CURSOR_OFFSETS, \ + IVB_COLORS, \ GEN_DEFAULT_PAGE_SIZES #define IVB_D_PLATFORM \ @@ -501,7 +502,6 @@ static const struct intel_device_info intel_haswell_gt3_info = { #define GEN8_FEATURES \ G75_FEATURES, \ GEN(8), \ - BDW_COLORS, \ .page_sizes = I915_GTT_PAGE_SIZE_4K | \ I915_GTT_PAGE_SIZE_2M, \ .has_logical_ring_contexts = 1, \ @@ -636,7 +636,7 @@ static const struct intel_device_info intel_skylake_gt4_info = { .display.has_ipc = 1, \ HSW_PIPE_OFFSETS, \ IVB_CURSOR_OFFSETS, \ - BDW_COLORS, \ + IVB_COLORS, \ GEN9_DEFAULT_PAGE_SIZES static const struct intel_device_info intel_broxton_info = { diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index b5ee68e1759b..cf830c3ba325 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -428,6 +428,8 @@ static void ilk_color_commit(const struct intel_crtc_state *crtc_state) val &= ~PIPECONF_GAMMA_MODE_MASK_ILK; val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode); I915_WRITE(PIPECONF(pipe), val); + + ilk_load_csc_matrix(crtc_state); } static void hsw_color_commit(const struct intel_crtc_state *crtc_state) @@ -466,6 +468,48 @@ static void skl_color_commit(const struct intel_crtc_state *crtc_state) ilk_load_csc_matrix(crtc_state); } +/* + * IVB/HSW Bspec / PAL_PREC_INDEX: + * "Restriction : Index auto increment mode is not + * supported and must not be enabled." + */ +static void ivb_load_lut_10(struct intel_crtc *crtc, + const struct drm_property_blob *blob, + u32 prec_index, bool duplicate) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_color_lut *lut = blob->data; + int i, lut_size = drm_color_lut_size(blob); + enum pipe pipe = crtc->pipe; + + /* + * We advertise the split gamma sizes. When not using split + * gamma we just duplicate each entry. + * + * TODO: expose the full LUT to userspace + */ + if (duplicate) { + for (i = 0; i < lut_size; i++) { + I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); + I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); + } + } else { + for (i = 0; i < lut_size; i++) { + I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); + } + } + + /* + * Reset the index, otherwise it prevents the legacy palette to be + * written properly. + */ + I915_WRITE(PREC_PAL_INDEX(pipe), 0); +} + +/* On BDW+ the index auto increment mode actually works */ static void bdw_load_lut_10(struct intel_crtc *crtc, const struct drm_property_blob *blob, u32 prec_index, bool duplicate) @@ -501,7 +545,7 @@ static void bdw_load_lut_10(struct intel_crtc *crtc, I915_WRITE(PREC_PAL_INDEX(pipe), 0); } -static void bdw_load_lut_10_max(struct intel_crtc *crtc) +static void ivb_load_lut_10_max(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; @@ -523,6 +567,29 @@ static void bdw_load_lut_10_max(struct intel_crtc *crtc) } } +static void ivb_load_luts(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; + const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut; + + if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { + i9xx_load_luts(crtc_state); + } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { + ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | + PAL_PREC_INDEX_VALUE(0), false); + ivb_load_lut_10_max(crtc); + ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | + PAL_PREC_INDEX_VALUE(512), false); + } else { + const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; + + ivb_load_lut_10(crtc, blob, + PAL_PREC_INDEX_VALUE(0), true); + ivb_load_lut_10_max(crtc); + } +} + static void bdw_load_luts(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); @@ -534,7 +601,7 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state) } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | PAL_PREC_INDEX_VALUE(0), false); - bdw_load_lut_10_max(crtc); + ivb_load_lut_10_max(crtc); bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | PAL_PREC_INDEX_VALUE(512), false); } else { @@ -542,7 +609,7 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state) bdw_load_lut_10(crtc, blob, PAL_PREC_INDEX_VALUE(0), true); - bdw_load_lut_10_max(crtc); + ivb_load_lut_10_max(crtc); } } @@ -634,7 +701,7 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) i9xx_load_luts(crtc_state); } else { bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); - bdw_load_lut_10_max(crtc); + ivb_load_lut_10_max(crtc); } } @@ -651,7 +718,7 @@ static void icl_load_luts(const struct intel_crtc_state *crtc_state) i9xx_load_luts(crtc_state); } else { bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); - bdw_load_lut_10_max(crtc); + ivb_load_lut_10_max(crtc); } } @@ -913,14 +980,13 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state) !crtc_state->c8_planes; /* - * We don't expose the ctm on ilk-hsw currently, - * nor do we enable YCbCr output. Only hsw uses - * the csc for RGB limited range output. + * We don't expose the ctm on ilk/snb currently, + * nor do we enable YCbCr output. Also RGB limited + * range output is handled by the hw automagically. */ - crtc_state->csc_enable = - ilk_csc_limited_range(crtc_state); + crtc_state->csc_enable = false; - /* We don't expose fancy gamma modes on ilk-hsw currently */ + /* We don't expose fancy gamma modes on ilk/snb currently */ crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; crtc_state->csc_mode = 0; @@ -932,7 +998,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state) return 0; } -static u32 bdw_gamma_mode(const struct intel_crtc_state *crtc_state) +static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state) { if (!crtc_state->gamma_enable || crtc_state_is_legacy_gamma(crtc_state)) @@ -944,22 +1010,25 @@ static u32 bdw_gamma_mode(const struct intel_crtc_state *crtc_state) return GAMMA_MODE_MODE_10BIT; } -static u32 bdw_csc_mode(const struct intel_crtc_state *crtc_state) +static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state) { + bool limited_color_range = ilk_csc_limited_range(crtc_state); + /* * CSC comes after the LUT in degamma, RGB->YCbCr, * and RGB full->limited range mode. */ if (crtc_state->base.degamma_lut || crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || - crtc_state->limited_color_range) + limited_color_range) return 0; return CSC_POSITION_BEFORE_GAMMA; } -static int bdw_color_check(struct intel_crtc_state *crtc_state) +static int ivb_color_check(struct intel_crtc_state *crtc_state) { + bool limited_color_range = ilk_csc_limited_range(crtc_state); int ret; ret = check_luts(crtc_state); @@ -973,11 +1042,11 @@ static int bdw_color_check(struct intel_crtc_state *crtc_state) crtc_state->csc_enable = crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || - crtc_state->base.ctm || crtc_state->limited_color_range; + crtc_state->base.ctm || limited_color_range; - crtc_state->gamma_mode = bdw_gamma_mode(crtc_state); + crtc_state->gamma_mode = ivb_gamma_mode(crtc_state); - crtc_state->csc_mode = bdw_csc_mode(crtc_state); + crtc_state->csc_mode = ivb_csc_mode(crtc_state); ret = intel_color_add_affected_planes(crtc_state); if (ret) @@ -1094,8 +1163,8 @@ void intel_color_init(struct intel_crtc *crtc) dev_priv->display.color_check = icl_color_check; else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) dev_priv->display.color_check = glk_color_check; - else if (INTEL_GEN(dev_priv) >= 8) - dev_priv->display.color_check = bdw_color_check; + else if (INTEL_GEN(dev_priv) >= 7) + dev_priv->display.color_check = ivb_color_check; else dev_priv->display.color_check = ilk_color_check; @@ -1110,8 +1179,10 @@ void intel_color_init(struct intel_crtc *crtc) dev_priv->display.load_luts = icl_load_luts; else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) dev_priv->display.load_luts = glk_load_luts; - else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) + else if (INTEL_GEN(dev_priv) >= 8) dev_priv->display.load_luts = bdw_load_luts; + else if (INTEL_GEN(dev_priv) >= 7) + dev_priv->display.load_luts = ivb_load_luts; else dev_priv->display.load_luts = i9xx_load_luts; } -- cgit v1.2.3 From 514462caf757700541e9d91adede9ea0eea1c6ad Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 1 Apr 2019 23:02:28 +0300 Subject: drm/i915: Add 10bit LUT for ilk/snb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plop in support for 10bit LUT on ilk/snb. There is no split gamma mode on these platforms, so we have to choose between degamma and gamma. That could be a runtime choice but for now let's just advertize the gamma as having 1024 entries. We'll also keep the ctm hidden for now. v2: Don't use I915_WRITE_FW() yet Introduce bool has_ctm (Maarten) Call drm_crtc_enable_color_mgmt() uncoditionally (Maarten) Reviewed-by: Matt Roper Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-5-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/i915_pci.c | 4 ++++ drivers/gpu/drm/i915/i915_reg.h | 9 +++++++ drivers/gpu/drm/i915/intel_color.c | 49 ++++++++++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 2b0d2f4f8a46..cbcfe1a5de9a 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -116,6 +116,8 @@ [PIPE_C] = IVB_CURSOR_C_OFFSET, \ } +#define ILK_COLORS \ + .color = { .gamma_lut_size = 1024 } #define IVB_COLORS \ .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } #define CHV_COLORS \ @@ -332,6 +334,7 @@ static const struct intel_device_info intel_gm45_info = { .has_rc6 = 0, \ I9XX_PIPE_OFFSETS, \ I9XX_CURSOR_OFFSETS, \ + ILK_COLORS, \ GEN_DEFAULT_PAGE_SIZES static const struct intel_device_info intel_ironlake_d_info = { @@ -360,6 +363,7 @@ static const struct intel_device_info intel_ironlake_m_info = { .ppgtt_size = 31, \ I9XX_PIPE_OFFSETS, \ I9XX_CURSOR_OFFSETS, \ + ILK_COLORS, \ GEN_DEFAULT_PAGE_SIZES #define SNB_D_PLATFORM \ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index bed2c52aebd8..d9b2bd226e57 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7209,6 +7209,15 @@ enum { #define _LGC_PALETTE_B 0x4a800 #define LGC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + (i) * 4) +/* ilk/snb precision palette */ +#define _PREC_PALETTE_A 0x4b000 +#define _PREC_PALETTE_B 0x4c000 +#define PREC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _PREC_PALETTE_A, _PREC_PALETTE_B) + (i) * 4) + +#define _PREC_PIPEAGCMAX 0x4d000 +#define _PREC_PIPEBGCMAX 0x4d010 +#define PREC_PIPEGCMAX(pipe, i) _MMIO(_PIPE(pipe, _PIPEAGCMAX, _PIPEBGCMAX) + (i) * 4) + #define _GAMMA_MODE_A 0x4a480 #define _GAMMA_MODE_B 0x4ac80 #define GAMMA_MODE(pipe) _MMIO_PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B) diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index cf830c3ba325..06c4012ec16b 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -468,6 +468,29 @@ static void skl_color_commit(const struct intel_crtc_state *crtc_state) ilk_load_csc_matrix(crtc_state); } +static void ilk_load_lut_10(struct intel_crtc *crtc, + const struct drm_property_blob *blob) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_color_lut *lut = blob->data; + int i, lut_size = drm_color_lut_size(blob); + enum pipe pipe = crtc->pipe; + + for (i = 0; i < lut_size; i++) + I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i])); +} + +static void ilk_load_luts(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; + + if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) + i9xx_load_luts(crtc_state); + else + ilk_load_lut_10(crtc, gamma_lut); +} + /* * IVB/HSW Bspec / PAL_PREC_INDEX: * "Restriction : Index auto increment mode is not @@ -967,6 +990,15 @@ static int chv_color_check(struct intel_crtc_state *crtc_state) return 0; } +static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state) +{ + if (!crtc_state->gamma_enable || + crtc_state_is_legacy_gamma(crtc_state)) + return GAMMA_MODE_MODE_8BIT; + else + return GAMMA_MODE_MODE_10BIT; +} + static int ilk_color_check(struct intel_crtc_state *crtc_state) { int ret; @@ -986,8 +1018,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state) */ crtc_state->csc_enable = false; - /* We don't expose fancy gamma modes on ilk/snb currently */ - crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; + crtc_state->gamma_mode = ilk_gamma_mode(crtc_state); crtc_state->csc_mode = 0; @@ -1145,6 +1176,7 @@ static int icl_color_check(struct intel_crtc_state *crtc_state) void intel_color_init(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + bool has_ctm = INTEL_INFO(dev_priv)->color.degamma_lut_size != 0; drm_mode_crtc_set_gamma_size(&crtc->base, 256); @@ -1184,14 +1216,11 @@ void intel_color_init(struct intel_crtc *crtc) else if (INTEL_GEN(dev_priv) >= 7) dev_priv->display.load_luts = ivb_load_luts; else - dev_priv->display.load_luts = i9xx_load_luts; + dev_priv->display.load_luts = ilk_load_luts; } - /* Enable color management support when we have degamma & gamma LUTs. */ - if (INTEL_INFO(dev_priv)->color.degamma_lut_size != 0 && - INTEL_INFO(dev_priv)->color.gamma_lut_size != 0) - drm_crtc_enable_color_mgmt(&crtc->base, - INTEL_INFO(dev_priv)->color.degamma_lut_size, - true, - INTEL_INFO(dev_priv)->color.gamma_lut_size); + drm_crtc_enable_color_mgmt(&crtc->base, + INTEL_INFO(dev_priv)->color.degamma_lut_size, + has_ctm, + INTEL_INFO(dev_priv)->color.gamma_lut_size); } -- cgit v1.2.3 From e262568eb58fe79917167817d16ebf8e39b7d696 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 1 Apr 2019 23:02:29 +0300 Subject: drm/i915: Add "10.6" LUT mode for i965+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i965+ have an interpolate 10bit LUT mode. Let's expose that so that we can actually enjoy real 10bpc. v2: Don't use I915_WRITE_FW() yet Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-6-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/i915_pci.c | 6 ++++ drivers/gpu/drm/i915/i915_reg.h | 4 +++ drivers/gpu/drm/i915/intel_color.c | 62 +++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index cbcfe1a5de9a..84078fbdb2d8 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -116,6 +116,10 @@ [PIPE_C] = IVB_CURSOR_C_OFFSET, \ } +#define I965_COLORS \ + .color = { .gamma_lut_size = 129, \ + .gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \ + } #define ILK_COLORS \ .color = { .gamma_lut_size = 1024 } #define IVB_COLORS \ @@ -285,6 +289,7 @@ static const struct intel_device_info intel_pineview_m_info = { .has_coherent_ggtt = true, \ I9XX_PIPE_OFFSETS, \ I9XX_CURSOR_OFFSETS, \ + I965_COLORS, \ GEN_DEFAULT_PAGE_SIZES static const struct intel_device_info intel_i965g_info = { @@ -469,6 +474,7 @@ static const struct intel_device_info intel_valleyview_info = { .display_mmio_offset = VLV_DISPLAY_BASE, I9XX_PIPE_OFFSETS, I9XX_CURSOR_OFFSETS, + I965_COLORS, GEN_DEFAULT_PAGE_SIZES, }; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d9b2bd226e57..00e03560c4e7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -5795,6 +5795,10 @@ enum { #define PIPEFRAMEPIXEL(pipe) _MMIO_PIPE2(pipe, _PIPEAFRAMEPIXEL) #define PIPESTAT(pipe) _MMIO_PIPE2(pipe, _PIPEASTAT) +#define _PIPEAGCMAX 0x70010 +#define _PIPEBGCMAX 0x71010 +#define PIPEGCMAX(pipe, i) _MMIO_PIPE2(pipe, _PIPEAGCMAX + (i) * 4) + #define _PIPE_MISC_A 0x70030 #define _PIPE_MISC_B 0x71030 #define PIPEMISC_YUV420_ENABLE (1 << 27) diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 06c4012ec16b..efcf9e2d0b56 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -359,6 +359,22 @@ static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode); } +/* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */ +static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color) +{ + return (color->red & 0xff) << 16 | + (color->green & 0xff) << 8 | + (color->blue & 0xff); +} + +/* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */ +static u32 i965_lut_10p6_udw(const struct drm_color_lut *color) +{ + return (color->red >> 8) << 16 | + (color->green >> 8) << 8 | + (color->blue >> 8); +} + static u32 ilk_lut_10(const struct drm_color_lut *color) { return drm_color_lut_extract(color->red, 10) << 20 | @@ -468,6 +484,37 @@ static void skl_color_commit(const struct intel_crtc_state *crtc_state) ilk_load_csc_matrix(crtc_state); } +static void i965_load_lut_10p6(struct intel_crtc *crtc, + const struct drm_property_blob *blob) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_color_lut *lut = blob->data; + int i, lut_size = drm_color_lut_size(blob); + enum pipe pipe = crtc->pipe; + + for (i = 0; i < lut_size - 1; i++) { + I915_WRITE(PALETTE(pipe, 2 * i + 0), + i965_lut_10p6_ldw(&lut[i])); + I915_WRITE(PALETTE(pipe, 2 * i + 1), + i965_lut_10p6_udw(&lut[i])); + } + + I915_WRITE(PIPEGCMAX(pipe, 0), lut[i].red); + I915_WRITE(PIPEGCMAX(pipe, 1), lut[i].green); + I915_WRITE(PIPEGCMAX(pipe, 2), lut[i].blue); +} + +static void i965_load_luts(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); + const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; + + if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) + i9xx_load_luts(crtc_state); + else + i965_load_lut_10p6(crtc, gamma_lut); +} + static void ilk_load_lut_10(struct intel_crtc *crtc, const struct drm_property_blob *blob) { @@ -917,6 +964,15 @@ static int check_luts(const struct intel_crtc_state *crtc_state) return 0; } +static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state) +{ + if (!crtc_state->gamma_enable || + crtc_state_is_legacy_gamma(crtc_state)) + return GAMMA_MODE_MODE_8BIT; + else + return GAMMA_MODE_MODE_10BIT; /* i965+ only */ +} + static int i9xx_color_check(struct intel_crtc_state *crtc_state) { int ret; @@ -929,7 +985,7 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state) crtc_state->base.gamma_lut && !crtc_state->c8_planes; - crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; + crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state); ret = intel_color_add_affected_planes(crtc_state); if (ret) @@ -1185,6 +1241,10 @@ void intel_color_init(struct intel_crtc *crtc) dev_priv->display.color_check = chv_color_check; dev_priv->display.color_commit = i9xx_color_commit; dev_priv->display.load_luts = cherryview_load_luts; + } else if (INTEL_GEN(dev_priv) >= 4) { + dev_priv->display.color_check = i9xx_color_check; + dev_priv->display.color_commit = i9xx_color_commit; + dev_priv->display.load_luts = i965_load_luts; } else { dev_priv->display.color_check = i9xx_color_check; dev_priv->display.color_commit = i9xx_color_commit; -- cgit v1.2.3 From 821062478ce4377b8333e96be8758670679868f3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 1 Apr 2019 23:02:30 +0300 Subject: drm/i915: Expose the legacy LUT via the GAMMA_LUT/GAMMA_LUT_SIZE props on gen2/3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just so we don't leave gen2/3 out in the cold let's advertize the legacy LUT via the GAMMA_LUT/GAMMA_LUT_SIZE props. Without the GAMMA_LUT prop we can't actually load a LUT using the atomic ioctl (in preparation for the day of 100% atomic driver). Supposedly some gen2/3 platforms have an interpolated 10bit gamma mode as well. It's slightly funkier than the i965+ mode since you have to specify the slope for the interpolation by hand. But when I tried it I couldn't get it to work, the hardware just insisted on using the 8bit more regardless of the state of the relevant PIPECONF bit. Reviewed-by: Maarten Lankhorst Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-7-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/i915_pci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 84078fbdb2d8..81d14dc2fa61 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -116,6 +116,8 @@ [PIPE_C] = IVB_CURSOR_C_OFFSET, \ } +#define I9XX_COLORS \ + .color = { .gamma_lut_size = 256 } #define I965_COLORS \ .color = { .gamma_lut_size = 129, \ .gamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \ @@ -156,6 +158,7 @@ .has_coherent_ggtt = false, \ I9XX_PIPE_OFFSETS, \ I9XX_CURSOR_OFFSETS, \ + I9XX_COLORS, \ GEN_DEFAULT_PAGE_SIZES #define I845_FEATURES \ @@ -172,6 +175,7 @@ .has_coherent_ggtt = false, \ I845_PIPE_OFFSETS, \ I845_CURSOR_OFFSETS, \ + I9XX_COLORS, \ GEN_DEFAULT_PAGE_SIZES static const struct intel_device_info intel_i830_info = { @@ -205,6 +209,7 @@ static const struct intel_device_info intel_i865g_info = { .has_coherent_ggtt = true, \ I9XX_PIPE_OFFSETS, \ I9XX_CURSOR_OFFSETS, \ + I9XX_COLORS, \ GEN_DEFAULT_PAGE_SIZES static const struct intel_device_info intel_i915g_info = { -- cgit v1.2.3 From 795f672b88ba4a616a10fb1bd9e0098edf108eb7 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 3 Apr 2019 22:16:33 +0300 Subject: drm/i915: Expose full 1024 LUT entries on ivb+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ivb+ we can select between the regular 10bit LUT mode with 1024 entries, and the split mode where the LUT is split into seprate degamma and gamma halves (each with 512 entries). Currently we expose the split gamma size of 512 as the GAMMA/DEGAMMA_LUT_SIZE. When using only degamma or gamma (not both) we are wasting half of the hardware LUT entries. Let's flip that around so that we expose the full 1024 entries and just throw away half of the user provided entries when using the split gamma mode. Cc: Matt Roper Suggested-by: Matt Roper Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-8-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/i915_pci.c | 2 +- drivers/gpu/drm/i915/intel_color.c | 75 +++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 43 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 81d14dc2fa61..6ffb85ddac53 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -125,7 +125,7 @@ #define ILK_COLORS \ .color = { .gamma_lut_size = 1024 } #define IVB_COLORS \ - .color = { .degamma_lut_size = 512, .gamma_lut_size = 512 } + .color = { .degamma_lut_size = 1024, .gamma_lut_size = 1024 } #define CHV_COLORS \ .color = { .degamma_lut_size = 65, .gamma_lut_size = 257, \ .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \ diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index efcf9e2d0b56..60f21a1fdbbe 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -538,6 +538,14 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state) ilk_load_lut_10(crtc, gamma_lut); } +static int ivb_lut_10_size(u32 prec_index) +{ + if (prec_index & PAL_PREC_SPLIT_MODE) + return 512; + else + return 1024; +} + /* * IVB/HSW Bspec / PAL_PREC_INDEX: * "Restriction : Index auto increment mode is not @@ -545,31 +553,21 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state) */ static void ivb_load_lut_10(struct intel_crtc *crtc, const struct drm_property_blob *blob, - u32 prec_index, bool duplicate) + u32 prec_index) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + int hw_lut_size = ivb_lut_10_size(prec_index); const struct drm_color_lut *lut = blob->data; int i, lut_size = drm_color_lut_size(blob); enum pipe pipe = crtc->pipe; - /* - * We advertise the split gamma sizes. When not using split - * gamma we just duplicate each entry. - * - * TODO: expose the full LUT to userspace - */ - if (duplicate) { - for (i = 0; i < lut_size; i++) { - I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - } - } else { - for (i = 0; i < lut_size; i++) { - I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - } + for (i = 0; i < hw_lut_size; i++) { + /* We discard half the user entries in split gamma mode */ + const struct drm_color_lut *entry = + &lut[i * (lut_size - 1) / (hw_lut_size - 1)]; + + I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++); + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry)); } /* @@ -582,9 +580,10 @@ static void ivb_load_lut_10(struct intel_crtc *crtc, /* On BDW+ the index auto increment mode actually works */ static void bdw_load_lut_10(struct intel_crtc *crtc, const struct drm_property_blob *blob, - u32 prec_index, bool duplicate) + u32 prec_index) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + int hw_lut_size = ivb_lut_10_size(prec_index); const struct drm_color_lut *lut = blob->data; int i, lut_size = drm_color_lut_size(blob); enum pipe pipe = crtc->pipe; @@ -592,20 +591,12 @@ static void bdw_load_lut_10(struct intel_crtc *crtc, I915_WRITE(PREC_PAL_INDEX(pipe), prec_index | PAL_PREC_AUTO_INCREMENT); - /* - * We advertise the split gamma sizes. When not using split - * gamma we just duplicate each entry. - * - * TODO: expose the full LUT to userspace - */ - if (duplicate) { - for (i = 0; i < lut_size; i++) { - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); - } - } else { - for (i = 0; i < lut_size; i++) - I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i])); + for (i = 0; i < hw_lut_size; i++) { + /* We discard half the user entries in split gamma mode */ + const struct drm_color_lut *entry = + &lut[i * (lut_size - 1) / (hw_lut_size - 1)]; + + I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry)); } /* @@ -647,15 +638,15 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state) i9xx_load_luts(crtc_state); } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(0), false); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(512), false); + PAL_PREC_INDEX_VALUE(512)); } else { const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; ivb_load_lut_10(crtc, blob, - PAL_PREC_INDEX_VALUE(0), true); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } @@ -670,15 +661,15 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state) i9xx_load_luts(crtc_state); } else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) { bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(0), false); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE | - PAL_PREC_INDEX_VALUE(512), false); + PAL_PREC_INDEX_VALUE(512)); } else { const struct drm_property_blob *blob = gamma_lut ?: degamma_lut; bdw_load_lut_10(crtc, blob, - PAL_PREC_INDEX_VALUE(0), true); + PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } @@ -770,7 +761,7 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) { i9xx_load_luts(crtc_state); } else { - bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); + bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } @@ -787,7 +778,7 @@ static void icl_load_luts(const struct intel_crtc_state *crtc_state) GAMMA_MODE_MODE_8BIT) { i9xx_load_luts(crtc_state); } else { - bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false); + bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0)); ivb_load_lut_10_max(crtc); } } -- cgit v1.2.3 From 7f1a93b1f1d1d2603a49a9e4226259db9272f305 Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Mon, 25 Mar 2019 16:29:19 +0800 Subject: drm/i915/gvt: Correct the calculation of plane size stride isn't in unit of pixel, it is bytes, so calculation of plane size doesn't need to multiple bpp. Fixes: e546e281d33d ("drm/i915/gvt: Dmabuf support for GVT-g") Signed-off-by: Xiong Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/dmabuf.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 3e7e2b80c857..5d887f7cc0d5 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -238,9 +238,6 @@ static int vgpu_get_plane_info(struct drm_device *dev, default: gvt_vgpu_err("invalid tiling mode: %x\n", p.tiled); } - - info->size = (((p.stride * p.height * p.bpp) / 8) + - (PAGE_SIZE - 1)) >> PAGE_SHIFT; } else if (plane_id == DRM_PLANE_TYPE_CURSOR) { ret = intel_vgpu_decode_cursor_plane(vgpu, &c); if (ret) @@ -262,14 +259,13 @@ static int vgpu_get_plane_info(struct drm_device *dev, info->x_hot = UINT_MAX; info->y_hot = UINT_MAX; } - - info->size = (((info->stride * c.height * c.bpp) / 8) - + (PAGE_SIZE - 1)) >> PAGE_SHIFT; } else { gvt_vgpu_err("invalid plane id:%d\n", plane_id); return -EINVAL; } + info->size = (info->stride * info->height + PAGE_SIZE - 1) + >> PAGE_SHIFT; if (info->size == 0) { gvt_vgpu_err("fb size is zero\n"); return -EINVAL; -- cgit v1.2.3 From cf9ed66671ec5f6cacc7b6efbad9d7c9e5e31776 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 Feb 2019 20:30:33 +0000 Subject: drm/i915/gvt: Fix kerneldoc typo for intel_vgpu_emulate_hotplug drivers/gpu/drm/i915/gvt/display.c:457: warning: Function parameter or member 'connected' not described in 'intel_vgpu_emulate_hotplug' drivers/gpu/drm/i915/gvt/display.c:457: warning: Excess function parameter 'conncted' description in 'intel_vgpu_emulate_hotplug' Fixes: 1ca20f33df42 ("drm/i915/gvt: add hotplug emulation") Signed-off-by: Chris Wilson Cc: Hang Yuan Cc: Zhenyu Wang Cc: Zhi Wang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 035479e273be..e3f9caa7839f 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -448,7 +448,7 @@ void intel_gvt_emulate_vblank(struct intel_gvt *gvt) /** * intel_vgpu_emulate_hotplug - trigger hotplug event for vGPU * @vgpu: a vGPU - * @conncted: link state + * @connected: link state * * This function is used to trigger hotplug interrupt for vGPU * -- cgit v1.2.3 From 28d618e9ab86f26a31af0b235ced55beb3e343c8 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Thu, 4 Apr 2019 17:43:58 +0300 Subject: drm/i915: Update DRIVER_DATE to 20190404 Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8f38d03b1c4e..4af815c3c02d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -92,8 +92,8 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20190328" -#define DRIVER_TIMESTAMP 1553776914 +#define DRIVER_DATE "20190404" +#define DRIVER_TIMESTAMP 1554389037 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions -- cgit v1.2.3 From e7ad88553aa1d48e950ca9a4934d246c1bee4be4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 3 Apr 2019 12:30:32 -0500 Subject: drm/amdkfd: Add picasso pci id Picasso is a new raven variant. Reviewed-by: Kent Russell Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 8be9677c0c07..cf9a49f49d3a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -320,6 +320,7 @@ static const struct kfd_deviceid supported_devices[] = { { 0x9876, &carrizo_device_info }, /* Carrizo */ { 0x9877, &carrizo_device_info }, /* Carrizo */ { 0x15DD, &raven_device_info }, /* Raven */ + { 0x15D8, &raven_device_info }, /* Raven */ #endif { 0x67A0, &hawaii_device_info }, /* Hawaii */ { 0x67A1, &hawaii_device_info }, /* Hawaii */ -- cgit v1.2.3 From 6960d9cfc721d9e577631b9057c07eecea8bdc0f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 4 Apr 2019 11:19:14 +0100 Subject: drm/i915: Be precise in types for i915_gem_busy Mixing u8 and -1u together leads to zero-extended integer expansion, and comparing 0x000000ff against 0xffffffff, causing us to report a mixed uabi-class request as not busy. The input flag is a u8, and we want to generate a u32 uABI response, mark our functions so. Fixes: c8b502422bfe ("drm/i915: Remove last traces of exec-id (GEM_BUSY)") Testcase: igt/gem_exec_balance/busy Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190404101914.7231-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf594a5e88bc..f25a1ba24927 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3841,16 +3841,16 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, return vma; } -static __always_inline unsigned int __busy_read_flag(unsigned int id) +static __always_inline u32 __busy_read_flag(u8 id) { - if (id == I915_ENGINE_CLASS_INVALID) - return 0xffff0000; + if (id == (u8)I915_ENGINE_CLASS_INVALID) + return 0xffff0000u; GEM_BUG_ON(id >= 16); - return 0x10000 << id; + return 0x10000u << id; } -static __always_inline unsigned int __busy_write_id(unsigned int id) +static __always_inline u32 __busy_write_id(u8 id) { /* * The uABI guarantees an active writer is also amongst the read @@ -3861,15 +3861,14 @@ static __always_inline unsigned int __busy_write_id(unsigned int id) * last_read - hence we always set both read and write busy for * last_write. */ - if (id == I915_ENGINE_CLASS_INVALID) - return 0xffffffff; + if (id == (u8)I915_ENGINE_CLASS_INVALID) + return 0xffffffffu; return (id + 1) | __busy_read_flag(id); } static __always_inline unsigned int -__busy_set_if_active(const struct dma_fence *fence, - unsigned int (*flag)(unsigned int id)) +__busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u8 id)) { const struct i915_request *rq; @@ -3889,6 +3888,8 @@ __busy_set_if_active(const struct dma_fence *fence, if (i915_request_completed(rq)) return 0; + /* Beware type-expansion follies! */ + BUILD_BUG_ON(!typecheck(u8, rq->engine->uabi_class)); return flag(rq->engine->uabi_class); } -- cgit v1.2.3 From 8fb44c1d82588860e84b7ca4fe2e836de6aa2585 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 4 Apr 2019 08:33:57 +0100 Subject: drm/i915: Fixup kerneldoc for intel_cdclk_needs_cd2x_update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/gpu/drm/i915/intel_cdclk.c:2116: warning: Function parameter or member 'dev_priv' not described in 'intel_cdclk_needs_cd2x_update' Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Abhay Kumar Cc: Imre Deak Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190404073357.18795-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_cdclk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index b8cd481f5e33..b911fe86be56 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -2104,6 +2104,7 @@ bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, /** * intel_cdclk_needs_cd2x_update - Determine if two CDCLK states require a cd2x divider update + * @dev_priv: Not a CDCLK state, it's the drm_i915_private! * @a: first CDCLK state * @b: second CDCLK state * -- cgit v1.2.3 From d4162c61e253177936fcfe6c29f7b224d9a1efb8 Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Mon, 1 Apr 2019 16:09:34 -0400 Subject: drm/amdgpu: Adjust IB test timeout for XGMI configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On XGMI configuration the ib test may take longer to finish Signed-off-by: shaoyunl Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 0b8ef2d27d6b..fe393a46f881 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -35,6 +35,7 @@ #include "amdgpu_trace.h" #define AMDGPU_IB_TEST_TIMEOUT msecs_to_jiffies(1000) +#define AMDGPU_IB_TEST_GFX_XGMI_TIMEOUT msecs_to_jiffies(2000) /* * IB @@ -344,6 +345,8 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) * cost waiting for it coming back under RUNTIME only */ tmo_gfx = 8 * AMDGPU_IB_TEST_TIMEOUT; + } else if (adev->gmc.xgmi.hive_id) { + tmo_gfx = AMDGPU_IB_TEST_GFX_XGMI_TIMEOUT; } for (i = 0; i < adev->num_rings; ++i) { -- cgit v1.2.3 From 1712fb1a2f6829150032ac76eb0e39b82a549cfb Mon Sep 17 00:00:00 2001 From: wentalou Date: Tue, 2 Apr 2019 17:13:05 +0800 Subject: drm/amdgpu: amdgpu_device_recover_vram always failed if only one node in shadow_list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amdgpu_bo_restore_shadow would assign zero to r if succeeded. r would remain zero if there is only one node in shadow_list. current code would always return failure when r <= 0. restart the timeout for each wait was a rather problematic bug as well. The value of tmo SHOULD be changed, otherwise we wait tmo jiffies on each loop. Signed-off-by: Wentao Lou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index ac0d646a7b74..5d8b30fd4534 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3173,11 +3173,16 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) break; if (fence) { - r = dma_fence_wait_timeout(fence, false, tmo); + tmo = dma_fence_wait_timeout(fence, false, tmo); dma_fence_put(fence); fence = next; - if (r <= 0) + if (tmo == 0) { + r = -ETIMEDOUT; break; + } else if (tmo < 0) { + r = tmo; + break; + } } else { fence = next; } @@ -3188,8 +3193,8 @@ static int amdgpu_device_recover_vram(struct amdgpu_device *adev) tmo = dma_fence_wait_timeout(fence, false, tmo); dma_fence_put(fence); - if (r <= 0 || tmo <= 0) { - DRM_ERROR("recover vram bo from shadow failed\n"); + if (r < 0 || tmo <= 0) { + DRM_ERROR("recover vram bo from shadow failed, r is %ld, tmo is %ld\n", r, tmo); return -EIO; } -- cgit v1.2.3 From c1cefe115d1cdc460014483319d440b2f0d07c68 Mon Sep 17 00:00:00 2001 From: tiancyin Date: Mon, 1 Apr 2019 10:15:31 +0800 Subject: drm/amd/display: fix cursor black issue [Why] the member sdr_white_level of struct dc_cursor_attributes was not initialized, then the random value result that dcn10_set_cursor_sdr_white_level() set error hw_scale value 0x20D9(normal value is 0x3c00), this cause the black cursor issue. [how] just initilize the obj of struct dc_cursor_attributes to zero to avoid the random value. Reviewed-by: Nicholas Kazlauskas Signed-off-by: Tianci Yin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 81127f7d6ed1..3082b55b1e77 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4533,6 +4533,7 @@ static void handle_cursor_update(struct drm_plane *plane, amdgpu_crtc->cursor_width = plane->state->crtc_w; amdgpu_crtc->cursor_height = plane->state->crtc_h; + memset(&attributes, 0, sizeof(attributes)); attributes.address.high_part = upper_32_bits(address); attributes.address.low_part = lower_32_bits(address); attributes.width = plane->state->crtc_w; -- cgit v1.2.3 From 7cdd4dc58d282904629c9131bf4a2ff1af34f442 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 28 Mar 2019 09:46:36 +0800 Subject: drm/amd/powerplay: check for invalid profile mode before switching Need to check for invalid profile mode settings before determining to switch to that. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index 476a072027a6..384c37875cd0 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -4915,9 +4915,6 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui uint8_t min_active_level; uint32_t power_profile_mode = input[size]; - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, - 1 << power_profile_mode); - if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { if (size != 0 && size != 4) return -EINVAL; @@ -4944,6 +4941,8 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui } out: + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, + 1 << power_profile_mode); hwmgr->power_profile_mode = power_profile_mode; return 0; -- cgit v1.2.3 From c2400ec3b6d15beea34d652ee18962ed13433528 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 3 Apr 2019 16:52:36 +0300 Subject: drm/i915: add Makefile magic for testing headers are self-contained The below commits added dummy files to test that certain headers are self-contained, i.e. compilable as standalone units: 39e2f501c1b4 ("drm/i915: Split struct intel_context definition to its own header") 3a891a626794 ("drm/i915: Move intel_engine_mask_t around for use by i915_request_types.h") 8b74594aa455 ("drm/i915: Split out i915_priolist_types into its own header") The idea is fine, but the implementation is a bit tedious and inflexible, and does not really scale well. Implement the same in make using autogenerated dummy sources to include the headers. v2 by Chris: - Use patsubst - Add .gitignore - Add clean-files for generated dummy sources v3 by Jani: - Fix make clean - Add the tests to i915-y instead of extra-y v4 by Jani: - quiet_cmd whitespace fix Cc: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190403135236.8398-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/.gitignore | 1 + drivers/gpu/drm/i915/Makefile | 16 ++++----------- drivers/gpu/drm/i915/Makefile.header-test | 23 ++++++++++++++++++++++ .../drm/i915/test_i915_active_types_standalone.c | 7 ------- .../i915/test_i915_gem_context_types_standalone.c | 7 ------- .../drm/i915/test_i915_priolist_types_standalone.c | 7 ------- .../i915/test_i915_scheduler_types_standalone.c | 7 ------- .../drm/i915/test_i915_timeline_types_standalone.c | 7 ------- .../drm/i915/test_intel_context_types_standalone.c | 7 ------- .../drm/i915/test_intel_engine_types_standalone.c | 7 ------- .../i915/test_intel_workarounds_types_standalone.c | 7 ------- 11 files changed, 28 insertions(+), 68 deletions(-) create mode 100644 drivers/gpu/drm/i915/.gitignore create mode 100644 drivers/gpu/drm/i915/Makefile.header-test delete mode 100644 drivers/gpu/drm/i915/test_i915_active_types_standalone.c delete mode 100644 drivers/gpu/drm/i915/test_i915_gem_context_types_standalone.c delete mode 100644 drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c delete mode 100644 drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c delete mode 100644 drivers/gpu/drm/i915/test_i915_timeline_types_standalone.c delete mode 100644 drivers/gpu/drm/i915/test_intel_context_types_standalone.c delete mode 100644 drivers/gpu/drm/i915/test_intel_engine_types_standalone.c delete mode 100644 drivers/gpu/drm/i915/test_intel_workarounds_types_standalone.c (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/.gitignore b/drivers/gpu/drm/i915/.gitignore new file mode 100644 index 000000000000..cff45d81f42f --- /dev/null +++ b/drivers/gpu/drm/i915/.gitignore @@ -0,0 +1 @@ +header_test_*.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 30bf3301ea24..fbcb0904f4a8 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -32,10 +32,13 @@ CFLAGS_intel_fbdev.o = $(call cc-disable-warning, override-init) subdir-ccflags-y += \ $(call as-instr,movntdqa (%eax)$(comma)%xmm0,-DCONFIG_AS_MOVNTDQA) +# Extra header tests +include $(src)/Makefile.header-test + # Please keep these build lists sorted! # core driver code -i915-y := i915_drv.o \ +i915-y += i915_drv.o \ i915_irq.o \ i915_memcpy.o \ i915_mm.o \ @@ -57,17 +60,6 @@ i915-$(CONFIG_COMPAT) += i915_ioc32.o i915-$(CONFIG_DEBUG_FS) += i915_debugfs.o intel_pipe_crc.o i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o -# Test the headers are compilable as standalone units -i915-$(CONFIG_DRM_I915_WERROR) += \ - test_i915_active_types_standalone.o \ - test_i915_gem_context_types_standalone.o \ - test_i915_priolist_types_standalone.o \ - test_i915_scheduler_types_standalone.o \ - test_i915_timeline_types_standalone.o \ - test_intel_context_types_standalone.o \ - test_intel_engine_types_standalone.o \ - test_intel_workarounds_types_standalone.o - # GEM code i915-y += \ i915_active.o \ diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test new file mode 100644 index 000000000000..f7809b5c21ad --- /dev/null +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: MIT +# Copyright © 2019 Intel Corporation + +# Test the headers are compilable as standalone units +header_test := \ + i915_active_types.h \ + i915_gem_context_types.h \ + i915_priolist_types.h \ + i915_scheduler_types.h \ + i915_timeline_types.h \ + intel_context_types.h \ + intel_engine_types.h \ + intel_workarounds_types.h + +quiet_cmd_header_test = HDRTEST $@ + cmd_header_test = echo "\#include \"$( $@ + +header_test_%.c: %.h + $(call cmd,header_test) + +i915-$(CONFIG_DRM_I915_WERROR) += $(foreach h,$(header_test),$(patsubst %.h,header_test_%.o,$(h))) + +clean-files += $(foreach h,$(header_test),$(patsubst %.h,header_test_%.c,$(h))) diff --git a/drivers/gpu/drm/i915/test_i915_active_types_standalone.c b/drivers/gpu/drm/i915/test_i915_active_types_standalone.c deleted file mode 100644 index 144ebd153e57..000000000000 --- a/drivers/gpu/drm/i915/test_i915_active_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "i915_active_types.h" diff --git a/drivers/gpu/drm/i915/test_i915_gem_context_types_standalone.c b/drivers/gpu/drm/i915/test_i915_gem_context_types_standalone.c deleted file mode 100644 index 4e4da4860bc2..000000000000 --- a/drivers/gpu/drm/i915/test_i915_gem_context_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "i915_gem_context_types.h" diff --git a/drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c b/drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c deleted file mode 100644 index f465eb99bb47..000000000000 --- a/drivers/gpu/drm/i915/test_i915_priolist_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "i915_priolist_types.h" diff --git a/drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c b/drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c deleted file mode 100644 index 8afa2c3719fb..000000000000 --- a/drivers/gpu/drm/i915/test_i915_scheduler_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "i915_scheduler_types.h" diff --git a/drivers/gpu/drm/i915/test_i915_timeline_types_standalone.c b/drivers/gpu/drm/i915/test_i915_timeline_types_standalone.c deleted file mode 100644 index f58e148e8946..000000000000 --- a/drivers/gpu/drm/i915/test_i915_timeline_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "i915_timeline_types.h" diff --git a/drivers/gpu/drm/i915/test_intel_context_types_standalone.c b/drivers/gpu/drm/i915/test_intel_context_types_standalone.c deleted file mode 100644 index b39e3c4e6551..000000000000 --- a/drivers/gpu/drm/i915/test_intel_context_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "intel_context_types.h" diff --git a/drivers/gpu/drm/i915/test_intel_engine_types_standalone.c b/drivers/gpu/drm/i915/test_intel_engine_types_standalone.c deleted file mode 100644 index d05e4cdcbcf9..000000000000 --- a/drivers/gpu/drm/i915/test_intel_engine_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "intel_engine_types.h" diff --git a/drivers/gpu/drm/i915/test_intel_workarounds_types_standalone.c b/drivers/gpu/drm/i915/test_intel_workarounds_types_standalone.c deleted file mode 100644 index 4f658bb00825..000000000000 --- a/drivers/gpu/drm/i915/test_intel_workarounds_types_standalone.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-License-Identifier: MIT - * - * Copyright © 2019 Intel Corporation - */ - -#include "intel_workarounds_types.h" -- cgit v1.2.3 From cd9063757a227cf31ebf5391ccda2bf583b0806e Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 24 Mar 2019 20:06:09 +0100 Subject: drm/sun4i: DW HDMI: Lower max. supported rate for H6 Currently resolutions with pixel clock higher than 340 MHz don't work with H6 HDMI controller. They just produce a blank screen. Limit maximum pixel clock rate to 340 MHz until scrambling is supported. Cc: stable@vger.kernel.org # 5.0 Fixes: 40bb9d3147b2 ("drm/sun4i: Add support for H6 DW HDMI controller") Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20190324190609.32721-1-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index dc47720c99ba..39d8509d96a0 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -48,8 +48,13 @@ static enum drm_mode_status sun8i_dw_hdmi_mode_valid_h6(struct drm_connector *connector, const struct drm_display_mode *mode) { - /* This is max for HDMI 2.0b (4K@60Hz) */ - if (mode->clock > 594000) + /* + * Controller support maximum of 594 MHz, which correlates to + * 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than + * 340 MHz scrambling has to be enabled. Because scrambling is + * not yet implemented, just limit to 340 MHz for now. + */ + if (mode->clock > 340000) return MODE_CLOCK_HIGH; return MODE_OK; -- cgit v1.2.3 From b66ea2c2cf59b80c38a14127fafb49fdf0df9180 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 3 Apr 2019 09:21:32 +0100 Subject: drm/i915: Use lockdep_pin_lock() over the construction of the request During request construction, we take the timeline->mutex to ensure exclusive access to the ringbuffer (for command emission) and the timeline itself (for command ordering). The timeline->mutex should not be dropped by callers until we release it in i915_request_add(). lockdep provides a pin/unpin lock facility to detect accidental unlocks inside critical sections, so put it to use for request construction. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190403082132.327-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_request.c | 5 +++++ drivers/gpu/drm/i915/i915_request.h | 10 ++++++++++ 2 files changed, 15 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 82094b9f5ba7..7f8a4eba98b8 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -751,7 +751,10 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx) rq->infix = rq->ring->emit; /* end of header; start of user payload */ /* Check that we didn't interrupt ourselves with a new request */ + lockdep_assert_held(&rq->timeline->mutex); GEM_BUG_ON(rq->timeline->seqno != rq->fence.seqno); + rq->cookie = lockdep_pin_lock(&rq->timeline->mutex); + return rq; err_unwind: @@ -1070,6 +1073,8 @@ void i915_request_add(struct i915_request *request) engine->name, request->fence.context, request->fence.seqno); lockdep_assert_held(&request->timeline->mutex); + lockdep_unpin_lock(&request->timeline->mutex, request->cookie); + trace_i915_request_add(request); /* diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index cd6c130964cd..875be6f71412 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -26,6 +26,7 @@ #define I915_REQUEST_H #include +#include #include "i915_gem.h" #include "i915_scheduler.h" @@ -120,6 +121,15 @@ struct i915_request { */ unsigned long rcustate; + /* + * We pin the timeline->mutex while constructing the request to + * ensure that no caller accidentally drops it during construction. + * The timeline->mutex must be held to ensure that only this caller + * can use the ring and manipulate the associated timeline during + * construction. + */ + struct pin_cookie cookie; + /* * Fences for the various phases in the request's lifetime. * -- cgit v1.2.3 From bac24f59f45419a3853af2f58130cb82b7bdca64 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Mar 2019 13:40:24 +0000 Subject: drm/i915/execlists: Enable coarse preemption boundaries for gen8 When we introduced preemption, we chose to keep it disabled for gen8 as supporting preemption inside GPGPU user batches required various w/a in userspace. Since then, the desire to preempt long queues of requests between batches (e.g. within busywaiting semaphores) has grown. So allow arbitration within the busywaits and between requests, but disable arbitration within user batches so that we can preempt between requests and not risk breaking GPGPU. However, since this preemption is much coarser and doesn't interfere with userspace, we decline to include it amongst the scheduler capabilities. (This is also required for us to skip over the preemption selftests that expect to be able to preempt user batches.) Michal suggested that we could perhaps allow preemption inside gen8 userspace batches if we can satisfy ourselves that the default preemption settings are viable with existing userspace (principally OpenCL which already should carry any known workaround). We could then merge the two code paths back into one, even dropping the artifical has-preemption device feature flag. Testcase: igt/gem_exec_scheduler/semaphore-user References: beecec901790 ("drm/i915/execlists: Preemption!") Fixes: e88619646971 ("drm/i915: Use HW semaphores for inter-engine synchronisation on gen8+") Signed-off-by: Chris Wilson Cc: Michal Winiarski Cc: Tvrtko Ursulin Reviewed-by: Michal Winiarski #irc Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190329134024.5254-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 50 +++++--- drivers/gpu/drm/i915/selftests/intel_lrc.c | 180 +++++++++++++++++++++++++++++ 3 files changed, 217 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index fe7ddb1f59e1..f8c94405670b 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -562,7 +562,7 @@ static void init_contexts(struct drm_i915_private *i915) static bool needs_preempt_context(struct drm_i915_private *i915) { - return HAS_LOGICAL_RING_PREEMPTION(i915); + return HAS_EXECLISTS(i915); } int i915_gem_contexts_init(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bec232acc8d7..b662a054f228 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -233,7 +233,7 @@ static inline bool need_preempt(const struct intel_engine_cs *engine, { int last_prio; - if (!intel_engine_has_preemption(engine)) + if (!engine->preempt_context) return false; if (i915_request_completed(rq)) @@ -2035,7 +2035,7 @@ static int gen8_emit_bb_start(struct i915_request *rq, { u32 *cs; - cs = intel_ring_begin(rq, 6); + cs = intel_ring_begin(rq, 4); if (IS_ERR(cs)) return PTR_ERR(cs); @@ -2046,19 +2046,37 @@ static int gen8_emit_bb_start(struct i915_request *rq, * particular all the gen that do not need the w/a at all!), if we * took care to make sure that on every switch into this context * (both ordinary and for preemption) that arbitrartion was enabled - * we would be fine. However, there doesn't seem to be a downside to - * being paranoid and making sure it is set before each batch and - * every context-switch. - * - * Note that if we fail to enable arbitration before the request - * is complete, then we do not see the context-switch interrupt and - * the engine hangs (with RING_HEAD == RING_TAIL). - * - * That satisfies both the GPGPU w/a and our heavy-handed paranoia. + * we would be fine. However, for gen8 there is another w/a that + * requires us to not preempt inside GPGPU execution, so we keep + * arbitration disabled for gen8 batches. Arbitration will be + * re-enabled before we close the request + * (engine->emit_fini_breadcrumb). */ + *cs++ = MI_ARB_ON_OFF | MI_ARB_DISABLE; + + /* FIXME(BDW+): Address space and security selectors. */ + *cs++ = MI_BATCH_BUFFER_START_GEN8 | + (flags & I915_DISPATCH_SECURE ? 0 : BIT(8)); + *cs++ = lower_32_bits(offset); + *cs++ = upper_32_bits(offset); + + intel_ring_advance(rq, cs); + + return 0; +} + +static int gen9_emit_bb_start(struct i915_request *rq, + u64 offset, u32 len, + const unsigned int flags) +{ + u32 *cs; + + cs = intel_ring_begin(rq, 6); + if (IS_ERR(cs)) + return PTR_ERR(cs); + *cs++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; - /* FIXME(BDW): Address space and security selectors. */ *cs++ = MI_BATCH_BUFFER_START_GEN8 | (flags & I915_DISPATCH_SECURE ? 0 : BIT(8)); *cs++ = lower_32_bits(offset); @@ -2316,7 +2334,8 @@ void intel_execlists_set_default_submission(struct intel_engine_cs *engine) engine->flags |= I915_ENGINE_SUPPORTS_STATS; if (!intel_vgpu_active(engine->i915)) engine->flags |= I915_ENGINE_HAS_SEMAPHORES; - if (engine->preempt_context) + if (engine->preempt_context && + HAS_LOGICAL_RING_PREEMPTION(engine->i915)) engine->flags |= I915_ENGINE_HAS_PREEMPTION; } @@ -2350,7 +2369,10 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine) * until a more refined solution exists. */ } - engine->emit_bb_start = gen8_emit_bb_start; + if (IS_GEN(engine->i915, 8)) + engine->emit_bb_start = gen8_emit_bb_start; + else + engine->emit_bb_start = gen9_emit_bb_start; } static inline void diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index 0d3cae564db8..8bcd4e1d58ee 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -76,6 +76,185 @@ err_unlock: return err; } +static int live_busywait_preempt(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx_hi, *ctx_lo; + struct intel_engine_cs *engine; + struct drm_i915_gem_object *obj; + struct i915_vma *vma; + enum intel_engine_id id; + intel_wakeref_t wakeref; + int err = -ENOMEM; + u32 *map; + + /* + * Verify that even without HAS_LOGICAL_RING_PREEMPTION, we can + * preempt the busywaits used to synchronise between rings. + */ + + mutex_lock(&i915->drm.struct_mutex); + wakeref = intel_runtime_pm_get(i915); + + ctx_hi = kernel_context(i915); + if (!ctx_hi) + goto err_unlock; + ctx_hi->sched.priority = INT_MAX; + + ctx_lo = kernel_context(i915); + if (!ctx_lo) + goto err_ctx_hi; + ctx_lo->sched.priority = INT_MIN; + + obj = i915_gem_object_create_internal(i915, PAGE_SIZE); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto err_ctx_lo; + } + + map = i915_gem_object_pin_map(obj, I915_MAP_WC); + if (IS_ERR(map)) { + err = PTR_ERR(map); + goto err_obj; + } + + vma = i915_vma_instance(obj, &i915->ggtt.vm, 0); + if (IS_ERR(vma)) { + err = PTR_ERR(vma); + goto err_map; + } + + err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL); + if (err) + goto err_map; + + for_each_engine(engine, i915, id) { + struct i915_request *lo, *hi; + struct igt_live_test t; + u32 *cs; + + if (!intel_engine_can_store_dword(engine)) + continue; + + if (igt_live_test_begin(&t, i915, __func__, engine->name)) { + err = -EIO; + goto err_vma; + } + + /* + * We create two requests. The low priority request + * busywaits on a semaphore (inside the ringbuffer where + * is should be preemptible) and the high priority requests + * uses a MI_STORE_DWORD_IMM to update the semaphore value + * allowing the first request to complete. If preemption + * fails, we hang instead. + */ + + lo = i915_request_alloc(engine, ctx_lo); + if (IS_ERR(lo)) { + err = PTR_ERR(lo); + goto err_vma; + } + + cs = intel_ring_begin(lo, 8); + if (IS_ERR(cs)) { + err = PTR_ERR(cs); + i915_request_add(lo); + goto err_vma; + } + + *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT; + *cs++ = i915_ggtt_offset(vma); + *cs++ = 0; + *cs++ = 1; + + /* XXX Do we need a flush + invalidate here? */ + + *cs++ = MI_SEMAPHORE_WAIT | + MI_SEMAPHORE_GLOBAL_GTT | + MI_SEMAPHORE_POLL | + MI_SEMAPHORE_SAD_EQ_SDD; + *cs++ = 0; + *cs++ = i915_ggtt_offset(vma); + *cs++ = 0; + + intel_ring_advance(lo, cs); + i915_request_add(lo); + + if (wait_for(READ_ONCE(*map), 10)) { + err = -ETIMEDOUT; + goto err_vma; + } + + /* Low priority request should be busywaiting now */ + if (i915_request_wait(lo, I915_WAIT_LOCKED, 1) != -ETIME) { + pr_err("%s: Busywaiting request did not!\n", + engine->name); + err = -EIO; + goto err_vma; + } + + hi = i915_request_alloc(engine, ctx_hi); + if (IS_ERR(hi)) { + err = PTR_ERR(hi); + goto err_vma; + } + + cs = intel_ring_begin(hi, 4); + if (IS_ERR(cs)) { + err = PTR_ERR(cs); + i915_request_add(hi); + goto err_vma; + } + + *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT; + *cs++ = i915_ggtt_offset(vma); + *cs++ = 0; + *cs++ = 0; + + intel_ring_advance(hi, cs); + i915_request_add(hi); + + if (i915_request_wait(lo, I915_WAIT_LOCKED, HZ / 5) < 0) { + struct drm_printer p = drm_info_printer(i915->drm.dev); + + pr_err("%s: Failed to preempt semaphore busywait!\n", + engine->name); + + intel_engine_dump(engine, &p, "%s\n", engine->name); + GEM_TRACE_DUMP(); + + i915_gem_set_wedged(i915); + err = -EIO; + goto err_vma; + } + GEM_BUG_ON(READ_ONCE(*map)); + + if (igt_live_test_end(&t)) { + err = -EIO; + goto err_vma; + } + } + + err = 0; +err_vma: + i915_vma_unpin(vma); +err_map: + i915_gem_object_unpin_map(obj); +err_obj: + i915_gem_object_put(obj); +err_ctx_lo: + kernel_context_close(ctx_lo); +err_ctx_hi: + kernel_context_close(ctx_hi); +err_unlock: + if (igt_flush_test(i915, I915_WAIT_LOCKED)) + err = -EIO; + intel_runtime_pm_put(i915, wakeref); + mutex_unlock(&i915->drm.struct_mutex); + return err; +} + static int live_preempt(void *arg) { struct drm_i915_private *i915 = arg; @@ -1127,6 +1306,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { SUBTEST(live_sanitycheck), + SUBTEST(live_busywait_preempt), SUBTEST(live_preempt), SUBTEST(live_late_preempt), SUBTEST(live_suppress_self_preempt), -- cgit v1.2.3 From e57ce4b193a306ac8ccaf47c1cac3c49e6bd7190 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 Apr 2019 12:14:30 +0100 Subject: drm/i915/selftests: Fix plain use of integer 0 as NULL Quelch a sparse warning: drivers/gpu/drm/i915/gt/selftest_lrc.c:119:54: warning: Using plain integer as NULL pointer Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Matthew Auld Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190405111430.18495-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/selftests/intel_lrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index 8bcd4e1d58ee..fbee030db940 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -118,7 +118,7 @@ static int live_busywait_preempt(void *arg) goto err_obj; } - vma = i915_vma_instance(obj, &i915->ggtt.vm, 0); + vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL); if (IS_ERR(vma)) { err = PTR_ERR(vma); goto err_map; -- cgit v1.2.3 From 6d4257284a87ecbd0fd7eaed0d98531a009f579f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 Apr 2019 13:38:31 +0100 Subject: drm/i915: Make RING_PDP relative to engine->mmio_base The PDP registers are an oddity inside the set of context saved registers in that they take the engine as a parameter to the macro and not the mmio_base as the others do. Make it accept the engine->mmio_base for consistency in programming the context registers. add/remove: 0/0 grow/shrink: 2/1 up/down: 3/-32 (-29) Function old new delta emit_ppgtt_update 324 326 +2 capture 5102 5103 +1 execlists_init_reg_state.isra 1128 1096 -32 And similar savings later! Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190405123831.9724-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_context.c | 9 +++++---- drivers/gpu/drm/i915/i915_gpu_error.c | 15 +++++++++------ drivers/gpu/drm/i915/i915_reg.h | 4 ++-- drivers/gpu/drm/i915/intel_lrc.c | 21 +++++++++++---------- 4 files changed, 27 insertions(+), 22 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index f8c94405670b..66b6852cb4d2 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -1028,6 +1028,7 @@ static int emit_ppgtt_update(struct i915_request *rq, void *data) { struct i915_hw_ppgtt *ppgtt = rq->gem_context->ppgtt; struct intel_engine_cs *engine = rq->engine; + u32 base = engine->mmio_base; u32 *cs; int i; @@ -1040,9 +1041,9 @@ static int emit_ppgtt_update(struct i915_request *rq, void *data) *cs++ = MI_LOAD_REGISTER_IMM(2); - *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(engine, 0)); + *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(base, 0)); *cs++ = upper_32_bits(pd_daddr); - *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(engine, 0)); + *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(base, 0)); *cs++ = lower_32_bits(pd_daddr); *cs++ = MI_NOOP; @@ -1056,9 +1057,9 @@ static int emit_ppgtt_update(struct i915_request *rq, void *data) for (i = GEN8_3LVL_PDPES; i--; ) { const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i); - *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(engine, i)); + *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(base, i)); *cs++ = upper_32_bits(pd_daddr); - *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(engine, i)); + *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(base, i)); *cs++ = lower_32_bits(pd_daddr); } *cs++ = MI_NOOP; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index c65d45bc63ee..43b68fdc8967 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1215,20 +1215,23 @@ static void error_record_engine_registers(struct i915_gpu_state *error, ee->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(engine)); - if (IS_GEN(dev_priv, 6)) + if (IS_GEN(dev_priv, 6)) { ee->vm_info.pp_dir_base = ENGINE_READ(engine, RING_PP_DIR_BASE_READ); - else if (IS_GEN(dev_priv, 7)) + } else if (IS_GEN(dev_priv, 7)) { ee->vm_info.pp_dir_base = - ENGINE_READ(engine, RING_PP_DIR_BASE); - else if (INTEL_GEN(dev_priv) >= 8) + ENGINE_READ(engine, RING_PP_DIR_BASE); + } else if (INTEL_GEN(dev_priv) >= 8) { + u32 base = engine->mmio_base; + for (i = 0; i < 4; i++) { ee->vm_info.pdp[i] = - I915_READ(GEN8_RING_PDP_UDW(engine, i)); + I915_READ(GEN8_RING_PDP_UDW(base, i)); ee->vm_info.pdp[i] <<= 32; ee->vm_info.pdp[i] |= - I915_READ(GEN8_RING_PDP_LDW(engine, i)); + I915_READ(GEN8_RING_PDP_LDW(base, i)); } + } } } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 00e03560c4e7..c18caa76f27c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -439,8 +439,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define RING_PP_DIR_DCLV(base) _MMIO((base) + 0x220) #define PP_DIR_DCLV_2G 0xffffffff -#define GEN8_RING_PDP_UDW(engine, n) _MMIO((engine)->mmio_base + 0x270 + (n) * 8 + 4) -#define GEN8_RING_PDP_LDW(engine, n) _MMIO((engine)->mmio_base + 0x270 + (n) * 8) +#define GEN8_RING_PDP_UDW(base, n) _MMIO((base) + 0x270 + (n) * 8 + 4) +#define GEN8_RING_PDP_LDW(base, n) _MMIO((base) + 0x270 + (n) * 8) #define GEN8_R_PWR_CLK_STATE _MMIO(0x20C8) #define GEN8_RPCS_ENABLE (1 << 31) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index b662a054f228..6931dbb2888c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1451,10 +1451,11 @@ static int emit_pdps(struct i915_request *rq) *cs++ = MI_LOAD_REGISTER_IMM(2 * GEN8_3LVL_PDPES) | MI_LRI_FORCE_POSTED; for (i = GEN8_3LVL_PDPES; i--; ) { const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i); + u32 base = engine->mmio_base; - *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(engine, i)); + *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(base, i)); *cs++ = upper_32_bits(pd_daddr); - *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(engine, i)); + *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(base, i)); *cs++ = lower_32_bits(pd_daddr); } *cs++ = MI_NOOP; @@ -2729,14 +2730,14 @@ static void execlists_init_reg_state(u32 *regs, CTX_REG(regs, CTX_CTX_TIMESTAMP, RING_CTX_TIMESTAMP(base), 0); /* PDP values well be assigned later if needed */ - CTX_REG(regs, CTX_PDP3_UDW, GEN8_RING_PDP_UDW(engine, 3), 0); - CTX_REG(regs, CTX_PDP3_LDW, GEN8_RING_PDP_LDW(engine, 3), 0); - CTX_REG(regs, CTX_PDP2_UDW, GEN8_RING_PDP_UDW(engine, 2), 0); - CTX_REG(regs, CTX_PDP2_LDW, GEN8_RING_PDP_LDW(engine, 2), 0); - CTX_REG(regs, CTX_PDP1_UDW, GEN8_RING_PDP_UDW(engine, 1), 0); - CTX_REG(regs, CTX_PDP1_LDW, GEN8_RING_PDP_LDW(engine, 1), 0); - CTX_REG(regs, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(engine, 0), 0); - CTX_REG(regs, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(engine, 0), 0); + CTX_REG(regs, CTX_PDP3_UDW, GEN8_RING_PDP_UDW(base, 3), 0); + CTX_REG(regs, CTX_PDP3_LDW, GEN8_RING_PDP_LDW(base, 3), 0); + CTX_REG(regs, CTX_PDP2_UDW, GEN8_RING_PDP_UDW(base, 2), 0); + CTX_REG(regs, CTX_PDP2_LDW, GEN8_RING_PDP_LDW(base, 2), 0); + CTX_REG(regs, CTX_PDP1_UDW, GEN8_RING_PDP_UDW(base, 1), 0); + CTX_REG(regs, CTX_PDP1_LDW, GEN8_RING_PDP_LDW(base, 1), 0); + CTX_REG(regs, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(base, 0), 0); + CTX_REG(regs, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(base, 0), 0); if (i915_vm_is_4lvl(&ppgtt->vm)) { /* 64b PPGTT (48bit canonical) -- cgit v1.2.3 From fdc4e9267f9b7bcfafb9d95940a8765c538fb507 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 Apr 2019 19:15:50 +0100 Subject: drm/i915: Make use of 'engine->uncore' The engine has a direct link to the intel_uncore mmio handler, so make use of it rather than going indirectly via &engine->i915->uncore. v2: Update gen11_lock_sfc() to use engine->uncore as well Signed-off-by: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Paulo Zanoni Reviewed-by: Paulo Zanoni Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20190405181550.7630-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_reset.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c index ddc403ee8855..d44dc8422e8c 100644 --- a/drivers/gpu/drm/i915/i915_reset.c +++ b/drivers/gpu/drm/i915/i915_reset.c @@ -331,11 +331,10 @@ static int gen6_reset_engines(struct drm_i915_private *i915, return gen6_hw_domain_reset(i915, hw_mask); } -static u32 gen11_lock_sfc(struct drm_i915_private *dev_priv, - struct intel_engine_cs *engine) +static u32 gen11_lock_sfc(struct intel_engine_cs *engine) { - struct intel_uncore *uncore = &dev_priv->uncore; - u8 vdbox_sfc_access = RUNTIME_INFO(dev_priv)->vdbox_sfc_access; + struct intel_uncore *uncore = engine->uncore; + u8 vdbox_sfc_access = RUNTIME_INFO(engine->i915)->vdbox_sfc_access; i915_reg_t sfc_forced_lock, sfc_forced_lock_ack; u32 sfc_forced_lock_bit, sfc_forced_lock_ack_bit; i915_reg_t sfc_usage; @@ -399,12 +398,13 @@ static u32 gen11_lock_sfc(struct drm_i915_private *dev_priv, return 0; } -static void gen11_unlock_sfc(struct drm_i915_private *dev_priv, - struct intel_engine_cs *engine) +static void gen11_unlock_sfc(struct intel_engine_cs *engine) { - u8 vdbox_sfc_access = RUNTIME_INFO(dev_priv)->vdbox_sfc_access; + struct intel_uncore *uncore = engine->uncore; + u8 vdbox_sfc_access = RUNTIME_INFO(engine->i915)->vdbox_sfc_access; i915_reg_t sfc_forced_lock; u32 sfc_forced_lock_bit; + u32 val; switch (engine->class) { case VIDEO_DECODE_CLASS: @@ -424,8 +424,9 @@ static void gen11_unlock_sfc(struct drm_i915_private *dev_priv, return; } - I915_WRITE_FW(sfc_forced_lock, - I915_READ_FW(sfc_forced_lock) & ~sfc_forced_lock_bit); + val = intel_uncore_read_fw(uncore, sfc_forced_lock); + val &= ~sfc_forced_lock_bit; + intel_uncore_write_fw(uncore, sfc_forced_lock, val); } static int gen11_reset_engines(struct drm_i915_private *i915, @@ -454,7 +455,7 @@ static int gen11_reset_engines(struct drm_i915_private *i915, for_each_engine_masked(engine, i915, engine_mask, tmp) { GEM_BUG_ON(engine->id >= ARRAY_SIZE(hw_engine_mask)); hw_mask |= hw_engine_mask[engine->id]; - hw_mask |= gen11_lock_sfc(i915, engine); + hw_mask |= gen11_lock_sfc(engine); } } @@ -462,17 +463,18 @@ static int gen11_reset_engines(struct drm_i915_private *i915, if (engine_mask != ALL_ENGINES) for_each_engine_masked(engine, i915, engine_mask, tmp) - gen11_unlock_sfc(i915, engine); + gen11_unlock_sfc(engine); return ret; } static int gen8_engine_reset_prepare(struct intel_engine_cs *engine) { - struct intel_uncore *uncore = &engine->i915->uncore; + struct intel_uncore *uncore = engine->uncore; int ret; - intel_uncore_write_fw(uncore, RING_RESET_CTL(engine->mmio_base), + intel_uncore_write_fw(uncore, + RING_RESET_CTL(engine->mmio_base), _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)); ret = __intel_wait_for_register_fw(uncore, @@ -647,7 +649,7 @@ static void reset_prepare_engine(struct intel_engine_cs *engine) * written to the powercontext is undefined and so we may lose * GPU state upon resume, i.e. fail to restart after a reset. */ - intel_uncore_forcewake_get(&engine->i915->uncore, FORCEWAKE_ALL); + intel_uncore_forcewake_get(engine->uncore, FORCEWAKE_ALL); engine->reset.prepare(engine); } @@ -719,7 +721,7 @@ static int gt_reset(struct drm_i915_private *i915, static void reset_finish_engine(struct intel_engine_cs *engine) { engine->reset.finish(engine); - intel_uncore_forcewake_put(&engine->i915->uncore, FORCEWAKE_ALL); + intel_uncore_forcewake_put(engine->uncore, FORCEWAKE_ALL); } struct i915_gpu_restart { -- cgit v1.2.3 From 95007efbe608fe888469b5c22d01c54c4d2b3bf1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 Apr 2019 21:24:19 +0100 Subject: drm/i915: Convert i915_reset.c over to using uncore mmio Currently i915_reset.c mixes calls to intel_uncore, pci and our old style I915_READ mmio interfaces. Cast aside the old implicit macros, and harmonise on using uncore throughout. add/remove: 1/1 grow/shrink: 0/4 up/down: 65/-207 (-142) Function old new delta rmw_register - 65 +65 gen8_reset_engines 945 942 -3 g4x_do_reset 407 376 -31 intel_gpu_reset 545 509 -36 clear_register 63 - -63 i915_clear_error_registers 461 387 -74 A little bit of pointer dancing elimination works wonders. v2: Roll up the helpers into intel_uncore for general use With the helpers gcc was a little more eager to inline: add/remove: 0/1 grow/shrink: 1/3 up/down: 99/-133 (-34) Function old new delta i915_clear_error_registers 461 560 +99 gen8_reset_engines 945 942 -3 g4x_do_reset 407 376 -31 intel_gpu_reset 545 509 -36 clear_register 63 - -63 Total: Before=1544400, After=1544366, chg -0.00% Win some, lose some, gcc is gcc. Signed-off-by: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Paulo Zanoni Reviewed-by: Paulo Zanoni Link: https://patchwork.freedesktop.org/patch/msgid/20190405202419.3093-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_reset.c | 122 +++++++++++++++++++++--------------- drivers/gpu/drm/i915/intel_uncore.h | 23 +++++-- 2 files changed, 89 insertions(+), 56 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c index d44dc8422e8c..68875ba43b8d 100644 --- a/drivers/gpu/drm/i915/i915_reset.c +++ b/drivers/gpu/drm/i915/i915_reset.c @@ -18,6 +18,26 @@ /* XXX How to handle concurrent GGTT updates using tiling registers? */ #define RESET_UNDER_STOP_MACHINE 0 +static void rmw_set(struct intel_uncore *uncore, i915_reg_t reg, u32 set) +{ + intel_uncore_rmw(uncore, reg, 0, set); +} + +static void rmw_clear(struct intel_uncore *uncore, i915_reg_t reg, u32 clr) +{ + intel_uncore_rmw(uncore, reg, clr, 0); +} + +static void rmw_set_fw(struct intel_uncore *uncore, i915_reg_t reg, u32 set) +{ + intel_uncore_rmw_fw(uncore, reg, 0, set); +} + +static void rmw_clear_fw(struct intel_uncore *uncore, i915_reg_t reg, u32 clr) +{ + intel_uncore_rmw_fw(uncore, reg, clr, 0); +} + static void engine_skip_context(struct i915_request *rq) { struct intel_engine_cs *engine = rq->engine; @@ -119,7 +139,7 @@ void i915_reset_request(struct i915_request *rq, bool guilty) static void gen3_stop_engine(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = engine->i915; + struct intel_uncore *uncore = engine->uncore; const u32 base = engine->mmio_base; GEM_TRACE("%s\n", engine->name); @@ -127,20 +147,23 @@ static void gen3_stop_engine(struct intel_engine_cs *engine) if (intel_engine_stop_cs(engine)) GEM_TRACE("%s: timed out on STOP_RING\n", engine->name); - I915_WRITE_FW(RING_HEAD(base), I915_READ_FW(RING_TAIL(base))); - POSTING_READ_FW(RING_HEAD(base)); /* paranoia */ + intel_uncore_write_fw(uncore, + RING_HEAD(base), + intel_uncore_read_fw(uncore, RING_TAIL(base))); + intel_uncore_posting_read_fw(uncore, RING_HEAD(base)); /* paranoia */ - I915_WRITE_FW(RING_HEAD(base), 0); - I915_WRITE_FW(RING_TAIL(base), 0); - POSTING_READ_FW(RING_TAIL(base)); + intel_uncore_write_fw(uncore, RING_HEAD(base), 0); + intel_uncore_write_fw(uncore, RING_TAIL(base), 0); + intel_uncore_posting_read_fw(uncore, RING_TAIL(base)); /* The ring must be empty before it is disabled */ - I915_WRITE_FW(RING_CTL(base), 0); + intel_uncore_write_fw(uncore, RING_CTL(base), 0); /* Check acts as a post */ - if (I915_READ_FW(RING_HEAD(base))) + if (intel_uncore_read_fw(uncore, RING_HEAD(base))) GEM_TRACE("%s: ring head [%x] not parked\n", - engine->name, I915_READ_FW(RING_HEAD(base))); + engine->name, + intel_uncore_read_fw(uncore, RING_HEAD(base))); } static void i915_stop_engines(struct drm_i915_private *i915, @@ -203,17 +226,17 @@ static int g33_do_reset(struct drm_i915_private *i915, return wait_for_atomic(g4x_reset_complete(pdev), 50); } -static int g4x_do_reset(struct drm_i915_private *dev_priv, +static int g4x_do_reset(struct drm_i915_private *i915, intel_engine_mask_t engine_mask, unsigned int retry) { - struct pci_dev *pdev = dev_priv->drm.pdev; + struct pci_dev *pdev = i915->drm.pdev; + struct intel_uncore *uncore = &i915->uncore; int ret; /* WaVcpClkGateDisableForMediaReset:ctg,elk */ - I915_WRITE_FW(VDECCLK_GATE_D, - I915_READ(VDECCLK_GATE_D) | VCP_UNIT_CLOCK_GATE_DISABLE); - POSTING_READ_FW(VDECCLK_GATE_D); + rmw_set_fw(uncore, VDECCLK_GATE_D, VCP_UNIT_CLOCK_GATE_DISABLE); + intel_uncore_posting_read_fw(uncore, VDECCLK_GATE_D); pci_write_config_byte(pdev, I915_GDRST, GRDOM_MEDIA | GRDOM_RESET_ENABLE); @@ -234,18 +257,17 @@ static int g4x_do_reset(struct drm_i915_private *dev_priv, out: pci_write_config_byte(pdev, I915_GDRST, 0); - I915_WRITE_FW(VDECCLK_GATE_D, - I915_READ(VDECCLK_GATE_D) & ~VCP_UNIT_CLOCK_GATE_DISABLE); - POSTING_READ_FW(VDECCLK_GATE_D); + rmw_clear_fw(uncore, VDECCLK_GATE_D, VCP_UNIT_CLOCK_GATE_DISABLE); + intel_uncore_posting_read_fw(uncore, VDECCLK_GATE_D); return ret; } -static int ironlake_do_reset(struct drm_i915_private *dev_priv, +static int ironlake_do_reset(struct drm_i915_private *i915, intel_engine_mask_t engine_mask, unsigned int retry) { - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_uncore *uncore = &i915->uncore; int ret; intel_uncore_write_fw(uncore, ILK_GDSR, @@ -277,10 +299,10 @@ out: } /* Reset the hardware domains (GENX_GRDOM_*) specified by mask */ -static int gen6_hw_domain_reset(struct drm_i915_private *dev_priv, +static int gen6_hw_domain_reset(struct drm_i915_private *i915, u32 hw_domain_mask) { - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_uncore *uncore = &i915->uncore; int err; /* @@ -381,7 +403,7 @@ static u32 gen11_lock_sfc(struct intel_engine_cs *engine) * ends up being locked to the engine we want to reset, we have to reset * it as well (we will unlock it once the reset sequence is completed). */ - intel_uncore_rmw_or_fw(uncore, sfc_forced_lock, sfc_forced_lock_bit); + rmw_set_fw(uncore, sfc_forced_lock, sfc_forced_lock_bit); if (__intel_wait_for_register_fw(uncore, sfc_forced_lock_ack, @@ -404,7 +426,6 @@ static void gen11_unlock_sfc(struct intel_engine_cs *engine) u8 vdbox_sfc_access = RUNTIME_INFO(engine->i915)->vdbox_sfc_access; i915_reg_t sfc_forced_lock; u32 sfc_forced_lock_bit; - u32 val; switch (engine->class) { case VIDEO_DECODE_CLASS: @@ -424,9 +445,7 @@ static void gen11_unlock_sfc(struct intel_engine_cs *engine) return; } - val = intel_uncore_read_fw(uncore, sfc_forced_lock); - val &= ~sfc_forced_lock_bit; - intel_uncore_write_fw(uncore, sfc_forced_lock, val); + rmw_clear_fw(uncore, sfc_forced_lock, sfc_forced_lock_bit); } static int gen11_reset_engines(struct drm_i915_private *i915, @@ -491,10 +510,9 @@ static int gen8_engine_reset_prepare(struct intel_engine_cs *engine) static void gen8_engine_reset_cancel(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = engine->i915; - - I915_WRITE_FW(RING_RESET_CTL(engine->mmio_base), - _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)); + intel_uncore_write_fw(engine->uncore, + RING_RESET_CTL(engine->mmio_base), + _MASKED_BIT_DISABLE(RESET_CTL_REQUEST_RESET)); } static int gen8_reset_engines(struct drm_i915_private *i915, @@ -1178,49 +1196,49 @@ static void i915_reset_device(struct drm_i915_private *i915, kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event); } -static void clear_register(struct drm_i915_private *dev_priv, i915_reg_t reg) +static void clear_register(struct intel_uncore *uncore, i915_reg_t reg) { - I915_WRITE(reg, I915_READ(reg)); + intel_uncore_rmw(uncore, reg, 0, 0); } -void i915_clear_error_registers(struct drm_i915_private *dev_priv) +void i915_clear_error_registers(struct drm_i915_private *i915) { + struct intel_uncore *uncore = &i915->uncore; u32 eir; - if (!IS_GEN(dev_priv, 2)) - clear_register(dev_priv, PGTBL_ER); + if (!IS_GEN(i915, 2)) + clear_register(uncore, PGTBL_ER); - if (INTEL_GEN(dev_priv) < 4) - clear_register(dev_priv, IPEIR(RENDER_RING_BASE)); + if (INTEL_GEN(i915) < 4) + clear_register(uncore, IPEIR(RENDER_RING_BASE)); else - clear_register(dev_priv, IPEIR_I965); + clear_register(uncore, IPEIR_I965); - clear_register(dev_priv, EIR); - eir = I915_READ(EIR); + clear_register(uncore, EIR); + eir = intel_uncore_read(uncore, EIR); if (eir) { /* * some errors might have become stuck, * mask them. */ DRM_DEBUG_DRIVER("EIR stuck: 0x%08x, masking\n", eir); - I915_WRITE(EMR, I915_READ(EMR) | eir); - I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT); + rmw_set(uncore, EMR, eir); + intel_uncore_write(uncore, IIR, I915_MASTER_ERROR_INTERRUPT); } - if (INTEL_GEN(dev_priv) >= 8) { - I915_WRITE(GEN8_RING_FAULT_REG, - I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID); - POSTING_READ(GEN8_RING_FAULT_REG); - } else if (INTEL_GEN(dev_priv) >= 6) { + if (INTEL_GEN(i915) >= 8) { + rmw_clear(uncore, GEN8_RING_FAULT_REG, RING_FAULT_VALID); + intel_uncore_posting_read(uncore, GEN8_RING_FAULT_REG); + } else if (INTEL_GEN(i915) >= 6) { struct intel_engine_cs *engine; enum intel_engine_id id; - for_each_engine(engine, dev_priv, id) { - I915_WRITE(RING_FAULT_REG(engine), - I915_READ(RING_FAULT_REG(engine)) & - ~RING_FAULT_VALID); + for_each_engine(engine, i915, id) { + rmw_clear(uncore, + RING_FAULT_REG(engine), RING_FAULT_VALID); + intel_uncore_posting_read(uncore, + RING_FAULT_REG(engine)); } - POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS0])); } } diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index a64d3dc0db4d..d6af3de70121 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -369,11 +369,26 @@ intel_uncore_read64_2x32(struct intel_uncore *uncore, #define intel_uncore_write64_fw(...) __raw_uncore_write64(__VA_ARGS__) #define intel_uncore_posting_read_fw(...) ((void)intel_uncore_read_fw(__VA_ARGS__)) -static inline void intel_uncore_rmw_or_fw(struct intel_uncore *uncore, - i915_reg_t reg, u32 or_val) +static inline void intel_uncore_rmw(struct intel_uncore *uncore, + i915_reg_t reg, u32 clear, u32 set) { - intel_uncore_write_fw(uncore, reg, - intel_uncore_read_fw(uncore, reg) | or_val); + u32 val; + + val = intel_uncore_read(uncore, reg); + val &= ~clear; + val |= set; + intel_uncore_write(uncore, reg, val); +} + +static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore, + i915_reg_t reg, u32 clear, u32 set) +{ + u32 val; + + val = intel_uncore_read_fw(uncore, reg); + val &= ~clear; + val |= set; + intel_uncore_write_fw(uncore, reg, val); } #define raw_reg_read(base, reg) \ -- cgit v1.2.3 From 141f3767e7b8f32ce7210ef4b716d41bae72a54d Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Sat, 6 Apr 2019 11:40:34 +0100 Subject: drm/i915: Mark GEM wedged right after marking device unplugged As soon as a device is considered unplugged, not only prevent pending users from accessing the device structures but also cancel all their pending requests so all consumed resources can be cleaned up as soon as possible. Suggested-by: Chris Wilson Signed-off-by: Janusz Krzysztofik Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190406104034.31380-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 7 +++++++ drivers/gpu/drm/i915/i915_drv.h | 1 + 2 files changed, 8 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0bbf3f5db5fc..c695b3a4deae 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1907,6 +1907,13 @@ void i915_driver_unload(struct drm_device *dev) i915_driver_unregister(dev_priv); + /* + * After unregistering the device to prevent any new users, cancel + * all in-flight requests so that we can quickly unbind the active + * resources. + */ + i915_gem_set_wedged(dev_priv); + /* Flush any external code that still may be under the RCU lock */ synchronize_rcu(); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4af815c3c02d..b9bedfa9652d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2917,6 +2917,7 @@ static inline void i915_gem_drain_workqueue(struct drm_i915_private *i915) int pass = 2; do { rcu_barrier(); + i915_gem_drain_freed_objects(i915); drain_workqueue(i915->wq); } while (--pass); } -- cgit v1.2.3 From 513a4c5589b4a07d3cc1c42329ff3e93505613e5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 6 Apr 2019 09:03:41 +0100 Subject: drm/i915: Track the temporary wakerefs used for hsw_get_pipe_config Haswell+ require many power wells to probe the current HW display state. Under the wakeref tracking scheme, we want each owner to store and release the wakeref they use, so we can identify callers that have leaked their wakeref. For hsw_get_pipe_config, this means we have to keep the array of all wakerefs as it current acquires its power wells piecemeal and releases them en masse. By tracking these wakerefs, we should be able to eliminate a lot of noise from the runtime-pm debug logs. Signed-off-by: Chris Wilson Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20190406080341.2654-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_display.c | 46 ++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7ecfb7d98839..d765769d6bab 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9754,7 +9754,8 @@ static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, static bool hsw_get_transcoder_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, - u64 *power_domain_mask) + u64 *power_domain_mask, + intel_wakeref_t *wakerefs) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); @@ -9762,6 +9763,7 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, unsigned long panel_transcoder_mask = 0; unsigned long enabled_panel_transcoders = 0; enum transcoder panel_transcoder; + intel_wakeref_t wf; u32 tmp; if (INTEL_GEN(dev_priv) >= 11) @@ -9827,10 +9829,13 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, enabled_panel_transcoders != BIT(TRANSCODER_EDP)); power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) + WARN_ON(*power_domain_mask & BIT_ULL(power_domain)); + + wf = intel_display_power_get_if_enabled(dev_priv, power_domain); + if (!wf) return false; - WARN_ON(*power_domain_mask & BIT_ULL(power_domain)); + wakerefs[power_domain] = wf; *power_domain_mask |= BIT_ULL(power_domain); tmp = I915_READ(PIPECONF(pipe_config->cpu_transcoder)); @@ -9840,13 +9845,15 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config, - u64 *power_domain_mask) + u64 *power_domain_mask, + intel_wakeref_t *wakerefs) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); enum intel_display_power_domain power_domain; - enum port port; enum transcoder cpu_transcoder; + intel_wakeref_t wf; + enum port port; u32 tmp; for_each_port_masked(port, BIT(PORT_A) | BIT(PORT_C)) { @@ -9856,10 +9863,13 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, cpu_transcoder = TRANSCODER_DSI_C; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) + WARN_ON(*power_domain_mask & BIT_ULL(power_domain)); + + wf = intel_display_power_get_if_enabled(dev_priv, power_domain); + if (!wf) continue; - WARN_ON(*power_domain_mask & BIT_ULL(power_domain)); + wakerefs[power_domain] = wf; *power_domain_mask |= BIT_ULL(power_domain); /* @@ -9938,6 +9948,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, struct intel_crtc_state *pipe_config) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + intel_wakeref_t wakerefs[POWER_DOMAIN_NUM], wf; enum intel_display_power_domain power_domain; u64 power_domain_mask; bool active; @@ -9945,16 +9956,21 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, intel_crtc_init_scalers(crtc, pipe_config); power_domain = POWER_DOMAIN_PIPE(crtc->pipe); - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) + wf = intel_display_power_get_if_enabled(dev_priv, power_domain); + if (!wf) return false; + + wakerefs[power_domain] = wf; power_domain_mask = BIT_ULL(power_domain); pipe_config->shared_dpll = NULL; - active = hsw_get_transcoder_state(crtc, pipe_config, &power_domain_mask); + active = hsw_get_transcoder_state(crtc, pipe_config, + &power_domain_mask, wakerefs); if (IS_GEN9_LP(dev_priv) && - bxt_get_dsi_transcoder_state(crtc, pipe_config, &power_domain_mask)) { + bxt_get_dsi_transcoder_state(crtc, pipe_config, + &power_domain_mask, wakerefs)) { WARN_ON(active); active = true; } @@ -9988,8 +10004,11 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, } power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); - if (intel_display_power_get_if_enabled(dev_priv, power_domain)) { - WARN_ON(power_domain_mask & BIT_ULL(power_domain)); + WARN_ON(power_domain_mask & BIT_ULL(power_domain)); + + wf = intel_display_power_get_if_enabled(dev_priv, power_domain); + if (wf) { + wakerefs[power_domain] = wf; power_domain_mask |= BIT_ULL(power_domain); if (INTEL_GEN(dev_priv) >= 9) @@ -10021,7 +10040,8 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, out: for_each_power_domain(power_domain, power_domain_mask) - intel_display_power_put_unchecked(dev_priv, power_domain); + intel_display_power_put(dev_priv, + power_domain, wakerefs[power_domain]); return active; } -- cgit v1.2.3 From 196a66275520ffc27513c56ecc06a2d9450fd12f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 4 Apr 2019 08:14:25 +0100 Subject: drm/i915/gvt: Annotate iomem usage Fix the sparse warning for blithely using iomem with normal memcpy: drivers/gpu/drm/i915/gvt/kvmgt.c:916:21: warning: incorrect type in assignment (different address spaces) drivers/gpu/drm/i915/gvt/kvmgt.c:916:21: expected void *aperture_va drivers/gpu/drm/i915/gvt/kvmgt.c:916:21: got void [noderef] * drivers/gpu/drm/i915/gvt/kvmgt.c:927:26: warning: incorrect type in argument 1 (different address spaces) drivers/gpu/drm/i915/gvt/kvmgt.c:927:26: expected void [noderef] *vaddr drivers/gpu/drm/i915/gvt/kvmgt.c:927:26: got void *aperture_va Fixes: d480b28a41a6 ("drm/i915/gvt: Fix aperture read/write emulation when enable x-no-mmap=on") Reviewed-by: Zhenyu Wang Signed-off-by: Chris Wilson Cc: Zhenyu Wang Cc: Changbin Du Cc: Zhi Wang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/kvmgt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index d5fcc447d22f..a68addf95c23 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -905,7 +905,7 @@ static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, u64 off) static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off, void *buf, unsigned long count, bool is_write) { - void *aperture_va; + void __iomem *aperture_va; if (!intel_vgpu_in_aperture(vgpu, off) || !intel_vgpu_in_aperture(vgpu, off + count)) { @@ -920,9 +920,9 @@ static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off, return -EIO; if (is_write) - memcpy(aperture_va + offset_in_page(off), buf, count); + memcpy_toio(aperture_va + offset_in_page(off), buf, count); else - memcpy(buf, aperture_va + offset_in_page(off), count); + memcpy_fromio(buf, aperture_va + offset_in_page(off), count); io_mapping_unmap(aperture_va); -- cgit v1.2.3 From 968a85b19d0a79dd8ed85f39e23eacd34b503e72 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 4 Apr 2019 08:30:56 +0100 Subject: drm/i915/gvt: Prevent use-after-free in ppgtt_free_all_spt() ppgtt_free_all_spt() iterates the radixtree as it is deleting it, forgoing all protection against the leaves being freed in the process (leaving the iter pointing into the void). A minimal fix seems to be to use the available post_shadow_list to decompose the tree into a list prior to destroying the radixtree. Alerted by the sparse warnings: drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in assignment (different address spaces) drivers/gpu/drm/i915/gvt/gtt.c:757:9: expected void **slot drivers/gpu/drm/i915/gvt/gtt.c:757:9: got void [noderef] ** drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in assignment (different address spaces) drivers/gpu/drm/i915/gvt/gtt.c:757:9: expected void **slot drivers/gpu/drm/i915/gvt/gtt.c:757:9: got void [noderef] ** drivers/gpu/drm/i915/gvt/gtt.c:758:45: warning: incorrect type in argument 1 (different address spaces) drivers/gpu/drm/i915/gvt/gtt.c:758:45: expected void [noderef] **slot drivers/gpu/drm/i915/gvt/gtt.c:758:45: got void **slot drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in argument 1 (different address spaces) drivers/gpu/drm/i915/gvt/gtt.c:757:9: expected void [noderef] **slot drivers/gpu/drm/i915/gvt/gtt.c:757:9: got void **slot drivers/gpu/drm/i915/gvt/gtt.c:757:9: warning: incorrect type in assignment (different address spaces) drivers/gpu/drm/i915/gvt/gtt.c:757:9: expected void **slot drivers/gpu/drm/i915/gvt/gtt.c:757:9: got void [noderef] ** This would also have been loudly warning if run through CI for the invalid RCU dereferences. Fixes: b6c126a39345 ("drm/i915/gvt: Manage shadow pages with radix tree") Reviewed-by: Zhenyu Wang Signed-off-by: Chris Wilson Cc: Changbin Du Cc: Zhenyu Wang Cc: Zhi Wang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/gtt.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index cf133ef03873..9814773882ec 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -750,14 +750,20 @@ static void ppgtt_free_spt(struct intel_vgpu_ppgtt_spt *spt) static void ppgtt_free_all_spt(struct intel_vgpu *vgpu) { - struct intel_vgpu_ppgtt_spt *spt; + struct intel_vgpu_ppgtt_spt *spt, *spn; struct radix_tree_iter iter; - void **slot; + LIST_HEAD(all_spt); + void __rcu **slot; + rcu_read_lock(); radix_tree_for_each_slot(slot, &vgpu->gtt.spt_tree, &iter, 0) { spt = radix_tree_deref_slot(slot); - ppgtt_free_spt(spt); + list_move(&spt->post_shadow_list, &all_spt); } + rcu_read_unlock(); + + list_for_each_entry_safe(spt, spn, &all_spt, post_shadow_list) + ppgtt_free_spt(spt); } static int ppgtt_handle_guest_write_page_table_bytes( -- cgit v1.2.3 From 499653501baf27d26e73cb5ce744869df3400509 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 5 Apr 2019 17:13:49 +0300 Subject: drm/i915: Fix pipe_bpp readout for BXT/GLK DSI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only bpc information in pipe registers for BXT/GLK DSI is the PIPEMISC dither bpc. Let's try to use that to read out pipe_bpp on these platforms. However, I'm not sure if this will be correctly populated by the GOP since bspec suggests it's only needed if dithering is actually enabled. If not I guess we'll have to go one step further and extract pipe_bpp from the DSI pixel format when dithering is disabled. Cc: Hans de Goede Fixes: ca0b04db14a5 ("drm/i915/dsi: Fix pipe_bpp for handling for 6 bpc pixel-formats") References: https://bugs.freedesktop.org/show_bug.cgi?id=109516 Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190405141349.11950-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/vlv_dsi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index 0a950c976bbb..6898541403a2 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -256,6 +256,28 @@ static void band_gap_reset(struct drm_i915_private *dev_priv) mutex_unlock(&dev_priv->sb_lock); } +static int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + u32 tmp; + + tmp = I915_READ(PIPEMISC(crtc->pipe)); + + switch (tmp & PIPEMISC_DITHER_BPC_MASK) { + case PIPEMISC_DITHER_6_BPC: + return 18; + case PIPEMISC_DITHER_8_BPC: + return 24; + case PIPEMISC_DITHER_10_BPC: + return 30; + case PIPEMISC_DITHER_12_BPC: + return 36; + default: + MISSING_CASE(tmp); + return 0; + } +} + static int intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -1082,6 +1104,8 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, bpp = mipi_dsi_pixel_format_to_bpp( pixel_format_from_register_bits(fmt)); + pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc); + /* Enable Frame time stamo based scanline reporting */ adjusted_mode->private_flags |= I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; -- cgit v1.2.3 From 9b39b013037fbfa8d4b999345d9e904d8a336fc2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 5 Apr 2019 13:17:13 +1000 Subject: drm/udl: add a release method and delay modeset teardown If we unplug a udl device, the usb callback with deinit the mode_config struct, however userspace will still have an open file descriptor and a framebuffer on that device. When userspace closes the fd, we'll oops because it'll try and look stuff up in the object idr which we've destroyed. This punts destroying the mode objects until release time instead. Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190405031715.5959-2-airlied@gmail.com --- drivers/gpu/drm/udl/udl_drv.c | 1 + drivers/gpu/drm/udl/udl_drv.h | 1 + drivers/gpu/drm/udl/udl_main.c | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 22cd2d13e272..ff47f890e6ad 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -52,6 +52,7 @@ static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, .load = udl_driver_load, .unload = udl_driver_unload, + .release = udl_driver_release, /* gem hooks */ .gem_free_object_unlocked = udl_gem_free_object, diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index e9e9b1ff678e..4ae67d882eae 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -104,6 +104,7 @@ void udl_urb_completion(struct urb *urb); int udl_driver_load(struct drm_device *dev, unsigned long flags); void udl_driver_unload(struct drm_device *dev); +void udl_driver_release(struct drm_device *dev); int udl_fbdev_init(struct drm_device *dev); void udl_fbdev_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 9086d0d1b880..1f8ef34ade24 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -379,6 +379,12 @@ void udl_driver_unload(struct drm_device *dev) udl_free_urb_list(dev); udl_fbdev_cleanup(dev); - udl_modeset_cleanup(dev); kfree(udl); } + +void udl_driver_release(struct drm_device *dev) +{ + udl_modeset_cleanup(dev); + drm_dev_fini(dev); + kfree(dev); +} -- cgit v1.2.3 From e1ef734eaec54b3162c61fcba1b49ba014a25ee5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:02 +0300 Subject: drm/i915: make intel_frontbuffer.h self-contained This will be helpful in the follow-up work. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/9a19d43987006e4249b335f3d843da43c998376c.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_drv.h | 11 ++--------- drivers/gpu/drm/i915/intel_frontbuffer.h | 10 ++++++++++ 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index f7809b5c21ad..243a64fb4cc7 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -10,6 +10,7 @@ header_test := \ i915_timeline_types.h \ intel_context_types.h \ intel_engine_types.h \ + intel_frontbuffer.h \ intel_workarounds_types.h quiet_cmd_header_test = HDRTEST $@ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b9bedfa9652d..63eca3061d10 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -66,13 +66,14 @@ #include "intel_device_info.h" #include "intel_display.h" #include "intel_dpll_mgr.h" +#include "intel_frontbuffer.h" #include "intel_lrc.h" #include "intel_opregion.h" #include "intel_ringbuffer.h" +#include "intel_uc.h" #include "intel_uncore.h" #include "intel_wopcm.h" #include "intel_workarounds.h" -#include "intel_uc.h" #include "i915_gem.h" #include "i915_gem_context.h" @@ -375,14 +376,6 @@ enum i915_cache_level { #define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */ -enum fb_op_origin { - ORIGIN_GTT, - ORIGIN_CPU, - ORIGIN_CS, - ORIGIN_FLIP, - ORIGIN_DIRTYFB, -}; - struct intel_fbc { /* This is always the inner lock when overlapping with struct_mutex and * it's the outer lock when overlapping with stolen_lock. */ diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.h b/drivers/gpu/drm/i915/intel_frontbuffer.h index 63cd9a753a72..d5894666f658 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/intel_frontbuffer.h @@ -24,9 +24,19 @@ #ifndef __INTEL_FRONTBUFFER_H__ #define __INTEL_FRONTBUFFER_H__ +#include "i915_gem_object.h" + struct drm_i915_private; struct drm_i915_gem_object; +enum fb_op_origin { + ORIGIN_GTT, + ORIGIN_CPU, + ORIGIN_CS, + ORIGIN_FLIP, + ORIGIN_DIRTYFB, +}; + void intel_frontbuffer_flip_prepare(struct drm_i915_private *dev_priv, unsigned frontbuffer_bits); void intel_frontbuffer_flip_complete(struct drm_i915_private *dev_priv, -- cgit v1.2.3 From 331c201a07261120cceb50ee71736bdc3dd07368 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:03 +0300 Subject: drm/i915: extract intel_audio.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e0284c4d62effa5bad72ce034206c26e3aa02884.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_drv.c | 5 +++-- drivers/gpu/drm/i915/intel_audio.c | 12 +++++++----- drivers/gpu/drm/i915/intel_audio.h | 24 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ddi.c | 2 ++ drivers/gpu/drm/i915/intel_dp.c | 11 +++++++---- drivers/gpu/drm/i915/intel_dp_mst.c | 6 ++++-- drivers/gpu/drm/i915/intel_drv.h | 13 ------------- drivers/gpu/drm/i915/intel_hdmi.c | 9 ++++++--- 9 files changed, 54 insertions(+), 29 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_audio.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 243a64fb4cc7..09bba7c9376c 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -8,6 +8,7 @@ header_test := \ i915_priolist_types.h \ i915_scheduler_types.h \ i915_timeline_types.h \ + intel_audio.h \ intel_context_types.h \ intel_engine_types.h \ intel_frontbuffer.h \ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c695b3a4deae..24f915d95d8b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -48,11 +48,12 @@ #include #include "i915_drv.h" -#include "i915_trace.h" #include "i915_pmu.h" -#include "i915_reset.h" #include "i915_query.h" +#include "i915_reset.h" +#include "i915_trace.h" #include "i915_vgpu.h" +#include "intel_audio.h" #include "intel_drv.h" #include "intel_uc.h" #include "intel_workarounds.h" diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c index 20324b0d34c7..bca4cc025d3d 100644 --- a/drivers/gpu/drm/i915/intel_audio.c +++ b/drivers/gpu/drm/i915/intel_audio.c @@ -21,14 +21,16 @@ * DEALINGS IN THE SOFTWARE. */ -#include #include +#include + +#include #include #include -#include "intel_drv.h" -#include #include "i915_drv.h" +#include "intel_audio.h" +#include "intel_drv.h" /** * DOC: High Definition Audio over HDMI and Display Port @@ -1045,7 +1047,7 @@ static const struct component_ops i915_audio_component_bind_ops = { * We ignore any error during registration and continue with reduced * functionality (i.e. without HDMI audio). */ -void i915_audio_component_init(struct drm_i915_private *dev_priv) +static void i915_audio_component_init(struct drm_i915_private *dev_priv) { int ret; @@ -1068,7 +1070,7 @@ void i915_audio_component_init(struct drm_i915_private *dev_priv) * Deregisters the audio component, breaking any existing binding to the * corresponding snd_hda_intel driver's master component. */ -void i915_audio_component_cleanup(struct drm_i915_private *dev_priv) +static void i915_audio_component_cleanup(struct drm_i915_private *dev_priv) { if (!dev_priv->audio_component_registered) return; diff --git a/drivers/gpu/drm/i915/intel_audio.h b/drivers/gpu/drm/i915/intel_audio.h new file mode 100644 index 000000000000..a3657c7a7ba2 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_audio.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_AUDIO_H__ +#define __INTEL_AUDIO_H__ + +struct drm_connector_state; +struct drm_i915_private; +struct intel_crtc_state; +struct intel_encoder; + +void intel_init_audio_hooks(struct drm_i915_private *dev_priv); +void intel_audio_codec_enable(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_audio_codec_disable(struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state); +void intel_audio_init(struct drm_i915_private *dev_priv); +void intel_audio_deinit(struct drm_i915_private *dev_priv); + +#endif /* __INTEL_AUDIO_H__ */ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3f1e491bd0c0..46a6adea815a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -26,7 +26,9 @@ */ #include + #include "i915_drv.h" +#include "intel_audio.h" #include "intel_drv.h" #include "intel_dsi.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 72c49070ed14..573cb04e2a56 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -25,22 +25,25 @@ * */ -#include -#include #include -#include +#include #include #include +#include +#include #include + #include #include #include #include #include #include -#include "intel_drv.h" #include + #include "i915_drv.h" +#include "intel_audio.h" +#include "intel_drv.h" #define DP_DPRX_ESI_LEN 14 diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 19d81cef2ab6..360e43b25fa5 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -23,12 +23,14 @@ * */ -#include "i915_drv.h" -#include "intel_drv.h" #include #include #include +#include "i915_drv.h" +#include "intel_audio.h" +#include "intel_drv.h" + static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 64544613920b..5dc434d74ada 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1669,19 +1669,6 @@ int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, int color_plane, unsigned int height); -/* intel_audio.c */ -void intel_init_audio_hooks(struct drm_i915_private *dev_priv); -void intel_audio_codec_enable(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_audio_codec_disable(struct intel_encoder *encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state); -void i915_audio_component_init(struct drm_i915_private *dev_priv); -void i915_audio_component_cleanup(struct drm_i915_private *dev_priv); -void intel_audio_init(struct drm_i915_private *dev_priv); -void intel_audio_deinit(struct drm_i915_private *dev_priv); - /* intel_cdclk.c */ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); void skl_init_cdclk(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 26767785f14a..1c76e20f9ebc 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -26,19 +26,22 @@ * Jesse Barnes */ -#include -#include #include #include +#include +#include + #include #include #include #include #include -#include "intel_drv.h" #include #include + #include "i915_drv.h" +#include "intel_audio.h" +#include "intel_drv.h" static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) { -- cgit v1.2.3 From d2ee2e8afeeab62a7049b02d57fd7a90eac48ada Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:04 +0300 Subject: drm/i915: extract intel_crt.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/19c39bfcfb82f50c77382e8dea4fe1ad6cd043ed.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_crt.c | 5 ++++- drivers/gpu/drm/i915/intel_crt.h | 21 +++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 11 ++--------- drivers/gpu/drm/i915/intel_drv.h | 6 ------ drivers/gpu/drm/i915/intel_runtime_pm.c | 1 + 6 files changed, 29 insertions(+), 16 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_crt.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 09bba7c9376c..fd0f33ea896d 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -10,6 +10,7 @@ header_test := \ i915_timeline_types.h \ intel_audio.h \ intel_context_types.h \ + intel_crt.h \ intel_engine_types.h \ intel_frontbuffer.h \ intel_workarounds_types.h diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 50530e49982c..a14afbe51b08 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -27,13 +27,16 @@ #include #include #include + #include #include #include #include -#include "intel_drv.h" #include + #include "i915_drv.h" +#include "intel_crt.h" +#include "intel_drv.h" /* Here's the desired hotplug mode */ #define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ diff --git a/drivers/gpu/drm/i915/intel_crt.h b/drivers/gpu/drm/i915/intel_crt.h new file mode 100644 index 000000000000..1b3fba359efc --- /dev/null +++ b/drivers/gpu/drm/i915/intel_crt.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_CRT_H__ +#define __INTEL_CRT_H__ + +#include "i915_reg.h" + +enum pipe; +struct drm_encoder; +struct drm_i915_private; +struct drm_i915_private; + +bool intel_crt_port_enabled(struct drm_i915_private *dev_priv, + i915_reg_t adpa_reg, enum pipe *pipe); +void intel_crt_init(struct drm_i915_private *dev_priv); +void intel_crt_reset(struct drm_encoder *encoder); + +#endif /* __INTEL_CRT_H__ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d765769d6bab..d601cc9fc3da 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -46,20 +46,13 @@ #include "i915_drv.h" #include "i915_gem_clflush.h" +#include "i915_reset.h" #include "i915_trace.h" +#include "intel_crt.h" #include "intel_drv.h" #include "intel_dsi.h" #include "intel_frontbuffer.h" -#include "intel_drv.h" -#include "intel_dsi.h" -#include "intel_frontbuffer.h" - -#include "i915_drv.h" -#include "i915_gem_clflush.h" -#include "i915_reset.h" -#include "i915_trace.h" - /* Primary plane formats for gen <= 3 */ static const u32 i8xx_primary_formats[] = { DRM_FORMAT_C8, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5dc434d74ada..847da5b24548 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1627,12 +1627,6 @@ void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv); void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv); void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv); -/* intel_crt.c */ -bool intel_crt_port_enabled(struct drm_i915_private *dev_priv, - i915_reg_t adpa_reg, enum pipe *pipe); -void intel_crt_init(struct drm_i915_private *dev_priv); -void intel_crt_reset(struct drm_encoder *encoder); - /* intel_ddi.c */ void intel_ddi_fdi_post_disable(struct intel_encoder *intel_encoder, const struct intel_crtc_state *old_crtc_state, diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 40ddfbb97acb..a9931081462b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -32,6 +32,7 @@ #include #include "i915_drv.h" +#include "intel_crt.h" #include "intel_drv.h" /** -- cgit v1.2.3 From fdc24cf30897d8ec96fe5a69fe4ac6c25b23bd8b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:05 +0300 Subject: drm/i915: extract intel_ddi.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/61d159117475a48a5db7bd7d652c198d4fa08d7b.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/icl_dsi.c | 4 ++- drivers/gpu/drm/i915/intel_crt.c | 1 + drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_ddi.h | 53 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_dp_mst.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 38 ++-------------------- drivers/gpu/drm/i915/intel_hdmi.c | 1 + 10 files changed, 65 insertions(+), 37 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_ddi.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index fd0f33ea896d..d9a6089f0de5 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -11,6 +11,7 @@ header_test := \ intel_audio.h \ intel_context_types.h \ intel_crt.h \ + intel_ddi.h \ intel_engine_types.h \ intel_frontbuffer.h \ intel_workarounds_types.h diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index b67ffaa283dc..64beb141c1ec 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -25,8 +25,10 @@ * Jani Nikula */ -#include #include +#include + +#include "intel_ddi.h" #include "intel_dsi.h" static inline int header_credits_available(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index a14afbe51b08..d649dae3cc70 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -36,6 +36,7 @@ #include "i915_drv.h" #include "intel_crt.h" +#include "intel_ddi.h" #include "intel_drv.h" /* Here's the desired hotplug mode */ diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 46a6adea815a..12135ffcff19 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -29,6 +29,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_ddi.h" #include "intel_drv.h" #include "intel_dsi.h" diff --git a/drivers/gpu/drm/i915/intel_ddi.h b/drivers/gpu/drm/i915/intel_ddi.h new file mode 100644 index 000000000000..9cf69175942e --- /dev/null +++ b/drivers/gpu/drm/i915/intel_ddi.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_DDI_H__ +#define __INTEL_DDI_H__ + +#include + +#include "intel_display.h" + +struct drm_connector_state; +struct drm_i915_private; +struct intel_connector; +struct intel_crtc; +struct intel_crtc_state; +struct intel_dp; +struct intel_dpll_hw_state; +struct intel_encoder; + +void intel_ddi_fdi_post_disable(struct intel_encoder *intel_encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state); +void hsw_fdi_link_train(struct intel_crtc *crtc, + const struct intel_crtc_state *crtc_state); +void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); +bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); +void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); +void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state); +void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state); +void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state); +void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state); +void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp); +bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector); +void intel_ddi_get_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config); +void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, + bool state); +void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, + struct intel_crtc_state *crtc_state); +u32 bxt_signal_levels(struct intel_dp *intel_dp); +u32 ddi_signal_levels(struct intel_dp *intel_dp); +u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder); +u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder, + u8 voltage_swing); +int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, + bool enable); +void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); +int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, + struct intel_dpll_hw_state *state); + +#endif /* __INTEL_DDI_H__ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d601cc9fc3da..0d0c363a5077 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -49,6 +49,7 @@ #include "i915_reset.h" #include "i915_trace.h" #include "intel_crt.h" +#include "intel_ddi.h" #include "intel_drv.h" #include "intel_dsi.h" #include "intel_frontbuffer.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 573cb04e2a56..ca3ed4ae253c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -43,6 +43,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_ddi.h" #include "intel_drv.h" #define DP_DPRX_ESI_LEN 14 diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 360e43b25fa5..62c240be8cc9 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -29,6 +29,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_ddi.h" #include "intel_drv.h" static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 847da5b24548..b61ec71e971e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1627,42 +1627,6 @@ void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv); void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv); void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv); -/* intel_ddi.c */ -void intel_ddi_fdi_post_disable(struct intel_encoder *intel_encoder, - const struct intel_crtc_state *old_crtc_state, - const struct drm_connector_state *old_conn_state); -void hsw_fdi_link_train(struct intel_crtc *crtc, - const struct intel_crtc_state *crtc_state); -void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port); -bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe); -void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state); -void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state); -void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state); -void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state); -void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state); -void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp); -bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector); -void intel_ddi_get_config(struct intel_encoder *encoder, - struct intel_crtc_state *pipe_config); - -void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, - bool state); -void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv, - struct intel_crtc_state *crtc_state); -u32 bxt_signal_levels(struct intel_dp *intel_dp); -u32 ddi_signal_levels(struct intel_dp *intel_dp); -u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder); -u8 intel_ddi_dp_pre_emphasis_max(struct intel_encoder *encoder, - u8 voltage_swing); -int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, - bool enable); -void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder); -int cnl_calc_wrpll_link(struct drm_i915_private *dev_priv, - struct intel_dpll_hw_state *state); - -unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, - int color_plane, unsigned int height); - /* intel_cdclk.c */ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); void skl_init_cdclk(struct drm_i915_private *dev_priv); @@ -1713,6 +1677,8 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv); unsigned int intel_fb_xy_to_linear(int x, int y, const struct intel_plane_state *state, int plane); +unsigned int intel_fb_align_height(const struct drm_framebuffer *fb, + int color_plane, unsigned int height); void intel_add_fb_offsets(int *x, int *y, const struct intel_plane_state *state, int plane); unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 1c76e20f9ebc..de1d420a73b9 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -41,6 +41,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_ddi.h" #include "intel_drv.h" static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) -- cgit v1.2.3 From ec7f29ff0d144c45d17d6e7c08f4e575956f9a56 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:06 +0300 Subject: drm/i915: extract intel_connector.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/4b8e9d1fa8f0f0420ecc65063bdb7d068c13086e.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/icl_dsi.c | 1 + drivers/gpu/drm/i915/intel_connector.c | 7 +++++-- drivers/gpu/drm/i915/intel_connector.h | 35 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_crt.c | 1 + drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_dp_mst.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 19 ----------------- drivers/gpu/drm/i915/intel_dvo.c | 8 +++++-- drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_lvds.c | 7 +++++-- drivers/gpu/drm/i915/intel_panel.c | 2 ++ drivers/gpu/drm/i915/intel_sdvo.c | 10 ++++++--- drivers/gpu/drm/i915/intel_tv.c | 4 +++- drivers/gpu/drm/i915/vlv_dsi.c | 9 +++++--- 16 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_connector.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index d9a6089f0de5..c0095a4ed26f 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -9,6 +9,7 @@ header_test := \ i915_scheduler_types.h \ i915_timeline_types.h \ intel_audio.h \ + intel_connector.h \ intel_context_types.h \ intel_crt.h \ intel_ddi.h \ diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 64beb141c1ec..08e471898c86 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -28,6 +28,7 @@ #include #include +#include "intel_connector.h" #include "intel_ddi.h" #include "intel_dsi.h" diff --git a/drivers/gpu/drm/i915/intel_connector.c b/drivers/gpu/drm/i915/intel_connector.c index 848dd9e728d8..297f1e51213a 100644 --- a/drivers/gpu/drm/i915/intel_connector.c +++ b/drivers/gpu/drm/i915/intel_connector.c @@ -23,12 +23,15 @@ * DEALINGS IN THE SOFTWARE. */ -#include #include +#include + #include #include -#include "intel_drv.h" + #include "i915_drv.h" +#include "intel_connector.h" +#include "intel_drv.h" int intel_connector_init(struct intel_connector *connector) { diff --git a/drivers/gpu/drm/i915/intel_connector.h b/drivers/gpu/drm/i915/intel_connector.h new file mode 100644 index 000000000000..93a7375c8196 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_connector.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_CONNECTOR_H__ +#define __INTEL_CONNECTOR_H__ + +#include "intel_display.h" + +struct drm_connector; +struct edid; +struct i2c_adapter; +struct intel_connector; +struct intel_encoder; + +int intel_connector_init(struct intel_connector *connector); +struct intel_connector *intel_connector_alloc(void); +void intel_connector_free(struct intel_connector *connector); +void intel_connector_destroy(struct drm_connector *connector); +int intel_connector_register(struct drm_connector *connector); +void intel_connector_unregister(struct drm_connector *connector); +void intel_connector_attach_encoder(struct intel_connector *connector, + struct intel_encoder *encoder); +bool intel_connector_get_hw_state(struct intel_connector *connector); +enum pipe intel_connector_get_pipe(struct intel_connector *connector); +int intel_connector_update_modes(struct drm_connector *connector, + struct edid *edid); +int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); +void intel_attach_force_audio_property(struct drm_connector *connector); +void intel_attach_broadcast_rgb_property(struct drm_connector *connector); +void intel_attach_aspect_ratio_property(struct drm_connector *connector); +void intel_attach_colorspace_property(struct drm_connector *connector); + +#endif /* __INTEL_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index d649dae3cc70..b665c370111b 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -35,6 +35,7 @@ #include #include "i915_drv.h" +#include "intel_connector.h" #include "intel_crt.h" #include "intel_ddi.h" #include "intel_drv.h" diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 12135ffcff19..af03d81d53f8 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -29,6 +29,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" #include "intel_dsi.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index ca3ed4ae253c..466e5a6b9513 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -43,6 +43,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 62c240be8cc9..041003884860 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -29,6 +29,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b61ec71e971e..2b2aa634fd4b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1846,25 +1846,6 @@ unsigned int i9xx_plane_max_stride(struct intel_plane *plane, u32 pixel_format, u64 modifier, unsigned int rotation); -/* intel_connector.c */ -int intel_connector_init(struct intel_connector *connector); -struct intel_connector *intel_connector_alloc(void); -void intel_connector_free(struct intel_connector *connector); -void intel_connector_destroy(struct drm_connector *connector); -int intel_connector_register(struct drm_connector *connector); -void intel_connector_unregister(struct drm_connector *connector); -void intel_connector_attach_encoder(struct intel_connector *connector, - struct intel_encoder *encoder); -bool intel_connector_get_hw_state(struct intel_connector *connector); -enum pipe intel_connector_get_pipe(struct intel_connector *connector); -int intel_connector_update_modes(struct drm_connector *connector, - struct edid *edid); -int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); -void intel_attach_force_audio_property(struct drm_connector *connector); -void intel_attach_broadcast_rgb_property(struct drm_connector *connector); -void intel_attach_aspect_ratio_property(struct drm_connector *connector); -void intel_attach_colorspace_property(struct drm_connector *connector); - /* intel_csr.c */ void intel_csr_ucode_init(struct drm_i915_private *); void intel_csr_load_program(struct drm_i915_private *); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a6c82482a841..58af409a6d58 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -24,14 +24,18 @@ * Authors: * Eric Anholt */ + #include #include + #include #include -#include "intel_drv.h" #include -#include "i915_drv.h" + #include "dvo.h" +#include "i915_drv.h" +#include "intel_connector.h" +#include "intel_drv.h" #define SIL164_ADDR 0x38 #define CH7xxx_ADDR 0x76 diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index de1d420a73b9..92f4d9b65150 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -41,6 +41,7 @@ #include "i915_drv.h" #include "intel_audio.h" +#include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 34dd2d71814b..fbc99af2158e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -28,17 +28,20 @@ */ #include +#include #include #include #include #include + #include #include #include -#include "intel_drv.h" #include + #include "i915_drv.h" -#include +#include "intel_connector.h" +#include "intel_drv.h" /* Private structure for the integrated LVDS support */ struct intel_lvds_pps { diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 47cd4a338db6..5bd92cf6395c 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -33,6 +33,8 @@ #include #include #include + +#include "intel_connector.h" #include "intel_drv.h" #define CRC_PMIC_PWM_PERIOD_NS 21333 diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 68f497493d43..e148c8956cb5 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -25,16 +25,20 @@ * Authors: * Eric Anholt */ -#include -#include + #include #include +#include +#include + #include #include #include -#include "intel_drv.h" #include + #include "i915_drv.h" +#include "intel_connector.h" +#include "intel_drv.h" #include "intel_sdvo_regs.h" #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 3924c4944e1f..14f862015070 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -33,9 +33,11 @@ #include #include #include -#include "intel_drv.h" #include + #include "i915_drv.h" +#include "intel_connector.h" +#include "intel_drv.h" enum tv_margin { TV_MARGIN_LEFT, TV_MARGIN_TOP, diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index 6898541403a2..118feaa9c54e 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -23,14 +23,17 @@ * Author: Jani Nikula */ +#include +#include + #include #include #include -#include #include -#include -#include +#include + #include "i915_drv.h" +#include "intel_connector.h" #include "intel_drv.h" #include "intel_dsi.h" -- cgit v1.2.3 From 174594db632a2d484ee462bda606239b400dd078 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:07 +0300 Subject: drm/i915: extract intel_csr.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. v2: Add function argument names to fix checkpatch warning Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/44ceebca0206de9c40dc6794b660d84b8994f700.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/intel_csr.c | 3 +++ drivers/gpu/drm/i915/intel_csr.h | 17 +++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 7 ------- drivers/gpu/drm/i915/intel_runtime_pm.c | 1 + 6 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_csr.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index c0095a4ed26f..e03285ccad24 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -12,6 +12,7 @@ header_test := \ intel_connector.h \ intel_context_types.h \ intel_crt.h \ + intel_csr.h \ intel_ddi.h \ intel_engine_types.h \ intel_frontbuffer.h \ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 24f915d95d8b..b902b73b8b71 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -54,6 +54,7 @@ #include "i915_trace.h" #include "i915_vgpu.h" #include "intel_audio.h" +#include "intel_csr.h" #include "intel_drv.h" #include "intel_uc.h" #include "intel_workarounds.h" diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 862a8f686ef5..f43c2a2563a5 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -21,9 +21,12 @@ * IN THE SOFTWARE. * */ + #include + #include "i915_drv.h" #include "i915_reg.h" +#include "intel_csr.h" /** * DOC: csr support for dmc diff --git a/drivers/gpu/drm/i915/intel_csr.h b/drivers/gpu/drm/i915/intel_csr.h new file mode 100644 index 000000000000..17a32c1e8a35 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_csr.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_CSR_H__ +#define __INTEL_CSR_H__ + +struct drm_i915_private; + +void intel_csr_ucode_init(struct drm_i915_private *i915); +void intel_csr_load_program(struct drm_i915_private *i915); +void intel_csr_ucode_fini(struct drm_i915_private *i915); +void intel_csr_ucode_suspend(struct drm_i915_private *i915); +void intel_csr_ucode_resume(struct drm_i915_private *i915); + +#endif /* __INTEL_CSR_H__ */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2b2aa634fd4b..9404dfcbfd3a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1846,13 +1846,6 @@ unsigned int i9xx_plane_max_stride(struct intel_plane *plane, u32 pixel_format, u64 modifier, unsigned int rotation); -/* intel_csr.c */ -void intel_csr_ucode_init(struct drm_i915_private *); -void intel_csr_load_program(struct drm_i915_private *); -void intel_csr_ucode_fini(struct drm_i915_private *); -void intel_csr_ucode_suspend(struct drm_i915_private *); -void intel_csr_ucode_resume(struct drm_i915_private *); - /* intel_dp.c */ struct link_config_limits { int min_clock, max_clock; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index a9931081462b..b72af95b893b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -33,6 +33,7 @@ #include "i915_drv.h" #include "intel_crt.h" +#include "intel_csr.h" #include "intel_drv.h" /** -- cgit v1.2.3 From 98afa316d1edb6e64c11a65385de6175849abd19 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:08 +0300 Subject: drm/i915: extract intel_fbc.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. v2: Remove stray newline (Chris) Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/db44ba199c86f24bfa9e490531eddf51cccd89da.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 8 +++--- drivers/gpu/drm/i915/i915_reset.h | 1 + drivers/gpu/drm/i915/i915_suspend.c | 4 ++- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 24 ----------------- drivers/gpu/drm/i915/intel_fbc.c | 3 ++- drivers/gpu/drm/i915/intel_fbc.h | 42 ++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_fifo_underrun.c | 1 + drivers/gpu/drm/i915/intel_frontbuffer.c | 3 ++- drivers/gpu/drm/i915/intel_pm.c | 1 + 11 files changed, 59 insertions(+), 30 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_fbc.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index e03285ccad24..1099de6c8bda 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -15,6 +15,7 @@ header_test := \ intel_csr.h \ intel_ddi.h \ intel_engine_types.h \ + intel_fbc.h \ intel_frontbuffer.h \ intel_workarounds_types.h diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4dd2d9ae3202..89a3b1802965 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -26,14 +26,16 @@ * */ -#include #include +#include + #include #include -#include "intel_drv.h" -#include "intel_guc_submission.h" #include "i915_reset.h" +#include "intel_drv.h" +#include "intel_fbc.h" +#include "intel_guc_submission.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) { diff --git a/drivers/gpu/drm/i915/i915_reset.h b/drivers/gpu/drm/i915/i915_reset.h index 86b1ac8116ce..3c0450289b8f 100644 --- a/drivers/gpu/drm/i915/i915_reset.h +++ b/drivers/gpu/drm/i915/i915_reset.h @@ -14,6 +14,7 @@ #include "intel_engine_types.h" struct drm_i915_private; +struct i915_request; struct intel_engine_cs; struct intel_guc; diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index d2f2a9c2fabd..95f3dab1b229 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -25,8 +25,10 @@ */ #include -#include "intel_drv.h" + #include "i915_reg.h" +#include "intel_drv.h" +#include "intel_fbc.h" static void i915_save_display(struct drm_i915_private *dev_priv) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0d0c363a5077..06ae3093b02b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -52,6 +52,7 @@ #include "intel_ddi.h" #include "intel_drv.h" #include "intel_dsi.h" +#include "intel_fbc.h" #include "intel_frontbuffer.h" /* Primary plane formats for gen <= 3 */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9404dfcbfd3a..cc0d179b6c43 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2012,30 +2012,6 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev) } #endif -/* intel_fbc.c */ -void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, - struct intel_atomic_state *state); -bool intel_fbc_is_active(struct drm_i915_private *dev_priv); -void intel_fbc_pre_update(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, - struct intel_plane_state *plane_state); -void intel_fbc_post_update(struct intel_crtc *crtc); -void intel_fbc_init(struct drm_i915_private *dev_priv); -void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv); -void intel_fbc_enable(struct intel_crtc *crtc, - struct intel_crtc_state *crtc_state, - struct intel_plane_state *plane_state); -void intel_fbc_disable(struct intel_crtc *crtc); -void intel_fbc_global_disable(struct drm_i915_private *dev_priv); -void intel_fbc_invalidate(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits, - enum fb_op_origin origin); -void intel_fbc_flush(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits, enum fb_op_origin origin); -void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv); -void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv); -int intel_fbc_reset_underrun(struct drm_i915_private *dev_priv); - /* intel_hdmi.c */ void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, enum port port); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 43fe08be3b7d..910a4c2e3419 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -40,8 +40,9 @@ #include -#include "intel_drv.h" #include "i915_drv.h" +#include "intel_drv.h" +#include "intel_fbc.h" static inline bool fbc_supported(struct drm_i915_private *dev_priv) { diff --git a/drivers/gpu/drm/i915/intel_fbc.h b/drivers/gpu/drm/i915/intel_fbc.h new file mode 100644 index 000000000000..50272eda8d43 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_fbc.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_FBC_H__ +#define __INTEL_FBC_H__ + +#include + +#include "intel_frontbuffer.h" + +struct drm_i915_private; +struct intel_atomic_state; +struct intel_crtc; +struct intel_crtc_state; +struct intel_plane_state; + +void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv, + struct intel_atomic_state *state); +bool intel_fbc_is_active(struct drm_i915_private *dev_priv); +void intel_fbc_pre_update(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state, + struct intel_plane_state *plane_state); +void intel_fbc_post_update(struct intel_crtc *crtc); +void intel_fbc_init(struct drm_i915_private *dev_priv); +void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv); +void intel_fbc_enable(struct intel_crtc *crtc, + struct intel_crtc_state *crtc_state, + struct intel_plane_state *plane_state); +void intel_fbc_disable(struct intel_crtc *crtc); +void intel_fbc_global_disable(struct drm_i915_private *dev_priv); +void intel_fbc_invalidate(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits, + enum fb_op_origin origin); +void intel_fbc_flush(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits, enum fb_op_origin origin); +void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv); +void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *dev_priv); +int intel_fbc_reset_underrun(struct drm_i915_private *dev_priv); + +#endif /* __INTEL_FBC_H__ */ diff --git a/drivers/gpu/drm/i915/intel_fifo_underrun.c b/drivers/gpu/drm/i915/intel_fifo_underrun.c index f33de4be4b89..74c8b0528294 100644 --- a/drivers/gpu/drm/i915/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/intel_fifo_underrun.c @@ -27,6 +27,7 @@ #include "i915_drv.h" #include "intel_drv.h" +#include "intel_fbc.h" /** * DOC: fifo underrun handling diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index 16f253deaf8d..1d19da2ffee8 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -61,9 +61,10 @@ */ +#include "i915_drv.h" #include "intel_drv.h" +#include "intel_fbc.h" #include "intel_frontbuffer.h" -#include "i915_drv.h" void __intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, enum fb_op_origin origin, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0e05ee1f3ea0..b3c4f640117f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -35,6 +35,7 @@ #include "i915_drv.h" #include "intel_drv.h" +#include "intel_fbc.h" #include "../../../platform/x86/intel_ips.h" /** -- cgit v1.2.3 From 55367a275ada04960a385c0371193f2953b870e6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:09 +0300 Subject: drm/i915: extract intel_psr.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. v2: Fix checkpatch whitespace complaint Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/7e776690bf139ccdd0306b30df08dc68e74603de.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/i915_irq.c | 11 +++++---- drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 26 -------------------- drivers/gpu/drm/i915/intel_fbc.c | 1 + drivers/gpu/drm/i915/intel_frontbuffer.c | 1 + drivers/gpu/drm/i915/intel_psr.c | 11 +++++---- drivers/gpu/drm/i915/intel_psr.h | 40 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_sprite.c | 13 ++++++---- 12 files changed, 68 insertions(+), 40 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_psr.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 1099de6c8bda..6da5c6722bee 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -17,6 +17,7 @@ header_test := \ intel_engine_types.h \ intel_fbc.h \ intel_frontbuffer.h \ + intel_psr.h \ intel_workarounds_types.h quiet_cmd_header_test = HDRTEST $@ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 89a3b1802965..bacebf983011 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include "intel_fbc.h" #include "intel_guc_submission.h" +#include "intel_psr.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index aa107a78cb36..6454ddc37f8b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -28,16 +28,19 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include #include -#include +#include +#include +#include + #include +#include #include + #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" +#include "intel_psr.h" /** * DOC: interrupt handling diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index af03d81d53f8..9830f693be35 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -33,6 +33,7 @@ #include "intel_ddi.h" #include "intel_drv.h" #include "intel_dsi.h" +#include "intel_psr.h" struct ddi_buf_trans { u32 trans1; /* balance leg enable, de-emph level */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 06ae3093b02b..994205ebf0c5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -54,6 +54,7 @@ #include "intel_dsi.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_psr.h" /* Primary plane formats for gen <= 3 */ static const u32 i8xx_primary_formats[] = { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 466e5a6b9513..00efbb59c422 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -46,6 +46,7 @@ #include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" +#include "intel_psr.h" #define DP_DPRX_ESI_LEN 14 diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cc0d179b6c43..3829d96d0233 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2114,32 +2114,6 @@ void intel_hdcp_component_fini(struct drm_i915_private *dev_priv); void intel_hdcp_cleanup(struct intel_connector *connector); void intel_hdcp_handle_cp_irq(struct intel_connector *connector); -/* intel_psr.c */ -#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support) -void intel_psr_init_dpcd(struct intel_dp *intel_dp); -void intel_psr_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_psr_disable(struct intel_dp *intel_dp, - const struct intel_crtc_state *old_crtc_state); -void intel_psr_update(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value); -void intel_psr_invalidate(struct drm_i915_private *dev_priv, - unsigned frontbuffer_bits, - enum fb_op_origin origin); -void intel_psr_flush(struct drm_i915_private *dev_priv, - unsigned frontbuffer_bits, - enum fb_op_origin origin); -void intel_psr_init(struct drm_i915_private *dev_priv); -void intel_psr_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *crtc_state); -void intel_psr_irq_control(struct drm_i915_private *dev_priv, u32 debug); -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir); -void intel_psr_short_pulse(struct intel_dp *intel_dp); -int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, - u32 *out_value); -bool intel_psr_enabled(struct intel_dp *intel_dp); - /* intel_quirks.c */ void intel_init_quirks(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 910a4c2e3419..c805a0966395 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -43,6 +43,7 @@ #include "i915_drv.h" #include "intel_drv.h" #include "intel_fbc.h" +#include "intel_frontbuffer.h" static inline bool fbc_supported(struct drm_i915_private *dev_priv) { diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index 1d19da2ffee8..a42f859ad22e 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -65,6 +65,7 @@ #include "intel_drv.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_psr.h" void __intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, enum fb_op_origin origin, diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index ec874d802d48..6592aa48c8ef 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -21,6 +21,12 @@ * DEALINGS IN THE SOFTWARE. */ +#include + +#include "i915_drv.h" +#include "intel_drv.h" +#include "intel_psr.h" + /** * DOC: Panel Self Refresh (PSR/SRD) * @@ -51,11 +57,6 @@ * must be correctly synchronized/cancelled when shutting down the pipe." */ -#include - -#include "intel_drv.h" -#include "i915_drv.h" - static bool psr_global_enabled(u32 debug) { switch (debug & I915_PSR_DEBUG_MODE_MASK) { diff --git a/drivers/gpu/drm/i915/intel_psr.h b/drivers/gpu/drm/i915/intel_psr.h new file mode 100644 index 000000000000..dc818826f36d --- /dev/null +++ b/drivers/gpu/drm/i915/intel_psr.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_PSR_H__ +#define __INTEL_PSR_H__ + +#include "intel_frontbuffer.h" + +struct drm_i915_private; +struct intel_crtc_state; +struct intel_dp; + +#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support) +void intel_psr_init_dpcd(struct intel_dp *intel_dp); +void intel_psr_enable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_psr_disable(struct intel_dp *intel_dp, + const struct intel_crtc_state *old_crtc_state); +void intel_psr_update(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value); +void intel_psr_invalidate(struct drm_i915_private *dev_priv, + unsigned frontbuffer_bits, + enum fb_op_origin origin); +void intel_psr_flush(struct drm_i915_private *dev_priv, + unsigned frontbuffer_bits, + enum fb_op_origin origin); +void intel_psr_init(struct drm_i915_private *dev_priv); +void intel_psr_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state); +void intel_psr_irq_control(struct drm_i915_private *dev_priv, u32 debug); +void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir); +void intel_psr_short_pulse(struct intel_dp *intel_dp); +int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, + u32 *out_value); +bool intel_psr_enabled(struct intel_dp *intel_dp); + +#endif /* __INTEL_PSR_H__ */ diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 65de7387bf1b..d02da53e9806 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -29,17 +29,20 @@ * registers; newer ones are much simpler and we can use the new DRM plane * support. */ + +#include #include +#include #include #include -#include -#include #include -#include "intel_drv.h" -#include "intel_frontbuffer.h" +#include #include + #include "i915_drv.h" -#include +#include "intel_drv.h" +#include "intel_frontbuffer.h" +#include "intel_psr.h" bool is_planar_yuv_format(u32 pixelformat) { -- cgit v1.2.3 From 78c61320c5423cda757ae9119df542ecca39eca5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:10 +0300 Subject: drm/i915: extract intel_color.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/fe5928586b4ca538cc4bc99212c5b699e891c75e.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_color.c | 1 + drivers/gpu/drm/i915/intel_color.h | 17 +++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 6 ------ 5 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_color.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 6da5c6722bee..cf6e6fce7b2c 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -9,6 +9,7 @@ header_test := \ i915_scheduler_types.h \ i915_timeline_types.h \ intel_audio.h \ + intel_color.h \ intel_connector.h \ intel_context_types.h \ intel_crt.h \ diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 60f21a1fdbbe..ca341a9e47e6 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -22,6 +22,7 @@ * */ +#include "intel_color.h" #include "intel_drv.h" #define CTM_COEFF_SIGN (1ULL << 63) diff --git a/drivers/gpu/drm/i915/intel_color.h b/drivers/gpu/drm/i915/intel_color.h new file mode 100644 index 000000000000..b8a3ce609587 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_color.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_COLOR_H__ +#define __INTEL_COLOR_H__ + +struct intel_crtc_state; +struct intel_crtc; + +void intel_color_init(struct intel_crtc *crtc); +int intel_color_check(struct intel_crtc_state *crtc_state); +void intel_color_commit(const struct intel_crtc_state *crtc_state); +void intel_color_load_luts(const struct intel_crtc_state *crtc_state); + +#endif /* __INTEL_COLOR_H__ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 994205ebf0c5..03b12147dd8c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -48,6 +48,7 @@ #include "i915_gem_clflush.h" #include "i915_reset.h" #include "i915_trace.h" +#include "intel_color.h" #include "intel_crt.h" #include "intel_ddi.h" #include "intel_drv.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3829d96d0233..9fd356c614ae 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2419,12 +2419,6 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ const struct intel_plane_state *old_plane_state, struct intel_plane_state *intel_state); -/* intel_color.c */ -void intel_color_init(struct intel_crtc *crtc); -int intel_color_check(struct intel_crtc_state *crtc_state); -void intel_color_commit(const struct intel_crtc_state *crtc_state); -void intel_color_load_luts(const struct intel_crtc_state *crtc_state); - /* intel_lspcon.c */ bool lspcon_init(struct intel_digital_port *intel_dig_port); void lspcon_resume(struct intel_lspcon *lspcon); -- cgit v1.2.3 From f3e18947942756d17b02d4f34436f2d6e4a5d68b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:11 +0300 Subject: drm/i915: extract intel_lspcon.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b01cae3b5307d31c34de2321d6d2913f1cc39a12.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 21 ----------------- drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_lspcon.c | 5 +++- drivers/gpu/drm/i915/intel_lspcon.h | 38 +++++++++++++++++++++++++++++++ 7 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_lspcon.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index cf6e6fce7b2c..589e5b513838 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -18,6 +18,7 @@ header_test := \ intel_engine_types.h \ intel_fbc.h \ intel_frontbuffer.h \ + intel_lspcon.h \ intel_psr.h \ intel_workarounds_types.h diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 9830f693be35..06c2948de9bf 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -33,6 +33,7 @@ #include "intel_ddi.h" #include "intel_drv.h" #include "intel_dsi.h" +#include "intel_lspcon.h" #include "intel_psr.h" struct ddi_buf_trans { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 00efbb59c422..2f50a4d81fcd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -46,6 +46,7 @@ #include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" +#include "intel_lspcon.h" #include "intel_psr.h" #define DP_DPRX_ESI_LEN 14 diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9fd356c614ae..5c1326c81cdb 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2419,27 +2419,6 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ const struct intel_plane_state *old_plane_state, struct intel_plane_state *intel_state); -/* intel_lspcon.c */ -bool lspcon_init(struct intel_digital_port *intel_dig_port); -void lspcon_resume(struct intel_lspcon *lspcon); -void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); -void lspcon_write_infoframe(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - unsigned int type, - const void *buf, ssize_t len); -void lspcon_read_infoframe(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - unsigned int type, - void *frame, ssize_t len); -void lspcon_set_infoframes(struct intel_encoder *encoder, - bool enable, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, - const struct intel_crtc_state *pipe_config); -void lspcon_ycbcr420_config(struct drm_connector *connector, - struct intel_crtc_state *crtc_state); - /* intel_pipe_crc.c */ #ifdef CONFIG_DEBUG_FS int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 92f4d9b65150..012ae7b1bda5 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -44,6 +44,7 @@ #include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" +#include "intel_lspcon.h" static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) { diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 8d202b13e24f..5f32e1f018b7 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -22,10 +22,13 @@ * * */ -#include + #include #include +#include + #include "intel_drv.h" +#include "intel_lspcon.h" /* LSPCON OUI Vendor ID(signatures) */ #define LSPCON_VENDOR_PARADE_OUI 0x001CF8 diff --git a/drivers/gpu/drm/i915/intel_lspcon.h b/drivers/gpu/drm/i915/intel_lspcon.h new file mode 100644 index 000000000000..37cfddf8a9c5 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lspcon.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_LSPCON_H__ +#define __INTEL_LSPCON_H__ + +#include + +struct drm_connector; +struct drm_connector_state; +struct intel_crtc_state; +struct intel_digital_port; +struct intel_encoder; +struct intel_lspcon; + +bool lspcon_init(struct intel_digital_port *intel_dig_port); +void lspcon_resume(struct intel_lspcon *lspcon); +void lspcon_wait_pcon_mode(struct intel_lspcon *lspcon); +void lspcon_write_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + const void *buf, ssize_t len); +void lspcon_read_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + unsigned int type, + void *frame, ssize_t len); +void lspcon_set_infoframes(struct intel_encoder *encoder, + bool enable, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, + const struct intel_crtc_state *pipe_config); +void lspcon_ycbcr420_config(struct drm_connector *connector, + struct intel_crtc_state *crtc_state); + +#endif /* __INTEL_LSPCON_H__ */ -- cgit v1.2.3 From 596fee14fbc9798ca1a969e87d7827d358ed2e5f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:12 +0300 Subject: drm/i915: extract intel_sdvo.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c507e15fef019541da5bb33f2fbe920a5ad2f3dc.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 7 ------- drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_sdvo.c | 1 + drivers/gpu/drm/i915/intel_sdvo.h | 23 +++++++++++++++++++++++ 6 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_sdvo.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 589e5b513838..f1f62794b457 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -20,6 +20,7 @@ header_test := \ intel_frontbuffer.h \ intel_lspcon.h \ intel_psr.h \ + intel_sdvo.h \ intel_workarounds_types.h quiet_cmd_header_test = HDRTEST $@ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 03b12147dd8c..7a0d52c984fe 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -56,6 +56,7 @@ #include "intel_fbc.h" #include "intel_frontbuffer.h" #include "intel_psr.h" +#include "intel_sdvo.h" /* Primary plane formats for gen <= 3 */ static const u32 i8xx_primary_formats[] = { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5c1326c81cdb..681f232fd305 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2314,13 +2314,6 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, void intel_init_ipc(struct drm_i915_private *dev_priv); void intel_enable_ipc(struct drm_i915_private *dev_priv); -/* intel_sdvo.c */ -bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv, - i915_reg_t sdvo_reg, enum pipe *pipe); -bool intel_sdvo_init(struct drm_i915_private *dev_priv, - i915_reg_t reg, enum port port); - - /* intel_sprite.c */ bool is_planar_yuv_format(u32 pixelformat); int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 012ae7b1bda5..03dcf5f7d69f 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -45,6 +45,7 @@ #include "intel_ddi.h" #include "intel_drv.h" #include "intel_lspcon.h" +#include "intel_sdvo.h" static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) { diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index e148c8956cb5..0cebf6ccc75a 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -39,6 +39,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_sdvo.h" #include "intel_sdvo_regs.h" #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) diff --git a/drivers/gpu/drm/i915/intel_sdvo.h b/drivers/gpu/drm/i915/intel_sdvo.h new file mode 100644 index 000000000000..c9e05bcdd141 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_sdvo.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_SDVO_H__ +#define __INTEL_SDVO_H__ + +#include + +#include + +#include "i915_reg.h" + +struct drm_i915_private; +enum pipe; + +bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv, + i915_reg_t sdvo_reg, enum pipe *pipe); +bool intel_sdvo_init(struct drm_i915_private *dev_priv, + i915_reg_t reg, enum port port); + +#endif /* __INTEL_SDVO_H__ */ -- cgit v1.2.3 From 408bd91786665b8cb78540d67dbd148f287a1685 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:13 +0300 Subject: drm/i915: extract intel_hdcp.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/8348620b32cb4438ccfb5f7bbe9a18ff6b7c48a0.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/intel_atomic.c | 1 + drivers/gpu/drm/i915/intel_connector.c | 1 + drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 15 -------------- drivers/gpu/drm/i915/intel_hdcp.c | 10 ++++++---- drivers/gpu/drm/i915/intel_hdcp.h | 33 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_hdmi.c | 1 + 11 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_hdcp.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index f1f62794b457..a4846d7eaf46 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -18,6 +18,7 @@ header_test := \ intel_engine_types.h \ intel_fbc.h \ intel_frontbuffer.h \ + intel_hdcp.h \ intel_lspcon.h \ intel_psr.h \ intel_sdvo.h \ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index bacebf983011..d043d6ed12e8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include "intel_fbc.h" #include "intel_guc_submission.h" +#include "intel_hdcp.h" #include "intel_psr.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index b844e8840c6f..2cbcf6ac24d8 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -35,6 +35,7 @@ #include #include "intel_drv.h" +#include "intel_hdcp.h" /** * intel_digital_connector_atomic_get_property - hook for connector->atomic_get_property. diff --git a/drivers/gpu/drm/i915/intel_connector.c b/drivers/gpu/drm/i915/intel_connector.c index 297f1e51213a..6627d92ece14 100644 --- a/drivers/gpu/drm/i915/intel_connector.c +++ b/drivers/gpu/drm/i915/intel_connector.c @@ -32,6 +32,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_hdcp.h" int intel_connector_init(struct intel_connector *connector) { diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 06c2948de9bf..bc7b00f43fae 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -33,6 +33,7 @@ #include "intel_ddi.h" #include "intel_drv.h" #include "intel_dsi.h" +#include "intel_hdcp.h" #include "intel_lspcon.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7a0d52c984fe..1220bb0008c7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -55,6 +55,7 @@ #include "intel_dsi.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_hdcp.h" #include "intel_psr.h" #include "intel_sdvo.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2f50a4d81fcd..efc411964bcc 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -46,6 +46,7 @@ #include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" +#include "intel_hdcp.h" #include "intel_lspcon.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 681f232fd305..e04a622a71ed 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2099,21 +2099,6 @@ static inline void intel_backlight_device_unregister(struct intel_connector *con } #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ -/* intel_hdcp.c */ -void intel_hdcp_atomic_check(struct drm_connector *connector, - struct drm_connector_state *old_state, - struct drm_connector_state *new_state); -int intel_hdcp_init(struct intel_connector *connector, - const struct intel_hdcp_shim *hdcp_shim); -int intel_hdcp_enable(struct intel_connector *connector); -int intel_hdcp_disable(struct intel_connector *connector); -bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port); -bool intel_hdcp_capable(struct intel_connector *connector); -void intel_hdcp_component_init(struct drm_i915_private *dev_priv); -void intel_hdcp_component_fini(struct drm_i915_private *dev_priv); -void intel_hdcp_cleanup(struct intel_connector *connector); -void intel_hdcp_handle_cp_irq(struct intel_connector *connector); - /* intel_quirks.c */ void intel_init_quirks(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c index 86965fa37739..99b007169c49 100644 --- a/drivers/gpu/drm/i915/intel_hdcp.c +++ b/drivers/gpu/drm/i915/intel_hdcp.c @@ -6,14 +6,16 @@ * Sean Paul */ -#include -#include +#include #include #include -#include -#include "intel_drv.h" +#include +#include + #include "i915_reg.h" +#include "intel_drv.h" +#include "intel_hdcp.h" #define KEY_LOAD_TRIES 5 #define ENCRYPT_STATUS_CHANGE_TIMEOUT_MS 50 diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h new file mode 100644 index 000000000000..a75f25f09d39 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_hdcp.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_HDCP_H__ +#define __INTEL_HDCP_H__ + +#include + +#include + +struct drm_connector; +struct drm_connector_state; +struct drm_i915_private; +struct intel_connector; +struct intel_hdcp_shim; + +void intel_hdcp_atomic_check(struct drm_connector *connector, + struct drm_connector_state *old_state, + struct drm_connector_state *new_state); +int intel_hdcp_init(struct intel_connector *connector, + const struct intel_hdcp_shim *hdcp_shim); +int intel_hdcp_enable(struct intel_connector *connector); +int intel_hdcp_disable(struct intel_connector *connector); +bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port); +bool intel_hdcp_capable(struct intel_connector *connector); +void intel_hdcp_component_init(struct drm_i915_private *dev_priv); +void intel_hdcp_component_fini(struct drm_i915_private *dev_priv); +void intel_hdcp_cleanup(struct intel_connector *connector); +void intel_hdcp_handle_cp_irq(struct intel_connector *connector); + +#endif /* __INTEL_HDCP_H__ */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 03dcf5f7d69f..18fef71fc4f8 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -44,6 +44,7 @@ #include "intel_connector.h" #include "intel_ddi.h" #include "intel_drv.h" +#include "intel_hdcp.h" #include "intel_lspcon.h" #include "intel_sdvo.h" -- cgit v1.2.3 From 44c1220a441ca79783c0c541c495c6978448d9f3 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:14 +0300 Subject: drm/i915: extract intel_panel.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c9f02ae09123866bc55269175ab75e844ffbd6ac.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/icl_dsi.c | 1 + drivers/gpu/drm/i915/intel_connector.c | 1 + drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 45 --------------------- drivers/gpu/drm/i915/intel_dvo.c | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_lvds.c | 1 + drivers/gpu/drm/i915/intel_opregion.c | 3 +- drivers/gpu/drm/i915/intel_panel.c | 1 + drivers/gpu/drm/i915/intel_panel.h | 65 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_sdvo.c | 1 + drivers/gpu/drm/i915/vlv_dsi.c | 1 + 14 files changed, 78 insertions(+), 46 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_panel.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index a4846d7eaf46..d3a8fc37d6b5 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -20,6 +20,7 @@ header_test := \ intel_frontbuffer.h \ intel_hdcp.h \ intel_lspcon.h \ + intel_panel.h \ intel_psr.h \ intel_sdvo.h \ intel_workarounds_types.h diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 08e471898c86..527aafc16e62 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -31,6 +31,7 @@ #include "intel_connector.h" #include "intel_ddi.h" #include "intel_dsi.h" +#include "intel_panel.h" static inline int header_credits_available(struct drm_i915_private *dev_priv, enum transcoder dsi_trans) diff --git a/drivers/gpu/drm/i915/intel_connector.c b/drivers/gpu/drm/i915/intel_connector.c index 6627d92ece14..073b6c3ab7cc 100644 --- a/drivers/gpu/drm/i915/intel_connector.c +++ b/drivers/gpu/drm/i915/intel_connector.c @@ -33,6 +33,7 @@ #include "intel_connector.h" #include "intel_drv.h" #include "intel_hdcp.h" +#include "intel_panel.h" int intel_connector_init(struct intel_connector *connector) { diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index bc7b00f43fae..ca66ac998008 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -35,6 +35,7 @@ #include "intel_dsi.h" #include "intel_hdcp.h" #include "intel_lspcon.h" +#include "intel_panel.h" #include "intel_psr.h" struct ddi_buf_trans { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index efc411964bcc..02d662ff5df9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -48,6 +48,7 @@ #include "intel_drv.h" #include "intel_hdcp.h" #include "intel_lspcon.h" +#include "intel_panel.h" #include "intel_psr.h" #define DP_DPRX_ESI_LEN 14 diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e04a622a71ed..8e23827a03d9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2054,51 +2054,6 @@ int intel_overlay_attrs_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); void intel_overlay_reset(struct drm_i915_private *dev_priv); - -/* intel_panel.c */ -int intel_panel_init(struct intel_panel *panel, - struct drm_display_mode *fixed_mode, - struct drm_display_mode *downclock_mode); -void intel_panel_fini(struct intel_panel *panel); -void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, - struct drm_display_mode *adjusted_mode); -void intel_pch_panel_fitting(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config, - int fitting_mode); -void intel_gmch_panel_fitting(struct intel_crtc *crtc, - struct intel_crtc_state *pipe_config, - int fitting_mode); -void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, - u32 level, u32 max); -int intel_panel_setup_backlight(struct drm_connector *connector, - enum pipe pipe); -void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_panel_update_backlight(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); -struct drm_display_mode * -intel_panel_edid_downclock_mode(struct intel_connector *connector, - const struct drm_display_mode *fixed_mode); -struct drm_display_mode * -intel_panel_edid_fixed_mode(struct intel_connector *connector); -struct drm_display_mode * -intel_panel_vbt_fixed_mode(struct intel_connector *connector); - -#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) -int intel_backlight_device_register(struct intel_connector *connector); -void intel_backlight_device_unregister(struct intel_connector *connector); -#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ -static inline int intel_backlight_device_register(struct intel_connector *connector) -{ - return 0; -} -static inline void intel_backlight_device_unregister(struct intel_connector *connector) -{ -} -#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ - /* intel_quirks.c */ void intel_init_quirks(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 58af409a6d58..4fda625ea2c1 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -36,6 +36,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_panel.h" #define SIL164_ADDR 0x38 #define CH7xxx_ADDR 0x76 diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 18fef71fc4f8..5725fedaceec 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -47,6 +47,7 @@ #include "intel_hdcp.h" #include "intel_lspcon.h" #include "intel_sdvo.h" +#include "intel_panel.h" static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi) { diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index fbc99af2158e..3788d2fe4a9e 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -42,6 +42,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_panel.h" /* Private structure for the integrated LVDS support */ struct intel_lvds_pps { diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 5e00ee9270b5..8fa1159d097f 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -32,9 +32,10 @@ #include -#include "intel_opregion.h" #include "i915_drv.h" #include "intel_drv.h" +#include "intel_opregion.h" +#include "intel_panel.h" #define OPREGION_HEADER_OFFSET 0 #define OPREGION_ACPI_OFFSET 0x100 diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 5bd92cf6395c..4ab4ce6569e7 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -36,6 +36,7 @@ #include "intel_connector.h" #include "intel_drv.h" +#include "intel_panel.h" #define CRC_PMIC_PWM_PERIOD_NS 21333 diff --git a/drivers/gpu/drm/i915/intel_panel.h b/drivers/gpu/drm/i915/intel_panel.h new file mode 100644 index 000000000000..cedeea443336 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_panel.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_PANEL_H__ +#define __INTEL_PANEL_H__ + +#include + +#include "intel_display.h" + +struct drm_connector; +struct drm_connector_state; +struct drm_display_mode; +struct intel_connector; +struct intel_crtc; +struct intel_crtc_state; +struct intel_encoder; +struct intel_panel; + +int intel_panel_init(struct intel_panel *panel, + struct drm_display_mode *fixed_mode, + struct drm_display_mode *downclock_mode); +void intel_panel_fini(struct intel_panel *panel); +void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, + struct drm_display_mode *adjusted_mode); +void intel_pch_panel_fitting(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config, + int fitting_mode); +void intel_gmch_panel_fitting(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config, + int fitting_mode); +void intel_panel_set_backlight_acpi(const struct drm_connector_state *conn_state, + u32 level, u32 max); +int intel_panel_setup_backlight(struct drm_connector *connector, + enum pipe pipe); +void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_panel_update_backlight(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); +struct drm_display_mode * +intel_panel_edid_downclock_mode(struct intel_connector *connector, + const struct drm_display_mode *fixed_mode); +struct drm_display_mode * +intel_panel_edid_fixed_mode(struct intel_connector *connector); +struct drm_display_mode * +intel_panel_vbt_fixed_mode(struct intel_connector *connector); + +#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) +int intel_backlight_device_register(struct intel_connector *connector); +void intel_backlight_device_unregister(struct intel_connector *connector); +#else /* CONFIG_BACKLIGHT_CLASS_DEVICE */ +static inline int intel_backlight_device_register(struct intel_connector *connector) +{ + return 0; +} +static inline void intel_backlight_device_unregister(struct intel_connector *connector) +{ +} +#endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ + +#endif /* __INTEL_PANEL_H__ */ diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 0cebf6ccc75a..c815845e8c34 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -39,6 +39,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_panel.h" #include "intel_sdvo.h" #include "intel_sdvo_regs.h" diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index 118feaa9c54e..e0b1ec821960 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -36,6 +36,7 @@ #include "intel_connector.h" #include "intel_drv.h" #include "intel_dsi.h" +#include "intel_panel.h" /* return pixels in terms of txbyteclkhs */ static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count, -- cgit v1.2.3 From 696173b064c6dacd4e88d2ca15021e9bfc91328e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:15 +0300 Subject: drm/i915: extract intel_pm.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. v2: gen6_rps_reset_ei() is in i915_irq.c not intel_pm.c. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/adc6463b95eef3440fba9826793f7d1c5f3b0b4a.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/i915_request.c | 3 +- drivers/gpu/drm/i915/intel_atomic_plane.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 52 +--------------------- drivers/gpu/drm/i915/intel_pm.c | 3 +- drivers/gpu/drm/i915/intel_pm.h | 71 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_sprite.c | 1 + drivers/gpu/drm/i915/intel_uncore.c | 9 ++-- 12 files changed, 88 insertions(+), 57 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_pm.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index d3a8fc37d6b5..ab7ac0ac17a1 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -21,6 +21,7 @@ header_test := \ intel_hdcp.h \ intel_lspcon.h \ intel_panel.h \ + intel_pm.h \ intel_psr.h \ intel_sdvo.h \ intel_workarounds_types.h diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d043d6ed12e8..7c8e3e5b8aab 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -37,6 +37,7 @@ #include "intel_fbc.h" #include "intel_guc_submission.h" #include "intel_hdcp.h" +#include "intel_pm.h" #include "intel_psr.h" static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b902b73b8b71..ef799fe20510 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -56,6 +56,7 @@ #include "intel_audio.h" #include "intel_csr.h" #include "intel_drv.h" +#include "intel_pm.h" #include "intel_uc.h" #include "intel_workarounds.h" diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f25a1ba24927..bf3d12f94365 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -50,6 +50,7 @@ #include "intel_drv.h" #include "intel_frontbuffer.h" #include "intel_mocs.h" +#include "intel_pm.h" #include "intel_workarounds.h" static void i915_gem_flush_free_objects(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 7f8a4eba98b8..2da0d6436a1a 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -29,10 +29,11 @@ #include #include -#include "i915_drv.h" #include "i915_active.h" +#include "i915_drv.h" #include "i915_globals.h" #include "i915_reset.h" +#include "intel_pm.h" struct execute_cb { struct list_head link; diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 9d32a6fcf840..42821f8e6031 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -36,6 +36,7 @@ #include #include "intel_drv.h" +#include "intel_pm.h" struct intel_plane *intel_plane_alloc(void) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1220bb0008c7..3c8b72dd150c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -56,6 +56,7 @@ #include "intel_fbc.h" #include "intel_frontbuffer.h" #include "intel_hdcp.h" +#include "intel_pm.h" #include "intel_psr.h" #include "intel_sdvo.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8e23827a03d9..5d4031f122dd 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1600,6 +1600,7 @@ void gen11_reset_rps_interrupts(struct drm_i915_private *dev_priv); void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv); void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv); void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv); +void gen6_rps_reset_ei(struct drm_i915_private *dev_priv); static inline u32 gen6_sanitize_rps_pm_mask(const struct drm_i915_private *i915, u32 mask) @@ -2203,57 +2204,6 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder, bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, enum dpio_channel ch, bool override); - -/* intel_pm.c */ -void intel_init_clock_gating(struct drm_i915_private *dev_priv); -void intel_suspend_hw(struct drm_i915_private *dev_priv); -int ilk_wm_max_level(const struct drm_i915_private *dev_priv); -void intel_update_watermarks(struct intel_crtc *crtc); -void intel_init_pm(struct drm_i915_private *dev_priv); -void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); -void intel_pm_setup(struct drm_i915_private *dev_priv); -void intel_gpu_ips_init(struct drm_i915_private *dev_priv); -void intel_gpu_ips_teardown(void); -void intel_init_gt_powersave(struct drm_i915_private *dev_priv); -void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv); -void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv); -void intel_enable_gt_powersave(struct drm_i915_private *dev_priv); -void intel_disable_gt_powersave(struct drm_i915_private *dev_priv); -void gen6_rps_busy(struct drm_i915_private *dev_priv); -void gen6_rps_reset_ei(struct drm_i915_private *dev_priv); -void gen6_rps_idle(struct drm_i915_private *dev_priv); -void gen6_rps_boost(struct i915_request *rq); -void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv); -void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv); -void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv); -void skl_wm_get_hw_state(struct drm_i915_private *dev_priv); -void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, - struct skl_ddb_entry *ddb_y, - struct skl_ddb_entry *ddb_uv); -void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, - struct skl_ddb_allocation *ddb /* out */); -void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, - struct skl_pipe_wm *out); -void g4x_wm_sanitize(struct drm_i915_private *dev_priv); -void vlv_wm_sanitize(struct drm_i915_private *dev_priv); -bool intel_can_enable_sagv(struct drm_atomic_state *state); -int intel_enable_sagv(struct drm_i915_private *dev_priv); -int intel_disable_sagv(struct drm_i915_private *dev_priv); -bool skl_wm_level_equals(const struct skl_wm_level *l1, - const struct skl_wm_level *l2); -bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, - const struct skl_ddb_entry entries[], - int num_entries, int ignore_idx); -void skl_write_plane_wm(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state); -void skl_write_cursor_wm(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state); -bool ilk_disable_lp_wm(struct drm_device *dev); -int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, - struct intel_crtc_state *cstate); -void intel_init_ipc(struct drm_i915_private *dev_priv); -void intel_enable_ipc(struct drm_i915_private *dev_priv); - /* intel_sprite.c */ bool is_planar_yuv_format(u32 pixelformat); int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b3c4f640117f..b48b3e9257d6 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -36,6 +36,7 @@ #include "i915_drv.h" #include "intel_drv.h" #include "intel_fbc.h" +#include "intel_pm.h" #include "../../../platform/x86/intel_ips.h" /** @@ -5252,7 +5253,7 @@ static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, } bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, - const struct skl_ddb_entry entries[], + const struct skl_ddb_entry *entries, int num_entries, int ignore_idx) { int i; diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h new file mode 100644 index 000000000000..674a3f0f16a7 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_pm.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_PM_H__ +#define __INTEL_PM_H__ + +#include + +struct drm_atomic_state; +struct drm_device; +struct drm_i915_private; +struct i915_request; +struct intel_crtc; +struct intel_crtc_state; +struct intel_plane; +struct skl_ddb_allocation; +struct skl_ddb_entry; +struct skl_pipe_wm; +struct skl_wm_level; + +void intel_init_clock_gating(struct drm_i915_private *dev_priv); +void intel_suspend_hw(struct drm_i915_private *dev_priv); +int ilk_wm_max_level(const struct drm_i915_private *dev_priv); +void intel_update_watermarks(struct intel_crtc *crtc); +void intel_init_pm(struct drm_i915_private *dev_priv); +void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); +void intel_pm_setup(struct drm_i915_private *dev_priv); +void intel_gpu_ips_init(struct drm_i915_private *dev_priv); +void intel_gpu_ips_teardown(void); +void intel_init_gt_powersave(struct drm_i915_private *dev_priv); +void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv); +void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv); +void intel_enable_gt_powersave(struct drm_i915_private *dev_priv); +void intel_disable_gt_powersave(struct drm_i915_private *dev_priv); +void gen6_rps_busy(struct drm_i915_private *dev_priv); +void gen6_rps_idle(struct drm_i915_private *dev_priv); +void gen6_rps_boost(struct i915_request *rq); +void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv); +void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv); +void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv); +void skl_wm_get_hw_state(struct drm_i915_private *dev_priv); +void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, + struct skl_ddb_entry *ddb_y, + struct skl_ddb_entry *ddb_uv); +void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, + struct skl_ddb_allocation *ddb /* out */); +void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, + struct skl_pipe_wm *out); +void g4x_wm_sanitize(struct drm_i915_private *dev_priv); +void vlv_wm_sanitize(struct drm_i915_private *dev_priv); +bool intel_can_enable_sagv(struct drm_atomic_state *state); +int intel_enable_sagv(struct drm_i915_private *dev_priv); +int intel_disable_sagv(struct drm_i915_private *dev_priv); +bool skl_wm_level_equals(const struct skl_wm_level *l1, + const struct skl_wm_level *l2); +bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, + const struct skl_ddb_entry *entries, + int num_entries, int ignore_idx); +void skl_write_plane_wm(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state); +void skl_write_cursor_wm(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state); +bool ilk_disable_lp_wm(struct drm_device *dev); +int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc, + struct intel_crtc_state *cstate); +void intel_init_ipc(struct drm_i915_private *dev_priv); +void intel_enable_ipc(struct drm_i915_private *dev_priv); + +#endif /* __INTEL_PM_H__ */ diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index d02da53e9806..0274e70f6034 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -42,6 +42,7 @@ #include "i915_drv.h" #include "intel_drv.h" #include "intel_frontbuffer.h" +#include "intel_pm.h" #include "intel_psr.h" bool is_planar_yuv_format(u32 pixelformat) diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index a01d1b352a7c..d1d51e1121e2 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -21,12 +21,13 @@ * IN THE SOFTWARE. */ +#include +#include + #include "i915_drv.h" -#include "intel_drv.h" #include "i915_vgpu.h" - -#include -#include +#include "intel_drv.h" +#include "intel_pm.h" #define FORCEWAKE_ACK_TIMEOUT_MS 50 #define GT_FIFO_TIMEOUT_MS 10 -- cgit v1.2.3 From 6dfccb95cf17cd7e144d5214f2c41c17e7e31ec4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:16 +0300 Subject: drm/i915: extract intel_fbdev.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/82d11bf634094f44a7469a096de3d3768314d6bc.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_pci.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 40 ----------------------- drivers/gpu/drm/i915/intel_fbdev.c | 17 +++++----- drivers/gpu/drm/i915/intel_fbdev.h | 53 +++++++++++++++++++++++++++++++ 7 files changed, 66 insertions(+), 48 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_fbdev.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index ab7ac0ac17a1..9fd6f3460334 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -17,6 +17,7 @@ header_test := \ intel_ddi.h \ intel_engine_types.h \ intel_fbc.h \ + intel_fbdev.h \ intel_frontbuffer.h \ intel_hdcp.h \ intel_lspcon.h \ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ef799fe20510..b356d984dd5c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -56,6 +56,7 @@ #include "intel_audio.h" #include "intel_csr.h" #include "intel_drv.h" +#include "intel_fbdev.h" #include "intel_pm.h" #include "intel_uc.h" #include "intel_workarounds.h" diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 6ffb85ddac53..f893c2cbce15 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -31,6 +31,7 @@ #include "i915_drv.h" #include "i915_globals.h" #include "i915_selftest.h" +#include "intel_fbdev.h" #define PLATFORM(x) .platform = (x) #define GEN(x) .gen = (x), .gen_mask = BIT((x) - 1) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3c8b72dd150c..898af6eb019f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -54,6 +54,7 @@ #include "intel_drv.h" #include "intel_dsi.h" #include "intel_fbc.h" +#include "intel_fbdev.h" #include "intel_frontbuffer.h" #include "intel_hdcp.h" #include "intel_pm.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5d4031f122dd..54170ced81dd 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1973,46 +1973,6 @@ void intel_hpd_poll_init(struct drm_i915_private *dev_priv); bool intel_encoder_hotplug(struct intel_encoder *encoder, struct intel_connector *connector); -/* legacy fbdev emulation in intel_fbdev.c */ -#ifdef CONFIG_DRM_FBDEV_EMULATION -extern int intel_fbdev_init(struct drm_device *dev); -extern void intel_fbdev_initial_config_async(struct drm_device *dev); -extern void intel_fbdev_unregister(struct drm_i915_private *dev_priv); -extern void intel_fbdev_fini(struct drm_i915_private *dev_priv); -extern void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous); -extern void intel_fbdev_output_poll_changed(struct drm_device *dev); -extern void intel_fbdev_restore_mode(struct drm_device *dev); -#else -static inline int intel_fbdev_init(struct drm_device *dev) -{ - return 0; -} - -static inline void intel_fbdev_initial_config_async(struct drm_device *dev) -{ -} - -static inline void intel_fbdev_unregister(struct drm_i915_private *dev_priv) -{ -} - -static inline void intel_fbdev_fini(struct drm_i915_private *dev_priv) -{ -} - -static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) -{ -} - -static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) -{ -} - -static inline void intel_fbdev_restore_mode(struct drm_device *dev) -{ -} -#endif - /* intel_hdmi.c */ void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, enum port port); diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index e8f694b57b8a..285a6e20a016 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -25,26 +25,27 @@ */ #include -#include -#include #include +#include #include -#include +#include +#include #include -#include +#include +#include #include -#include -#include +#include #include #include #include #include +#include +#include "i915_drv.h" #include "intel_drv.h" +#include "intel_fbdev.h" #include "intel_frontbuffer.h" -#include -#include "i915_drv.h" static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev) { diff --git a/drivers/gpu/drm/i915/intel_fbdev.h b/drivers/gpu/drm/i915/intel_fbdev.h new file mode 100644 index 000000000000..de7c84250eb5 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_fbdev.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_FBDEV_H__ +#define __INTEL_FBDEV_H__ + +#include + +struct drm_device; +struct drm_i915_private; + +#ifdef CONFIG_DRM_FBDEV_EMULATION +int intel_fbdev_init(struct drm_device *dev); +void intel_fbdev_initial_config_async(struct drm_device *dev); +void intel_fbdev_unregister(struct drm_i915_private *dev_priv); +void intel_fbdev_fini(struct drm_i915_private *dev_priv); +void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous); +void intel_fbdev_output_poll_changed(struct drm_device *dev); +void intel_fbdev_restore_mode(struct drm_device *dev); +#else +static inline int intel_fbdev_init(struct drm_device *dev) +{ + return 0; +} + +static inline void intel_fbdev_initial_config_async(struct drm_device *dev) +{ +} + +static inline void intel_fbdev_unregister(struct drm_i915_private *dev_priv) +{ +} + +static inline void intel_fbdev_fini(struct drm_i915_private *dev_priv) +{ +} + +static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) +{ +} + +static inline void intel_fbdev_output_poll_changed(struct drm_device *dev) +{ +} + +static inline void intel_fbdev_restore_mode(struct drm_device *dev) +{ +} +#endif + +#endif /* __INTEL_FBDEV_H__ */ -- cgit v1.2.3 From 27fec1f9734d33539df6c05fceb84fd981792899 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:17 +0300 Subject: drm/i915: extract intel_dp.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/f86f9beed730eaad0bdcc18b18817b3d221e16e2.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_dp.h | 121 ++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dp_link_training.c | 1 + drivers/gpu/drm/i915/intel_dp_mst.c | 1 + drivers/gpu/drm/i915/intel_dpio_phy.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 97 +-------------------- drivers/gpu/drm/i915/intel_frontbuffer.c | 1 + drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_lspcon.c | 1 + drivers/gpu/drm/i915/intel_psr.c | 1 + drivers/gpu/drm/i915/intel_runtime_pm.c | 1 + 16 files changed, 137 insertions(+), 95 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_dp.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 9fd6f3460334..fbc172a26cb1 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -15,6 +15,7 @@ header_test := \ intel_crt.h \ intel_csr.h \ intel_ddi.h \ + intel_dp.h \ intel_engine_types.h \ intel_fbc.h \ intel_fbdev.h \ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 7c8e3e5b8aab..3d86265f05ed 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -33,6 +33,7 @@ #include #include "i915_reset.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_fbc.h" #include "intel_guc_submission.h" diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b356d984dd5c..91c75de8c6a5 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -55,6 +55,7 @@ #include "i915_vgpu.h" #include "intel_audio.h" #include "intel_csr.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_fbdev.h" #include "intel_pm.h" diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ca66ac998008..395e515b91bd 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -31,6 +31,7 @@ #include "intel_audio.h" #include "intel_connector.h" #include "intel_ddi.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_dsi.h" #include "intel_hdcp.h" diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 898af6eb019f..4939db5a62e2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -51,6 +51,7 @@ #include "intel_color.h" #include "intel_crt.h" #include "intel_ddi.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_dsi.h" #include "intel_fbc.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 02d662ff5df9..46d27ed6954b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -45,6 +45,7 @@ #include "intel_audio.h" #include "intel_connector.h" #include "intel_ddi.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_hdcp.h" #include "intel_lspcon.h" diff --git a/drivers/gpu/drm/i915/intel_dp.h b/drivers/gpu/drm/i915/intel_dp.h new file mode 100644 index 000000000000..5c152ca6f9ed --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dp.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_DP_H__ +#define __INTEL_DP_H__ + +#include + +#include + +#include "i915_reg.h" + +enum pipe; +struct drm_connector_state; +struct drm_encoder; +struct drm_i915_private; +struct drm_modeset_acquire_ctx; +struct intel_connector; +struct intel_crtc_state; +struct intel_digital_port; +struct intel_dp; +struct intel_encoder; + +struct link_config_limits { + int min_clock, max_clock; + int min_lane_count, max_lane_count; + int min_bpp, max_bpp; +}; + +void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, + struct intel_crtc_state *pipe_config, + struct link_config_limits *limits); +bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +bool intel_dp_port_enabled(struct drm_i915_private *dev_priv, + i915_reg_t dp_reg, enum port port, + enum pipe *pipe); +bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg, + enum port port); +bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector); +void intel_dp_set_link_params(struct intel_dp *intel_dp, + int link_rate, u8 lane_count, + bool link_mst); +int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, + int link_rate, u8 lane_count); +int intel_dp_retrain_link(struct intel_encoder *encoder, + struct drm_modeset_acquire_ctx *ctx); +void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); +void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + bool enable); +void intel_dp_encoder_reset(struct drm_encoder *encoder); +void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); +void intel_dp_encoder_flush_work(struct drm_encoder *encoder); +int intel_dp_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state); +bool intel_dp_is_edp(struct intel_dp *intel_dp); +bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port); +enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, + bool long_hpd); +void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); +void intel_edp_backlight_off(const struct drm_connector_state *conn_state); +void intel_edp_panel_vdd_on(struct intel_dp *intel_dp); +void intel_edp_panel_on(struct intel_dp *intel_dp); +void intel_edp_panel_off(struct intel_dp *intel_dp); +void intel_dp_mst_suspend(struct drm_i915_private *dev_priv); +void intel_dp_mst_resume(struct drm_i915_private *dev_priv); +int intel_dp_max_link_rate(struct intel_dp *intel_dp); +int intel_dp_max_lane_count(struct intel_dp *intel_dp); +int intel_dp_rate_select(struct intel_dp *intel_dp, int rate); +void intel_power_sequencer_reset(struct drm_i915_private *dev_priv); +u32 intel_dp_pack_aux(const u8 *src, int src_bytes); + +void intel_edp_drrs_enable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_edp_drrs_disable(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state); +void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits); +void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, + unsigned int frontbuffer_bits); + +void +intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, + u8 dp_train_pat); +void +intel_dp_set_signal_levels(struct intel_dp *intel_dp); +void intel_dp_set_idle_link_train(struct intel_dp *intel_dp); +u8 +intel_dp_voltage_max(struct intel_dp *intel_dp); +u8 +intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing); +void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, + u8 *link_bw, u8 *rate_select); +bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); +bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp); +bool +intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status); +u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count, + int mode_clock, int mode_hdisplay); +u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock, + int mode_hdisplay); + +bool intel_dp_read_dpcd(struct intel_dp *intel_dp); +int intel_dp_link_required(int pixel_clock, int bpp); +int intel_dp_max_data_rate(int max_link_clock, int max_lanes); +bool intel_digital_port_connected(struct intel_encoder *encoder); +void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv, + struct intel_digital_port *dig_port); + +static inline unsigned int intel_dp_unused_lane_mask(int lane_count) +{ + return ~((1 << lane_count) - 1) & 0xf; +} + +#endif /* __INTEL_DP_H__ */ diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c index b59c87daa4f7..54b069333e2f 100644 --- a/drivers/gpu/drm/i915/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/intel_dp_link_training.c @@ -21,6 +21,7 @@ * IN THE SOFTWARE. */ +#include "intel_dp.h" #include "intel_drv.h" static void diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 041003884860..9c4c0589c0fc 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -31,6 +31,7 @@ #include "intel_audio.h" #include "intel_connector.h" #include "intel_ddi.h" +#include "intel_dp.h" #include "intel_drv.h" static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c index db295c77ff0d..ab4ac7158b79 100644 --- a/drivers/gpu/drm/i915/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/intel_dpio_phy.c @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include "intel_dp.h" #include "intel_drv.h" /** diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 54170ced81dd..334f05d2346d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1664,6 +1664,7 @@ void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, const char *context); /* intel_display.c */ +void intel_plane_destroy(struct drm_plane *plane); void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc); @@ -1847,91 +1848,9 @@ unsigned int i9xx_plane_max_stride(struct intel_plane *plane, u32 pixel_format, u64 modifier, unsigned int rotation); -/* intel_dp.c */ -struct link_config_limits { - int min_clock, max_clock; - int min_lane_count, max_lane_count; - int min_bpp, max_bpp; -}; -void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - struct link_config_limits *limits); -bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -bool intel_dp_port_enabled(struct drm_i915_private *dev_priv, - i915_reg_t dp_reg, enum port port, - enum pipe *pipe); -bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg, - enum port port); -bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, - struct intel_connector *intel_connector); -void intel_dp_set_link_params(struct intel_dp *intel_dp, - int link_rate, u8 lane_count, - bool link_mst); -int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, - int link_rate, u8 lane_count); +/* intel_dp_link_training.c */ void intel_dp_start_link_train(struct intel_dp *intel_dp); void intel_dp_stop_link_train(struct intel_dp *intel_dp); -int intel_dp_retrain_link(struct intel_encoder *encoder, - struct drm_modeset_acquire_ctx *ctx); -void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); -void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - bool enable); -void intel_dp_encoder_reset(struct drm_encoder *encoder); -void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); -void intel_dp_encoder_flush_work(struct drm_encoder *encoder); -int intel_dp_compute_config(struct intel_encoder *encoder, - struct intel_crtc_state *pipe_config, - struct drm_connector_state *conn_state); -bool intel_dp_is_edp(struct intel_dp *intel_dp); -bool intel_dp_is_port_edp(struct drm_i915_private *dev_priv, enum port port); -enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, - bool long_hpd); -void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, - const struct drm_connector_state *conn_state); -void intel_edp_backlight_off(const struct drm_connector_state *conn_state); -void intel_edp_panel_vdd_on(struct intel_dp *intel_dp); -void intel_edp_panel_on(struct intel_dp *intel_dp); -void intel_edp_panel_off(struct intel_dp *intel_dp); -void intel_dp_mst_suspend(struct drm_i915_private *dev_priv); -void intel_dp_mst_resume(struct drm_i915_private *dev_priv); -int intel_dp_max_link_rate(struct intel_dp *intel_dp); -int intel_dp_max_lane_count(struct intel_dp *intel_dp); -int intel_dp_rate_select(struct intel_dp *intel_dp, int rate); -void intel_dp_hot_plug(struct intel_encoder *intel_encoder); -void intel_power_sequencer_reset(struct drm_i915_private *dev_priv); -u32 intel_dp_pack_aux(const u8 *src, int src_bytes); -void intel_plane_destroy(struct drm_plane *plane); -void intel_edp_drrs_enable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_disable(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state); -void intel_edp_drrs_invalidate(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits); -void intel_edp_drrs_flush(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits); - -void -intel_dp_program_link_training_pattern(struct intel_dp *intel_dp, - u8 dp_train_pat); -void -intel_dp_set_signal_levels(struct intel_dp *intel_dp); -void intel_dp_set_idle_link_train(struct intel_dp *intel_dp); -u8 -intel_dp_voltage_max(struct intel_dp *intel_dp); -u8 -intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, u8 voltage_swing); -void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, - u8 *link_bw, u8 *rate_select); -bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); -bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp); -bool -intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE]); -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count, - int mode_clock, int mode_hdisplay); -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock, - int mode_hdisplay); /* intel_vdsc.c */ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp, @@ -1939,18 +1858,6 @@ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp, enum intel_display_power_domain intel_dsc_power_domain(const struct intel_crtc_state *crtc_state); -static inline unsigned int intel_dp_unused_lane_mask(int lane_count) -{ - return ~((1 << lane_count) - 1) & 0xf; -} - -bool intel_dp_read_dpcd(struct intel_dp *intel_dp); -int intel_dp_link_required(int pixel_clock, int bpp); -int intel_dp_max_data_rate(int max_link_clock, int max_lanes); -bool intel_digital_port_connected(struct intel_encoder *encoder); -void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv, - struct intel_digital_port *dig_port); - /* intel_dp_aux_backlight.c */ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector); diff --git a/drivers/gpu/drm/i915/intel_frontbuffer.c b/drivers/gpu/drm/i915/intel_frontbuffer.c index a42f859ad22e..aa34e33b6087 100644 --- a/drivers/gpu/drm/i915/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/intel_frontbuffer.c @@ -62,6 +62,7 @@ #include "i915_drv.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 5725fedaceec..2207cc4f5012 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -43,6 +43,7 @@ #include "intel_audio.h" #include "intel_connector.h" #include "intel_ddi.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_hdcp.h" #include "intel_lspcon.h" diff --git a/drivers/gpu/drm/i915/intel_lspcon.c b/drivers/gpu/drm/i915/intel_lspcon.c index 5f32e1f018b7..7028d0cf3bb1 100644 --- a/drivers/gpu/drm/i915/intel_lspcon.c +++ b/drivers/gpu/drm/i915/intel_lspcon.c @@ -27,6 +27,7 @@ #include #include +#include "intel_dp.h" #include "intel_drv.h" #include "intel_lspcon.h" diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 6592aa48c8ef..30016e054344 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -24,6 +24,7 @@ #include #include "i915_drv.h" +#include "intel_dp.h" #include "intel_drv.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index b72af95b893b..d78256116cb8 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -34,6 +34,7 @@ #include "i915_drv.h" #include "intel_crt.h" #include "intel_csr.h" +#include "intel_dp.h" #include "intel_drv.h" /** -- cgit v1.2.3 From 0550691d58f9ce7e72118916f05f9c510183767f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:18 +0300 Subject: drm/i915: extract intel_hdmi.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/357856c31e309f0af8eed0d800623a5253ff3a37.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/intel_ddi.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 38 +++++------------------ drivers/gpu/drm/i915/intel_hdmi.c | 1 + drivers/gpu/drm/i915/intel_hdmi.h | 51 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_sdvo.c | 1 + 9 files changed, 65 insertions(+), 31 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_hdmi.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index fbc172a26cb1..e78eeaa8ec33 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -21,6 +21,7 @@ header_test := \ intel_fbdev.h \ intel_frontbuffer.h \ intel_hdcp.h \ + intel_hdmi.h \ intel_lspcon.h \ intel_panel.h \ intel_pm.h \ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3d86265f05ed..4622afa22827 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -38,6 +38,7 @@ #include "intel_fbc.h" #include "intel_guc_submission.h" #include "intel_hdcp.h" +#include "intel_hdmi.h" #include "intel_pm.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 395e515b91bd..720de7a3f5e6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -35,6 +35,7 @@ #include "intel_drv.h" #include "intel_dsi.h" #include "intel_hdcp.h" +#include "intel_hdmi.h" #include "intel_lspcon.h" #include "intel_panel.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4939db5a62e2..947e2b049056 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -58,6 +58,7 @@ #include "intel_fbdev.h" #include "intel_frontbuffer.h" #include "intel_hdcp.h" +#include "intel_hdmi.h" #include "intel_pm.h" #include "intel_psr.h" #include "intel_sdvo.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 46d27ed6954b..a5eeb1b89376 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -48,6 +48,7 @@ #include "intel_dp.h" #include "intel_drv.h" #include "intel_hdcp.h" +#include "intel_hdmi.h" #include "intel_lspcon.h" #include "intel_panel.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 334f05d2346d..d54b6134e533 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -27,23 +27,24 @@ #include #include -#include #include #include -#include -#include "i915_drv.h" + +#include #include -#include -#include #include #include +#include +#include #include #include #include -#include +#include #include #include +#include "i915_drv.h" + struct drm_printer; /** @@ -1880,31 +1881,6 @@ void intel_hpd_poll_init(struct drm_i915_private *dev_priv); bool intel_encoder_hotplug(struct intel_encoder *encoder, struct intel_connector *connector); -/* intel_hdmi.c */ -void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, - enum port port); -void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, - struct intel_connector *intel_connector); -struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); -int intel_hdmi_compute_config(struct intel_encoder *encoder, - struct intel_crtc_state *pipe_config, - struct drm_connector_state *conn_state); -bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, - struct drm_connector *connector, - bool high_tmds_clock_ratio, - bool scrambling); -void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable); -void intel_infoframe_init(struct intel_digital_port *intel_dig_port); -u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state); -u32 intel_hdmi_infoframe_enable(unsigned int type); -void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state); -void intel_read_infoframe(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - enum hdmi_infoframe_type type, - union hdmi_infoframe *frame); - /* intel_lvds.c */ bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv, i915_reg_t lvds_reg, enum pipe *pipe); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 2207cc4f5012..e1005d7b75fd 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -46,6 +46,7 @@ #include "intel_dp.h" #include "intel_drv.h" #include "intel_hdcp.h" +#include "intel_hdmi.h" #include "intel_lspcon.h" #include "intel_sdvo.h" #include "intel_panel.h" diff --git a/drivers/gpu/drm/i915/intel_hdmi.h b/drivers/gpu/drm/i915/intel_hdmi.h new file mode 100644 index 000000000000..106c2e0bc3c9 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_hdmi.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_HDMI_H__ +#define __INTEL_HDMI_H__ + +#include +#include + +#include + +#include "i915_reg.h" + +struct drm_connector; +struct drm_encoder; +struct drm_i915_private; +struct intel_connector; +struct intel_digital_port; +struct intel_encoder; +struct intel_crtc_state; +struct intel_hdmi; +struct drm_connector_state; +union hdmi_infoframe; + +void intel_hdmi_init(struct drm_i915_private *dev_priv, i915_reg_t hdmi_reg, + enum port port); +void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, + struct intel_connector *intel_connector); +struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder); +int intel_hdmi_compute_config(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config, + struct drm_connector_state *conn_state); +bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, + struct drm_connector *connector, + bool high_tmds_clock_ratio, + bool scrambling); +void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable); +void intel_infoframe_init(struct intel_digital_port *intel_dig_port); +u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); +u32 intel_hdmi_infoframe_enable(unsigned int type); +void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state); +void intel_read_infoframe(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + enum hdmi_infoframe_type type, + union hdmi_infoframe *frame); + +#endif /* __INTEL_HDMI_H__ */ diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c815845e8c34..0e3d91d9ef13 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -39,6 +39,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_hdmi.h" #include "intel_panel.h" #include "intel_sdvo.h" #include "intel_sdvo_regs.h" -- cgit v1.2.3 From 56dabc93025220eb5d09ff95adfc560cb665d3e0 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:19 +0300 Subject: drm/i915: extract intel_atomic_plane.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. v2: revert intel_plane_destroy_state() movement within intel_atomic_plane.c Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/fd56c1cbba22b9f195ad944d79f7977423b2b533.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_atomic_plane.c | 1 + drivers/gpu/drm/i915/intel_atomic_plane.h | 40 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 24 ------------------- drivers/gpu/drm/i915/intel_sprite.c | 1 + 6 files changed, 44 insertions(+), 24 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_atomic_plane.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index e78eeaa8ec33..43c939da9665 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -8,6 +8,7 @@ header_test := \ i915_priolist_types.h \ i915_scheduler_types.h \ i915_timeline_types.h \ + intel_atomic_plane.h \ intel_audio.h \ intel_color.h \ intel_connector.h \ diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 42821f8e6031..07222466506f 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -35,6 +35,7 @@ #include #include +#include "intel_atomic_plane.h" #include "intel_drv.h" #include "intel_pm.h" diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.h b/drivers/gpu/drm/i915/intel_atomic_plane.h new file mode 100644 index 000000000000..14678620440f --- /dev/null +++ b/drivers/gpu/drm/i915/intel_atomic_plane.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_ATOMIC_PLANE_H__ +#define __INTEL_ATOMIC_PLANE_H__ + +struct drm_plane; +struct intel_atomic_state; +struct intel_crtc; +struct intel_crtc_state; +struct intel_plane; +struct intel_plane_state; + +extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; + +void intel_update_plane(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state); +void intel_update_slave(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state); +void intel_disable_plane(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state); +struct intel_plane *intel_plane_alloc(void); +void intel_plane_free(struct intel_plane *plane); +struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane); +void intel_plane_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state); +void skl_update_planes_on_crtc(struct intel_atomic_state *state, + struct intel_crtc *crtc); +void i9xx_update_planes_on_crtc(struct intel_atomic_state *state, + struct intel_crtc *crtc); +int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *crtc_state, + const struct intel_plane_state *old_plane_state, + struct intel_plane_state *intel_state); + +#endif /* __INTEL_ATOMIC_PLANE_H__ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 947e2b049056..4f53fc31dd0a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -48,6 +48,7 @@ #include "i915_gem_clflush.h" #include "i915_reset.h" #include "i915_trace.h" +#include "intel_atomic_plane.h" #include "intel_color.h" #include "intel_crt.h" #include "intel_ddi.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d54b6134e533..ad53165d3151 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2121,30 +2121,6 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state); -/* intel_atomic_plane.c */ -void intel_update_plane(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state); -void intel_update_slave(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state, - const struct intel_plane_state *plane_state); -void intel_disable_plane(struct intel_plane *plane, - const struct intel_crtc_state *crtc_state); -struct intel_plane *intel_plane_alloc(void); -void intel_plane_free(struct intel_plane *plane); -struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane); -void intel_plane_destroy_state(struct drm_plane *plane, - struct drm_plane_state *state); -extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; -void skl_update_planes_on_crtc(struct intel_atomic_state *state, - struct intel_crtc *crtc); -void i9xx_update_planes_on_crtc(struct intel_atomic_state *state, - struct intel_crtc *crtc); -int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state, - struct intel_crtc_state *crtc_state, - const struct intel_plane_state *old_plane_state, - struct intel_plane_state *intel_state); - /* intel_pipe_crc.c */ #ifdef CONFIG_DEBUG_FS int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 0274e70f6034..50ba32eaee9e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -40,6 +40,7 @@ #include #include "i915_drv.h" +#include "intel_atomic_plane.h" #include "intel_drv.h" #include "intel_frontbuffer.h" #include "intel_pm.h" -- cgit v1.2.3 From c6a35b9cf9e2af89a34fc35ed8006c666b8fcad9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:20 +0300 Subject: drm/i915: extract intel_pipe_crc.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/b106b21ef11ff7fc34537b2c029a1332c8573fcc.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 21 ------------------- drivers/gpu/drm/i915/intel_pipe_crc.c | 4 +++- drivers/gpu/drm/i915/intel_pipe_crc.h | 35 +++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_pipe_crc.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 43c939da9665..2724ccff61ea 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -25,6 +25,7 @@ header_test := \ intel_hdmi.h \ intel_lspcon.h \ intel_panel.h \ + intel_pipe_crc.h \ intel_pm.h \ intel_psr.h \ intel_sdvo.h \ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4f53fc31dd0a..0058c951fb2b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -60,6 +60,7 @@ #include "intel_frontbuffer.h" #include "intel_hdcp.h" #include "intel_hdmi.h" +#include "intel_pipe_crc.h" #include "intel_pm.h" #include "intel_psr.h" #include "intel_sdvo.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ad53165d3151..c024ef9dfe6d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2121,25 +2121,4 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state); -/* intel_pipe_crc.c */ -#ifdef CONFIG_DEBUG_FS -int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name); -int intel_crtc_verify_crc_source(struct drm_crtc *crtc, - const char *source_name, size_t *values_cnt); -const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc, - size_t *count); -void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc); -void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc); -#else -#define intel_crtc_set_crc_source NULL -#define intel_crtc_verify_crc_source NULL -#define intel_crtc_get_crc_sources NULL -static inline void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc) -{ -} - -static inline void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc) -{ -} -#endif #endif /* __INTEL_DRV_H__ */ diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c index 0b1378f0bff7..e94b5b1bc1b7 100644 --- a/drivers/gpu/drm/i915/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c @@ -24,11 +24,13 @@ * */ -#include #include #include #include +#include + #include "intel_drv.h" +#include "intel_pipe_crc.h" static const char * const pipe_crc_sources[] = { [INTEL_PIPE_CRC_SOURCE_NONE] = "none", diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.h b/drivers/gpu/drm/i915/intel_pipe_crc.h new file mode 100644 index 000000000000..81eaf1854788 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_pipe_crc.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_PIPE_CRC_H__ +#define __INTEL_PIPE_CRC_H__ + +#include + +struct drm_crtc; +struct intel_crtc; + +#ifdef CONFIG_DEBUG_FS +int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name); +int intel_crtc_verify_crc_source(struct drm_crtc *crtc, + const char *source_name, size_t *values_cnt); +const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc, + size_t *count); +void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc); +void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc); +#else +#define intel_crtc_set_crc_source NULL +#define intel_crtc_verify_crc_source NULL +#define intel_crtc_get_crc_sources NULL +static inline void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc) +{ +} + +static inline void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc) +{ +} +#endif + +#endif /* __INTEL_PIPE_CRC_H__ */ -- cgit v1.2.3 From efe57eeae510229703bc6544dbefb801335a00de Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:21 +0300 Subject: drm/i915: extract intel_tv.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/f44c21e3d154e47233ebef4267ce1a924fa38df7.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 3 --- drivers/gpu/drm/i915/intel_tv.c | 1 + drivers/gpu/drm/i915/intel_tv.h | 13 +++++++++++++ 5 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_tv.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 2724ccff61ea..595d9b34d866 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -29,6 +29,7 @@ header_test := \ intel_pm.h \ intel_psr.h \ intel_sdvo.h \ + intel_tv.h \ intel_workarounds_types.h quiet_cmd_header_test = HDRTEST $@ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0058c951fb2b..50e848057a20 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -64,6 +64,7 @@ #include "intel_pm.h" #include "intel_psr.h" #include "intel_sdvo.h" +#include "intel_tv.h" /* Primary plane formats for gen <= 3 */ static const u32 i8xx_primary_formats[] = { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c024ef9dfe6d..d03ae74b4765 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2082,9 +2082,6 @@ static inline bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, return plane_id < PLANE_SPRITE2; } -/* intel_tv.c */ -void intel_tv_init(struct drm_i915_private *dev_priv); - /* intel_atomic.c */ int intel_digital_connector_atomic_get_property(struct drm_connector *connector, const struct drm_connector_state *state, diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 14f862015070..5dbba33f4202 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -38,6 +38,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_tv.h" enum tv_margin { TV_MARGIN_LEFT, TV_MARGIN_TOP, diff --git a/drivers/gpu/drm/i915/intel_tv.h b/drivers/gpu/drm/i915/intel_tv.h new file mode 100644 index 000000000000..44518575ec5c --- /dev/null +++ b/drivers/gpu/drm/i915/intel_tv.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_TV_H__ +#define __INTEL_TV_H__ + +struct drm_i915_private; + +void intel_tv_init(struct drm_i915_private *dev_priv); + +#endif /* __INTEL_TV_H__ */ -- cgit v1.2.3 From 42406fdc282c7f2447a80063f5030260524f8091 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:22 +0300 Subject: drm/i915: extract intel_lvds.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/5d54d02cf7b7bfe3f78ed60d28534c5726371af3.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 7 ------- drivers/gpu/drm/i915/intel_lvds.c | 1 + drivers/gpu/drm/i915/intel_lvds.h | 22 ++++++++++++++++++++++ 6 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_lvds.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 595d9b34d866..486ad9679d7f 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -24,6 +24,7 @@ header_test := \ intel_hdcp.h \ intel_hdmi.h \ intel_lspcon.h \ + intel_lvds.h \ intel_panel.h \ intel_pipe_crc.h \ intel_pm.h \ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 50e848057a20..2ac63c073fda 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -60,6 +60,7 @@ #include "intel_frontbuffer.h" #include "intel_hdcp.h" #include "intel_hdmi.h" +#include "intel_lvds.h" #include "intel_pipe_crc.h" #include "intel_pm.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a5eeb1b89376..c4e36759a756 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -50,6 +50,7 @@ #include "intel_hdcp.h" #include "intel_hdmi.h" #include "intel_lspcon.h" +#include "intel_lvds.h" #include "intel_panel.h" #include "intel_psr.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d03ae74b4765..948b15aa8b9e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1881,13 +1881,6 @@ void intel_hpd_poll_init(struct drm_i915_private *dev_priv); bool intel_encoder_hotplug(struct intel_encoder *encoder, struct intel_connector *connector); -/* intel_lvds.c */ -bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv, - i915_reg_t lvds_reg, enum pipe *pipe); -void intel_lvds_init(struct drm_i915_private *dev_priv); -struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *dev_priv); -bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv); - /* intel_overlay.c */ void intel_overlay_setup(struct drm_i915_private *dev_priv); void intel_overlay_cleanup(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 3788d2fe4a9e..51d1d59c1619 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -42,6 +42,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_lvds.h" #include "intel_panel.h" /* Private structure for the integrated LVDS support */ diff --git a/drivers/gpu/drm/i915/intel_lvds.h b/drivers/gpu/drm/i915/intel_lvds.h new file mode 100644 index 000000000000..bc9c8b84ba2f --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lvds.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_LVDS_H__ +#define __INTEL_LVDS_H__ + +#include + +#include "i915_reg.h" + +enum pipe; +struct drm_i915_private; + +bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv, + i915_reg_t lvds_reg, enum pipe *pipe); +void intel_lvds_init(struct drm_i915_private *dev_priv); +struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *dev_priv); +bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv); + +#endif /* __INTEL_LVDS_H__ */ -- cgit v1.2.3 From 75a4639a9f9a15de1525eaa898574179b09d7b26 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:23 +0300 Subject: drm/i915: extract intel_dvo.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1ccf9000ad33b895aea06be41053a5b7bac8459e.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 2 -- drivers/gpu/drm/i915/intel_dvo.c | 1 + drivers/gpu/drm/i915/intel_dvo.h | 13 +++++++++++++ 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_dvo.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 486ad9679d7f..24cfbb5c0f51 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -17,6 +17,7 @@ header_test := \ intel_csr.h \ intel_ddi.h \ intel_dp.h \ + intel_dvo.h \ intel_engine_types.h \ intel_fbc.h \ intel_fbdev.h \ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2ac63c073fda..7f7dbcd7b6aa 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -55,6 +55,7 @@ #include "intel_dp.h" #include "intel_drv.h" #include "intel_dsi.h" +#include "intel_dvo.h" #include "intel_fbc.h" #include "intel_fbdev.h" #include "intel_frontbuffer.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 948b15aa8b9e..4bb8edea65a0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1874,8 +1874,6 @@ void icl_dsi_init(struct drm_i915_private *dev_priv); /* intel_dsi_dcs_backlight.c */ int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector); -/* intel_dvo.c */ -void intel_dvo_init(struct drm_i915_private *dev_priv); /* intel_hotplug.c */ void intel_hpd_poll_init(struct drm_i915_private *dev_priv); bool intel_encoder_hotplug(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 4fda625ea2c1..adef81c8cccb 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -36,6 +36,7 @@ #include "i915_drv.h" #include "intel_connector.h" #include "intel_drv.h" +#include "intel_dvo.h" #include "intel_panel.h" #define SIL164_ADDR 0x38 diff --git a/drivers/gpu/drm/i915/intel_dvo.h b/drivers/gpu/drm/i915/intel_dvo.h new file mode 100644 index 000000000000..3ed0fdf8efff --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dvo.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_DVO_H__ +#define __INTEL_DVO_H__ + +struct drm_i915_private; + +void intel_dvo_init(struct drm_i915_private *dev_priv); + +#endif /* __INTEL_DVO_H__ */ -- cgit v1.2.3 From f9a79f9aeeee6e5e139e93d9e79915f313489d33 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:24 +0300 Subject: drm/i915: extract intel_sprite.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/679c857a1933ee3d0706f978ab05ca880cd30a00.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/intel_atomic.c | 1 + drivers/gpu/drm/i915/intel_atomic_plane.c | 1 + drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 35 -------------------- drivers/gpu/drm/i915/intel_pm.c | 1 + drivers/gpu/drm/i915/intel_psr.c | 1 + drivers/gpu/drm/i915/intel_sprite.c | 1 + drivers/gpu/drm/i915/intel_sprite.h | 55 +++++++++++++++++++++++++++++++ 10 files changed, 63 insertions(+), 35 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_sprite.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 24cfbb5c0f51..83db8f79e3bc 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -31,6 +31,7 @@ header_test := \ intel_pm.h \ intel_psr.h \ intel_sdvo.h \ + intel_sprite.h \ intel_tv.h \ intel_workarounds_types.h diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 91c75de8c6a5..0808f9459447 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -59,6 +59,7 @@ #include "intel_drv.h" #include "intel_fbdev.h" #include "intel_pm.h" +#include "intel_sprite.h" #include "intel_uc.h" #include "intel_workarounds.h" diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index 2cbcf6ac24d8..8c8fae32ec50 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -36,6 +36,7 @@ #include "intel_drv.h" #include "intel_hdcp.h" +#include "intel_sprite.h" /** * intel_digital_connector_atomic_get_property - hook for connector->atomic_get_property. diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 07222466506f..d11681d71add 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -38,6 +38,7 @@ #include "intel_atomic_plane.h" #include "intel_drv.h" #include "intel_pm.h" +#include "intel_sprite.h" struct intel_plane *intel_plane_alloc(void) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 7f7dbcd7b6aa..159a4ed35548 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -66,6 +66,7 @@ #include "intel_pm.h" #include "intel_psr.h" #include "intel_sdvo.h" +#include "intel_sprite.h" #include "intel_tv.h" /* Primary plane formats for gen <= 3 */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4bb8edea65a0..2619264e2b0d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2038,41 +2038,6 @@ void chv_phy_powergate_lanes(struct intel_encoder *encoder, bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy, enum dpio_channel ch, bool override); -/* intel_sprite.c */ -bool is_planar_yuv_format(u32 pixelformat); -int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, - int usecs); -struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, - enum pipe pipe, int plane); -int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state); -void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state); -int intel_plane_check_stride(const struct intel_plane_state *plane_state); -int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); -int chv_plane_check_rotation(const struct intel_plane_state *plane_state); -struct intel_plane * -skl_universal_plane_create(struct drm_i915_private *dev_priv, - enum pipe pipe, enum plane_id plane_id); - -static inline bool icl_is_nv12_y_plane(enum plane_id id) -{ - /* Don't need to do a gen check, these planes are only available on gen11 */ - if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5) - return true; - - return false; -} - -static inline bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, - enum plane_id plane_id) -{ - if (INTEL_GEN(dev_priv) < 11) - return false; - - return plane_id < PLANE_SPRITE2; -} - /* intel_atomic.c */ int intel_digital_connector_atomic_get_property(struct drm_connector *connector, const struct drm_connector_state *state, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b48b3e9257d6..bba477e62a12 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -37,6 +37,7 @@ #include "intel_drv.h" #include "intel_fbc.h" #include "intel_pm.h" +#include "intel_sprite.h" #include "../../../platform/x86/intel_ips.h" /** diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 30016e054344..aacf5c6f6d95 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -27,6 +27,7 @@ #include "intel_dp.h" #include "intel_drv.h" #include "intel_psr.h" +#include "intel_sprite.h" /** * DOC: Panel Self Refresh (PSR/SRD) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 50ba32eaee9e..2913e89280d7 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -45,6 +45,7 @@ #include "intel_frontbuffer.h" #include "intel_pm.h" #include "intel_psr.h" +#include "intel_sprite.h" bool is_planar_yuv_format(u32 pixelformat) { diff --git a/drivers/gpu/drm/i915/intel_sprite.h b/drivers/gpu/drm/i915/intel_sprite.h new file mode 100644 index 000000000000..84be8686be16 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_sprite.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_SPRITE_H__ +#define __INTEL_SPRITE_H__ + +#include + +#include "i915_drv.h" +#include "intel_display.h" + +struct drm_device; +struct drm_display_mode; +struct drm_file; +struct drm_i915_private; +struct intel_crtc_state; +struct intel_plane_state; + +bool is_planar_yuv_format(u32 pixelformat); +int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, + int usecs); +struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv, + enum pipe pipe, int plane); +int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state); +void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state); +int intel_plane_check_stride(const struct intel_plane_state *plane_state); +int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); +int chv_plane_check_rotation(const struct intel_plane_state *plane_state); +struct intel_plane * +skl_universal_plane_create(struct drm_i915_private *dev_priv, + enum pipe pipe, enum plane_id plane_id); + +static inline bool icl_is_nv12_y_plane(enum plane_id id) +{ + /* Don't need to do a gen check, these planes are only available on gen11 */ + if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5) + return true; + + return false; +} + +static inline bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, + enum plane_id plane_id) +{ + if (INTEL_GEN(dev_priv) < 11) + return false; + + return plane_id < PLANE_SPRITE2; +} + +#endif /* __INTEL_SPRITE_H__ */ -- cgit v1.2.3 From e7674ef682f2a018bc34a25f0b32ac9baddf44da Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:25 +0300 Subject: drm/i915: extract intel_cdclk.h from intel_drv.h It used to be handy that we only had a couple of headers, but over time intel_drv.h has become unwieldy. Extract declarations to a separate header file corresponding to the implementation module, clarifying the modularity of the driver. Ensure the new header is self-contained, and do so with minimal further includes, using forward declarations as needed. Include the new header only where needed, and sort the modified include directives while at it and as needed. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/c128d7be3f621391e571e86b03f302f3ffd0ed2b.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile.header-test | 1 + drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/intel_cdclk.c | 1 + drivers/gpu/drm/i915/intel_cdclk.h | 52 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 35 --------------------- drivers/gpu/drm/i915/intel_runtime_pm.c | 1 + 7 files changed, 57 insertions(+), 35 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_cdclk.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile.header-test b/drivers/gpu/drm/i915/Makefile.header-test index 83db8f79e3bc..c1c391816fa7 100644 --- a/drivers/gpu/drm/i915/Makefile.header-test +++ b/drivers/gpu/drm/i915/Makefile.header-test @@ -10,6 +10,7 @@ header_test := \ i915_timeline_types.h \ intel_atomic_plane.h \ intel_audio.h \ + intel_cdclk.h \ intel_color.h \ intel_connector.h \ intel_context_types.h \ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0808f9459447..1ad88e6d7c04 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -54,6 +54,7 @@ #include "i915_trace.h" #include "i915_vgpu.h" #include "intel_audio.h" +#include "intel_cdclk.h" #include "intel_csr.h" #include "intel_dp.h" #include "intel_drv.h" diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index b911fe86be56..c6e163d26158 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -21,6 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include "intel_cdclk.h" #include "intel_drv.h" /** diff --git a/drivers/gpu/drm/i915/intel_cdclk.h b/drivers/gpu/drm/i915/intel_cdclk.h new file mode 100644 index 000000000000..ae4a60b76756 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_cdclk.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_CDCLK_H__ +#define __INTEL_CDCLK_H__ + +#include + +#include "intel_display.h" + +struct drm_i915_private; +struct intel_atomic_state; +struct intel_cdclk_state; +struct intel_crtc_state; + +int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); +void skl_init_cdclk(struct drm_i915_private *dev_priv); +void skl_uninit_cdclk(struct drm_i915_private *dev_priv); +void cnl_init_cdclk(struct drm_i915_private *dev_priv); +void cnl_uninit_cdclk(struct drm_i915_private *dev_priv); +void bxt_init_cdclk(struct drm_i915_private *dev_priv); +void bxt_uninit_cdclk(struct drm_i915_private *dev_priv); +void icl_init_cdclk(struct drm_i915_private *dev_priv); +void icl_uninit_cdclk(struct drm_i915_private *dev_priv); +void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); +void intel_update_max_cdclk(struct drm_i915_private *dev_priv); +void intel_update_cdclk(struct drm_i915_private *dev_priv); +void intel_update_rawclk(struct drm_i915_private *dev_priv); +bool intel_cdclk_needs_cd2x_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *a, + const struct intel_cdclk_state *b); +bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, + const struct intel_cdclk_state *b); +bool intel_cdclk_changed(const struct intel_cdclk_state *a, + const struct intel_cdclk_state *b); +void intel_cdclk_swap_state(struct intel_atomic_state *state); +void +intel_set_cdclk_pre_plane_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *old_state, + const struct intel_cdclk_state *new_state, + enum pipe pipe); +void +intel_set_cdclk_post_plane_update(struct drm_i915_private *dev_priv, + const struct intel_cdclk_state *old_state, + const struct intel_cdclk_state *new_state, + enum pipe pipe); +void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, + const char *context); + +#endif /* __INTEL_CDCLK_H__ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 159a4ed35548..cb7f99618f02 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -50,6 +50,7 @@ #include "i915_trace.h" #include "intel_atomic_plane.h" #include "intel_color.h" +#include "intel_cdclk.h" #include "intel_crt.h" #include "intel_ddi.h" #include "intel_dp.h" diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 2619264e2b0d..766234a123e0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1629,41 +1629,6 @@ void gen9_reset_guc_interrupts(struct drm_i915_private *dev_priv); void gen9_enable_guc_interrupts(struct drm_i915_private *dev_priv); void gen9_disable_guc_interrupts(struct drm_i915_private *dev_priv); -/* intel_cdclk.c */ -int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); -void skl_init_cdclk(struct drm_i915_private *dev_priv); -void skl_uninit_cdclk(struct drm_i915_private *dev_priv); -void cnl_init_cdclk(struct drm_i915_private *dev_priv); -void cnl_uninit_cdclk(struct drm_i915_private *dev_priv); -void bxt_init_cdclk(struct drm_i915_private *dev_priv); -void bxt_uninit_cdclk(struct drm_i915_private *dev_priv); -void icl_init_cdclk(struct drm_i915_private *dev_priv); -void icl_uninit_cdclk(struct drm_i915_private *dev_priv); -void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); -void intel_update_max_cdclk(struct drm_i915_private *dev_priv); -void intel_update_cdclk(struct drm_i915_private *dev_priv); -void intel_update_rawclk(struct drm_i915_private *dev_priv); -bool intel_cdclk_needs_cd2x_update(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *a, - const struct intel_cdclk_state *b); -bool intel_cdclk_needs_modeset(const struct intel_cdclk_state *a, - const struct intel_cdclk_state *b); -bool intel_cdclk_changed(const struct intel_cdclk_state *a, - const struct intel_cdclk_state *b); -void intel_cdclk_swap_state(struct intel_atomic_state *state); -void -intel_set_cdclk_pre_plane_update(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *old_state, - const struct intel_cdclk_state *new_state, - enum pipe pipe); -void -intel_set_cdclk_post_plane_update(struct drm_i915_private *dev_priv, - const struct intel_cdclk_state *old_state, - const struct intel_cdclk_state *new_state, - enum pipe pipe); -void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, - const char *context); - /* intel_display.c */ void intel_plane_destroy(struct drm_plane *plane); void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index d78256116cb8..606f7a1074d8 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -32,6 +32,7 @@ #include #include "i915_drv.h" +#include "intel_cdclk.h" #include "intel_crt.h" #include "intel_csr.h" #include "intel_dp.h" -- cgit v1.2.3 From 93a643f29bcbaac1f2199a5802536b202a553bbe Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 14:00:26 +0300 Subject: drm/i915/cdclk: have only one init/uninit function While transitioning to having better clarity between the modules, it's desirable to have the function name prefixes reflect the module. Functions in intel_foo.c should be prefixed intel_foo_. Expose only one CDCLK init/uninit function from intel_cdclk.c instead of one per platform. Obviously this adds one "unnecessary" if ladder within the entry points. However it should be considered more of a CDCLK implementation detail how this is done per platform, instead of exposing the fact. In other words, abstract the CDCLK module better. No functional changes. Reviewed-by: Chris Wilson Acked-by: Joonas Lahtinen Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/f63ed6e129098a32c63735be6cffa4756e7947af.1554461791.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_cdclk.c | 120 +++++++++++++------------------- drivers/gpu/drm/i915/intel_cdclk.h | 10 +-- drivers/gpu/drm/i915/intel_runtime_pm.c | 16 ++--- 3 files changed, 58 insertions(+), 88 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index c6e163d26158..7f060eaf1b17 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -1129,16 +1129,7 @@ sanitize: dev_priv->cdclk.hw.vco = -1; } -/** - * skl_init_cdclk - Initialize CDCLK on SKL - * @dev_priv: i915 device - * - * Initialize CDCLK for SKL and derivatives. This is generally - * done only during the display core initialization sequence, - * after which the DMC will take care of turning CDCLK off/on - * as needed. - */ -void skl_init_cdclk(struct drm_i915_private *dev_priv) +static void skl_init_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state; @@ -1167,14 +1158,7 @@ void skl_init_cdclk(struct drm_i915_private *dev_priv) skl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } -/** - * skl_uninit_cdclk - Uninitialize CDCLK on SKL - * @dev_priv: i915 device - * - * Uninitialize CDCLK for SKL and derivatives. This is done only - * during the display core uninitialization sequence. - */ -void skl_uninit_cdclk(struct drm_i915_private *dev_priv) +static void skl_uninit_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; @@ -1499,16 +1483,7 @@ sanitize: dev_priv->cdclk.hw.vco = -1; } -/** - * bxt_init_cdclk - Initialize CDCLK on BXT - * @dev_priv: i915 device - * - * Initialize CDCLK for BXT and derivatives. This is generally - * done only during the display core initialization sequence, - * after which the DMC will take care of turning CDCLK off/on - * as needed. - */ -void bxt_init_cdclk(struct drm_i915_private *dev_priv) +static void bxt_init_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state; @@ -1537,14 +1512,7 @@ void bxt_init_cdclk(struct drm_i915_private *dev_priv) bxt_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } -/** - * bxt_uninit_cdclk - Uninitialize CDCLK on BXT - * @dev_priv: i915 device - * - * Uninitialize CDCLK for BXT and derivatives. This is done only - * during the display core uninitialization sequence. - */ -void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) +static void bxt_uninit_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; @@ -1977,16 +1945,7 @@ out: icl_calc_voltage_level(cdclk_state->cdclk); } -/** - * icl_init_cdclk - Initialize CDCLK on ICL - * @dev_priv: i915 device - * - * Initialize CDCLK for ICL. This consists mainly of initializing - * dev_priv->cdclk.hw and sanitizing the state of the hardware if needed. This - * is generally done only during the display core initialization sequence, after - * which the DMC will take care of turning CDCLK off/on as needed. - */ -void icl_init_cdclk(struct drm_i915_private *dev_priv) +static void icl_init_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state sanitized_state; u32 val; @@ -2023,14 +1982,7 @@ sanitize: icl_set_cdclk(dev_priv, &sanitized_state, INVALID_PIPE); } -/** - * icl_uninit_cdclk - Uninitialize CDCLK on ICL - * @dev_priv: i915 device - * - * Uninitialize CDCLK for ICL. This is done only during the display core - * uninitialization sequence. - */ -void icl_uninit_cdclk(struct drm_i915_private *dev_priv) +static void icl_uninit_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; @@ -2041,16 +1993,7 @@ void icl_uninit_cdclk(struct drm_i915_private *dev_priv) icl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } -/** - * cnl_init_cdclk - Initialize CDCLK on CNL - * @dev_priv: i915 device - * - * Initialize CDCLK for CNL. This is generally - * done only during the display core initialization sequence, - * after which the DMC will take care of turning CDCLK off/on - * as needed. - */ -void cnl_init_cdclk(struct drm_i915_private *dev_priv) +static void cnl_init_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state; @@ -2069,14 +2012,7 @@ void cnl_init_cdclk(struct drm_i915_private *dev_priv) cnl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } -/** - * cnl_uninit_cdclk - Uninitialize CDCLK on CNL - * @dev_priv: i915 device - * - * Uninitialize CDCLK for CNL. This is done only - * during the display core uninitialization sequence. - */ -void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) +static void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) { struct intel_cdclk_state cdclk_state = dev_priv->cdclk.hw; @@ -2087,6 +2023,46 @@ void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) cnl_set_cdclk(dev_priv, &cdclk_state, INVALID_PIPE); } +/** + * intel_cdclk_init - Initialize CDCLK + * @i915: i915 device + * + * Initialize CDCLK. This consists mainly of initializing dev_priv->cdclk.hw and + * sanitizing the state of the hardware if needed. This is generally done only + * during the display core initialization sequence, after which the DMC will + * take care of turning CDCLK off/on as needed. + */ +void intel_cdclk_init(struct drm_i915_private *i915) +{ + if (IS_ICELAKE(i915)) + icl_init_cdclk(i915); + else if (IS_CANNONLAKE(i915)) + cnl_init_cdclk(i915); + else if (IS_GEN9_BC(i915)) + skl_init_cdclk(i915); + else if (IS_GEN9_LP(i915)) + bxt_init_cdclk(i915); +} + +/** + * intel_cdclk_uninit - Uninitialize CDCLK + * @i915: i915 device + * + * Uninitialize CDCLK. This is done only during the display core + * uninitialization sequence. + */ +void intel_cdclk_uninit(struct drm_i915_private *i915) +{ + if (IS_ICELAKE(i915)) + icl_uninit_cdclk(i915); + else if (IS_CANNONLAKE(i915)) + cnl_uninit_cdclk(i915); + else if (IS_GEN9_BC(i915)) + skl_uninit_cdclk(i915); + else if (IS_GEN9_LP(i915)) + bxt_uninit_cdclk(i915); +} + /** * intel_cdclk_needs_modeset - Determine if two CDCLK states require a modeset on all pipes * @a: first CDCLK state diff --git a/drivers/gpu/drm/i915/intel_cdclk.h b/drivers/gpu/drm/i915/intel_cdclk.h index ae4a60b76756..4d6f7f5f8930 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.h +++ b/drivers/gpu/drm/i915/intel_cdclk.h @@ -16,14 +16,8 @@ struct intel_cdclk_state; struct intel_crtc_state; int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state); -void skl_init_cdclk(struct drm_i915_private *dev_priv); -void skl_uninit_cdclk(struct drm_i915_private *dev_priv); -void cnl_init_cdclk(struct drm_i915_private *dev_priv); -void cnl_uninit_cdclk(struct drm_i915_private *dev_priv); -void bxt_init_cdclk(struct drm_i915_private *dev_priv); -void bxt_uninit_cdclk(struct drm_i915_private *dev_priv); -void icl_init_cdclk(struct drm_i915_private *dev_priv); -void icl_uninit_cdclk(struct drm_i915_private *dev_priv); +void intel_cdclk_init(struct drm_i915_private *i915); +void intel_cdclk_uninit(struct drm_i915_private *i915); void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv); void intel_update_max_cdclk(struct drm_i915_private *dev_priv); void intel_update_cdclk(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 606f7a1074d8..e6d1e592225b 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -3664,7 +3664,7 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv, mutex_unlock(&power_domains->lock); - skl_init_cdclk(dev_priv); + intel_cdclk_init(dev_priv); gen9_dbuf_enable(dev_priv); @@ -3681,7 +3681,7 @@ static void skl_display_core_uninit(struct drm_i915_private *dev_priv) gen9_dbuf_disable(dev_priv); - skl_uninit_cdclk(dev_priv); + intel_cdclk_uninit(dev_priv); /* The spec doesn't call for removing the reset handshake flag */ /* disable PG1 and Misc I/O */ @@ -3726,7 +3726,7 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv, mutex_unlock(&power_domains->lock); - bxt_init_cdclk(dev_priv); + intel_cdclk_init(dev_priv); gen9_dbuf_enable(dev_priv); @@ -3743,7 +3743,7 @@ void bxt_display_core_uninit(struct drm_i915_private *dev_priv) gen9_dbuf_disable(dev_priv); - bxt_uninit_cdclk(dev_priv); + intel_cdclk_uninit(dev_priv); /* The spec doesn't call for removing the reset handshake flag */ @@ -3785,7 +3785,7 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume mutex_unlock(&power_domains->lock); /* 5. Enable CD clock */ - cnl_init_cdclk(dev_priv); + intel_cdclk_init(dev_priv); /* 6. Enable DBUF */ gen9_dbuf_enable(dev_priv); @@ -3807,7 +3807,7 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv) gen9_dbuf_disable(dev_priv); /* 3. Disable CD clock */ - cnl_uninit_cdclk(dev_priv); + intel_cdclk_uninit(dev_priv); /* * 4. Disable Power Well 1 (PG1). @@ -3849,7 +3849,7 @@ void icl_display_core_init(struct drm_i915_private *dev_priv, mutex_unlock(&power_domains->lock); /* 5. Enable CDCLK. */ - icl_init_cdclk(dev_priv); + intel_cdclk_init(dev_priv); /* 6. Enable DBUF. */ icl_dbuf_enable(dev_priv); @@ -3874,7 +3874,7 @@ void icl_display_core_uninit(struct drm_i915_private *dev_priv) icl_dbuf_disable(dev_priv); /* 3. Disable CD clock */ - icl_uninit_cdclk(dev_priv); + intel_cdclk_uninit(dev_priv); /* * 4. Disable Power Well 1 (PG1). -- cgit v1.2.3 From 1a07a94b47b1f528f39c3e6187b5eaf02efe44ea Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Sat, 6 Apr 2019 01:30:48 +0200 Subject: drm/sun4i: tcon top: Fix NULL/invalid pointer dereference in sun8i_tcon_top_un/bind There are two problems here: 1. Not all clk_data->hws[] need to be initialized, depending on various configured quirks. This leads to NULL ptr deref in clk_hw_unregister_gate() in sun8i_tcon_top_unbind() 2. If there is error when registering the clk_data->hws[], err_unregister_gates error path will try to unregister IS_ERR()=true (invalid) pointer. For problem (1) I have this stack trace: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008 Call trace: clk_hw_unregister+0x8/0x18 clk_hw_unregister_gate+0x14/0x28 sun8i_tcon_top_unbind+0x2c/0x60 component_unbind.isra.4+0x2c/0x50 component_bind_all+0x1d4/0x230 sun4i_drv_bind+0xc4/0x1a0 try_to_bring_up_master+0x164/0x1c0 __component_add+0xa0/0x168 component_add+0x10/0x18 sun8i_dw_hdmi_probe+0x18/0x20 platform_drv_probe+0x3c/0x70 really_probe+0xcc/0x278 driver_probe_device+0x34/0xa8 Problem (2) was identified by head scratching. Signed-off-by: Ondrej Jirman Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20190405233048.3823-1-megous@megous.com --- drivers/gpu/drm/sun4i/sun8i_tcon_top.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c index fc36e0c10a37..b1e7c76e9c17 100644 --- a/drivers/gpu/drm/sun4i/sun8i_tcon_top.c +++ b/drivers/gpu/drm/sun4i/sun8i_tcon_top.c @@ -227,7 +227,7 @@ static int sun8i_tcon_top_bind(struct device *dev, struct device *master, err_unregister_gates: for (i = 0; i < CLK_NUM; i++) - if (clk_data->hws[i]) + if (!IS_ERR_OR_NULL(clk_data->hws[i])) clk_hw_unregister_gate(clk_data->hws[i]); clk_disable_unprepare(tcon_top->bus); err_assert_reset: @@ -245,7 +245,8 @@ static void sun8i_tcon_top_unbind(struct device *dev, struct device *master, of_clk_del_provider(dev->of_node); for (i = 0; i < CLK_NUM; i++) - clk_hw_unregister_gate(clk_data->hws[i]); + if (clk_data->hws[i]) + clk_hw_unregister_gate(clk_data->hws[i]); clk_disable_unprepare(tcon_top->bus); reset_control_assert(tcon_top->rst); -- cgit v1.2.3 From 3a52fb7e7953f0b13df8c05d0d74b56a66888f30 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Sun, 7 Apr 2019 15:46:55 +0300 Subject: drm/i915: Get power refs in encoder->get_power_domains() Push getting the reference for the encoders' power domains into the encoder get_power_domains() hook instead of doing this from the caller. This way the encoder can store away the corresponding wakerefs. This fixes the DSI encoder disabling, which didn't release these power references it acquired during HW state readout. Note that longtime ownership for the corresponding wakerefs can be thus acquired / released in two ways. Nevertheless there is always only one owner for them: After HW readout (booting/system resume): - encoder->get_power_domains() acquires - encoder->disable*() releases After a modeset (calling intel_atomic_commit()): - encoder->enable*() acquires - encoder->disable*() releases * can be any of the encoder enable/disable hooks. v2: - Check that the DSI io_wakerefs are unset both during encoder HW readout and enabling. (Chris) Fixes: 0e6e0be4c9523 ("drm/i915: Markup paired operations on display power domains") Cc: Vandita Kulkarni Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190407124655.31536-1-imre.deak@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 40 ++++++++++++++++++------------------ drivers/gpu/drm/i915/intel_ddi.c | 17 ++++++++------- drivers/gpu/drm/i915/intel_display.c | 6 +----- drivers/gpu/drm/i915/intel_drv.h | 10 +++++---- 4 files changed, 35 insertions(+), 38 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 527aafc16e62..462936dbeec5 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -327,6 +327,21 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) } } +static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv, + struct intel_dsi *intel_dsi) +{ + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + WARN_ON(intel_dsi->io_wakeref[port]); + intel_dsi->io_wakeref[port] = + intel_display_power_get(dev_priv, + port == PORT_A ? + POWER_DOMAIN_PORT_DDI_A_IO : + POWER_DOMAIN_PORT_DDI_B_IO); + } +} + static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -340,13 +355,7 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp); } - for_each_dsi_port(port, intel_dsi->ports) { - intel_dsi->io_wakeref[port] = - intel_display_power_get(dev_priv, - port == PORT_A ? - POWER_DOMAIN_PORT_DDI_A_IO : - POWER_DOMAIN_PORT_DDI_B_IO); - } + get_dsi_io_power_domains(dev_priv, intel_dsi); } static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) @@ -1223,20 +1232,11 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder, return 0; } -static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state) +static void gen11_dsi_get_power_domains(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state) { - struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - u64 domains = 0; - enum port port; - - for_each_dsi_port(port, intel_dsi->ports) - if (port == PORT_A) - domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO); - else - domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO); - - return domains; + get_dsi_io_power_domains(to_i915(encoder->base.dev), + enc_to_intel_dsi(&encoder->base)); } static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 720de7a3f5e6..0ab3a8a43848 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2053,12 +2053,11 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port) intel_aux_power_domain(dig_port); } -static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state) +static void intel_ddi_get_power_domains(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port; - u64 domains; /* * TODO: Add support for MST encoders. Atm, the following should never @@ -2066,10 +2065,10 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, * hook. */ if (WARN_ON(intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) - return 0; + return; dig_port = enc_to_dig_port(&encoder->base); - domains = BIT_ULL(dig_port->ddi_io_power_domain); + intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); /* * AUX power is only needed for (e)DP mode, and for HDMI mode on TC @@ -2077,15 +2076,15 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, */ if (intel_crtc_has_dp_encoder(crtc_state) || intel_port_is_tc(dev_priv, encoder->port)) - domains |= BIT_ULL(intel_ddi_main_link_aux_domain(dig_port)); + intel_display_power_get(dev_priv, + intel_ddi_main_link_aux_domain(dig_port)); /* * VDSC power is needed when DSC is enabled */ if (crtc_state->dsc_params.compression_enable) - domains |= BIT_ULL(intel_dsc_power_domain(crtc_state)); - - return domains; + intel_display_power_get(dev_priv, + intel_dsc_power_domain(crtc_state)); } void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cb7f99618f02..f29a348e8d71 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -16285,8 +16285,6 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) struct intel_encoder *encoder; for_each_intel_encoder(&dev_priv->drm, encoder) { - u64 get_domains; - enum intel_display_power_domain domain; struct intel_crtc_state *crtc_state; if (!encoder->get_power_domains) @@ -16300,9 +16298,7 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) continue; crtc_state = to_intel_crtc_state(encoder->base.crtc->state); - get_domains = encoder->get_power_domains(encoder, crtc_state); - for_each_power_domain(domain, get_domains) - intel_display_power_get(dev_priv, domain); + encoder->get_power_domains(encoder, crtc_state); } } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 766234a123e0..a38b9cff5cd0 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -272,10 +272,12 @@ struct intel_encoder { * be set correctly before calling this function. */ void (*get_config)(struct intel_encoder *, struct intel_crtc_state *pipe_config); - /* Returns a mask of power domains that need to be referenced as part - * of the hardware state readout code. */ - u64 (*get_power_domains)(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state); + /* + * Acquires the power domains needed for an active encoder during + * hardware state readout. + */ + void (*get_power_domains)(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state); /* * Called during system suspend after all pending requests for the * encoder are flushed (for example for DP AUX transactions) and -- cgit v1.2.3 From 99fa4bc26d74e49e3d7d70f29a106943f48924ea Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 5 Apr 2019 18:36:57 +0300 Subject: drm/i915/icl: Simplify release of encoder power refs We can unconditionally release the power references during encoder disabling. The references for each port used by the encoder are guaranteed to be enabled at this point. Cc: Vandita Kulkarni Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190405153657.20921-2-imre.deak@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 462936dbeec5..6fc48479c97b 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1146,13 +1146,11 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) intel_wakeref_t wakeref; wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port]); - if (wakeref) { - intel_display_power_put(dev_priv, - port == PORT_A ? - POWER_DOMAIN_PORT_DDI_A_IO : - POWER_DOMAIN_PORT_DDI_B_IO, - wakeref); - } + intel_display_power_put(dev_priv, + port == PORT_A ? + POWER_DOMAIN_PORT_DDI_A_IO : + POWER_DOMAIN_PORT_DDI_B_IO, + wakeref); } /* set mode to DDI */ -- cgit v1.2.3 From bd13b2b874eceb4677cd26eebdc5f45cc52fa400 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 1 Feb 2019 09:36:59 -0500 Subject: drm/amd/display: Fix negative cursor pos programming (v2) [Why] If the cursor pos passed from DM is less than the plane_state->dst_rect top left corner then the unsigned cursor pos wraps around to a large positive number since cursor pos is a u32. There was an attempt to guard against this in hubp1_cursor_set_position by checking the src_x_offset and src_y_offset and offseting the cursor hotspot within hubp1_cursor_set_position. However, the cursor position itself is still being programmed incorrectly as a large value. This manifests itself visually as the cursor disappearing or containing strange artifacts near the middle of the screen on raven. [How] Don't subtract the destination rect top left corner from the pos but add it to the hotspot instead. This happens before the pos gets passed into hubp1_cursor_set_position. This achieves the same result but avoids the subtraction wrap around. With this fix the original cursor programming logic can be used again. v2: add hunk that got dropped accidently when this patch was originally committed. (Alex) Fixes: 0921c41e1902831 ("drm/amd/display: Fix negative cursor pos programming") Signed-off-by: Nicholas Kazlauskas Reviewed-by: Charlene Liu Acked-by: Leo Li Acked-by: Murton Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 683829466a44..0ba68d41b9c3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -1150,28 +1150,9 @@ void hubp1_cursor_set_position( REG_UPDATE(CURSOR_CONTROL, CURSOR_ENABLE, cur_en); - //account for cases where we see negative offset relative to overlay plane - if (src_x_offset < 0 && src_y_offset < 0) { - REG_SET_2(CURSOR_POSITION, 0, - CURSOR_X_POSITION, 0, - CURSOR_Y_POSITION, 0); - x_hotspot -= src_x_offset; - y_hotspot -= src_y_offset; - } else if (src_x_offset < 0) { - REG_SET_2(CURSOR_POSITION, 0, - CURSOR_X_POSITION, 0, - CURSOR_Y_POSITION, pos->y); - x_hotspot -= src_x_offset; - } else if (src_y_offset < 0) { - REG_SET_2(CURSOR_POSITION, 0, + REG_SET_2(CURSOR_POSITION, 0, CURSOR_X_POSITION, pos->x, - CURSOR_Y_POSITION, 0); - y_hotspot -= src_y_offset; - } else { - REG_SET_2(CURSOR_POSITION, 0, - CURSOR_X_POSITION, pos->x, - CURSOR_Y_POSITION, pos->y); - } + CURSOR_Y_POSITION, pos->y); REG_SET_2(CURSOR_HOT_SPOT, 0, CURSOR_HOT_SPOT_X, x_hotspot, -- cgit v1.2.3 From e1b7058ece718c0350ad2e5bfbdab17885bd9f39 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 5 Apr 2019 17:13:49 +0300 Subject: drm/i915: Fix pipe_bpp readout for BXT/GLK DSI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only bpc information in pipe registers for BXT/GLK DSI is the PIPEMISC dither bpc. Let's try to use that to read out pipe_bpp on these platforms. However, I'm not sure if this will be correctly populated by the GOP since bspec suggests it's only needed if dithering is actually enabled. If not I guess we'll have to go one step further and extract pipe_bpp from the DSI pixel format when dithering is disabled. Cc: Hans de Goede Fixes: ca0b04db14a5 ("drm/i915/dsi: Fix pipe_bpp for handling for 6 bpc pixel-formats") References: https://bugs.freedesktop.org/show_bug.cgi?id=109516 Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190405141349.11950-1-ville.syrjala@linux.intel.com (cherry picked from commit 499653501baf27d26e73cb5ce744869df3400509) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/vlv_dsi.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c index 6403728fe778..31c93c3ccd00 100644 --- a/drivers/gpu/drm/i915/vlv_dsi.c +++ b/drivers/gpu/drm/i915/vlv_dsi.c @@ -256,6 +256,28 @@ static void band_gap_reset(struct drm_i915_private *dev_priv) mutex_unlock(&dev_priv->sb_lock); } +static int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + u32 tmp; + + tmp = I915_READ(PIPEMISC(crtc->pipe)); + + switch (tmp & PIPEMISC_DITHER_BPC_MASK) { + case PIPEMISC_DITHER_6_BPC: + return 18; + case PIPEMISC_DITHER_8_BPC: + return 24; + case PIPEMISC_DITHER_10_BPC: + return 30; + case PIPEMISC_DITHER_12_BPC: + return 36; + default: + MISSING_CASE(tmp); + return 0; + } +} + static int intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) @@ -1071,6 +1093,8 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, bpp = mipi_dsi_pixel_format_to_bpp( pixel_format_from_register_bits(fmt)); + pipe_config->pipe_bpp = bdw_get_pipemisc_bpp(crtc); + /* Enable Frame time stamo based scanline reporting */ adjusted_mode->private_flags |= I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; -- cgit v1.2.3 From bfd04533138427846ab711c68320c71c6275a0a3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 8 Apr 2019 10:17:01 +0100 Subject: drm/i915/guc: Replace WARN with a DRM_ERROR Replace the WARN with a simple if() + error message to squech the sparse warning that entire wait_for() macro was being stringified: drivers/gpu/drm/i915/intel_guc_submission.c:658:9: error: too long token expansion Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190408091728.20207-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_guc_submission.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index c58922226d47..42fcd622d7a3 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -650,9 +650,10 @@ static void wait_for_guc_preempt_report(struct intel_engine_cs *engine) struct guc_ctx_report *report = &data->preempt_ctx_report[engine->guc_id]; - WARN_ON(wait_for_atomic(report->report_return_status == - INTEL_GUC_REPORT_STATUS_COMPLETE, - GUC_PREEMPT_POSTPROCESS_DELAY_MS)); + if (wait_for_atomic(report->report_return_status == + INTEL_GUC_REPORT_STATUS_COMPLETE, + GUC_PREEMPT_POSTPROCESS_DELAY_MS)) + DRM_ERROR("Timed out waiting for GuC preemption report\n"); /* * GuC is expecting that we're also going to clear the affected context * counter, let's also reset the return status to not depend on GuC -- cgit v1.2.3 From da23379f1508dba4a02feb1ed4f53122fb4ecf64 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 8 Apr 2019 10:17:02 +0100 Subject: drm/i915: Use static allocation for i915_globals_park() In order to avoid the malloc inside i915_globals_park() occurring underneath a lock connected to the shrinker (thus causing circular lockdeps warnings), move the rcu_worker to a global. <4> [39.085073] ====================================================== <4> [39.085273] WARNING: possible circular locking dependency detected <4> [39.085552] 5.1.0-rc3-CI-Trybot_4088+ #1 Tainted: G U <4> [39.085752] ------------------------------------------------------ <4> [39.085949] kswapd0/32 is trying to acquire lock: <4> [39.086121] 00000000004b5f91 (wakeref#3){+.+.}, at: intel_engine_pm_put+0x1b/0x40 [i915] <4> [39.086493] but task is already holding lock: <4> [39.086682] 00000000dd009a9a (fs_reclaim){+.+.}, at: __fs_reclaim_acquire+0x0/0x30 <4> [39.086910] which lock already depends on the new lock. <4> [39.087139] the existing dependency chain (in reverse order) is: <4> [39.087356] -> #2 (fs_reclaim){+.+.}: <4> [39.087604] fs_reclaim_acquire.part.24+0x24/0x30 <4> [39.087785] kmem_cache_alloc_trace+0x2a/0x290 <4> [39.087998] i915_globals_park+0x22/0xa0 [i915] <4> [39.088478] idle_work_handler+0x1df/0x220 [i915] <4> [39.089016] process_one_work+0x245/0x610 <4> [39.089447] worker_thread+0x37/0x380 <4> [39.089956] kthread+0x119/0x130 <4> [39.090374] ret_from_fork+0x3a/0x50 <4> [39.090868] -> #1 (wakeref#4){+.+.}: <4> [39.091569] __mutex_lock+0x8c/0x960 <4> [39.092054] atomic_dec_and_mutex_lock+0x33/0x50 <4> [39.092521] intel_gt_pm_put+0x1b/0x40 [i915] <4> [39.093047] intel_engine_park+0xeb/0x1d0 [i915] <4> [39.093514] __intel_wakeref_put_once+0x10/0x30 [i915] <4> [39.094062] i915_request_retire+0x477/0xaf0 [i915] <4> [39.094547] ring_retire_requests+0x86/0x160 [i915] <4> [39.095110] i915_retire_requests+0x58/0xc0 [i915] <4> [39.095587] i915_gem_wait_for_idle.part.22+0xb2/0xf0 [i915] <4> [39.096142] switch_to_kernel_context_sync+0x2a/0x70 [i915] <4> [39.096633] i915_gem_init+0x59c/0x9c0 [i915] <4> [39.097174] i915_driver_load+0xd96/0x1880 [i915] <4> [39.097640] i915_pci_probe+0x29/0xa0 [i915] <4> [39.098145] pci_device_probe+0xa1/0x120 <4> [39.098607] really_probe+0xf3/0x3e0 <4> [39.099031] driver_probe_device+0x10a/0x120 <4> [39.099599] device_driver_attach+0x4b/0x50 <4> [39.100033] __driver_attach+0x97/0x130 <4> [39.100525] bus_for_each_dev+0x74/0xc0 <4> [39.100954] bus_add_driver+0x13f/0x210 <4> [39.101441] driver_register+0x56/0xe0 <4> [39.101891] do_one_initcall+0x58/0x2e0 <4> [39.102319] do_init_module+0x56/0x1ea <4> [39.102805] load_module+0x2701/0x29e0 <4> [39.103231] __se_sys_finit_module+0xd3/0xf0 <4> [39.103727] do_syscall_64+0x55/0x190 <4> [39.104153] entry_SYSCALL_64_after_hwframe+0x49/0xbe <4> [39.104736] -> #0 (wakeref#3){+.+.}: <4> [39.105437] lock_acquire+0xa6/0x1c0 <4> [39.105923] __mutex_lock+0x8c/0x960 <4> [39.106345] atomic_dec_and_mutex_lock+0x33/0x50 <4> [39.106897] intel_engine_pm_put+0x1b/0x40 [i915] <4> [39.107375] i915_request_retire+0x477/0xaf0 [i915] <4> [39.107930] ring_retire_requests+0x86/0x160 [i915] <4> [39.108412] i915_retire_requests+0x58/0xc0 [i915] <4> [39.108934] i915_gem_shrink+0xd8/0x5b0 [i915] <4> [39.109431] i915_gem_shrinker_scan+0x59/0x130 [i915] <4> [39.109884] do_shrink_slab+0x131/0x3e0 <4> [39.110380] shrink_slab+0x228/0x2c0 <4> [39.110810] shrink_node+0x177/0x460 <4> [39.111317] balance_pgdat+0x239/0x580 <4> [39.111743] kswapd+0x186/0x570 <4> [39.112221] kthread+0x119/0x130 <4> [39.112641] ret_from_fork+0x3a/0x50 Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190408091728.20207-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_globals.c | 74 ++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 42 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_globals.c b/drivers/gpu/drm/i915/i915_globals.c index 2f5c72e2a9d1..81e5c2ce336b 100644 --- a/drivers/gpu/drm/i915/i915_globals.c +++ b/drivers/gpu/drm/i915/i915_globals.c @@ -17,6 +17,33 @@ static LIST_HEAD(globals); +static atomic_t active; +static atomic_t epoch; +static struct park_work { + struct rcu_work work; + int epoch; +} park; + +static void i915_globals_shrink(void) +{ + struct i915_global *global; + + /* + * kmem_cache_shrink() discards empty slabs and reorders partially + * filled slabs to prioritise allocating from the mostly full slabs, + * with the aim of reducing fragmentation. + */ + list_for_each_entry(global, &globals, link) + global->shrink(); +} + +static void __i915_globals_park(struct work_struct *work) +{ + /* Confirm nothing woke up in the last grace period */ + if (park.epoch == atomic_read(&epoch)) + i915_globals_shrink(); +} + void __init i915_global_register(struct i915_global *global) { GEM_BUG_ON(!global->shrink); @@ -57,44 +84,12 @@ int __init i915_globals_init(void) } } + INIT_RCU_WORK(&park.work, __i915_globals_park); return 0; } -static void i915_globals_shrink(void) -{ - struct i915_global *global; - - /* - * kmem_cache_shrink() discards empty slabs and reorders partially - * filled slabs to prioritise allocating from the mostly full slabs, - * with the aim of reducing fragmentation. - */ - list_for_each_entry(global, &globals, link) - global->shrink(); -} - -static atomic_t active; -static atomic_t epoch; -struct park_work { - struct rcu_work work; - int epoch; -}; - -static void __i915_globals_park(struct work_struct *work) -{ - struct park_work *wrk = container_of(work, typeof(*wrk), work.work); - - /* Confirm nothing woke up in the last grace period */ - if (wrk->epoch == atomic_read(&epoch)) - i915_globals_shrink(); - - kfree(wrk); -} - void i915_globals_park(void) { - struct park_work *wrk; - /* * Defer shrinking the global slab caches (and other work) until * after a RCU grace period has completed with no activity. This @@ -107,13 +102,8 @@ void i915_globals_park(void) if (!atomic_dec_and_test(&active)) return; - wrk = kmalloc(sizeof(*wrk), GFP_KERNEL); - if (!wrk) - return; - - wrk->epoch = atomic_inc_return(&epoch); - INIT_RCU_WORK(&wrk->work, __i915_globals_park); - queue_rcu_work(system_wq, &wrk->work); + park.epoch = atomic_inc_return(&epoch); + queue_rcu_work(system_wq, &park.work); } void i915_globals_unpark(void) @@ -125,8 +115,8 @@ void i915_globals_unpark(void) void __exit i915_globals_exit(void) { /* Flush any residual park_work */ - rcu_barrier(); - flush_scheduled_work(); + atomic_inc(&epoch); + flush_rcu_work(&park.work); __i915_globals_cleanup(); -- cgit v1.2.3 From de220cc21967fd745d91fbd3fc23a13372730db8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 8 Apr 2019 10:17:03 +0100 Subject: drm/i915: Consolidate the timeline->barrier The timeline is strictly ordered, so by inserting the timeline->barrier request into the timeline->last_request it naturally provides the same barrier. Consolidate the pair of barriers into one as they serve the same purpose. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190408091728.20207-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_context.c | 13 ++----------- drivers/gpu/drm/i915/i915_request.c | 9 --------- drivers/gpu/drm/i915/i915_timeline.c | 2 -- drivers/gpu/drm/i915/i915_timeline.h | 15 --------------- drivers/gpu/drm/i915/i915_timeline_types.h | 10 ---------- drivers/gpu/drm/i915/selftests/mock_timeline.c | 1 - 6 files changed, 2 insertions(+), 48 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 66b6852cb4d2..7fc34ab6df87 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -1167,7 +1167,7 @@ static int gen8_modify_rpcs(struct intel_context *ce, struct intel_sseu sseu) { struct drm_i915_private *i915 = ce->engine->i915; - struct i915_request *rq, *prev; + struct i915_request *rq; intel_wakeref_t wakeref; int ret; @@ -1192,16 +1192,7 @@ gen8_modify_rpcs(struct intel_context *ce, struct intel_sseu sseu) } /* Queue this switch after all other activity by this context. */ - prev = i915_active_request_raw(&ce->ring->timeline->last_request, - &i915->drm.struct_mutex); - if (prev && !i915_request_completed(prev)) { - ret = i915_request_await_dma_fence(rq, &prev->fence); - if (ret < 0) - goto out_add; - } - - /* Order all following requests to be after. */ - ret = i915_timeline_set_barrier(ce->ring->timeline, rq); + ret = i915_active_request_set(&ce->ring->timeline->last_request, rq); if (ret) goto out_add; diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 2da0d6436a1a..96a9e8bcd805 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -584,11 +584,6 @@ out: return kmem_cache_alloc(global.slab_requests, GFP_KERNEL); } -static int add_timeline_barrier(struct i915_request *rq) -{ - return i915_request_await_active_request(rq, &rq->timeline->barrier); -} - /** * i915_request_alloc - allocate a request structure * @@ -738,10 +733,6 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx) */ rq->head = rq->ring->emit; - ret = add_timeline_barrier(rq); - if (ret) - goto err_unwind; - ret = engine->request_alloc(rq); if (ret) goto err_unwind; diff --git a/drivers/gpu/drm/i915/i915_timeline.c b/drivers/gpu/drm/i915/i915_timeline.c index 2f4907364920..5fbea0892f33 100644 --- a/drivers/gpu/drm/i915/i915_timeline.c +++ b/drivers/gpu/drm/i915/i915_timeline.c @@ -253,7 +253,6 @@ int i915_timeline_init(struct drm_i915_private *i915, spin_lock_init(&timeline->lock); mutex_init(&timeline->mutex); - INIT_ACTIVE_REQUEST(&timeline->barrier); INIT_ACTIVE_REQUEST(&timeline->last_request); INIT_LIST_HEAD(&timeline->requests); @@ -326,7 +325,6 @@ void i915_timeline_fini(struct i915_timeline *timeline) { GEM_BUG_ON(timeline->pin_count); GEM_BUG_ON(!list_empty(&timeline->requests)); - GEM_BUG_ON(i915_active_request_isset(&timeline->barrier)); i915_syncmap_free(&timeline->sync); diff --git a/drivers/gpu/drm/i915/i915_timeline.h b/drivers/gpu/drm/i915/i915_timeline.h index 4ca7f80bdf6d..27668a1a69a3 100644 --- a/drivers/gpu/drm/i915/i915_timeline.h +++ b/drivers/gpu/drm/i915/i915_timeline.h @@ -110,19 +110,4 @@ void i915_timelines_init(struct drm_i915_private *i915); void i915_timelines_park(struct drm_i915_private *i915); void i915_timelines_fini(struct drm_i915_private *i915); -/** - * i915_timeline_set_barrier - orders submission between different timelines - * @timeline: timeline to set the barrier on - * @rq: request after which new submissions can proceed - * - * Sets the passed in request as the serialization point for all subsequent - * submissions on @timeline. Subsequent requests will not be submitted to GPU - * until the barrier has been completed. - */ -static inline int -i915_timeline_set_barrier(struct i915_timeline *tl, struct i915_request *rq) -{ - return i915_active_request_set(&tl->barrier, rq); -} - #endif diff --git a/drivers/gpu/drm/i915/i915_timeline_types.h b/drivers/gpu/drm/i915/i915_timeline_types.h index 1f5b55d9ffb5..5256a0b5c5f7 100644 --- a/drivers/gpu/drm/i915/i915_timeline_types.h +++ b/drivers/gpu/drm/i915/i915_timeline_types.h @@ -61,16 +61,6 @@ struct i915_timeline { */ struct i915_syncmap *sync; - /** - * Barrier provides the ability to serialize ordering between different - * timelines. - * - * Users can call i915_timeline_set_barrier which will make all - * subsequent submissions to this timeline be executed only after the - * barrier has been completed. - */ - struct i915_active_request barrier; - struct list_head link; struct drm_i915_private *i915; diff --git a/drivers/gpu/drm/i915/selftests/mock_timeline.c b/drivers/gpu/drm/i915/selftests/mock_timeline.c index 416d85233263..e084476469ef 100644 --- a/drivers/gpu/drm/i915/selftests/mock_timeline.c +++ b/drivers/gpu/drm/i915/selftests/mock_timeline.c @@ -16,7 +16,6 @@ void mock_timeline_init(struct i915_timeline *timeline, u64 context) spin_lock_init(&timeline->lock); mutex_init(&timeline->mutex); - INIT_ACTIVE_REQUEST(&timeline->barrier); INIT_ACTIVE_REQUEST(&timeline->last_request); INIT_LIST_HEAD(&timeline->requests); -- cgit v1.2.3 From a9f58c456e9dde6f272e7be4d6bed607fd7008aa Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 20 Feb 2019 08:21:26 +0100 Subject: drm/vmwgfx: Be more restrictive when dirtying resources Currently we flag resources as dirty (GPU contents not yet read back to the backing MOB) whenever they have been part of a command stream. Obviously many resources can't be dirty and others can only be dirty when written to by the GPU. That is when they are either bound to the context as render-targets, depth-stencil, copy / clear destinations and stream-output targets, or similarly when there are corresponding views into them. So mark resources dirty only in these special cases. Context- and cotable resources are always marked dirty when referenced. This is important for upcoming emulated coherent memory, since we can avoid issuing automatic readbacks to non-dirty resources when the CPU tries to access part of the backing MOB. Testing: Unigine Heaven with max GPU memory set to 256MB resulting in heavy resource thrashing. --- v2: Addressed review comments by Deepak Rawat. v3: Added some documentation Signed-off-by: Thomas Hellstrom Reviewed-by: Deepak Rawat --- drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 26 +++++ drivers/gpu/drm/vmwgfx/vmwgfx_binding.h | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 166 ++++++++++++++++++----------- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 5 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 21 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 3 +- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 24 +++++ drivers/gpu/drm/vmwgfx/vmwgfx_so.h | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 12 ++- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 58 ++++++++-- drivers/gpu/drm/vmwgfx/vmwgfx_validation.h | 7 ++ 12 files changed, 234 insertions(+), 93 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index 0b9ee7fb45d6..ef1469c4e91f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -1269,6 +1269,32 @@ void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs) vmw_binding_drop(entry); } +/** + * vmw_binding_dirtying - Return whether a binding type is dirtying its resource + * @binding_type: The binding type + * + * Each time a resource is put on the validation list as the result of a + * context binding referencing it, we need to determine whether that resource + * will be dirtied (written to by the GPU) as a result of the corresponding + * GPU operation. Currently rendertarget-, depth-stencil-, and + * stream-output-target bindings are capable of dirtying its resource. + * + * Return: Whether the binding type dirties the resource its binding points to. + */ +u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type) +{ + static u32 is_binding_dirtying[vmw_ctx_binding_max] = { + [vmw_ctx_binding_rt] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_dx_rt] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_ds] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_so] = VMW_RES_DIRTY_SET, + }; + + /* Review this function as new bindings are added. */ + BUILD_BUG_ON(vmw_ctx_binding_max != 11); + return is_binding_dirtying[binding_type]; +} + /* * This function is unused at run-time, and only used to hold various build * asserts important for code optimization assumptions. diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h index 6a2a9d69043b..f6ab79d23923 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h @@ -205,5 +205,7 @@ extern void vmw_binding_state_free(struct vmw_ctx_binding_state *cbs); extern struct list_head * vmw_binding_state_list(struct vmw_ctx_binding_state *cbs); extern void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs); +extern u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type); + #endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 6302c12c2298..abe975b7ea89 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -699,6 +699,8 @@ extern int vmw_user_stream_lookup(struct vmw_private *dev_priv, uint32_t *inout_id, struct vmw_resource **out); extern void vmw_resource_unreserve(struct vmw_resource *res, + bool dirty_set, + bool dirty, bool switch_backup, struct vmw_buffer_object *new_backup, unsigned long new_backup_offset); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 88b8178d4687..dc5698fbb654 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -272,13 +272,15 @@ static void vmw_execbuf_rcache_update(struct vmw_res_cache_entry *rcache, * unreferenced rcu-protected pointer to the validation list. * @sw_context: Pointer to the software context. * @res: Unreferenced rcu-protected pointer to the resource. + * @dirty: Whether to change dirty status. * * Returns: 0 on success. Negative error code on failure. Typical error * codes are %-EINVAL on inconsistency and %-ESRCH if the resource was * doomed. */ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, - struct vmw_resource *res) + struct vmw_resource *res, + u32 dirty) { struct vmw_private *dev_priv = res->dev_priv; int ret; @@ -290,13 +292,17 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, rcache = &sw_context->res_cache[res_type]; if (likely(rcache->valid && rcache->res == res)) { + if (dirty) + vmw_validation_res_set_dirty(sw_context->ctx, + rcache->private, dirty); vmw_user_resource_noref_release(); return 0; } priv_size = vmw_execbuf_res_size(dev_priv, res_type); ret = vmw_validation_add_resource(sw_context->ctx, res, priv_size, - (void **)&ctx_info, &first_usage); + dirty, (void **)&ctx_info, + &first_usage); vmw_user_resource_noref_release(); if (ret) return ret; @@ -317,11 +323,13 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, * validation list if it's not already on it * @sw_context: Pointer to the software context. * @res: Pointer to the resource. + * @dirty: Whether to change dirty status. * * Returns: Zero on success. Negative error code on failure. */ static int vmw_execbuf_res_noctx_val_add(struct vmw_sw_context *sw_context, - struct vmw_resource *res) + struct vmw_resource *res, + u32 dirty) { struct vmw_res_cache_entry *rcache; enum vmw_res_type res_type = vmw_res_type(res); @@ -329,10 +337,15 @@ static int vmw_execbuf_res_noctx_val_add(struct vmw_sw_context *sw_context, int ret; rcache = &sw_context->res_cache[res_type]; - if (likely(rcache->valid && rcache->res == res)) + if (likely(rcache->valid && rcache->res == res)) { + if (dirty) + vmw_validation_res_set_dirty(sw_context->ctx, + rcache->private, dirty); return 0; + } - ret = vmw_validation_add_resource(sw_context->ctx, res, 0, &ptr, NULL); + ret = vmw_validation_add_resource(sw_context->ctx, res, 0, dirty, + &ptr, NULL); if (ret) return ret; @@ -359,11 +372,13 @@ static int vmw_view_res_val_add(struct vmw_sw_context *sw_context, * First add the resource the view is pointing to, otherwise * it may be swapped out when the view is validated. */ - ret = vmw_execbuf_res_noctx_val_add(sw_context, vmw_view_srf(view)); + ret = vmw_execbuf_res_noctx_val_add(sw_context, vmw_view_srf(view), + vmw_view_dirtying(view)); if (ret) return ret; - return vmw_execbuf_res_noctx_val_add(sw_context, view); + return vmw_execbuf_res_noctx_val_add(sw_context, view, + VMW_RES_DIRTY_NONE); } /** @@ -433,7 +448,8 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, if (IS_ERR(res)) continue; - ret = vmw_execbuf_res_noctx_val_add(sw_context, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_SET); if (unlikely(ret != 0)) return ret; } @@ -448,8 +464,9 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, if (vmw_res_type(entry->res) == vmw_res_view) ret = vmw_view_res_val_add(sw_context, entry->res); else - ret = vmw_execbuf_res_noctx_val_add(sw_context, - entry->res); + ret = vmw_execbuf_res_noctx_val_add + (sw_context, entry->res, + vmw_binding_dirtying(entry->bt)); if (unlikely(ret != 0)) break; } @@ -598,6 +615,7 @@ static int vmw_resources_reserve(struct vmw_sw_context *sw_context) * @dev_priv: Pointer to a device private structure. * @sw_context: Pointer to the software context. * @res_type: Resource type. + * @dirty: Whether to change dirty status. * @converter: User-space visisble type specific information. * @id_loc: Pointer to the location in the command buffer currently being * parsed from where the user-space resource id handle is located. @@ -608,6 +626,7 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, enum vmw_res_type res_type, + u32 dirty, const struct vmw_user_resource_conv *converter, uint32_t *id_loc, struct vmw_resource **p_res) @@ -629,6 +648,9 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, if (likely(rcache->valid_handle && *id_loc == rcache->handle)) { res = rcache->res; + if (dirty) + vmw_validation_res_set_dirty(sw_context->ctx, + rcache->private, dirty); } else { unsigned int size = vmw_execbuf_res_size(dev_priv, res_type); @@ -644,7 +666,7 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, return PTR_ERR(res); } - ret = vmw_execbuf_res_noref_val_add(sw_context, res); + ret = vmw_execbuf_res_noref_val_add(sw_context, res, dirty); if (unlikely(ret != 0)) return ret; @@ -805,7 +827,8 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_cid_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->cid, NULL); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->cid, NULL); } /** @@ -857,14 +880,14 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, } ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->body.cid, - &ctx); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->body.cid, &ctx); if (unlikely(ret != 0)) return ret; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, &cmd->body.target.sid, - &res); + VMW_RES_DIRTY_SET, user_surface_converter, + &cmd->body.target.sid, &res); if (unlikely(ret)) return ret; @@ -899,13 +922,13 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_sid_cmd, header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, - &cmd->body.src.sid, NULL); + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.src.sid, NULL); if (ret) return ret; return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_SET, user_surface_converter, &cmd->body.dest.sid, NULL); } @@ -921,13 +944,13 @@ static int vmw_cmd_buffer_copy_check(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.src, NULL); if (ret != 0) return ret; return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_SET, user_surface_converter, &cmd->body.dest, NULL); } @@ -943,13 +966,13 @@ static int vmw_cmd_pred_copy_check(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.srcSid, NULL); if (ret != 0) return ret; return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_SET, user_surface_converter, &cmd->body.dstSid, NULL); } @@ -965,12 +988,12 @@ static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_sid_cmd, header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.src.sid, NULL); if (unlikely(ret != 0)) return ret; return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_SET, user_surface_converter, &cmd->body.dest.sid, NULL); } @@ -986,7 +1009,7 @@ static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_sid_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.srcImage.sid, NULL); } @@ -1003,8 +1026,8 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_sid_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, &cmd->body.sid, - NULL); + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.sid, NULL); } /** @@ -1344,8 +1367,8 @@ static int vmw_cmd_begin_gb_query(struct vmw_private *dev_priv, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->q.cid, - NULL); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->q.cid, NULL); } /** @@ -1385,8 +1408,8 @@ static int vmw_cmd_begin_query(struct vmw_private *dev_priv, } return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->q.cid, - NULL); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->q.cid, NULL); } /** @@ -1572,6 +1595,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, int ret; SVGA3dCmdSurfaceDMASuffix *suffix; uint32_t bo_size; + bool dirty; cmd = container_of(header, struct vmw_dma_cmd, header); suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma + @@ -1600,9 +1624,11 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, if (unlikely(suffix->maximumOffset > bo_size)) suffix->maximumOffset = bo_size; + dirty = (cmd->dma.transfer == SVGA3D_WRITE_HOST_VRAM) ? + VMW_RES_DIRTY_SET : 0; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, &cmd->dma.host.sid, - NULL); + dirty, user_surface_converter, + &cmd->dma.host.sid, NULL); if (unlikely(ret != 0)) { if (unlikely(ret != -ERESTARTSYS)) DRM_ERROR("could not find surface for DMA.\n"); @@ -1646,6 +1672,7 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv, for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) { ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, &decl->array.surfaceId, NULL); if (unlikely(ret != 0)) @@ -1662,6 +1689,7 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv, range = (SVGA3dPrimitiveRange *) decl; for (i = 0; i < cmd->body.numRanges; ++i, ++range) { ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, &range->indexArray.surfaceId, NULL); if (unlikely(ret != 0)) @@ -1692,7 +1720,8 @@ static int vmw_cmd_tex_state(struct vmw_private *dev_priv, header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->state.cid, + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->state.cid, &ctx); if (unlikely(ret != 0)) return ret; @@ -1708,6 +1737,7 @@ static int vmw_cmd_tex_state(struct vmw_private *dev_priv, } ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, &cur_state->value, &res); if (unlikely(ret != 0)) @@ -1818,7 +1848,7 @@ static int vmw_cmd_switch_backup(struct vmw_private *dev_priv, int ret; ret = vmw_cmd_res_check(dev_priv, sw_context, res_type, - converter, res_id, &res); + VMW_RES_DIRTY_NONE, converter, res_id, &res); if (ret) return ret; @@ -1871,7 +1901,7 @@ static int vmw_cmd_update_gb_image(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_gb_surface_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.image.sid, NULL); } @@ -1895,7 +1925,7 @@ static int vmw_cmd_update_gb_surface(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_gb_surface_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_CLEAR, user_surface_converter, &cmd->body.sid, NULL); } @@ -1919,7 +1949,7 @@ static int vmw_cmd_readback_gb_image(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_gb_surface_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.image.sid, NULL); } @@ -1943,7 +1973,7 @@ static int vmw_cmd_readback_gb_surface(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_gb_surface_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_CLEAR, user_surface_converter, &cmd->body.sid, NULL); } @@ -1967,7 +1997,7 @@ static int vmw_cmd_invalidate_gb_image(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_gb_surface_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.image.sid, NULL); } @@ -1991,7 +2021,7 @@ static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv, cmd = container_of(header, struct vmw_gb_surface_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_CLEAR, user_surface_converter, &cmd->body.sid, NULL); } @@ -2020,8 +2050,8 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->body.cid, - &ctx); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->body.cid, &ctx); if (unlikely(ret != 0)) return ret; @@ -2067,8 +2097,8 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->body.cid, - &ctx); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->body.cid, &ctx); if (unlikely(ret != 0)) return ret; @@ -2120,8 +2150,8 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, } ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->body.cid, - &ctx); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->body.cid, &ctx); if (unlikely(ret != 0)) return ret; @@ -2134,7 +2164,8 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, cmd->body.type); if (!IS_ERR(res)) { - ret = vmw_execbuf_res_noctx_val_add(sw_context, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_NONE); if (unlikely(ret != 0)) return ret; } @@ -2142,7 +2173,7 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, if (IS_ERR_OR_NULL(res)) { ret = vmw_cmd_res_check(dev_priv, sw_context, - vmw_res_shader, + vmw_res_shader, VMW_RES_DIRTY_NONE, user_shader_converter, &cmd->body.shid, &res); if (unlikely(ret != 0)) @@ -2184,8 +2215,8 @@ static int vmw_cmd_set_shader_const(struct vmw_private *dev_priv, header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, &cmd->body.cid, - NULL); + VMW_RES_DIRTY_SET, user_context_converter, + &cmd->body.cid, NULL); if (unlikely(ret != 0)) return ret; @@ -2250,7 +2281,7 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.sid, &res); if (unlikely(ret != 0)) return ret; @@ -2351,7 +2382,8 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, return PTR_ERR(res); } - ret = vmw_execbuf_res_noctx_val_add(sw_context, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_NONE); if (ret) return ret; } @@ -2405,6 +2437,7 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv, for (i = 0; i < num; i++) { ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->buf[i].sid, &res); if (unlikely(ret != 0)) @@ -2452,7 +2485,7 @@ static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.sid, &res); if (unlikely(ret != 0)) return ret; @@ -2575,7 +2608,7 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->sid, &srf); if (unlikely(ret != 0)) return ret; @@ -2633,6 +2666,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, for (i = 0; i < num; i++) { ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_SET, user_surface_converter, &cmd->targets[i].sid, &res); if (unlikely(ret != 0)) @@ -2714,7 +2748,7 @@ static int vmw_cmd_dx_check_subresource(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->sid, NULL); } @@ -2870,8 +2904,9 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, if (cmd->body.cid != SVGA3D_INVALID_ID) { ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, - user_context_converter, - &cmd->body.cid, &ctx); + VMW_RES_DIRTY_SET, + user_context_converter, &cmd->body.cid, + &ctx); if (ret) return ret; } else { @@ -2889,7 +2924,8 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, return PTR_ERR(res); } - ret = vmw_execbuf_res_noctx_val_add(sw_context, res); + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_NONE); if (ret) { DRM_ERROR("Error creating resource validation node.\n"); return ret; @@ -2939,13 +2975,13 @@ static int vmw_cmd_dx_transfer_from_buffer(struct vmw_private *dev_priv, int ret; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.srcSid, NULL); if (ret != 0) return ret; return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, + VMW_RES_DIRTY_SET, user_surface_converter, &cmd->body.destSid, NULL); } @@ -2970,8 +3006,8 @@ static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv, return -EINVAL; return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, - &cmd->body.surface.sid, NULL); + VMW_RES_DIRTY_SET, user_surface_converter, + &cmd->body.surface.sid, NULL); } @@ -3805,7 +3841,7 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, return PTR_ERR(res); } - ret = vmw_execbuf_res_noref_val_add(sw_context, res); + ret = vmw_execbuf_res_noref_val_add(sw_context, res, VMW_RES_DIRTY_SET); if (unlikely(ret != 0)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index ed2f67822f45..de367e8612af 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1202,7 +1202,7 @@ static int vmw_create_bo_proxy(struct drm_device *dev, vmw_bo_unreference(&res->backup); res->backup = vmw_bo_reference(bo_mob); res->backup_offset = 0; - vmw_resource_unreserve(res, false, NULL, 0); + vmw_resource_unreserve(res, false, false, false, NULL, 0); mutex_unlock(&res->dev_priv->cmdbuf_mutex); return 0; @@ -2827,7 +2827,8 @@ int vmw_du_helper_plane_update(struct vmw_du_update_plane *update) container_of(update->vfb, typeof(*vfbs), base); ret = vmw_validation_add_resource(&val_ctx, &vfbs->surface->res, - 0, NULL, NULL); + 0, VMW_RES_DIRTY_NONE, NULL, + NULL); } if (ret) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index a7c30e567f09..c8feeaa85143 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -365,14 +365,6 @@ static int vmw_resource_do_validate(struct vmw_resource *res, list_add_tail(&res->mob_head, &res->backup->res_list); } - /* - * Only do this on write operations, and move to - * vmw_resource_unreserve if it can be called after - * backup buffers have been unreserved. Otherwise - * sort out locking. - */ - res->res_dirty = true; - return 0; out_bind_failed: @@ -386,6 +378,8 @@ out_bind_failed: * command submission. * * @res: Pointer to the struct vmw_resource to unreserve. + * @dirty_set: Change dirty status of the resource. + * @dirty: When changing dirty status indicates the new status. * @switch_backup: Backup buffer has been switched. * @new_backup: Pointer to new backup buffer if command submission * switched. May be NULL. @@ -395,6 +389,8 @@ out_bind_failed: * resource lru list, so that it can be evicted if necessary. */ void vmw_resource_unreserve(struct vmw_resource *res, + bool dirty_set, + bool dirty, bool switch_backup, struct vmw_buffer_object *new_backup, unsigned long new_backup_offset) @@ -422,6 +418,9 @@ void vmw_resource_unreserve(struct vmw_resource *res, if (switch_backup) res->backup_offset = new_backup_offset; + if (dirty_set) + res->res_dirty = dirty; + if (!res->func->may_evict || res->id == -1 || res->pin_count) return; @@ -696,7 +695,7 @@ void vmw_resource_unbind_list(struct vmw_buffer_object *vbo) if (!res->func->unbind) continue; - (void) res->func->unbind(res, true, &val_buf); + (void) res->func->unbind(res, res->res_dirty, &val_buf); res->backup_dirty = true; res->res_dirty = false; list_del_init(&res->mob_head); @@ -932,7 +931,7 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible) res->pin_count++; out_no_validate: - vmw_resource_unreserve(res, false, NULL, 0UL); + vmw_resource_unreserve(res, false, false, false, NULL, 0UL); out_no_reserve: mutex_unlock(&dev_priv->cmdbuf_mutex); ttm_write_unlock(&dev_priv->reservation_sem); @@ -968,7 +967,7 @@ void vmw_resource_unpin(struct vmw_resource *res) ttm_bo_unreserve(&vbo->base); } - vmw_resource_unreserve(res, false, NULL, 0UL); + vmw_resource_unreserve(res, false, false, false, NULL, 0UL); mutex_unlock(&dev_priv->cmdbuf_mutex); ttm_read_unlock(&dev_priv->reservation_sem); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index cd586c52af7e..9c2bdb56a6d3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -1148,7 +1148,8 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv, if (!srf) srf = &vfbs->surface->res; - ret = vmw_validation_add_resource(&val_ctx, srf, 0, NULL, NULL); + ret = vmw_validation_add_resource(&val_ctx, srf, 0, VMW_RES_DIRTY_NONE, + NULL, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c index bc8bb690f1ea..4ef8460eaf2c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c @@ -497,6 +497,30 @@ struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man, vmw_view_key(user_key, view_type)); } +/** + * vmw_view_dirtying - Return whether a view type is dirtying its resource + * @res: Pointer to the view + * + * Each time a resource is put on the validation list as the result of a + * view pointing to it, we need to determine whether that resource will + * be dirtied (written to by the GPU) as a result of the corresponding + * GPU operation. Currently only rendertarget- and depth-stencil views are + * capable of dirtying its resource. + * + * Return: Whether the view type of @res dirties the resource it points to. + */ +u32 vmw_view_dirtying(struct vmw_resource *res) +{ + static u32 view_is_dirtying[vmw_view_max] = { + [vmw_view_rt] = VMW_RES_DIRTY_SET, + [vmw_view_ds] = VMW_RES_DIRTY_SET, + }; + + /* Update this function as we add more view types */ + BUILD_BUG_ON(vmw_view_max != 3); + return view_is_dirtying[vmw_view(res)->view_type]; +} + const u32 vmw_view_destroy_cmds[] = { [vmw_view_sr] = SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW, [vmw_view_rt] = SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h index b80c7252f2fd..12565047bc55 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h @@ -157,4 +157,5 @@ extern struct vmw_resource *vmw_view_srf(struct vmw_resource *res); extern struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man, enum vmw_view_type view_type, u32 user_key); +extern u32 vmw_view_dirtying(struct vmw_resource *res); #endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 096c2941a8e4..1a65008a27b2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -111,7 +111,7 @@ struct vmw_stdu_update_gb_image { */ struct vmw_screen_target_display_unit { struct vmw_display_unit base; - const struct vmw_surface *display_srf; + struct vmw_surface *display_srf; enum stdu_content_type content_fb_type; s32 display_width, display_height; @@ -533,6 +533,7 @@ static void vmw_stdu_bo_fifo_commit(struct vmw_kms_dirty *dirty) vmw_fifo_commit(dirty->dev_priv, sizeof(*cmd) + blit_size); + stdu->display_srf->res.res_dirty = true; ddirty->left = ddirty->top = S32_MAX; ddirty->right = ddirty->bottom = S32_MIN; } @@ -629,9 +630,8 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) region.x2 = diff.rect.x2; region.y1 = diff.rect.y1; region.y2 = diff.rect.y2; - ret = vmw_kms_update_proxy( - (struct vmw_resource *) &stdu->display_srf->res, - (const struct drm_clip_rect *) ®ion, 1, 1); + ret = vmw_kms_update_proxy(&stdu->display_srf->res, ®ion, + 1, 1); if (ret) goto out_cleanup; @@ -820,6 +820,7 @@ static void vmw_kms_stdu_surface_fifo_commit(struct vmw_kms_dirty *dirty) cmd->body.dest.sid = stdu->display_srf->res.id; update = (struct vmw_stdu_update *) &blit[dirty->num_hits]; commit_size = sizeof(*cmd) + blit_size + sizeof(*update); + stdu->display_srf->res.res_dirty = true; } else { update = dirty->cmd; commit_size = sizeof(*update); @@ -876,7 +877,8 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv, if (!srf) srf = &vfbs->surface->res; - ret = vmw_validation_add_resource(&val_ctx, srf, 0, NULL, NULL); + ret = vmw_validation_add_resource(&val_ctx, srf, 0, VMW_RES_DIRTY_NONE, + NULL, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index e9944ac2e057..5ab7da1cbb45 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -76,6 +76,8 @@ struct vmw_validation_res_node { u32 switching_backup : 1; u32 first_usage : 1; u32 reserved : 1; + u32 dirty : 1; + u32 dirty_set : 1; unsigned long private[0]; }; @@ -299,6 +301,7 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx, * @ctx: The validation context. * @res: The resource. * @priv_size: Size of private, additional metadata. + * @dirty: Whether to change dirty status. * @p_node: Output pointer of additional metadata address. * @first_usage: Whether this was the first time this resource was seen. * @@ -307,6 +310,7 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx, int vmw_validation_add_resource(struct vmw_validation_context *ctx, struct vmw_resource *res, size_t priv_size, + u32 dirty, void **p_node, bool *first_usage) { @@ -358,6 +362,11 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, } out_fill: + if (dirty) { + node->dirty_set = 1; + /* Overwriting previous information here is intentional! */ + node->dirty = (dirty & VMW_RES_DIRTY_SET) ? 1 : 0; + } if (first_usage) *first_usage = node->first_usage; if (p_node) @@ -366,6 +375,29 @@ out_fill: return 0; } +/** + * vmw_validation_res_set_dirty - Register a resource dirty set or clear during + * validation. + * @ctx: The validation context. + * @val_private: The additional meta-data pointer returned when the + * resource was registered with the validation context. Used to identify + * the resource. + * @dirty: Dirty information VMW_RES_DIRTY_XX + */ +void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, + void *val_private, u32 dirty) +{ + struct vmw_validation_res_node *val; + + if (!dirty) + return; + + val = container_of(val_private, typeof(*val), private); + val->dirty_set = 1; + /* Overwriting previous information here is intentional! */ + val->dirty = (dirty & VMW_RES_DIRTY_SET) ? 1 : 0; +} + /** * vmw_validation_res_switch_backup - Register a backup MOB switch during * validation. @@ -450,15 +482,23 @@ void vmw_validation_res_unreserve(struct vmw_validation_context *ctx, struct vmw_validation_res_node *val; list_splice_init(&ctx->resource_ctx_list, &ctx->resource_list); - - list_for_each_entry(val, &ctx->resource_list, head) { - if (val->reserved) - vmw_resource_unreserve(val->res, - !backoff && - val->switching_backup, - val->new_backup, - val->new_backup_offset); - } + if (backoff) + list_for_each_entry(val, &ctx->resource_list, head) { + if (val->reserved) + vmw_resource_unreserve(val->res, + false, false, false, + NULL, 0); + } + else + list_for_each_entry(val, &ctx->resource_list, head) { + if (val->reserved) + vmw_resource_unreserve(val->res, + val->dirty_set, + val->dirty, + val->switching_backup, + val->new_backup, + val->new_backup_offset); + } } /** diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h index 3b396fea40d7..523f6ac5c335 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h @@ -33,6 +33,10 @@ #include #include +#define VMW_RES_DIRTY_NONE 0 +#define VMW_RES_DIRTY_SET BIT(0) +#define VMW_RES_DIRTY_CLEAR BIT(1) + /** * struct vmw_validation_mem - Custom interface to provide memory reservations * for the validation code. @@ -237,6 +241,7 @@ void vmw_validation_unref_lists(struct vmw_validation_context *ctx); int vmw_validation_add_resource(struct vmw_validation_context *ctx, struct vmw_resource *res, size_t priv_size, + u32 dirty, void **p_node, bool *first_usage); void vmw_validation_drop_ht(struct vmw_validation_context *ctx); @@ -261,4 +266,6 @@ void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx, int vmw_validation_preload_bo(struct vmw_validation_context *ctx); int vmw_validation_preload_res(struct vmw_validation_context *ctx, unsigned int size); +void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx, + void *val_private, u32 dirty); #endif -- cgit v1.2.3 From b2130cca9c8db5073b71d832da2a6c8311a8f3bb Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 1 Mar 2019 09:47:43 -0800 Subject: drm/vmwgfx: Remove set but not used variable 'restart' Fixes gcc '-Wunused-but-set-variable' warning: drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c: In function 'vmw_cmdbuf_work_func': drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c:514:7: warning: variable 'restart' set but not used [-Wunused-but-set-variable] It not used any more after commit dc366364c4ef ("drm/vmwgfx: Fix multiple command buffer context use") Signed-off-by: YueHaibing Reviewed-by: Deepak Rawat Signed-off-by: Deepak Rawat Fixes: dc366364c4ef ("drm/vmwgfx: Fix multiple command buffer context use") --- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index 70dab55e7888..ed15655eacd2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -511,17 +511,14 @@ static void vmw_cmdbuf_work_func(struct work_struct *work) container_of(work, struct vmw_cmdbuf_man, work); struct vmw_cmdbuf_header *entry, *next; uint32_t dummy; - bool restart[SVGA_CB_CONTEXT_MAX]; bool send_fence = false; struct list_head restart_head[SVGA_CB_CONTEXT_MAX]; int i; struct vmw_cmdbuf_context *ctx; bool global_block = false; - for_each_cmdbuf_ctx(man, i, ctx) { + for_each_cmdbuf_ctx(man, i, ctx) INIT_LIST_HEAD(&restart_head[i]); - restart[i] = false; - } mutex_lock(&man->error_mutex); spin_lock(&man->lock); @@ -533,7 +530,6 @@ static void vmw_cmdbuf_work_func(struct work_struct *work) const char *cmd_name; list_del_init(&entry->list); - restart[entry->cb_context] = true; global_block = true; if (!vmw_cmd_describe(header, &error_cmd_size, &cmd_name)) { -- cgit v1.2.3 From 4efa6661154f8a33d9a91b8d71499b9077c4564b Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Fri, 1 Mar 2019 10:14:06 -0800 Subject: drm/vmwgfx: remove redundant unlikely annotation unlikely has already included in IS_ERR(), so just remove redundant unlikely annotation. Signed-off-by: Chengguang Xu Reviewed-by: Deepak Rawat Signed-off-by: Deepak Rawat --- drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index 14bd760a62fd..694fabafaeee 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -210,7 +210,7 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv, for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { uctx->cotables[i] = vmw_cotable_alloc(dev_priv, &uctx->res, i); - if (unlikely(IS_ERR(uctx->cotables[i]))) { + if (IS_ERR(uctx->cotables[i])) { ret = PTR_ERR(uctx->cotables[i]); goto out_cotables; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index dc5698fbb654..4955a48a9d86 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -660,7 +660,7 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, res = vmw_user_resource_noref_lookup_handle (dev_priv, sw_context->fp->tfile, *id_loc, converter); - if (unlikely(IS_ERR(res))) { + if (IS_ERR(res)) { DRM_ERROR("Could not find or use resource 0x%08x.\n", (unsigned int) *id_loc); return PTR_ERR(res); @@ -3835,7 +3835,7 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, res = vmw_user_resource_noref_lookup_handle (dev_priv, sw_context->fp->tfile, handle, user_context_converter); - if (unlikely(IS_ERR(res))) { + if (IS_ERR(res)) { DRM_ERROR("Could not find or user DX context 0x%08x.\n", (unsigned) handle); return PTR_ERR(res); -- cgit v1.2.3 From 6f74fd911d19187673edce52a28c391b2aa987e9 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Fri, 8 Feb 2019 12:53:57 -0800 Subject: drm/vmwgfx: Use preprocessor macro to get valid context node Several command verifier function check if context node is present or not and if not present print an error and return. Use a preprocessor macro to print the message. v2: Name-space distinction for preprocessor macro Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 102 ++++++++++++++------------------ 1 file changed, 45 insertions(+), 57 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 4955a48a9d86..4f5445c53111 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -35,6 +35,19 @@ #define VMW_RES_HT_ORDER 12 +/* + * Helper macro to get dx_ctx_node if available otherwise print an error + * message. This is for use in command verifier function where if dx_ctx_node + * is not set then command is invalid. + */ +#define VMW_GET_CTX_NODE(__sw_context) \ +({ \ + __sw_context->dx_ctx_node ? __sw_context->dx_ctx_node : ({ \ + DRM_ERROR("SM context is not set at %s\n", __func__); \ + __sw_context->dx_ctx_node; \ + }); \ +}) + /* * struct vmw_relocation - Buffer object relocation * @@ -774,13 +787,11 @@ static int vmw_view_bindings_add(struct vmw_sw_context *sw_context, uint32 view_ids[], u32 num_views, u32 first_slot) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); u32 i; - if (!ctx_node) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } for (i = 0; i < num_views; ++i) { struct vmw_ctx_bindinfo_view binding; @@ -1280,14 +1291,11 @@ static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv, } *cmd; int ret; - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_resource *cotable_res; - - if (ctx_node == NULL) { - DRM_ERROR("DX Context not set for query.\n"); + if (!ctx_node) return -EINVAL; - } cmd = container_of(header, struct vmw_dx_define_query_cmd, header); @@ -2270,14 +2278,12 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, SVGA3dCmdDXSetSingleConstantBuffer body; } *cmd; struct vmw_resource *res = NULL; - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_cb binding; int ret; - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, @@ -2358,14 +2364,12 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, SVGA3dCmdDXSetShader body; } *cmd; struct vmw_resource *res = NULL; - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_shader binding; int ret = 0; - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } cmd = container_of(header, typeof(*cmd), header); @@ -2411,7 +2415,7 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_vb binding; struct vmw_resource *res; struct { @@ -2421,10 +2425,8 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv, } *cmd; int i, ret, num; - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } cmd = container_of(header, typeof(*cmd), header); num = (cmd->header.size - sizeof(cmd->body)) / @@ -2469,7 +2471,7 @@ static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_ib binding; struct vmw_resource *res; struct { @@ -2478,10 +2480,8 @@ static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv, } *cmd; int ret; - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, @@ -2583,7 +2583,7 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_resource *srf; struct vmw_resource *res; enum vmw_view_type view_type; @@ -2598,10 +2598,8 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, uint32 sid; } *cmd; - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } view_type = vmw_view_cmd_to_type(header->id); if (view_type == vmw_view_max) @@ -2640,7 +2638,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_so binding; struct vmw_resource *res; struct { @@ -2650,10 +2648,8 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, } *cmd; int i, ret, num; - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } cmd = container_of(header, typeof(*cmd), header); num = (cmd->header.size - sizeof(cmd->body)) / @@ -2690,7 +2686,7 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_resource *res; /* * This is based on the fact that all affected define commands have @@ -2703,10 +2699,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv, enum vmw_so_type so_type; int ret; - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } so_type = vmw_so_cmd_to_type(header->id); res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]); @@ -2756,12 +2750,10 @@ static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); - if (unlikely(ctx_node == NULL)) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } return 0; } @@ -2781,7 +2773,7 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct { SVGA3dCmdHeader header; union vmw_view_destroy body; @@ -2790,10 +2782,8 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, struct vmw_resource *view; int ret; - if (!ctx_node) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } ret = vmw_view_remove(sw_context->man, cmd->body.view_id, view_type, @@ -2827,7 +2817,7 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_resource *res; struct { SVGA3dCmdHeader header; @@ -2835,10 +2825,8 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv, } *cmd = container_of(header, typeof(*cmd), header); int ret; - if (!ctx_node) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER); ret = vmw_cotable_notify(res, cmd->body.shaderId); @@ -2862,17 +2850,15 @@ static int vmw_cmd_dx_destroy_shader(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct { SVGA3dCmdHeader header; SVGA3dCmdDXDestroyShader body; } *cmd = container_of(header, typeof(*cmd), header); int ret; - if (!ctx_node) { - DRM_ERROR("DX Context not set.\n"); + if (!ctx_node) return -EINVAL; - } ret = vmw_shader_remove(sw_context->man, cmd->body.shaderId, 0, &sw_context->staged_cmd_res); @@ -2910,11 +2896,13 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, if (ret) return ret; } else { - if (!sw_context->dx_ctx_node) { - DRM_ERROR("DX Context not set.\n"); + struct vmw_ctx_validation_info *ctx_node = + VMW_GET_CTX_NODE(sw_context); + + if (!ctx_node) return -EINVAL; - } - ctx = sw_context->dx_ctx_node->ctx; + + ctx = ctx_node->ctx; } res = vmw_shader_lookup(vmw_context_res_man(ctx), -- cgit v1.2.3 From d01316d0469fdda754cdae0351b6e96c90698485 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Fri, 8 Feb 2019 15:50:40 -0800 Subject: drm/vmwgfx: Use preprocessor macro for cmd struct Use preprocessor macro for repetitive device command struct format. v2: Name-space distinction for preprocessor macro. v3: Struct name as macro parameter and rebase. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 405 ++++++++++---------------------- 1 file changed, 125 insertions(+), 280 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 4f5445c53111..2c92744817ec 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -48,6 +48,12 @@ }); \ }) +#define VMW_DECLARE_CMD_VAR(__var, __type) \ + struct { \ + SVGA3dCmdHeader header; \ + __type body; \ + } __var + /* * struct vmw_relocation - Buffer object relocation * @@ -710,11 +716,7 @@ static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res) { struct vmw_private *dev_priv = ctx_res->dev_priv; struct vmw_buffer_object *dx_query_mob; - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXBindAllQuery body; - } *cmd; - + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindAllQuery); dx_query_mob = vmw_context_get_dx_query_mob(ctx_res); @@ -831,15 +833,12 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_cid_cmd { - SVGA3dCmdHeader header; - uint32_t cid; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, uint32_t) = + container_of(header, typeof(*cmd), header); - cmd = container_of(header, struct vmw_cid_cmd, header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, - &cmd->cid, NULL); + &cmd->body, NULL); } /** @@ -874,15 +873,12 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_sid_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdSetRenderTarget body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetRenderTarget); struct vmw_resource *ctx; struct vmw_resource *res; int ret; - cmd = container_of(header, struct vmw_sid_cmd, header); + cmd = container_of(header, typeof(*cmd), header); if (cmd->body.type >= SVGA3D_RT_MAX) { DRM_ERROR("Illegal render target type %u.\n", @@ -924,13 +920,10 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_sid_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdSurfaceCopy body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceCopy); int ret; - cmd = container_of(header, struct vmw_sid_cmd, header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -947,10 +940,7 @@ static int vmw_cmd_buffer_copy_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXBufferCopy body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBufferCopy); int ret; cmd = container_of(header, typeof(*cmd), header); @@ -969,10 +959,7 @@ static int vmw_cmd_pred_copy_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXPredCopyRegion body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXPredCopyRegion); int ret; cmd = container_of(header, typeof(*cmd), header); @@ -991,13 +978,10 @@ static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_sid_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdSurfaceStretchBlt body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceStretchBlt); int ret; - cmd = container_of(header, struct vmw_sid_cmd, header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.src.sid, NULL); @@ -1012,12 +996,8 @@ static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_sid_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdBlitSurfaceToScreen body; - } *cmd; - - cmd = container_of(header, struct vmw_sid_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBlitSurfaceToScreen) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -1028,13 +1008,8 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_sid_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdPresent body; - } *cmd; - - - cmd = container_of(header, struct vmw_sid_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdPresent) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -1285,26 +1260,22 @@ static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_dx_define_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdDXDefineQuery q; - } *cmd; - - int ret; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXDefineQuery); struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_resource *cotable_res; + int ret; if (!ctx_node) return -EINVAL; - cmd = container_of(header, struct vmw_dx_define_query_cmd, header); + cmd = container_of(header, typeof(*cmd), header); - if (cmd->q.type < SVGA3D_QUERYTYPE_MIN || - cmd->q.type >= SVGA3D_QUERYTYPE_MAX) + if (cmd->body.type < SVGA3D_QUERYTYPE_MIN || + cmd->body.type >= SVGA3D_QUERYTYPE_MAX) return -EINVAL; cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY); - ret = vmw_cotable_notify(cotable_res, cmd->q.queryId); + ret = vmw_cotable_notify(cotable_res, cmd->body.queryId); return ret; } @@ -1327,22 +1298,17 @@ static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_dx_bind_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdDXBindQuery q; - } *cmd; - + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindQuery); struct vmw_buffer_object *vmw_bo; - int ret; - + int ret; - cmd = container_of(header, struct vmw_dx_bind_query_cmd, header); + cmd = container_of(header, typeof(*cmd), header); /* * Look up the buffer pointed to by q.mobid, put it on the relocation * list so its kernel mode MOB ID can be filled in later */ - ret = vmw_translate_mob_ptr(dev_priv, sw_context, &cmd->q.mobid, + ret = vmw_translate_mob_ptr(dev_priv, sw_context, &cmd->body.mobid, &vmw_bo); if (ret != 0) @@ -1366,17 +1332,12 @@ static int vmw_cmd_begin_gb_query(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_begin_gb_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdBeginGBQuery q; - } *cmd; - - cmd = container_of(header, struct vmw_begin_gb_query_cmd, - header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBeginGBQuery) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, - &cmd->q.cid, NULL); + &cmd->body.cid, NULL); } /** @@ -1390,26 +1351,18 @@ static int vmw_cmd_begin_query(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_begin_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdBeginQuery q; - } *cmd; - - cmd = container_of(header, struct vmw_begin_query_cmd, - header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBeginQuery) = + container_of(header, typeof(*cmd), header); if (unlikely(dev_priv->has_mob)) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdBeginGBQuery q; - } gb_cmd; + VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdBeginGBQuery); BUG_ON(sizeof(gb_cmd) != sizeof(*cmd)); gb_cmd.header.id = SVGA_3D_CMD_BEGIN_GB_QUERY; gb_cmd.header.size = cmd->header.size; - gb_cmd.q.cid = cmd->q.cid; - gb_cmd.q.type = cmd->q.type; + gb_cmd.body.cid = cmd->body.cid; + gb_cmd.body.type = cmd->body.type; memcpy(cmd, &gb_cmd, sizeof(*cmd)); return vmw_cmd_begin_gb_query(dev_priv, sw_context, header); @@ -1417,7 +1370,7 @@ static int vmw_cmd_begin_query(struct vmw_private *dev_priv, return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, - &cmd->q.cid, NULL); + &cmd->body.cid, NULL); } /** @@ -1432,19 +1385,16 @@ static int vmw_cmd_end_gb_query(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { struct vmw_buffer_object *vmw_bo; - struct vmw_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdEndGBQuery q; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdEndGBQuery); int ret; - cmd = container_of(header, struct vmw_query_cmd, header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_cid_check(dev_priv, sw_context, header); if (unlikely(ret != 0)) return ret; ret = vmw_translate_mob_ptr(dev_priv, sw_context, - &cmd->q.mobid, + &cmd->body.mobid, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1466,27 +1416,21 @@ static int vmw_cmd_end_query(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { struct vmw_buffer_object *vmw_bo; - struct vmw_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdEndQuery q; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdEndQuery); int ret; - cmd = container_of(header, struct vmw_query_cmd, header); + cmd = container_of(header, typeof(*cmd), header); if (dev_priv->has_mob) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdEndGBQuery q; - } gb_cmd; + VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdEndGBQuery); BUG_ON(sizeof(gb_cmd) != sizeof(*cmd)); gb_cmd.header.id = SVGA_3D_CMD_END_GB_QUERY; gb_cmd.header.size = cmd->header.size; - gb_cmd.q.cid = cmd->q.cid; - gb_cmd.q.type = cmd->q.type; - gb_cmd.q.mobid = cmd->q.guestResult.gmrId; - gb_cmd.q.offset = cmd->q.guestResult.offset; + gb_cmd.body.cid = cmd->body.cid; + gb_cmd.body.type = cmd->body.type; + gb_cmd.body.mobid = cmd->body.guestResult.gmrId; + gb_cmd.body.offset = cmd->body.guestResult.offset; memcpy(cmd, &gb_cmd, sizeof(*cmd)); return vmw_cmd_end_gb_query(dev_priv, sw_context, header); @@ -1497,7 +1441,7 @@ static int vmw_cmd_end_query(struct vmw_private *dev_priv, return ret; ret = vmw_translate_guest_ptr(dev_priv, sw_context, - &cmd->q.guestResult, + &cmd->body.guestResult, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1519,19 +1463,16 @@ static int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { struct vmw_buffer_object *vmw_bo; - struct vmw_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdWaitForGBQuery q; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdWaitForGBQuery); int ret; - cmd = container_of(header, struct vmw_query_cmd, header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_cid_check(dev_priv, sw_context, header); if (unlikely(ret != 0)) return ret; ret = vmw_translate_mob_ptr(dev_priv, sw_context, - &cmd->q.mobid, + &cmd->body.mobid, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1551,27 +1492,21 @@ static int vmw_cmd_wait_query(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { struct vmw_buffer_object *vmw_bo; - struct vmw_query_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdWaitForQuery q; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdWaitForQuery); int ret; - cmd = container_of(header, struct vmw_query_cmd, header); + cmd = container_of(header, typeof(*cmd), header); if (dev_priv->has_mob) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdWaitForGBQuery q; - } gb_cmd; + VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdWaitForGBQuery); BUG_ON(sizeof(gb_cmd) != sizeof(*cmd)); gb_cmd.header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY; gb_cmd.header.size = cmd->header.size; - gb_cmd.q.cid = cmd->q.cid; - gb_cmd.q.type = cmd->q.type; - gb_cmd.q.mobid = cmd->q.guestResult.gmrId; - gb_cmd.q.offset = cmd->q.guestResult.offset; + gb_cmd.body.cid = cmd->body.cid; + gb_cmd.body.type = cmd->body.type; + gb_cmd.body.mobid = cmd->body.guestResult.gmrId; + gb_cmd.body.offset = cmd->body.guestResult.offset; memcpy(cmd, &gb_cmd, sizeof(*cmd)); return vmw_cmd_wait_gb_query(dev_priv, sw_context, header); @@ -1582,7 +1517,7 @@ static int vmw_cmd_wait_query(struct vmw_private *dev_priv, return ret; ret = vmw_translate_guest_ptr(dev_priv, sw_context, - &cmd->q.guestResult, + &cmd->body.guestResult, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1596,17 +1531,14 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, { struct vmw_buffer_object *vmw_bo = NULL; struct vmw_surface *srf = NULL; - struct vmw_dma_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdSurfaceDMA dma; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceDMA); int ret; SVGA3dCmdSurfaceDMASuffix *suffix; uint32_t bo_size; bool dirty; - cmd = container_of(header, struct vmw_dma_cmd, header); - suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma + + cmd = container_of(header, typeof(*cmd), header); + suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->body + header->size - sizeof(*suffix)); /* Make sure device and verifier stays in sync. */ @@ -1616,27 +1548,27 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, } ret = vmw_translate_guest_ptr(dev_priv, sw_context, - &cmd->dma.guest.ptr, + &cmd->body.guest.ptr, &vmw_bo); if (unlikely(ret != 0)) return ret; /* Make sure DMA doesn't cross BO boundaries. */ bo_size = vmw_bo->base.num_pages * PAGE_SIZE; - if (unlikely(cmd->dma.guest.ptr.offset > bo_size)) { + if (unlikely(cmd->body.guest.ptr.offset > bo_size)) { DRM_ERROR("Invalid DMA offset.\n"); return -EINVAL; } - bo_size -= cmd->dma.guest.ptr.offset; + bo_size -= cmd->body.guest.ptr.offset; if (unlikely(suffix->maximumOffset > bo_size)) suffix->maximumOffset = bo_size; - dirty = (cmd->dma.transfer == SVGA3D_WRITE_HOST_VRAM) ? + dirty = (cmd->body.transfer == SVGA3D_WRITE_HOST_VRAM) ? VMW_RES_DIRTY_SET : 0; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, dirty, user_surface_converter, - &cmd->dma.host.sid, NULL); + &cmd->body.host.sid, NULL); if (unlikely(ret != 0)) { if (unlikely(ret != -ERESTARTSYS)) DRM_ERROR("could not find surface for DMA.\n"); @@ -1655,10 +1587,7 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_draw_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdDrawPrimitives body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDrawPrimitives); SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)( (unsigned long)header + sizeof(*cmd)); SVGA3dPrimitiveRange *range; @@ -1670,7 +1599,7 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv, if (unlikely(ret != 0)) return ret; - cmd = container_of(header, struct vmw_draw_cmd, header); + cmd = container_of(header, typeof(*cmd), header); maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl); if (unlikely(cmd->body.numVertexDecls > maxnum)) { @@ -1711,26 +1640,20 @@ static int vmw_cmd_tex_state(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_tex_state_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdSetTextureState state; - } *cmd; - + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetTextureState); SVGA3dTextureState *last_state = (SVGA3dTextureState *) ((unsigned long) header + header->size + sizeof(header)); SVGA3dTextureState *cur_state = (SVGA3dTextureState *) - ((unsigned long) header + sizeof(struct vmw_tex_state_cmd)); + ((unsigned long) header + sizeof(*cmd)); struct vmw_resource *ctx; struct vmw_resource *res; int ret; - cmd = container_of(header, struct vmw_tex_state_cmd, - header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, - &cmd->state.cid, - &ctx); + &cmd->body.cid, &ctx); if (unlikely(ret != 0)) return ret; @@ -1876,12 +1799,8 @@ static int vmw_cmd_bind_gb_surface(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_bind_gb_surface_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdBindGBSurface body; - } *cmd; - - cmd = container_of(header, struct vmw_bind_gb_surface_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBindGBSurface) = + container_of(header, typeof(*cmd), header); return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_surface, user_surface_converter, @@ -1901,12 +1820,8 @@ static int vmw_cmd_update_gb_image(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_gb_surface_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdUpdateGBImage body; - } *cmd; - - cmd = container_of(header, struct vmw_gb_surface_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdUpdateGBImage) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -1925,12 +1840,8 @@ static int vmw_cmd_update_gb_surface(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_gb_surface_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdUpdateGBSurface body; - } *cmd; - - cmd = container_of(header, struct vmw_gb_surface_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdUpdateGBSurface) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_CLEAR, user_surface_converter, @@ -1949,12 +1860,8 @@ static int vmw_cmd_readback_gb_image(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_gb_surface_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdReadbackGBImage body; - } *cmd; - - cmd = container_of(header, struct vmw_gb_surface_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdReadbackGBImage) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -1973,12 +1880,8 @@ static int vmw_cmd_readback_gb_surface(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_gb_surface_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdReadbackGBSurface body; - } *cmd; - - cmd = container_of(header, struct vmw_gb_surface_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdReadbackGBSurface) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_CLEAR, user_surface_converter, @@ -1997,12 +1900,8 @@ static int vmw_cmd_invalidate_gb_image(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_gb_surface_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdInvalidateGBImage body; - } *cmd; - - cmd = container_of(header, struct vmw_gb_surface_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdInvalidateGBImage) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -2021,12 +1920,8 @@ static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_gb_surface_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdInvalidateGBSurface body; - } *cmd; - - cmd = container_of(header, struct vmw_gb_surface_cmd, header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdInvalidateGBSurface) = + container_of(header, typeof(*cmd), header); return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_CLEAR, user_surface_converter, @@ -2046,16 +1941,12 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_shader_define_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdDefineShader body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDefineShader); int ret; size_t size; struct vmw_resource *ctx; - cmd = container_of(header, struct vmw_shader_define_cmd, - header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, @@ -2094,15 +1985,11 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_shader_destroy_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdDestroyShader body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDestroyShader); int ret; struct vmw_resource *ctx; - cmd = container_of(header, struct vmw_shader_destroy_cmd, - header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, @@ -2139,17 +2026,13 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_set_shader_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdSetShader body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetShader); struct vmw_ctx_bindinfo_shader binding; struct vmw_resource *ctx, *res = NULL; struct vmw_ctx_validation_info *ctx_info; int ret; - cmd = container_of(header, struct vmw_set_shader_cmd, - header); + cmd = container_of(header, typeof(*cmd), header); if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) { DRM_ERROR("Illegal shader type %u.\n", @@ -2213,14 +2096,10 @@ static int vmw_cmd_set_shader_const(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_set_shader_const_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdSetShaderConst body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetShaderConst); int ret; - cmd = container_of(header, struct vmw_set_shader_const_cmd, - header); + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, @@ -2246,13 +2125,8 @@ static int vmw_cmd_bind_gb_shader(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct vmw_bind_gb_shader_cmd { - SVGA3dCmdHeader header; - SVGA3dCmdBindGBShader body; - } *cmd; - - cmd = container_of(header, struct vmw_bind_gb_shader_cmd, - header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBindGBShader) = + container_of(header, typeof(*cmd), header); return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_shader, user_shader_converter, @@ -2273,10 +2147,7 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXSetSingleConstantBuffer body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetSingleConstantBuffer); struct vmw_resource *res = NULL; struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_cb binding; @@ -2326,10 +2197,8 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXSetShaderResources body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) = + container_of(header, typeof(*cmd), header); u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dShaderResourceViewId); @@ -2359,10 +2228,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXSetShader body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShader); struct vmw_resource *res = NULL; struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_shader binding; @@ -2474,10 +2340,7 @@ static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv, struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_ib binding; struct vmw_resource *res; - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXSetIndexBuffer body; - } *cmd; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetIndexBuffer); int ret; if (!ctx_node) @@ -2513,13 +2376,11 @@ static int vmw_cmd_dx_set_rendertargets(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXSetRenderTargets body; - } *cmd = container_of(header, typeof(*cmd), header); - int ret; + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetRenderTargets) = + container_of(header, typeof(*cmd), header); u32 num_rt_view = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dRenderTargetViewId); + int ret; if (num_rt_view > SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS) { DRM_ERROR("Invalid DX Rendertarget binding.\n"); @@ -2549,10 +2410,8 @@ static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXClearRenderTargetView body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearRenderTargetView) = + container_of(header, typeof(*cmd), header); return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_rt, cmd->body.renderTargetViewId)); @@ -2570,10 +2429,8 @@ static int vmw_cmd_dx_clear_depthstencil_view(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXClearDepthStencilView body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearDepthStencilView) = + container_of(header, typeof(*cmd), header); return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_ds, cmd->body.depthStencilViewId)); @@ -2819,10 +2676,8 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv, { struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_resource *res; - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXDefineShader body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXDefineShader) = + container_of(header, typeof(*cmd), header); int ret; if (!ctx_node) @@ -2851,10 +2706,8 @@ static int vmw_cmd_dx_destroy_shader(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXDestroyShader body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXDestroyShader) = + container_of(header, typeof(*cmd), header); int ret; if (!ctx_node) @@ -2882,10 +2735,8 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, { struct vmw_resource *ctx; struct vmw_resource *res; - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXBindShader body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindShader) = + container_of(header, typeof(*cmd), header); int ret; if (cmd->body.cid != SVGA3D_INVALID_ID) { @@ -2935,10 +2786,8 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXGenMips body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXGenMips) = + container_of(header, typeof(*cmd), header); return PTR_RET(vmw_view_id_val_add(sw_context, vmw_view_sr, cmd->body.shaderResourceViewId)); @@ -2956,10 +2805,8 @@ static int vmw_cmd_dx_transfer_from_buffer(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdDXTransferFromBuffer body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXTransferFromBuffer) = + container_of(header, typeof(*cmd), header); int ret; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, @@ -2985,10 +2832,8 @@ static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) { - struct { - SVGA3dCmdHeader header; - SVGA3dCmdIntraSurfaceCopy body; - } *cmd = container_of(header, typeof(*cmd), header); + VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdIntraSurfaceCopy) = + container_of(header, typeof(*cmd), header); if (!(dev_priv->capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY)) return -EINVAL; -- cgit v1.2.3 From 5724f899ed8265386c2b1f067f836c35aebc7d6e Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Mon, 11 Feb 2019 11:46:27 -0800 Subject: drm/vmwgfx: Add a new define for vmwgfx user-space debugging Error messages or debugging message reported during user-space command submission should not be printed to dmesg by default. So add a new preprocessor define called VMW_DEBUG_USER which translates to DRM_DEBUG_DRIVER. v2: Use VMW_DEBUG_USER instead of using DRM_DEBUG_DRIVER directly. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 14 +++ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 140 ++++++++++++------------ drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 12 +- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 7 +- drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c | 12 +- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 9 +- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 32 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_validation.c | 3 +- 9 files changed, 119 insertions(+), 112 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index 694fabafaeee..39e96bb86329 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -751,7 +751,7 @@ static int vmw_context_define(struct drm_device *dev, void *data, int ret; if (!dev_priv->has_dx && dx) { - DRM_ERROR("DX contexts not supported by device.\n"); + VMW_DEBUG_USER("DX contexts not supported by device.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index abe975b7ea89..92367d4ebdf3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1313,6 +1313,20 @@ int vmw_host_get_guestinfo(const char *guest_info_param, char *buffer, size_t *length); int vmw_host_log(const char *log); +/* VMW logging */ + +/** + * VMW_DEBUG_USER - Debug output for user-space debugging. + * + * @fmt: printf() like format string. + * + * This macro is for logging user-space error and debugging messages for e.g. + * command buffer execution errors due to malformed commands, invalid context, + * etc. + */ +#define VMW_DEBUG_USER(fmt, ...) \ + DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) + /** * Inline helper functions */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 2c92744817ec..9362670af03c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -43,7 +43,7 @@ #define VMW_GET_CTX_NODE(__sw_context) \ ({ \ __sw_context->dx_ctx_node ? __sw_context->dx_ctx_node : ({ \ - DRM_ERROR("SM context is not set at %s\n", __func__); \ + VMW_DEBUG_USER("SM context is not set at %s\n", __func__); \ __sw_context->dx_ctx_node; \ }); \ }) @@ -217,8 +217,7 @@ static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv, sw_context->staged_bindings = vmw_binding_state_alloc(dev_priv); if (IS_ERR(sw_context->staged_bindings)) { - DRM_ERROR("Failed to allocate context binding " - "information.\n"); + VMW_DEBUG_USER("Failed to alloc ctx binding info.\n"); ret = PTR_ERR(sw_context->staged_bindings); sw_context->staged_bindings = NULL; goto out_err; @@ -228,8 +227,7 @@ static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv, if (sw_context->staged_bindings_inuse) { node->staged = vmw_binding_state_alloc(dev_priv); if (IS_ERR(node->staged)) { - DRM_ERROR("Failed to allocate context binding " - "information.\n"); + VMW_DEBUG_USER("Failed to alloc ctx binding info.\n"); ret = PTR_ERR(node->staged); node->staged = NULL; goto out_err; @@ -424,7 +422,7 @@ vmw_view_id_val_add(struct vmw_sw_context *sw_context, int ret; if (!ctx_node) { - DRM_ERROR("DX Context not set.\n"); + VMW_DEBUG_USER("DX Context not set.\n"); return ERR_PTR(-EINVAL); } @@ -522,7 +520,7 @@ static int vmw_resource_relocation_add(struct vmw_sw_context *sw_context, rel = vmw_validation_mem_alloc(sw_context->ctx, sizeof(*rel)); if (unlikely(!rel)) { - DRM_ERROR("Failed to allocate a resource relocation.\n"); + VMW_DEBUG_USER("Failed to allocate a resource relocation.\n"); return -ENOMEM; } @@ -659,7 +657,7 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, if (*id_loc == SVGA3D_INVALID_ID) { if (res_type == vmw_res_context) { - DRM_ERROR("Illegal context invalid id.\n"); + VMW_DEBUG_USER("Illegal context invalid id.\n"); return -EINVAL; } return 0; @@ -680,8 +678,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv, res = vmw_user_resource_noref_lookup_handle (dev_priv, sw_context->fp->tfile, *id_loc, converter); if (IS_ERR(res)) { - DRM_ERROR("Could not find or use resource 0x%08x.\n", - (unsigned int) *id_loc); + VMW_DEBUG_USER("Could not find/use resource 0x%08x.\n", + (unsigned int) *id_loc); return PTR_ERR(res); } @@ -726,7 +724,7 @@ static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res) cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), ctx_res->id); if (cmd == NULL) { - DRM_ERROR("Failed to rebind queries.\n"); + VMW_DEBUG_USER("Failed to rebind queries.\n"); return -ENOMEM; } @@ -758,7 +756,7 @@ static int vmw_rebind_contexts(struct vmw_sw_context *sw_context) ret = vmw_binding_rebind_all(val->cur); if (unlikely(ret != 0)) { if (ret != -ERESTARTSYS) - DRM_ERROR("Failed to rebind context.\n"); + VMW_DEBUG_USER("Failed to rebind context.\n"); return ret; } @@ -803,7 +801,7 @@ static int vmw_view_bindings_add(struct vmw_sw_context *sw_context, view = vmw_view_id_val_add(sw_context, view_type, view_ids[i]); if (IS_ERR(view)) { - DRM_ERROR("View not found.\n"); + VMW_DEBUG_USER("View not found.\n"); return PTR_ERR(view); } } @@ -881,8 +879,8 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); if (cmd->body.type >= SVGA3D_RT_MAX) { - DRM_ERROR("Illegal render target type %u.\n", - (unsigned) cmd->body.type); + VMW_DEBUG_USER("Illegal render target type %u.\n", + (unsigned int) cmd->body.type); return -EINVAL; } @@ -1043,7 +1041,7 @@ static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv, if (unlikely(new_query_bo != sw_context->cur_query_bo)) { if (unlikely(new_query_bo->base.num_pages > 4)) { - DRM_ERROR("Query buffer too large.\n"); + VMW_DEBUG_USER("Query buffer too large.\n"); return -EINVAL; } @@ -1106,7 +1104,7 @@ static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv, ret = vmw_fifo_emit_dummy_query(dev_priv, ctx->id); if (unlikely(ret != 0)) - DRM_ERROR("Out of fifo space for dummy query.\n"); + VMW_DEBUG_USER("Out of fifo space for dummy query.\n"); } if (dev_priv->pinned_bo != sw_context->cur_query_bo) { @@ -1170,7 +1168,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, vmw_validation_preload_bo(sw_context->ctx); vmw_bo = vmw_user_bo_noref_lookup(sw_context->fp->tfile, handle); if (IS_ERR(vmw_bo)) { - DRM_ERROR("Could not find or use MOB buffer.\n"); + VMW_DEBUG_USER("Could not find or use MOB buffer.\n"); return PTR_ERR(vmw_bo); } @@ -1224,7 +1222,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, vmw_validation_preload_bo(sw_context->ctx); vmw_bo = vmw_user_bo_noref_lookup(sw_context->fp->tfile, handle); if (IS_ERR(vmw_bo)) { - DRM_ERROR("Could not find or use GMR region.\n"); + VMW_DEBUG_USER("Could not find or use GMR region.\n"); return PTR_ERR(vmw_bo); } @@ -1543,7 +1541,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, /* Make sure device and verifier stays in sync. */ if (unlikely(suffix->suffixSize != sizeof(*suffix))) { - DRM_ERROR("Invalid DMA suffix size.\n"); + VMW_DEBUG_USER("Invalid DMA suffix size.\n"); return -EINVAL; } @@ -1556,7 +1554,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, /* Make sure DMA doesn't cross BO boundaries. */ bo_size = vmw_bo->base.num_pages * PAGE_SIZE; if (unlikely(cmd->body.guest.ptr.offset > bo_size)) { - DRM_ERROR("Invalid DMA offset.\n"); + VMW_DEBUG_USER("Invalid DMA offset.\n"); return -EINVAL; } @@ -1571,7 +1569,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, &cmd->body.host.sid, NULL); if (unlikely(ret != 0)) { if (unlikely(ret != -ERESTARTSYS)) - DRM_ERROR("could not find surface for DMA.\n"); + VMW_DEBUG_USER("could not find surface for DMA.\n"); return ret; } @@ -1603,7 +1601,7 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv, maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl); if (unlikely(cmd->body.numVertexDecls > maxnum)) { - DRM_ERROR("Illegal number of vertex declarations.\n"); + VMW_DEBUG_USER("Illegal number of vertex declarations.\n"); return -EINVAL; } @@ -1619,7 +1617,7 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv, maxnum = (header->size - sizeof(cmd->body) - cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range); if (unlikely(cmd->body.numRanges > maxnum)) { - DRM_ERROR("Illegal number of index ranges.\n"); + VMW_DEBUG_USER("Illegal number of index ranges.\n"); return -EINVAL; } @@ -1662,8 +1660,8 @@ static int vmw_cmd_tex_state(struct vmw_private *dev_priv, continue; if (cur_state->stage >= SVGA3D_NUM_TEXTURE_UNITS) { - DRM_ERROR("Illegal texture/sampler unit %u.\n", - (unsigned) cur_state->stage); + VMW_DEBUG_USER("Illegal texture/sampler unit %u.\n", + (unsigned int) cur_state->stage); return -EINVAL; } @@ -2035,8 +2033,8 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) { - DRM_ERROR("Illegal shader type %u.\n", - (unsigned) cmd->body.type); + VMW_DEBUG_USER("Illegal shader type %u.\n", + (unsigned int) cmd->body.type); return -EINVAL; } @@ -2173,9 +2171,9 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, if (binding.shader_slot >= SVGA3D_NUM_SHADERTYPE_DX10 || binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { - DRM_ERROR("Illegal const buffer shader %u slot %u.\n", - (unsigned) cmd->body.type, - (unsigned) binding.slot); + VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", + (unsigned int) cmd->body.type, + (unsigned int) binding.slot); return -EINVAL; } @@ -2205,7 +2203,7 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, if ((u64) cmd->body.startView + (u64) num_sr_view > (u64) SVGA3D_DX_MAX_SRVIEWS || cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { - DRM_ERROR("Invalid shader binding.\n"); + VMW_DEBUG_USER("Invalid shader binding.\n"); return -EINVAL; } @@ -2240,15 +2238,15 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { - DRM_ERROR("Illegal shader type %u.\n", - (unsigned) cmd->body.type); + VMW_DEBUG_USER("Illegal shader type %u.\n", + (unsigned int) cmd->body.type); return -EINVAL; } if (cmd->body.shaderId != SVGA3D_INVALID_ID) { res = vmw_shader_lookup(sw_context->man, cmd->body.shaderId, 0); if (IS_ERR(res)) { - DRM_ERROR("Could not find shader for binding.\n"); + VMW_DEBUG_USER("Could not find shader for binding.\n"); return PTR_ERR(res); } @@ -2299,7 +2297,7 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv, sizeof(SVGA3dVertexBuffer); if ((u64)num + (u64)cmd->body.startBuffer > (u64)SVGA3D_DX_MAX_VERTEXBUFFERS) { - DRM_ERROR("Invalid number of vertex buffers.\n"); + VMW_DEBUG_USER("Invalid number of vertex buffers.\n"); return -EINVAL; } @@ -2383,7 +2381,7 @@ static int vmw_cmd_dx_set_rendertargets(struct vmw_private *dev_priv, int ret; if (num_rt_view > SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS) { - DRM_ERROR("Invalid DX Rendertarget binding.\n"); + VMW_DEBUG_USER("Invalid DX Rendertarget binding.\n"); return -EINVAL; } @@ -2513,7 +2511,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, sizeof(SVGA3dSoTarget); if (num > SVGA3D_DX_MAX_SOTARGETS) { - DRM_ERROR("Invalid DX SO binding.\n"); + VMW_DEBUG_USER("Invalid DX SO binding.\n"); return -EINVAL; } @@ -2716,7 +2714,7 @@ static int vmw_cmd_dx_destroy_shader(struct vmw_private *dev_priv, ret = vmw_shader_remove(sw_context->man, cmd->body.shaderId, 0, &sw_context->staged_cmd_res); if (ret) - DRM_ERROR("Could not find shader to remove.\n"); + VMW_DEBUG_USER("Could not find shader to remove.\n"); return ret; } @@ -2759,14 +2757,14 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, res = vmw_shader_lookup(vmw_context_res_man(ctx), cmd->body.shid, 0); if (IS_ERR(res)) { - DRM_ERROR("Could not find shader to bind.\n"); + VMW_DEBUG_USER("Could not find shader to bind.\n"); return PTR_ERR(res); } ret = vmw_execbuf_res_noctx_val_add(sw_context, res, VMW_RES_DIRTY_NONE); if (ret) { - DRM_ERROR("Error creating resource validation node.\n"); + VMW_DEBUG_USER("Error creating resource validation node.\n"); return ret; } @@ -2866,18 +2864,18 @@ static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen); break; default: - DRM_ERROR("Unsupported SVGA command: %u.\n", cmd_id); + VMW_DEBUG_USER("Unsupported SVGA command: %u.\n", cmd_id); return -EINVAL; } if (*size > size_remaining) { - DRM_ERROR("Invalid SVGA command (size mismatch):" - " %u.\n", cmd_id); + VMW_DEBUG_USER("Invalid SVGA command (size mismatch): %u.\n", + cmd_id); return -EINVAL; } if (unlikely(!sw_context->kernel)) { - DRM_ERROR("Kernel only SVGA command: %u.\n", cmd_id); + VMW_DEBUG_USER("Kernel only SVGA command: %u.\n", cmd_id); return -EPERM; } @@ -3294,20 +3292,20 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, return 0; out_invalid: - DRM_ERROR("Invalid SVGA3D command: %d\n", - cmd_id + SVGA_3D_CMD_BASE); + VMW_DEBUG_USER("Invalid SVGA3D command: %d\n", + cmd_id + SVGA_3D_CMD_BASE); return -EINVAL; out_privileged: - DRM_ERROR("Privileged SVGA3D command: %d\n", - cmd_id + SVGA_3D_CMD_BASE); + VMW_DEBUG_USER("Privileged SVGA3D command: %d\n", + cmd_id + SVGA_3D_CMD_BASE); return -EPERM; out_old: - DRM_ERROR("Deprecated (disallowed) SVGA3D command: %d\n", - cmd_id + SVGA_3D_CMD_BASE); + VMW_DEBUG_USER("Deprecated (disallowed) SVGA3D command: %d\n", + cmd_id + SVGA_3D_CMD_BASE); return -EINVAL; out_new: - DRM_ERROR("SVGA3D command: %d not supported by virtual hardware.\n", - cmd_id + SVGA_3D_CMD_BASE); + VMW_DEBUG_USER("SVGA3D command: %d not supported by virtual device.\n", + cmd_id + SVGA_3D_CMD_BASE); return -EINVAL; } @@ -3331,7 +3329,7 @@ static int vmw_cmd_check_all(struct vmw_private *dev_priv, } if (unlikely(cur_size != 0)) { - DRM_ERROR("Command verifier out of sync.\n"); + VMW_DEBUG_USER("Command verifier out of sync.\n"); return -EINVAL; } @@ -3389,7 +3387,7 @@ static int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context, sw_context->cmd_bounce = vmalloc(sw_context->cmd_bounce_size); if (sw_context->cmd_bounce == NULL) { - DRM_ERROR("Failed to allocate command bounce buffer.\n"); + VMW_DEBUG_USER("Failed to allocate command bounce buffer.\n"); sw_context->cmd_bounce_size = 0; return -ENOMEM; } @@ -3422,7 +3420,7 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv, ret = vmw_fifo_send_fence(dev_priv, &sequence); if (unlikely(ret != 0)) { - DRM_ERROR("Fence submission error. Syncing.\n"); + VMW_DEBUG_USER("Fence submission error. Syncing.\n"); synced = true; } @@ -3515,7 +3513,7 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle, TTM_REF_USAGE); - DRM_ERROR("Fence copy error. Syncing.\n"); + VMW_DEBUG_USER("Fence copy error. Syncing.\n"); (void) vmw_fence_obj_wait(fence, false, false, VMW_FENCE_WAIT_TIMEOUT); } @@ -3546,7 +3544,7 @@ static int vmw_execbuf_submit_fifo(struct vmw_private *dev_priv, else cmd = vmw_fifo_reserve(dev_priv, command_size); if (!cmd) { - DRM_ERROR("Failed reserving fifo space for commands.\n"); + VMW_DEBUG_USER("Failed reserving fifo space for commands.\n"); return -ENOMEM; } @@ -3622,7 +3620,7 @@ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv, *header = NULL; if (command_size > SVGA_CB_MAX_SIZE) { - DRM_ERROR("Command buffer is too large.\n"); + VMW_DEBUG_USER("Command buffer is too large.\n"); return ERR_PTR(-EINVAL); } @@ -3640,7 +3638,7 @@ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv, ret = copy_from_user(kernel_commands, user_commands, command_size); if (ret) { - DRM_ERROR("Failed copying commands.\n"); + VMW_DEBUG_USER("Failed copying commands.\n"); vmw_cmdbuf_header_free(*header); *header = NULL; return ERR_PTR(-EFAULT); @@ -3669,8 +3667,8 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, (dev_priv, sw_context->fp->tfile, handle, user_context_converter); if (IS_ERR(res)) { - DRM_ERROR("Could not find or user DX context 0x%08x.\n", - (unsigned) handle); + VMW_DEBUG_USER("Could not find or user DX context 0x%08x.\n", + (unsigned int) handle); return PTR_ERR(res); } @@ -3709,7 +3707,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) { out_fence_fd = get_unused_fd_flags(O_CLOEXEC); if (out_fence_fd < 0) { - DRM_ERROR("Failed to get a fence file descriptor.\n"); + VMW_DEBUG_USER("Failed to get a fence fd.\n"); return out_fence_fd; } } @@ -3748,7 +3746,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, if (unlikely(ret != 0)) { ret = -EFAULT; - DRM_ERROR("Failed copying commands.\n"); + VMW_DEBUG_USER("Failed copying commands.\n"); goto out_unlock; } kernel_commands = sw_context->cmd_bounce; @@ -3838,7 +3836,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, */ if (ret != 0) - DRM_ERROR("Fence submission error. Syncing.\n"); + VMW_DEBUG_USER("Fence submission error. Syncing.\n"); vmw_execbuf_bindings_commit(sw_context, false); vmw_bind_dx_query_mob(sw_context); @@ -3860,7 +3858,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, sync_file = sync_file_create(&fence->base); if (!sync_file) { - DRM_ERROR("Unable to create sync file for fence\n"); + VMW_DEBUG_USER("Sync file create failed for fence\n"); put_unused_fd(out_fence_fd); out_fence_fd = -1; @@ -3939,7 +3937,7 @@ out_free_fence_fd: */ static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv) { - DRM_ERROR("Can't unpin query buffer. Trying to recover.\n"); + VMW_DEBUG_USER("Can't unpin query buffer. Trying to recover.\n"); (void) vmw_fallback_wait(dev_priv, false, true, 0, false, 10*HZ); vmw_bo_pin_reserved(dev_priv->pinned_bo, false); @@ -4072,8 +4070,8 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, struct dma_fence *in_fence = NULL; if (unlikely(size < copy_offset[0])) { - DRM_ERROR("Invalid command size, ioctl %d\n", - DRM_VMW_EXECBUF); + VMW_DEBUG_USER("Invalid command size, ioctl %d\n", + DRM_VMW_EXECBUF); return -EINVAL; } @@ -4089,7 +4087,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, if (unlikely(arg.version > DRM_VMW_EXECBUF_VERSION || arg.version == 0)) { - DRM_ERROR("Incorrect execbuf version.\n"); + VMW_DEBUG_USER("Incorrect execbuf version.\n"); return -EINVAL; } @@ -4115,7 +4113,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, in_fence = sync_file_get_fence(arg.imported_fence_fd); if (!in_fence) { - DRM_ERROR("Cannot get imported fence\n"); + VMW_DEBUG_USER("Cannot get imported fence\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 172a6ba6539c..a15375eb476e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -188,7 +188,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) { - DRM_ERROR("Illegal GET_3D_CAP argument.\n"); + VMW_DEBUG_USER("Illegal GET_3D_CAP argument.\n"); return -EINVAL; } @@ -268,7 +268,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, return 0; if (clips_ptr == NULL) { - DRM_ERROR("Variable clips_ptr must be specified.\n"); + VMW_DEBUG_USER("Variable clips_ptr must be specified.\n"); ret = -EINVAL; goto out_clips; } @@ -291,7 +291,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); if (!fb) { - DRM_ERROR("Invalid framebuffer id.\n"); + VMW_DEBUG_USER("Invalid framebuffer id.\n"); ret = -ENOENT; goto out_no_fb; } @@ -351,7 +351,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, return 0; if (clips_ptr == NULL) { - DRM_ERROR("Argument clips_ptr must be specified.\n"); + VMW_DEBUG_USER("Argument clips_ptr must be specified.\n"); ret = -EINVAL; goto out_clips; } @@ -374,14 +374,14 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); if (!fb) { - DRM_ERROR("Invalid framebuffer id.\n"); + VMW_DEBUG_USER("Invalid framebuffer id.\n"); ret = -ENOENT; goto out_no_fb; } vfb = vmw_framebuffer_to_vfb(fb); if (!vfb->bo) { - DRM_ERROR("Framebuffer not buffer backed.\n"); + VMW_DEBUG_USER("Framebuffer not buffer backed.\n"); ret = -EINVAL; goto out_no_ttm_lock; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index bf32fe446219..bbc95743a381 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c @@ -865,14 +865,13 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, ret = vmw_user_bo_lookup(tfile, buffer_handle, &buffer, NULL); if (unlikely(ret != 0)) { - DRM_ERROR("Could not find buffer for shader " - "creation.\n"); + VMW_DEBUG_USER("Couldn't find buffer for shader creation.\n"); return ret; } if ((u64)buffer->base.num_pages * PAGE_SIZE < (u64)size + (u64)offset) { - DRM_ERROR("Illegal buffer- or shader size.\n"); + VMW_DEBUG_USER("Illegal buffer- or shader size.\n"); ret = -EINVAL; goto out_bad_arg; } @@ -886,7 +885,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv, shader_type = SVGA3D_SHADERTYPE_PS; break; default: - DRM_ERROR("Illegal shader type.\n"); + VMW_DEBUG_USER("Illegal shader type.\n"); ret = -EINVAL; goto out_bad_arg; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c index 6a6865384e91..73e9a487e659 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c @@ -239,17 +239,17 @@ vmw_simple_resource_lookup(struct ttm_object_file *tfile, base = ttm_base_object_lookup(tfile, handle); if (!base) { - DRM_ERROR("Invalid %s handle 0x%08lx.\n", - func->res_func.type_name, - (unsigned long) handle); + VMW_DEBUG_USER("Invalid %s handle 0x%08lx.\n", + func->res_func.type_name, + (unsigned long) handle); return ERR_PTR(-ESRCH); } if (ttm_base_object_type(base) != func->ttm_res_type) { ttm_base_object_unref(&base); - DRM_ERROR("Invalid type of %s handle 0x%08lx.\n", - func->res_func.type_name, - (unsigned long) handle); + VMW_DEBUG_USER("Invalid type of %s handle 0x%08lx.\n", + func->res_func.type_name, + (unsigned long) handle); return ERR_PTR(-EINVAL); } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c index 4ef8460eaf2c..c50002a3db27 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c @@ -338,12 +338,12 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man, if (cmd_size != vmw_view_define_sizes[view_type] + sizeof(SVGA3dCmdHeader)) { - DRM_ERROR("Illegal view create command size.\n"); + VMW_DEBUG_USER("Illegal view create command size.\n"); return -EINVAL; } if (!vmw_view_id_ok(user_key, view_type)) { - DRM_ERROR("Illegal view add view id.\n"); + VMW_DEBUG_USER("Illegal view add view id.\n"); return -EINVAL; } @@ -352,8 +352,7 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man, ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), size, &ttm_opt_ctx); if (ret) { if (ret != -ERESTARTSYS) - DRM_ERROR("Out of graphics memory for view" - " creation.\n"); + DRM_ERROR("Out of graphics memory for view creation\n"); return ret; } @@ -413,7 +412,7 @@ int vmw_view_remove(struct vmw_cmdbuf_res_manager *man, struct vmw_resource **res_p) { if (!vmw_view_id_ok(user_key, view_type)) { - DRM_ERROR("Illegal view remove view id.\n"); + VMW_DEBUG_USER("Illegal view remove view id.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index ef09f7edf931..b550f69578e8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -748,11 +748,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, ttm_round_pot(num_sizes * sizeof(struct drm_vmw_size)) + ttm_round_pot(num_sizes * sizeof(struct vmw_surface_offset)); - desc = svga3dsurface_get_desc(req->format); if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) { - DRM_ERROR("Invalid surface format for surface creation.\n"); - DRM_ERROR("Format requested is: %d\n", req->format); + VMW_DEBUG_USER("Invalid format %d for surface creation.\n", + req->format); return -EINVAL; } @@ -764,8 +763,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, size, &ctx); if (unlikely(ret != 0)) { if (ret != -ERESTARTSYS) - DRM_ERROR("Out of graphics memory for surface" - " creation.\n"); + DRM_ERROR("Out of graphics memory for surface.\n"); goto out_unlock; } @@ -939,12 +937,12 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv, ret = -EINVAL; base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle); if (unlikely(!base)) { - DRM_ERROR("Could not find surface to reference.\n"); + VMW_DEBUG_USER("Could not find surface to reference.\n"); goto out_no_lookup; } if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) { - DRM_ERROR("Referenced object is not a surface.\n"); + VMW_DEBUG_USER("Referenced object is not a surface.\n"); goto out_bad_resource; } @@ -1022,8 +1020,8 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, ret = copy_to_user(user_sizes, &srf->base_size, sizeof(srf->base_size)); if (unlikely(ret != 0)) { - DRM_ERROR("copy_to_user failed %p %u\n", - user_sizes, srf->num_sizes); + VMW_DEBUG_USER("copy_to_user failed %p %u\n", user_sizes, + srf->num_sizes); ttm_ref_object_base_unref(tfile, base->handle, TTM_REF_USAGE); ret = -EFAULT; } @@ -1405,16 +1403,16 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, if (for_scanout) { if (!svga3dsurface_is_screen_target_format(format)) { - DRM_ERROR("Invalid Screen Target surface format."); + VMW_DEBUG_USER("Invalid Screen Target surface format."); return -EINVAL; } if (size.width > dev_priv->texture_max_width || size.height > dev_priv->texture_max_height) { - DRM_ERROR("%ux%u\n, exceeds max surface size %ux%u", - size.width, size.height, - dev_priv->texture_max_width, - dev_priv->texture_max_height); + VMW_DEBUG_USER("%ux%u\n, exceeds max surface size %ux%u", + size.width, size.height, + dev_priv->texture_max_width, + dev_priv->texture_max_height); return -EINVAL; } } else { @@ -1422,14 +1420,14 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, desc = svga3dsurface_get_desc(format); if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) { - DRM_ERROR("Invalid surface format.\n"); + VMW_DEBUG_USER("Invalid surface format.\n"); return -EINVAL; } } /* array_size must be null for non-GL3 host. */ if (array_size > 0 && !dev_priv->has_dx) { - DRM_ERROR("Tried to create DX surface on non-DX host.\n"); + VMW_DEBUG_USER("Tried to create DX surface on non-DX host.\n"); return -EINVAL; } @@ -1651,7 +1649,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, if (ret == 0) { if (res->backup->base.num_pages * PAGE_SIZE < res->backup_size) { - DRM_ERROR("Surface backup buffer too small.\n"); + VMW_DEBUG_USER("Surface backup buffer too small.\n"); vmw_bo_unreference(&res->backup); ret = -EINVAL; goto out_unlock; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c index 5ab7da1cbb45..f611b2290a1b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c @@ -325,8 +325,7 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx, node = vmw_validation_mem_alloc(ctx, sizeof(*node) + priv_size); if (!node) { - DRM_ERROR("Failed to allocate a resource validation " - "entry.\n"); + VMW_DEBUG_USER("Failed to allocate a resource validation entry.\n"); return -ENOMEM; } -- cgit v1.2.3 From 45399b112a72e8ab41684164e860765fb96be99d Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Mon, 11 Feb 2019 12:57:38 -0800 Subject: drm/vmwgfx: Print message when command verifier returns with error Whenever command verifier function returns with an error, print a debug message using VMW_DEBUG_USER. This will make sure failing commands can be easily tracked for debugging purpose. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 9362670af03c..9df334340146 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -3287,8 +3287,11 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, goto out_new; ret = entry->func(dev_priv, sw_context, header); - if (unlikely(ret != 0)) - goto out_invalid; + if (unlikely(ret != 0)) { + VMW_DEBUG_USER("SVGA3D command: %d failed with error %d\n", + cmd_id + SVGA_3D_CMD_BASE, ret); + return ret; + } return 0; out_invalid: -- cgit v1.2.3 From b289840455ce99a12f202587a9dc1939c698d501 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Mon, 11 Feb 2019 14:59:57 -0800 Subject: drm/vmwgfx: Clean up some debug messages in vmwgfx_execbuf.c Now that vmw_cmd_check prints debug message whenever a command verifier fails, some of debug statements are unnecessary. Also rearranged some debug print-out with this patch. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 9df334340146..e7c93f422a7e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -217,7 +217,6 @@ static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv, sw_context->staged_bindings = vmw_binding_state_alloc(dev_priv); if (IS_ERR(sw_context->staged_bindings)) { - VMW_DEBUG_USER("Failed to alloc ctx binding info.\n"); ret = PTR_ERR(sw_context->staged_bindings); sw_context->staged_bindings = NULL; goto out_err; @@ -227,7 +226,6 @@ static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv, if (sw_context->staged_bindings_inuse) { node->staged = vmw_binding_state_alloc(dev_priv); if (IS_ERR(node->staged)) { - VMW_DEBUG_USER("Failed to alloc ctx binding info.\n"); ret = PTR_ERR(node->staged); node->staged = NULL; goto out_err; @@ -327,8 +325,10 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, if (priv_size && first_usage) { ret = vmw_cmd_ctx_first_setup(dev_priv, sw_context, res, ctx_info); - if (ret) + if (ret) { + VMW_DEBUG_USER("Failed first usage context setup.\n"); return ret; + } } vmw_execbuf_rcache_update(rcache, res, ctx_info); @@ -421,10 +421,8 @@ vmw_view_id_val_add(struct vmw_sw_context *sw_context, struct vmw_resource *view; int ret; - if (!ctx_node) { - VMW_DEBUG_USER("DX Context not set.\n"); + if (!ctx_node) return ERR_PTR(-EINVAL); - } view = vmw_view_lookup(sw_context->man, view_type, id); if (IS_ERR(view)) @@ -723,10 +721,8 @@ static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res) cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), ctx_res->id); - if (cmd == NULL) { - VMW_DEBUG_USER("Failed to rebind queries.\n"); + if (cmd == NULL) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_BIND_ALL_QUERY; cmd->header.size = sizeof(cmd->body); @@ -761,8 +757,10 @@ static int vmw_rebind_contexts(struct vmw_sw_context *sw_context) } ret = vmw_rebind_all_dx_query(val->ctx); - if (ret != 0) + if (ret != 0) { + VMW_DEBUG_USER("Failed to rebind queries.\n"); return ret; + } } return 0; @@ -2713,8 +2711,6 @@ static int vmw_cmd_dx_destroy_shader(struct vmw_private *dev_priv, ret = vmw_shader_remove(sw_context->man, cmd->body.shaderId, 0, &sw_context->staged_cmd_res); - if (ret) - VMW_DEBUG_USER("Could not find shader to remove.\n"); return ret; } -- cgit v1.2.3 From 4062dd3e6ad6b6fbc910406562a41c7110e5374d Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Wed, 13 Feb 2019 15:39:51 -0800 Subject: drm/vmwgfx: Use VMW_DEBUG_USER for device command buffer errors DRM_ERROR overwhelms dmesgi so use VMW_DEBUG_USER instead. Any malformed command should not really go to device so WARN_ONCE to spot this. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index ed15655eacd2..56979e412ca8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -393,6 +393,7 @@ static void vmw_cmdbuf_ctx_process(struct vmw_cmdbuf_man *man, __vmw_cmdbuf_header_free(entry); break; case SVGA_CB_STATUS_COMMAND_ERROR: + WARN_ONCE(true, "Command buffer error.\n"); entry->cb_header->status = SVGA_CB_STATUS_NONE; list_add_tail(&entry->list, &man->error); schedule_work(&man->work); @@ -533,19 +534,20 @@ static void vmw_cmdbuf_work_func(struct work_struct *work) global_block = true; if (!vmw_cmd_describe(header, &error_cmd_size, &cmd_name)) { - DRM_ERROR("Unknown command causing device error.\n"); - DRM_ERROR("Command buffer offset is %lu\n", - (unsigned long) cb_hdr->errorOffset); + VMW_DEBUG_USER("Unknown command causing device error.\n"); + VMW_DEBUG_USER("Command buffer offset is %lu\n", + (unsigned long) cb_hdr->errorOffset); __vmw_cmdbuf_header_free(entry); send_fence = true; continue; } - DRM_ERROR("Command \"%s\" causing device error.\n", cmd_name); - DRM_ERROR("Command buffer offset is %lu\n", - (unsigned long) cb_hdr->errorOffset); - DRM_ERROR("Command size is %lu\n", - (unsigned long) error_cmd_size); + VMW_DEBUG_USER("Command \"%s\" causing device error.\n", + cmd_name); + VMW_DEBUG_USER("Command buffer offset is %lu\n", + (unsigned long) cb_hdr->errorOffset); + VMW_DEBUG_USER("Command size is %lu\n", + (unsigned long) error_cmd_size); new_start_offset = cb_hdr->errorOffset + error_cmd_size; -- cgit v1.2.3 From 680360a4d3f6958f18029264bdc277e130f43ab4 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Wed, 13 Feb 2019 13:20:42 -0800 Subject: drm/vmwgfx: Fix formatting and spaces in vmwgfx_execbuf.c No functional change with this change, just fixing formatting and spaces. v2: Rebase. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 687 ++++++++++++++------------------ 1 file changed, 302 insertions(+), 385 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index e7c93f422a7e..0d703f431f1f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -54,7 +54,7 @@ __type body; \ } __var -/* +/** * struct vmw_relocation - Buffer object relocation * * @head: List head for the command submission context's relocation list @@ -78,9 +78,8 @@ struct vmw_relocation { * command stream is replaced with the actual id after validation. * @vmw_res_rel_nop: NOP relocation. The command is unconditionally replaced * with a NOP. - * @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id - * after validation is -1, the command is replaced with a NOP. Otherwise no - * action. + * @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id after + * validation is -1, the command is replaced with a NOP. Otherwise no action. */ enum vmw_resource_relocation_type { vmw_res_rel_normal, @@ -94,8 +93,8 @@ enum vmw_resource_relocation_type { * * @head: List head for the software context's relocation list. * @res: Non-ref-counted pointer to the resource. - * @offset: Offset of single byte entries into the command buffer where the - * id that needs fixup is located. + * @offset: Offset of single byte entries into the command buffer where the id + * that needs fixup is located. * @rel_type: Type of relocation. */ struct vmw_resource_relocation { @@ -105,8 +104,9 @@ struct vmw_resource_relocation { enum vmw_resource_relocation_type rel_type:3; }; -/* +/** * struct vmw_ctx_validation_info - Extra validation metadata for contexts + * * @head: List head of context list * @ctx: The context resource * @cur: The context's persistent binding state @@ -161,9 +161,10 @@ static size_t vmw_ptr_diff(void *a, void *b) /** * vmw_execbuf_bindings_commit - Commit modified binding state + * * @sw_context: The command submission context - * @backoff: Whether this is part of the error path and binding state - * changes should be ignored + * @backoff: Whether this is part of the error path and binding state changes + * should be ignored */ static void vmw_execbuf_bindings_commit(struct vmw_sw_context *sw_context, bool backoff) @@ -173,6 +174,7 @@ static void vmw_execbuf_bindings_commit(struct vmw_sw_context *sw_context, list_for_each_entry(entry, &sw_context->ctx_list, head) { if (!backoff) vmw_binding_state_commit(entry->cur, entry->staged); + if (entry->staged != sw_context->staged_bindings) vmw_binding_state_free(entry->staged); else @@ -185,6 +187,7 @@ static void vmw_execbuf_bindings_commit(struct vmw_sw_context *sw_context, /** * vmw_bind_dx_query_mob - Bind the DX query MOB if referenced + * * @sw_context: The command submission context */ static void vmw_bind_dx_query_mob(struct vmw_sw_context *sw_context) @@ -195,8 +198,8 @@ static void vmw_bind_dx_query_mob(struct vmw_sw_context *sw_context) } /** - * vmw_cmd_ctx_first_setup - Perform the setup needed when a context is - * added to the validate list. + * vmw_cmd_ctx_first_setup - Perform the setup needed when a context is added to + * the validate list. * * @dev_priv: Pointer to the device private: * @sw_context: The command submission context @@ -214,8 +217,7 @@ static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv, goto out_err; if (!sw_context->staged_bindings) { - sw_context->staged_bindings = - vmw_binding_state_alloc(dev_priv); + sw_context->staged_bindings = vmw_binding_state_alloc(dev_priv); if (IS_ERR(sw_context->staged_bindings)) { ret = PTR_ERR(sw_context->staged_bindings); sw_context->staged_bindings = NULL; @@ -240,19 +242,20 @@ static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv, list_add_tail(&node->head, &sw_context->ctx_list); return 0; + out_err: return ret; } /** - * vmw_execbuf_res_size - calculate extra size fore the resource validation - * node + * vmw_execbuf_res_size - calculate extra size fore the resource validation node + * * @dev_priv: Pointer to the device private struct. * @res_type: The resource type. * - * Guest-backed contexts and DX contexts require extra size to store - * execbuf private information in the validation node. Typically the - * binding manager associated data structures. + * Guest-backed contexts and DX contexts require extra size to store execbuf + * private information in the validation node. Typically the binding manager + * associated data structures. * * Returns: The extra size requirement based on resource type. */ @@ -269,8 +272,8 @@ static unsigned int vmw_execbuf_res_size(struct vmw_private *dev_priv, * * @rcache: Pointer to the entry to update. * @res: Pointer to the resource. - * @private: Pointer to the execbuf-private space in the resource - * validation node. + * @private: Pointer to the execbuf-private space in the resource validation + * node. */ static void vmw_execbuf_rcache_update(struct vmw_res_cache_entry *rcache, struct vmw_resource *res, @@ -283,15 +286,15 @@ static void vmw_execbuf_rcache_update(struct vmw_res_cache_entry *rcache, } /** - * vmw_execbuf_res_noref_val_add - Add a resource described by an - * unreferenced rcu-protected pointer to the validation list. + * vmw_execbuf_res_noref_val_add - Add a resource described by an unreferenced + * rcu-protected pointer to the validation list. + * * @sw_context: Pointer to the software context. * @res: Unreferenced rcu-protected pointer to the resource. * @dirty: Whether to change dirty status. * - * Returns: 0 on success. Negative error code on failure. Typical error - * codes are %-EINVAL on inconsistency and %-ESRCH if the resource was - * doomed. + * Returns: 0 on success. Negative error code on failure. Typical error codes + * are %-EINVAL on inconsistency and %-ESRCH if the resource was doomed. */ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, struct vmw_resource *res, @@ -338,6 +341,7 @@ static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context, /** * vmw_execbuf_res_noctx_val_add - Add a non-context resource to the resource * validation list if it's not already on it + * * @sw_context: Pointer to the software context. * @res: Pointer to the resource. * @dirty: Whether to change dirty status. @@ -372,8 +376,8 @@ static int vmw_execbuf_res_noctx_val_add(struct vmw_sw_context *sw_context, } /** - * vmw_view_res_val_add - Add a view and the surface it's pointing to - * to the validation list + * vmw_view_res_val_add - Add a view and the surface it's pointing to to the + * validation list * * @sw_context: The software context holding the validation list. * @view: Pointer to the view resource. @@ -386,8 +390,8 @@ static int vmw_view_res_val_add(struct vmw_sw_context *sw_context, int ret; /* - * First add the resource the view is pointing to, otherwise - * it may be swapped out when the view is validated. + * First add the resource the view is pointing to, otherwise it may be + * swapped out when the view is validated. */ ret = vmw_execbuf_res_noctx_val_add(sw_context, vmw_view_srf(view), vmw_view_dirtying(view)); @@ -399,16 +403,16 @@ static int vmw_view_res_val_add(struct vmw_sw_context *sw_context, } /** - * vmw_view_id_val_add - Look up a view and add it and the surface it's - * pointing to to the validation list. + * vmw_view_id_val_add - Look up a view and add it and the surface it's pointing + * to to the validation list. * * @sw_context: The software context holding the validation list. * @view_type: The view type to look up. * @id: view id of the view. * - * The view is represented by a view id and the DX context it's created on, - * or scheduled for creation on. If there is no DX context set, the function - * will return an -EINVAL error pointer. + * The view is represented by a view id and the DX context it's created on, or + * scheduled for creation on. If there is no DX context set, the function will + * return an -EINVAL error pointer. * * Returns: Unreferenced pointer to the resource on success, negative error * pointer on failure. @@ -443,8 +447,8 @@ vmw_view_id_val_add(struct vmw_sw_context *sw_context, * @sw_context: Pointer to a software context used for this command submission * @ctx: Pointer to the context resource * - * This function puts all resources that were previously bound to @ctx on - * the resource validation list. This is part of the context state reemission + * This function puts all resources that were previously bound to @ctx on the + * resource validation list. This is part of the context state reemission */ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, @@ -470,7 +474,6 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, } } - /* Add all resources bound to the context to the validation list */ mutex_lock(&dev_priv->binding_mutex); binding_list = vmw_context_binding_list(ctx); @@ -504,8 +507,8 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, * * @list: Pointer to head of relocation list. * @res: The resource. - * @offset: Offset into the command buffer currently being parsed where the - * id that needs fixup is located. Granularity is one byte. + * @offset: Offset into the command buffer currently being parsed where the id + * that needs fixup is located. Granularity is one byte. * @rel_type: Relocation type. */ static int vmw_resource_relocation_add(struct vmw_sw_context *sw_context, @@ -538,17 +541,15 @@ static int vmw_resource_relocation_add(struct vmw_sw_context *sw_context, static void vmw_resource_relocations_free(struct list_head *list) { /* Memory is validation context memory, so no need to free it */ - INIT_LIST_HEAD(list); } /** * vmw_resource_relocations_apply - Apply all relocations on a list * - * @cb: Pointer to the start of the command buffer bein patch. This need - * not be the same buffer as the one being parsed when the relocation - * list was built, but the contents must be the same modulo the - * resource ids. + * @cb: Pointer to the start of the command buffer bein patch. This need not be + * the same buffer as the one being parsed when the relocation list was built, + * but the contents must be the same modulo the resource ids. * @list: Pointer to the head of the relocation list. */ static void vmw_resource_relocations_apply(uint32_t *cb, @@ -592,14 +593,14 @@ static int vmw_cmd_ok(struct vmw_private *dev_priv, } /** - * vmw_resources_reserve - Reserve all resources on the sw_context's - * resource list. + * vmw_resources_reserve - Reserve all resources on the sw_context's resource + * list. * * @sw_context: Pointer to the software context. * - * Note that since vmware's command submission currently is protected by - * the cmdbuf mutex, no fancy deadlock avoidance is required for resources, - * since only a single thread at once will attempt this. + * Note that since vmware's command submission currently is protected by the + * cmdbuf mutex, no fancy deadlock avoidance is required for resources, since + * only a single thread at once will attempt this. */ static int vmw_resources_reserve(struct vmw_sw_context *sw_context) { @@ -624,18 +625,18 @@ static int vmw_resources_reserve(struct vmw_sw_context *sw_context) } /** - * vmw_cmd_res_check - Check that a resource is present and if so, put it - * on the resource validate list unless it's already there. + * vmw_cmd_res_check - Check that a resource is present and if so, put it on the + * resource validate list unless it's already there. * * @dev_priv: Pointer to a device private structure. * @sw_context: Pointer to the software context. * @res_type: Resource type. * @dirty: Whether to change dirty status. * @converter: User-space visisble type specific information. - * @id_loc: Pointer to the location in the command buffer currently being - * parsed from where the user-space resource id handle is located. - * @p_val: Pointer to pointer to resource validalidation node. Populated - * on exit. + * @id_loc: Pointer to the location in the command buffer currently being parsed + * from where the user-space resource id handle is located. + * @p_val: Pointer to pointer to resource validalidation node. Populated on + * exit. */ static int vmw_cmd_res_check(struct vmw_private *dev_priv, @@ -736,8 +737,8 @@ static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res) } /** - * vmw_rebind_contexts - Rebind all resources previously bound to - * referenced contexts. + * vmw_rebind_contexts - Rebind all resources previously bound to referenced + * contexts. * * @sw_context: Pointer to the software context. * @@ -767,8 +768,8 @@ static int vmw_rebind_contexts(struct vmw_sw_context *sw_context) } /** - * vmw_view_bindings_add - Add an array of view bindings to a context - * binding state tracker. + * vmw_view_bindings_add - Add an array of view bindings to a context binding + * state tracker. * * @sw_context: The execbuf state used for this command. * @view_type: View type for the bindings. @@ -840,6 +841,7 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, /** * vmw_execbuf_info_from_res - Get the private validation metadata for a * recently validated resource + * * @sw_context: Pointer to the command submission context * @res: The resource * @@ -847,8 +849,8 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, * context's resource cache and hence the last resource of that type to be * processed by the validation code. * - * Return: a pointer to the private metadata of the resource, or NULL - * if it wasn't found + * Return: a pointer to the private metadata of the resource, or NULL if it + * wasn't found */ static struct vmw_ctx_validation_info * vmw_execbuf_info_from_res(struct vmw_sw_context *sw_context, @@ -864,7 +866,6 @@ vmw_execbuf_info_from_res(struct vmw_sw_context *sw_context, return NULL; } - static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) @@ -933,8 +934,8 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, } static int vmw_cmd_buffer_copy_check(struct vmw_private *dev_priv, - struct vmw_sw_context *sw_context, - SVGA3dCmdHeader *header) + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBufferCopy); int ret; @@ -983,6 +984,7 @@ static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, &cmd->body.src.sid, NULL); if (unlikely(ret != 0)) return ret; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_SET, user_surface_converter, &cmd->body.dest.sid, NULL); @@ -1019,11 +1021,10 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, * @new_query_bo: The new buffer holding query results. * @sw_context: The software context used for this command submission. * - * This function checks whether @new_query_bo is suitable for holding - * query results, and if another buffer currently is pinned for query - * results. If so, the function prepares the state of @sw_context for - * switching pinned buffers after successful submission of the current - * command batch. + * This function checks whether @new_query_bo is suitable for holding query + * results, and if another buffer currently is pinned for query results. If so, + * the function prepares the state of @sw_context for switching pinned buffers + * after successful submission of the current command batch. */ static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv, struct vmw_buffer_object *new_query_bo, @@ -1058,13 +1059,11 @@ static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv, dev_priv->has_mob, false); if (unlikely(ret != 0)) return ret; - } return 0; } - /** * vmw_query_bo_switch_commit - Finalize switching pinned query buffer * @@ -1073,11 +1072,11 @@ static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv, * * This function will check if we're switching query buffers, and will then, * issue a dummy occlusion query wait used as a query barrier. When the fence - * object following that query wait has signaled, we are sure that all - * preceding queries have finished, and the old query buffer can be unpinned. - * However, since both the new query buffer and the old one are fenced with - * that fence, we can do an asynchronus unpin now, and be sure that the - * old query buffer won't be moved until the fence has signaled. + * object following that query wait has signaled, we are sure that all preceding + * queries have finished, and the old query buffer can be unpinned. However, + * since both the new query buffer and the old one are fenced with that fence, + * we can do an asynchronus unpin now, and be sure that the old query buffer + * won't be moved until the fence has signaled. * * As mentioned above, both the new - and old query buffers need to be fenced * using a sequence emitted *after* calling this function. @@ -1089,7 +1088,6 @@ static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv, * The validate list should still hold references to all * contexts here. */ - if (sw_context->needs_post_query_barrier) { struct vmw_res_cache_entry *ctx_entry = &sw_context->res_cache[vmw_res_context]; @@ -1116,10 +1114,9 @@ static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv, /* * We pin also the dummy_query_bo buffer so that we - * don't need to validate it when emitting - * dummy queries in context destroy paths. + * don't need to validate it when emitting dummy queries + * in context destroy paths. */ - if (!dev_priv->dummy_query_bo_pinned) { vmw_bo_pin_reserved(dev_priv->dummy_query_bo, true); @@ -1136,22 +1133,24 @@ static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv, } /** - * vmw_translate_mob_pointer - Prepare to translate a user-space buffer - * handle to a MOB id. + * vmw_translate_mob_pointer - Prepare to translate a user-space buffer handle + * to a MOB id. * * @dev_priv: Pointer to a device private structure. * @sw_context: The software context used for this command batch validation. * @id: Pointer to the user-space handle to be translated. - * @vmw_bo_p: Points to a location that, on successful return will carry - * a non-reference-counted pointer to the buffer object identified by the + * @vmw_bo_p: Points to a location that, on successful return will carry a + * non-reference-counted pointer to the buffer object identified by the * user-space handle in @id. * * This function saves information needed to translate a user-space buffer * handle to a MOB id. The translation does not take place immediately, but - * during a call to vmw_apply_relocations(). This function builds a relocation - * list and a list of buffers to validate. The former needs to be freed using - * either vmw_apply_relocations() or vmw_free_relocations(). The latter - * needs to be freed using vmw_clear_validations. + * during a call to vmw_apply_relocations(). + * + * This function builds a relocation list and a list of buffers to validate. The + * former needs to be freed using either vmw_apply_relocations() or + * vmw_free_relocations(). The latter needs to be freed using + * vmw_clear_validations. */ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, @@ -1189,19 +1188,20 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, } /** - * vmw_translate_guest_pointer - Prepare to translate a user-space buffer - * handle to a valid SVGAGuestPtr + * vmw_translate_guest_pointer - Prepare to translate a user-space buffer handle + * to a valid SVGAGuestPtr * * @dev_priv: Pointer to a device private structure. * @sw_context: The software context used for this command batch validation. * @ptr: Pointer to the user-space handle to be translated. - * @vmw_bo_p: Points to a location that, on successful return will carry - * a non-reference-counted pointer to the DMA buffer identified by the - * user-space handle in @id. + * @vmw_bo_p: Points to a location that, on successful return will carry a + * non-reference-counted pointer to the DMA buffer identified by the user-space + * handle in @id. * * This function saves information needed to translate a user-space buffer * handle to a valid SVGAGuestPtr. The translation does not take place * immediately, but during a call to vmw_apply_relocations(). + * * This function builds a relocation list and a list of buffers to validate. * The former needs to be freed using either vmw_apply_relocations() or * vmw_free_relocations(). The latter needs to be freed using @@ -1241,10 +1241,8 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, return 0; } - - /** - * vmw_cmd_dx_define_query - validate a SVGA_3D_CMD_DX_DEFINE_QUERY command. + * vmw_cmd_dx_define_query - validate SVGA_3D_CMD_DX_DEFINE_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. @@ -1276,19 +1274,16 @@ static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv, return ret; } - - /** - * vmw_cmd_dx_bind_query - validate a SVGA_3D_CMD_DX_BIND_QUERY command. + * vmw_cmd_dx_bind_query - validate SVGA_3D_CMD_DX_BIND_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. * @header: Pointer to the command header in the command stream. * - * The query bind operation will eventually associate the query ID - * with its backing MOB. In this function, we take the user mode - * MOB ID and use vmw_translate_mob_ptr() to translate it to its - * kernel mode equivalent. + * The query bind operation will eventually associate the query ID with its + * backing MOB. In this function, we take the user mode MOB ID and use + * vmw_translate_mob_ptr() to translate it to its kernel mode equivalent. */ static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, @@ -1315,10 +1310,8 @@ static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv, return 0; } - - /** - * vmw_cmd_begin_gb_query - validate a SVGA_3D_CMD_BEGIN_GB_QUERY command. + * vmw_cmd_begin_gb_query - validate SVGA_3D_CMD_BEGIN_GB_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. @@ -1337,7 +1330,7 @@ static int vmw_cmd_begin_gb_query(struct vmw_private *dev_priv, } /** - * vmw_cmd_begin_query - validate a SVGA_3D_CMD_BEGIN_QUERY command. + * vmw_cmd_begin_query - validate SVGA_3D_CMD_BEGIN_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. @@ -1370,7 +1363,7 @@ static int vmw_cmd_begin_query(struct vmw_private *dev_priv, } /** - * vmw_cmd_end_gb_query - validate a SVGA_3D_CMD_END_GB_QUERY command. + * vmw_cmd_end_gb_query - validate SVGA_3D_CMD_END_GB_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. @@ -1389,8 +1382,7 @@ static int vmw_cmd_end_gb_query(struct vmw_private *dev_priv, if (unlikely(ret != 0)) return ret; - ret = vmw_translate_mob_ptr(dev_priv, sw_context, - &cmd->body.mobid, + ret = vmw_translate_mob_ptr(dev_priv, sw_context, &cmd->body.mobid, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1401,7 +1393,7 @@ static int vmw_cmd_end_gb_query(struct vmw_private *dev_priv, } /** - * vmw_cmd_end_query - validate a SVGA_3D_CMD_END_QUERY command. + * vmw_cmd_end_query - validate SVGA_3D_CMD_END_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. @@ -1437,8 +1429,7 @@ static int vmw_cmd_end_query(struct vmw_private *dev_priv, return ret; ret = vmw_translate_guest_ptr(dev_priv, sw_context, - &cmd->body.guestResult, - &vmw_bo); + &cmd->body.guestResult, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1448,7 +1439,7 @@ static int vmw_cmd_end_query(struct vmw_private *dev_priv, } /** - * vmw_cmd_wait_gb_query - validate a SVGA_3D_CMD_WAIT_GB_QUERY command. + * vmw_cmd_wait_gb_query - validate SVGA_3D_CMD_WAIT_GB_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. @@ -1467,8 +1458,7 @@ static int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv, if (unlikely(ret != 0)) return ret; - ret = vmw_translate_mob_ptr(dev_priv, sw_context, - &cmd->body.mobid, + ret = vmw_translate_mob_ptr(dev_priv, sw_context, &cmd->body.mobid, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1477,7 +1467,7 @@ static int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv, } /** - * vmw_cmd_wait_query - validate a SVGA_3D_CMD_WAIT_QUERY command. + * vmw_cmd_wait_query - validate SVGA_3D_CMD_WAIT_QUERY command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context used for this command submission. @@ -1513,8 +1503,7 @@ static int vmw_cmd_wait_query(struct vmw_private *dev_priv, return ret; ret = vmw_translate_guest_ptr(dev_priv, sw_context, - &cmd->body.guestResult, - &vmw_bo); + &cmd->body.guestResult, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1544,8 +1533,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, } ret = vmw_translate_guest_ptr(dev_priv, sw_context, - &cmd->body.guest.ptr, - &vmw_bo); + &cmd->body.guest.ptr, &vmw_bo); if (unlikely(ret != 0)) return ret; @@ -1573,8 +1561,7 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res); - vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->base, - header); + vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->base, header); return 0; } @@ -1631,7 +1618,6 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv, return 0; } - static int vmw_cmd_tex_state(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) @@ -1701,12 +1687,10 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv, SVGAFifoCmdDefineGMRFB body; } *cmd = buf; - return vmw_translate_guest_ptr(dev_priv, sw_context, - &cmd->body.ptr, + return vmw_translate_guest_ptr(dev_priv, sw_context, &cmd->body.ptr, &vmw_bo); } - /** * vmw_cmd_res_switch_backup - Utility function to handle backup buffer * switching @@ -1718,14 +1702,13 @@ static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv, * stream. * @backup_offset: Offset of backup into MOB. * - * This function prepares for registering a switch of backup buffers - * in the resource metadata just prior to unreserving. It's basically a wrapper - * around vmw_cmd_res_switch_backup with a different interface. + * This function prepares for registering a switch of backup buffers in the + * resource metadata just prior to unreserving. It's basically a wrapper around + * vmw_cmd_res_switch_backup with a different interface. */ static int vmw_cmd_res_switch_backup(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, - struct vmw_resource *res, - uint32_t *buf_id, + struct vmw_resource *res, uint32_t *buf_id, unsigned long backup_offset) { struct vmw_buffer_object *vbo; @@ -1745,7 +1728,6 @@ static int vmw_cmd_res_switch_backup(struct vmw_private *dev_priv, return 0; } - /** * vmw_cmd_switch_backup - Utility function to handle backup buffer switching * @@ -1758,17 +1740,15 @@ static int vmw_cmd_res_switch_backup(struct vmw_private *dev_priv, * stream. * @backup_offset: Offset of backup into MOB. * - * This function prepares for registering a switch of backup buffers - * in the resource metadata just prior to unreserving. It's basically a wrapper - * around vmw_cmd_res_switch_backup with a different interface. + * This function prepares for registering a switch of backup buffers in the + * resource metadata just prior to unreserving. It's basically a wrapper around + * vmw_cmd_res_switch_backup with a different interface. */ static int vmw_cmd_switch_backup(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, enum vmw_res_type res_type, const struct vmw_user_resource_conv - *converter, - uint32_t *res_id, - uint32_t *buf_id, + *converter, uint32_t *res_id, uint32_t *buf_id, unsigned long backup_offset) { struct vmw_resource *res; @@ -1779,13 +1759,12 @@ static int vmw_cmd_switch_backup(struct vmw_private *dev_priv, if (ret) return ret; - return vmw_cmd_res_switch_backup(dev_priv, sw_context, res, - buf_id, backup_offset); + return vmw_cmd_res_switch_backup(dev_priv, sw_context, res, buf_id, + backup_offset); } /** - * vmw_cmd_bind_gb_surface - Validate an SVGA_3D_CMD_BIND_GB_SURFACE - * command + * vmw_cmd_bind_gb_surface - Validate SVGA_3D_CMD_BIND_GB_SURFACE command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -1799,14 +1778,12 @@ static int vmw_cmd_bind_gb_surface(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_surface, - user_surface_converter, - &cmd->body.sid, &cmd->body.mobid, - 0); + user_surface_converter, &cmd->body.sid, + &cmd->body.mobid, 0); } /** - * vmw_cmd_update_gb_image - Validate an SVGA_3D_CMD_UPDATE_GB_IMAGE - * command + * vmw_cmd_update_gb_image - Validate SVGA_3D_CMD_UPDATE_GB_IMAGE command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -1825,8 +1802,7 @@ static int vmw_cmd_update_gb_image(struct vmw_private *dev_priv, } /** - * vmw_cmd_update_gb_surface - Validate an SVGA_3D_CMD_UPDATE_GB_SURFACE - * command + * vmw_cmd_update_gb_surface - Validate SVGA_3D_CMD_UPDATE_GB_SURFACE command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -1845,8 +1821,7 @@ static int vmw_cmd_update_gb_surface(struct vmw_private *dev_priv, } /** - * vmw_cmd_readback_gb_image - Validate an SVGA_3D_CMD_READBACK_GB_IMAGE - * command + * vmw_cmd_readback_gb_image - Validate SVGA_3D_CMD_READBACK_GB_IMAGE command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -1865,7 +1840,7 @@ static int vmw_cmd_readback_gb_image(struct vmw_private *dev_priv, } /** - * vmw_cmd_readback_gb_surface - Validate an SVGA_3D_CMD_READBACK_GB_SURFACE + * vmw_cmd_readback_gb_surface - Validate SVGA_3D_CMD_READBACK_GB_SURFACE * command * * @dev_priv: Pointer to a device private struct. @@ -1885,7 +1860,7 @@ static int vmw_cmd_readback_gb_surface(struct vmw_private *dev_priv, } /** - * vmw_cmd_invalidate_gb_image - Validate an SVGA_3D_CMD_INVALIDATE_GB_IMAGE + * vmw_cmd_invalidate_gb_image - Validate SVGA_3D_CMD_INVALIDATE_GB_IMAGE * command * * @dev_priv: Pointer to a device private struct. @@ -1905,8 +1880,8 @@ static int vmw_cmd_invalidate_gb_image(struct vmw_private *dev_priv, } /** - * vmw_cmd_invalidate_gb_surface - Validate an - * SVGA_3D_CMD_INVALIDATE_GB_SURFACE command + * vmw_cmd_invalidate_gb_surface - Validate SVGA_3D_CMD_INVALIDATE_GB_SURFACE + * command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -1924,10 +1899,8 @@ static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv, &cmd->body.sid, NULL); } - /** - * vmw_cmd_shader_define - Validate an SVGA_3D_CMD_SHADER_DEFINE - * command + * vmw_cmd_shader_define - Validate SVGA_3D_CMD_SHADER_DEFINE command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -1954,24 +1927,20 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, return 0; size = cmd->header.size - sizeof(cmd->body); - ret = vmw_compat_shader_add(dev_priv, - vmw_context_res_man(ctx), - cmd->body.shid, cmd + 1, - cmd->body.type, size, - &sw_context->staged_cmd_res); + ret = vmw_compat_shader_add(dev_priv, vmw_context_res_man(ctx), + cmd->body.shid, cmd + 1, cmd->body.type, + size, &sw_context->staged_cmd_res); if (unlikely(ret != 0)) return ret; - return vmw_resource_relocation_add(sw_context, - NULL, + return vmw_resource_relocation_add(sw_context, NULL, vmw_ptr_diff(sw_context->buf_start, &cmd->header.id), vmw_res_rel_nop); } /** - * vmw_cmd_shader_destroy - Validate an SVGA_3D_CMD_SHADER_DESTROY - * command + * vmw_cmd_shader_destroy - Validate SVGA_3D_CMD_SHADER_DESTROY command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -1996,23 +1965,19 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, if (unlikely(!dev_priv->has_mob)) return 0; - ret = vmw_shader_remove(vmw_context_res_man(ctx), - cmd->body.shid, - cmd->body.type, - &sw_context->staged_cmd_res); + ret = vmw_shader_remove(vmw_context_res_man(ctx), cmd->body.shid, + cmd->body.type, &sw_context->staged_cmd_res); if (unlikely(ret != 0)) return ret; - return vmw_resource_relocation_add(sw_context, - NULL, + return vmw_resource_relocation_add(sw_context, NULL, vmw_ptr_diff(sw_context->buf_start, &cmd->header.id), vmw_res_rel_nop); } /** - * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER - * command + * vmw_cmd_set_shader - Validate SVGA_3D_CMD_SET_SHADER command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2047,9 +2012,7 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, if (cmd->body.shid != SVGA3D_INVALID_ID) { res = vmw_shader_lookup(vmw_context_res_man(ctx), - cmd->body.shid, - cmd->body.type); - + cmd->body.shid, cmd->body.type); if (!IS_ERR(res)) { ret = vmw_execbuf_res_noctx_val_add(sw_context, res, VMW_RES_DIRTY_NONE); @@ -2059,10 +2022,10 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, } if (IS_ERR_OR_NULL(res)) { - ret = vmw_cmd_res_check(dev_priv, sw_context, - vmw_res_shader, VMW_RES_DIRTY_NONE, - user_shader_converter, - &cmd->body.shid, &res); + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_shader, + VMW_RES_DIRTY_NONE, + user_shader_converter, &cmd->body.shid, + &res); if (unlikely(ret != 0)) return ret; } @@ -2075,14 +2038,13 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, binding.bi.res = res; binding.bi.bt = vmw_ctx_binding_shader; binding.shader_slot = cmd->body.type - SVGA3D_SHADERTYPE_MIN; - vmw_binding_add(ctx_info->staged, &binding.bi, - binding.shader_slot, 0); + vmw_binding_add(ctx_info->staged, &binding.bi, binding.shader_slot, 0); + return 0; } /** - * vmw_cmd_set_shader_const - Validate an SVGA_3D_CMD_SET_SHADER_CONST - * command + * vmw_cmd_set_shader_const - Validate SVGA_3D_CMD_SET_SHADER_CONST command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2110,8 +2072,7 @@ static int vmw_cmd_set_shader_const(struct vmw_private *dev_priv, } /** - * vmw_cmd_bind_gb_shader - Validate an SVGA_3D_CMD_BIND_GB_SHADER - * command + * vmw_cmd_bind_gb_shader - Validate SVGA_3D_CMD_BIND_GB_SHADER command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2125,13 +2086,12 @@ static int vmw_cmd_bind_gb_shader(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_shader, - user_shader_converter, - &cmd->body.shid, &cmd->body.mobid, - cmd->body.offsetInBytes); + user_shader_converter, &cmd->body.shid, + &cmd->body.mobid, cmd->body.offsetInBytes); } /** - * vmw_cmd_dx_set_single_constant_buffer - Validate an + * vmw_cmd_dx_set_single_constant_buffer - Validate * SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER command. * * @dev_priv: Pointer to a device private struct. @@ -2175,15 +2135,15 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, return -EINVAL; } - vmw_binding_add(ctx_node->staged, &binding.bi, - binding.shader_slot, binding.slot); + vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot, + binding.slot); return 0; } /** - * vmw_cmd_dx_set_shader_res - Validate an - * SVGA_3D_CMD_DX_SET_SHADER_RESOURCES command + * vmw_cmd_dx_set_shader_res - Validate SVGA_3D_CMD_DX_SET_SHADER_RESOURCES + * command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2213,8 +2173,7 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_set_shader - Validate an SVGA_3D_CMD_DX_SET_SHADER - * command + * vmw_cmd_dx_set_shader - Validate SVGA_3D_CMD_DX_SET_SHADER command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2259,15 +2218,14 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, binding.bi.bt = vmw_ctx_binding_dx_shader; binding.shader_slot = cmd->body.type - SVGA3D_SHADERTYPE_MIN; - vmw_binding_add(ctx_node->staged, &binding.bi, - binding.shader_slot, 0); + vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot, 0); return 0; } /** - * vmw_cmd_dx_set_vertex_buffers - Validates an - * SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS command + * vmw_cmd_dx_set_vertex_buffers - Validates SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS + * command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2314,15 +2272,14 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv, binding.stride = cmd->buf[i].stride; binding.slot = i + cmd->body.startBuffer; - vmw_binding_add(ctx_node->staged, &binding.bi, - 0, binding.slot); + vmw_binding_add(ctx_node->staged, &binding.bi, 0, binding.slot); } return 0; } /** - * vmw_cmd_dx_ia_set_vertex_buffers - Validate an + * vmw_cmd_dx_ia_set_vertex_buffers - Validate * SVGA_3D_CMD_DX_IA_SET_INDEX_BUFFER command. * * @dev_priv: Pointer to a device private struct. @@ -2361,8 +2318,8 @@ static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_set_rendertarget - Validate an - * SVGA_3D_CMD_DX_SET_RENDERTARGETS command + * vmw_cmd_dx_set_rendertarget - Validate SVGA_3D_CMD_DX_SET_RENDERTARGETS + * command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2383,19 +2340,18 @@ static int vmw_cmd_dx_set_rendertargets(struct vmw_private *dev_priv, return -EINVAL; } - ret = vmw_view_bindings_add(sw_context, vmw_view_ds, - vmw_ctx_binding_ds, 0, - &cmd->body.depthStencilViewId, 1, 0); + ret = vmw_view_bindings_add(sw_context, vmw_view_ds, vmw_ctx_binding_ds, + 0, &cmd->body.depthStencilViewId, 1, 0); if (ret) return ret; return vmw_view_bindings_add(sw_context, vmw_view_rt, - vmw_ctx_binding_dx_rt, 0, - (void *)&cmd[1], num_rt_view, 0); + vmw_ctx_binding_dx_rt, 0, (void *)&cmd[1], + num_rt_view, 0); } /** - * vmw_cmd_dx_clear_rendertarget_view - Validate an + * vmw_cmd_dx_clear_rendertarget_view - Validate * SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW command * * @dev_priv: Pointer to a device private struct. @@ -2414,7 +2370,7 @@ static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_clear_rendertarget_view - Validate an + * vmw_cmd_dx_clear_rendertarget_view - Validate * SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW command * * @dev_priv: Pointer to a device private struct. @@ -2442,8 +2398,8 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, enum vmw_view_type view_type; int ret; /* - * This is based on the fact that all affected define commands have - * the same initial command body layout. + * This is based on the fact that all affected define commands have the + * same initial command body layout. */ struct { SVGA3dCmdHeader header; @@ -2457,6 +2413,7 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, view_type = vmw_view_cmd_to_type(header->id); if (view_type == vmw_view_max) return -EINVAL; + cmd = container_of(header, typeof(*cmd), header); ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -2469,19 +2426,14 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, if (unlikely(ret != 0)) return ret; - return vmw_view_add(sw_context->man, - ctx_node->ctx, - srf, - view_type, - cmd->defined_id, - header, + return vmw_view_add(sw_context->man, ctx_node->ctx, srf, view_type, + cmd->defined_id, header, header->size + sizeof(*header), &sw_context->staged_cmd_res); } /** - * vmw_cmd_dx_set_so_targets - Validate an - * SVGA_3D_CMD_DX_SET_SOTARGETS command. + * vmw_cmd_dx_set_so_targets - Validate SVGA_3D_CMD_DX_SET_SOTARGETS command. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2505,8 +2457,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); - num = (cmd->header.size - sizeof(cmd->body)) / - sizeof(SVGA3dSoTarget); + num = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dSoTarget); if (num > SVGA3D_DX_MAX_SOTARGETS) { VMW_DEBUG_USER("Invalid DX SO binding.\n"); @@ -2528,8 +2479,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, binding.size = cmd->targets[i].sizeInBytes; binding.slot = i; - vmw_binding_add(ctx_node->staged, &binding.bi, - 0, binding.slot); + vmw_binding_add(ctx_node->staged, &binding.bi, 0, binding.slot); } return 0; @@ -2564,8 +2514,8 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_check_subresource - Validate an - * SVGA_3D_CMD_DX_[X]_SUBRESOURCE command + * vmw_cmd_dx_check_subresource - Validate SVGA_3D_CMD_DX_[X]_SUBRESOURCE + * command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2612,15 +2562,15 @@ static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_view_remove - validate a view remove command and - * schedule the view resource for removal. + * vmw_cmd_dx_view_remove - validate a view remove command and schedule the view + * resource for removal. * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. * @header: Pointer to the command header in the command stream. * - * Check that the view exists, and if it was not created using this - * command batch, conditionally make this command a NOP. + * Check that the view exists, and if it was not created using this command + * batch, conditionally make this command a NOP. */ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, @@ -2638,10 +2588,8 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, if (!ctx_node) return -EINVAL; - ret = vmw_view_remove(sw_context->man, - cmd->body.view_id, view_type, - &sw_context->staged_cmd_res, - &view); + ret = vmw_view_remove(sw_context->man, cmd->body.view_id, view_type, + &sw_context->staged_cmd_res, &view); if (ret || !view) return ret; @@ -2651,16 +2599,14 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, * relocation to conditionally make this command a NOP to avoid * device errors. */ - return vmw_resource_relocation_add(sw_context, - view, + return vmw_resource_relocation_add(sw_context, view, vmw_ptr_diff(sw_context->buf_start, &cmd->header.id), vmw_res_rel_cond_nop); } /** - * vmw_cmd_dx_define_shader - Validate an SVGA_3D_CMD_DX_DEFINE_SHADER - * command + * vmw_cmd_dx_define_shader - Validate SVGA_3D_CMD_DX_DEFINE_SHADER command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2690,8 +2636,7 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_destroy_shader - Validate an SVGA_3D_CMD_DX_DESTROY_SHADER - * command + * vmw_cmd_dx_destroy_shader - Validate SVGA_3D_CMD_DX_DESTROY_SHADER command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2716,8 +2661,7 @@ static int vmw_cmd_dx_destroy_shader(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_bind_shader - Validate an SVGA_3D_CMD_DX_BIND_SHADER - * command + * vmw_cmd_dx_bind_shader - Validate SVGA_3D_CMD_DX_BIND_SHADER command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2750,8 +2694,7 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, ctx = ctx_node->ctx; } - res = vmw_shader_lookup(vmw_context_res_man(ctx), - cmd->body.shid, 0); + res = vmw_shader_lookup(vmw_context_res_man(ctx), cmd->body.shid, 0); if (IS_ERR(res)) { VMW_DEBUG_USER("Could not find shader to bind.\n"); return PTR_ERR(res); @@ -2770,7 +2713,7 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_genmips - Validate an SVGA_3D_CMD_DX_GENMIPS command + * vmw_cmd_dx_genmips - Validate SVGA_3D_CMD_DX_GENMIPS command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2788,8 +2731,8 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv, } /** - * vmw_cmd_dx_transfer_from_buffer - - * Validate an SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER command + * vmw_cmd_dx_transfer_from_buffer - Validate + * SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2815,8 +2758,7 @@ static int vmw_cmd_dx_transfer_from_buffer(struct vmw_private *dev_priv, } /** - * vmw_cmd_intra_surface_copy - - * Validate an SVGA_3D_CMD_INTRA_SURFACE_COPY command + * vmw_cmd_intra_surface_copy - Validate SVGA_3D_CMD_INTRA_SURFACE_COPY command * * @dev_priv: Pointer to a device private struct. * @sw_context: The software context being used for this batch. @@ -2837,7 +2779,6 @@ static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv, &cmd->body.surface.sid, NULL); } - static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, void *buf, uint32_t *size) @@ -3059,9 +3000,7 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SURFACE_V2, &vmw_cmd_invalid, false, false, true), - /* - * DX commands - */ + /* SM commands */ VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_CONTEXT, &vmw_cmd_invalid, false, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_CONTEXT, &vmw_cmd_invalid, @@ -3243,8 +3182,8 @@ bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd) } static int vmw_cmd_check(struct vmw_private *dev_priv, - struct vmw_sw_context *sw_context, - void *buf, uint32_t *size) + struct vmw_sw_context *sw_context, void *buf, + uint32_t *size) { uint32_t cmd_id; uint32_t size_remaining = *size; @@ -3309,8 +3248,7 @@ out_new: } static int vmw_cmd_check_all(struct vmw_private *dev_priv, - struct vmw_sw_context *sw_context, - void *buf, + struct vmw_sw_context *sw_context, void *buf, uint32_t size) { int32_t cur_size = size; @@ -3338,7 +3276,6 @@ static int vmw_cmd_check_all(struct vmw_private *dev_priv, static void vmw_free_relocations(struct vmw_sw_context *sw_context) { /* Memory is validation context memory, so no need to free it */ - INIT_LIST_HEAD(&sw_context->bo_relocations); } @@ -3401,8 +3338,8 @@ static int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context, * If this fails for some reason, We sync the fifo and return NULL. * It is then safe to fence buffers with a NULL pointer. * - * If @p_handle is not NULL @file_priv must also not be NULL. Creates - * a userspace handle if @p_handle is not NULL, otherwise not. + * If @p_handle is not NULL @file_priv must also not be NULL. Creates a + * userspace handle if @p_handle is not NULL, otherwise not. */ int vmw_execbuf_fence_commands(struct drm_file *file_priv, @@ -3430,9 +3367,8 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv, ret = vmw_fence_create(dev_priv->fman, sequence, p_fence); if (unlikely(ret != 0 && !synced)) { - (void) vmw_fallback_wait(dev_priv, false, false, - sequence, false, - VMW_FENCE_WAIT_TIMEOUT); + (void) vmw_fallback_wait(dev_priv, false, false, sequence, + false, VMW_FENCE_WAIT_TIMEOUT); *p_fence = NULL; } @@ -3440,36 +3376,32 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv, } /** - * vmw_execbuf_copy_fence_user - copy fence object information to - * user-space. + * vmw_execbuf_copy_fence_user - copy fence object information to user-space. * * @dev_priv: Pointer to a vmw_private struct. * @vmw_fp: Pointer to the struct vmw_fpriv representing the calling file. * @ret: Return value from fence object creation. - * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to - * which the information should be copied. + * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to which + * the information should be copied. * @fence: Pointer to the fenc object. * @fence_handle: User-space fence handle. * @out_fence_fd: exported file descriptor for the fence. -1 if not used * @sync_file: Only used to clean up in case of an error in this function. * - * This function copies fence information to user-space. If copying fails, - * The user-space struct drm_vmw_fence_rep::error member is hopefully - * left untouched, and if it's preloaded with an -EFAULT by user-space, - * the error will hopefully be detected. - * Also if copying fails, user-space will be unable to signal the fence - * object so we wait for it immediately, and then unreference the - * user-space reference. + * This function copies fence information to user-space. If copying fails, the + * user-space struct drm_vmw_fence_rep::error member is hopefully left + * untouched, and if it's preloaded with an -EFAULT by user-space, the error + * will hopefully be detected. + * + * Also if copying fails, user-space will be unable to signal the fence object + * so we wait for it immediately, and then unreference the user-space reference. */ void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, - struct vmw_fpriv *vmw_fp, - int ret, + struct vmw_fpriv *vmw_fp, int ret, struct drm_vmw_fence_rep __user *user_fence_rep, - struct vmw_fence_obj *fence, - uint32_t fence_handle, - int32_t out_fence_fd, - struct sync_file *sync_file) + struct vmw_fence_obj *fence, uint32_t fence_handle, + int32_t out_fence_fd, struct sync_file *sync_file) { struct drm_vmw_fence_rep fence_rep; @@ -3490,16 +3422,16 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, } /* - * copy_to_user errors will be detected by user space not - * seeing fence_rep::error filled in. Typically - * user-space would have pre-set that member to -EFAULT. + * copy_to_user errors will be detected by user space not seeing + * fence_rep::error filled in. Typically user-space would have pre-set + * that member to -EFAULT. */ ret = copy_to_user(user_fence_rep, &fence_rep, sizeof(fence_rep)); /* - * User-space lost the fence object. We need to sync - * and unreference the handle. + * User-space lost the fence object. We need to sync and unreference the + * handle. */ if (unlikely(ret != 0) && (fence_rep.error == 0)) { if (sync_file) @@ -3510,8 +3442,8 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, fence_rep.fd = -1; } - ttm_ref_object_base_unref(vmw_fp->tfile, - fence_handle, TTM_REF_USAGE); + ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle, + TTM_REF_USAGE); VMW_DEBUG_USER("Fence copy error. Syncing.\n"); (void) vmw_fence_obj_wait(fence, false, false, VMW_FENCE_WAIT_TIMEOUT); @@ -3519,20 +3451,18 @@ vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, } /** - * vmw_execbuf_submit_fifo - Patch a command batch and submit it using - * the fifo. + * vmw_execbuf_submit_fifo - Patch a command batch and submit it using the fifo. * * @dev_priv: Pointer to a device private structure. * @kernel_commands: Pointer to the unpatched command batch. * @command_size: Size of the unpatched command batch. * @sw_context: Structure holding the relocation lists. * - * Side effects: If this function returns 0, then the command batch - * pointed to by @kernel_commands will have been modified. + * Side effects: If this function returns 0, then the command batch pointed to + * by @kernel_commands will have been modified. */ static int vmw_execbuf_submit_fifo(struct vmw_private *dev_priv, - void *kernel_commands, - u32 command_size, + void *kernel_commands, u32 command_size, struct vmw_sw_context *sw_context) { void *cmd; @@ -3557,16 +3487,16 @@ static int vmw_execbuf_submit_fifo(struct vmw_private *dev_priv, } /** - * vmw_execbuf_submit_cmdbuf - Patch a command batch and submit it using - * the command buffer manager. + * vmw_execbuf_submit_cmdbuf - Patch a command batch and submit it using the + * command buffer manager. * * @dev_priv: Pointer to a device private structure. * @header: Opaque handle to the command buffer allocation. * @command_size: Size of the unpatched command batch. * @sw_context: Structure holding the relocation lists. * - * Side effects: If this function returns 0, then the command buffer - * represented by @header will have been modified. + * Side effects: If this function returns 0, then the command buffer represented + * by @header will have been modified. */ static int vmw_execbuf_submit_cmdbuf(struct vmw_private *dev_priv, struct vmw_cmdbuf_header *header, @@ -3575,8 +3505,8 @@ static int vmw_execbuf_submit_cmdbuf(struct vmw_private *dev_priv, { u32 id = ((sw_context->dx_ctx_node) ? sw_context->dx_ctx_node->ctx->id : SVGA3D_INVALID_ID); - void *cmd = vmw_cmdbuf_reserve(dev_priv->cman, command_size, - id, false, header); + void *cmd = vmw_cmdbuf_reserve(dev_priv->cman, command_size, id, false, + header); vmw_apply_relocations(sw_context); vmw_resource_relocations_apply(cmd, &sw_context->res_relocations); @@ -3596,22 +3526,23 @@ static int vmw_execbuf_submit_cmdbuf(struct vmw_private *dev_priv, * @header: Out parameter returning the opaque pointer to the command buffer. * * This function checks whether we can use the command buffer manager for - * submission and if so, creates a command buffer of suitable size and - * copies the user data into that buffer. + * submission and if so, creates a command buffer of suitable size and copies + * the user data into that buffer. * * On successful return, the function returns a pointer to the data in the * command buffer and *@header is set to non-NULL. - * If command buffers could not be used, the function will return the value - * of @kernel_commands on function call. That value may be NULL. In that case, - * the value of *@header will be set to NULL. + * + * If command buffers could not be used, the function will return the value of + * @kernel_commands on function call. That value may be NULL. In that case, the + * value of *@header will be set to NULL. + * * If an error is encountered, the function will return a pointer error value. * If the function is interrupted by a signal while sleeping, it will return * -ERESTARTSYS casted to a pointer error value. */ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv, void __user *user_commands, - void *kernel_commands, - u32 command_size, + void *kernel_commands, u32 command_size, struct vmw_cmdbuf_header **header) { size_t cmdbuf_size; @@ -3629,13 +3560,12 @@ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv, /* If possible, add a little space for fencing. */ cmdbuf_size = command_size + 512; cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE); - kernel_commands = vmw_cmdbuf_alloc(dev_priv->cman, cmdbuf_size, - true, header); + kernel_commands = vmw_cmdbuf_alloc(dev_priv->cman, cmdbuf_size, true, + header); if (IS_ERR(kernel_commands)) return kernel_commands; - ret = copy_from_user(kernel_commands, user_commands, - command_size); + ret = copy_from_user(kernel_commands, user_commands, command_size); if (ret) { VMW_DEBUG_USER("Failed copying commands.\n"); vmw_cmdbuf_header_free(*header); @@ -3683,14 +3613,11 @@ static int vmw_execbuf_tie_context(struct vmw_private *dev_priv, int vmw_execbuf_process(struct drm_file *file_priv, struct vmw_private *dev_priv, - void __user *user_commands, - void *kernel_commands, - uint32_t command_size, - uint64_t throttle_us, + void __user *user_commands, void *kernel_commands, + uint32_t command_size, uint64_t throttle_us, uint32_t dx_context_handle, struct drm_vmw_fence_rep __user *user_fence_rep, - struct vmw_fence_obj **out_fence, - uint32_t flags) + struct vmw_fence_obj **out_fence, uint32_t flags) { struct vmw_sw_context *sw_context = &dev_priv->ctx; struct vmw_fence_obj *fence = NULL; @@ -3739,18 +3666,18 @@ int vmw_execbuf_process(struct drm_file *file_priv, if (unlikely(ret != 0)) goto out_unlock; - - ret = copy_from_user(sw_context->cmd_bounce, - user_commands, command_size); - + ret = copy_from_user(sw_context->cmd_bounce, user_commands, + command_size); if (unlikely(ret != 0)) { ret = -EFAULT; VMW_DEBUG_USER("Failed copying commands.\n"); goto out_unlock; } + kernel_commands = sw_context->cmd_bounce; - } else if (!header) + } else if (!header) { sw_context->kernel = true; + } sw_context->fp = vmw_fpriv(file_priv); INIT_LIST_HEAD(&sw_context->ctx_list); @@ -3763,6 +3690,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, memset(sw_context->res_cache, 0, sizeof(sw_context->res_cache)); INIT_LIST_HEAD(&sw_context->res_relocations); INIT_LIST_HEAD(&sw_context->bo_relocations); + if (sw_context->staged_bindings) vmw_binding_state_reset(sw_context->staged_bindings); @@ -3770,8 +3698,10 @@ int vmw_execbuf_process(struct drm_file *file_priv, ret = drm_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER); if (unlikely(ret != 0)) goto out_unlock; + sw_context->res_ht_initialized = true; } + INIT_LIST_HEAD(&sw_context->staged_cmd_res); sw_context->ctx = &val_ctx; ret = vmw_execbuf_tie_context(dev_priv, sw_context, dx_context_handle); @@ -3798,6 +3728,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, ret = vmw_validation_res_validate(&val_ctx, true); if (unlikely(ret != 0)) goto out_err; + vmw_validation_drop_ht(&val_ctx); ret = mutex_lock_interruptible(&dev_priv->binding_mutex); @@ -3825,15 +3756,13 @@ int vmw_execbuf_process(struct drm_file *file_priv, goto out_err; vmw_query_bo_switch_commit(dev_priv, sw_context); - ret = vmw_execbuf_fence_commands(file_priv, dev_priv, - &fence, + ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence, (user_fence_rep) ? &handle : NULL); /* * This error is harmless, because if fence submission fails, * vmw_fifo_send_fence will sync. The error will be propagated to * user-space in @fence_rep */ - if (ret != 0) VMW_DEBUG_USER("Fence submission error. Syncing.\n"); @@ -3843,15 +3772,13 @@ int vmw_execbuf_process(struct drm_file *file_priv, vmw_validation_bo_fence(sw_context->ctx, fence); - if (unlikely(dev_priv->pinned_bo != NULL && - !dev_priv->query_cid_valid)) + if (unlikely(dev_priv->pinned_bo != NULL && !dev_priv->query_cid_valid)) __vmw_execbuf_release_pinned_bo(dev_priv, fence); /* - * If anything fails here, give up trying to export the fence - * and do a sync since the user mode will not be able to sync - * the fence itself. This ensures we are still functionally - * correct. + * If anything fails here, give up trying to export the fence and do a + * sync since the user mode will not be able to sync the fence itself. + * This ensures we are still functionally correct. */ if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) { @@ -3870,8 +3797,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, } vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, - user_fence_rep, fence, handle, - out_fence_fd, sync_file); + user_fence_rep, fence, handle, out_fence_fd, + sync_file); /* Don't unreference when handing fence out */ if (unlikely(out_fence != NULL)) { @@ -3885,8 +3812,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, mutex_unlock(&dev_priv->cmdbuf_mutex); /* - * Unreference resources outside of the cmdbuf_mutex to - * avoid deadlocks in resource destruction paths. + * Unreference resources outside of the cmdbuf_mutex to avoid deadlocks + * in resource destruction paths. */ vmw_validation_unref_lists(&val_ctx); @@ -3901,8 +3828,7 @@ out_err_nores: vmw_validation_res_unreserve(&val_ctx, true); vmw_resource_relocations_free(&sw_context->res_relocations); vmw_free_relocations(sw_context); - if (unlikely(dev_priv->pinned_bo != NULL && - !dev_priv->query_cid_valid)) + if (unlikely(dev_priv->pinned_bo != NULL && !dev_priv->query_cid_valid)) __vmw_execbuf_release_pinned_bo(dev_priv, NULL); out_unlock: vmw_cmdbuf_res_revert(&sw_context->staged_cmd_res); @@ -3911,8 +3837,8 @@ out_unlock: mutex_unlock(&dev_priv->cmdbuf_mutex); /* - * Unreference resources outside of the cmdbuf_mutex to - * avoid deadlocks in resource destruction paths. + * Unreference resources outside of the cmdbuf_mutex to avoid deadlocks + * in resource destruction paths. */ vmw_validation_unref_lists(&val_ctx); out_free_header: @@ -3930,9 +3856,9 @@ out_free_fence_fd: * * @dev_priv: The device private structure. * - * This function is called to idle the fifo and unpin the query buffer - * if the normal way to do this hits an error, which should typically be - * extremely rare. + * This function is called to idle the fifo and unpin the query buffer if the + * normal way to do this hits an error, which should typically be extremely + * rare. */ static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv) { @@ -3948,28 +3874,27 @@ static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv) /** - * __vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned - * query bo. + * __vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned query + * bo. * * @dev_priv: The device private structure. - * @fence: If non-NULL should point to a struct vmw_fence_obj issued - * _after_ a query barrier that flushes all queries touching the current - * buffer pointed to by @dev_priv->pinned_bo + * @fence: If non-NULL should point to a struct vmw_fence_obj issued _after_ a + * query barrier that flushes all queries touching the current buffer pointed to + * by @dev_priv->pinned_bo * - * This function should be used to unpin the pinned query bo, or - * as a query barrier when we need to make sure that all queries have - * finished before the next fifo command. (For example on hardware - * context destructions where the hardware may otherwise leak unfinished - * queries). + * This function should be used to unpin the pinned query bo, or as a query + * barrier when we need to make sure that all queries have finished before the + * next fifo command. (For example on hardware context destructions where the + * hardware may otherwise leak unfinished queries). * - * This function does not return any failure codes, but make attempts - * to do safe unpinning in case of errors. + * This function does not return any failure codes, but make attempts to do safe + * unpinning in case of errors. * - * The function will synchronize on the previous query barrier, and will - * thus not finish until that barrier has executed. + * The function will synchronize on the previous query barrier, and will thus + * not finish until that barrier has executed. * - * the @dev_priv->cmdbuf_mutex needs to be held by the current thread - * before calling this function. + * the @dev_priv->cmdbuf_mutex needs to be held by the current thread before + * calling this function. */ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, struct vmw_fence_obj *fence) @@ -4019,35 +3944,32 @@ void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, vmw_validation_unref_lists(&val_ctx); vmw_bo_unreference(&dev_priv->pinned_bo); + out_unlock: return; - out_no_emit: vmw_validation_bo_backoff(&val_ctx); out_no_reserve: vmw_validation_unref_lists(&val_ctx); vmw_execbuf_unpin_panic(dev_priv); vmw_bo_unreference(&dev_priv->pinned_bo); - } /** - * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned - * query bo. + * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned query bo. * * @dev_priv: The device private structure. * - * This function should be used to unpin the pinned query bo, or - * as a query barrier when we need to make sure that all queries have - * finished before the next fifo command. (For example on hardware - * context destructions where the hardware may otherwise leak unfinished - * queries). + * This function should be used to unpin the pinned query bo, or as a query + * barrier when we need to make sure that all queries have finished before the + * next fifo command. (For example on hardware context destructions where the + * hardware may otherwise leak unfinished queries). * - * This function does not return any failure codes, but make attempts - * to do safe unpinning in case of errors. + * This function does not return any failure codes, but make attempts to do safe + * unpinning in case of errors. * - * The function will synchronize on the previous query barrier, and will - * thus not finish until that barrier has executed. + * The function will synchronize on the previous query barrier, and will thus + * not finish until that barrier has executed. */ void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv) { @@ -4078,12 +4000,9 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, return -EFAULT; /* - * Extend the ioctl argument while - * maintaining backwards compatibility: - * We take different code paths depending on the value of - * arg.version. + * Extend the ioctl argument while maintaining backwards compatibility: + * We take different code paths depending on the value of arg.version. */ - if (unlikely(arg.version > DRM_VMW_EXECBUF_VERSION || arg.version == 0)) { VMW_DEBUG_USER("Incorrect execbuf version.\n"); @@ -4093,8 +4012,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, if (arg.version > 1 && copy_from_user(&arg.context_handle, (void __user *) (data + copy_offset[0]), - copy_offset[arg.version - 1] - - copy_offset[0]) != 0) + copy_offset[arg.version - 1] - copy_offset[0]) != 0) return -EFAULT; switch (arg.version) { @@ -4106,7 +4024,6 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, break; } - /* If imported a fence FD from elsewhere, then wait on it */ if (arg.flags & DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD) { in_fence = sync_file_get_fence(arg.imported_fence_fd); @@ -4130,8 +4047,8 @@ int vmw_execbuf_ioctl(struct drm_device *dev, unsigned long data, NULL, arg.command_size, arg.throttle_us, arg.context_handle, (void __user *)(unsigned long)arg.fence_rep, - NULL, - arg.flags); + NULL, arg.flags); + ttm_read_unlock(&dev_priv->reservation_sem); if (unlikely(ret != 0)) goto out; -- cgit v1.2.3 From 11c454196610ae25784ac19dc3f886a4328007e4 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 14 Feb 2019 16:15:39 -0800 Subject: drm/vmwgfx: Use preprocessor macro for FIFO allocation Whenever FIFO allocation fails an error message is printed to dmesg. Since this is common operation a lot of similar messages are scattered everywhere. Use preprocessor macro to remove this cluttering. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 72 ++++++++++---------------------- drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 55 +++++++----------------- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 23 ++++------ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 13 +++++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 12 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 27 +++--------- drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c | 9 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 23 ++++------ drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 6 +-- drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 25 ++++------- drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 7 +--- drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 20 +++------ drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 37 +++++----------- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 12 ++---- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 35 +++++----------- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 48 +++++++-------------- 17 files changed, 138 insertions(+), 290 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index ef1469c4e91f..66e14e38d5e8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -499,12 +499,9 @@ static int vmw_binding_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind) SVGA3dCmdSetShader body; } *cmd; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for shader " - "unbinding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_SET_SHADER; cmd->header.size = sizeof(cmd->body); @@ -534,12 +531,9 @@ static int vmw_binding_scrub_render_target(struct vmw_ctx_bindinfo *bi, SVGA3dCmdSetRenderTarget body; } *cmd; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for render target " - "unbinding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_SETRENDERTARGET; cmd->header.size = sizeof(cmd->body); @@ -576,12 +570,9 @@ static int vmw_binding_scrub_texture(struct vmw_ctx_bindinfo *bi, } body; } *cmd; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for texture " - "unbinding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_SETTEXTURESTATE; cmd->header.size = sizeof(cmd->body); @@ -610,12 +601,10 @@ static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi, bool rebind) SVGA3dCmdDXSetShader body; } *cmd; - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), bi->ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for DX shader " - "unbinding.\n"); + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } + cmd->header.id = SVGA_3D_CMD_DX_SET_SHADER; cmd->header.size = sizeof(cmd->body); cmd->body.type = binding->shader_slot + SVGA3D_SHADERTYPE_MIN; @@ -641,12 +630,9 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind) SVGA3dCmdDXSetSingleConstantBuffer body; } *cmd; - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), bi->ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for DX shader " - "unbinding.\n"); + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER; cmd->header.size = sizeof(cmd->body); @@ -768,12 +754,9 @@ static int vmw_emit_set_sr(struct vmw_ctx_binding_state *cbs, view_id_size = cbs->bind_cmd_count*sizeof(uint32); cmd_size = sizeof(*cmd) + view_id_size; - cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for DX shader" - " resource binding.\n"); + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_SET_SHADER_RESOURCES; cmd->header.size = sizeof(cmd->body) + view_id_size; @@ -807,12 +790,9 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs) vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS); view_id_size = cbs->bind_cmd_count*sizeof(uint32); cmd_size = sizeof(*cmd) + view_id_size; - cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for DX render-target" - " binding.\n"); + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_SET_RENDERTARGETS; cmd->header.size = sizeof(cmd->body) + view_id_size; @@ -894,12 +874,9 @@ static int vmw_emit_set_so(struct vmw_ctx_binding_state *cbs) so_target_size = cbs->bind_cmd_count*sizeof(SVGA3dSoTarget); cmd_size = sizeof(*cmd) + so_target_size; - cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for DX SO target" - " binding.\n"); + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_SET_SOTARGETS; cmd->header.size = sizeof(cmd->body) + so_target_size; @@ -1011,12 +988,9 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs) set_vb_size = cbs->bind_cmd_count*sizeof(SVGA3dVertexBuffer); cmd_size = sizeof(*cmd) + set_vb_size; - cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for DX vertex buffer" - " binding.\n"); + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS; cmd->header.size = sizeof(cmd->body) + set_vb_size; @@ -1167,12 +1141,10 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind) SVGA3dCmdDXSetIndexBuffer body; } *cmd; - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), bi->ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for DX index buffer " - "binding.\n"); + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } + cmd->header.id = SVGA_3D_CMD_DX_SET_INDEX_BUFFER; cmd->header.size = sizeof(cmd->body); if (rebind) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index 39e96bb86329..63f111068a44 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -156,12 +156,9 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) } vmw_execbuf_release_pinned_bo(dev_priv); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "destruction.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return; - } cmd->header.id = SVGA_3D_CMD_CONTEXT_DESTROY; cmd->header.size = sizeof(cmd->body); @@ -259,9 +256,8 @@ static int vmw_context_init(struct vmw_private *dev_priv, return -ENOMEM; } - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); if (unlikely(cmd == NULL)) { - DRM_ERROR("Fifo reserve failed.\n"); vmw_resource_unreference(&res); return -ENOMEM; } @@ -311,10 +307,8 @@ static int vmw_gb_context_create(struct vmw_resource *res) goto out_no_fifo; } - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "creation.\n"); ret = -ENOMEM; goto out_no_fifo; } @@ -345,12 +339,10 @@ static int vmw_gb_context_bind(struct vmw_resource *res, BUG_ON(bo->mem.mem_type != VMW_PL_MOB); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "binding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } + cmd->header.id = SVGA_3D_CMD_BIND_GB_CONTEXT; cmd->header.size = sizeof(cmd->body); cmd->body.cid = res->id; @@ -391,10 +383,8 @@ static int vmw_gb_context_unbind(struct vmw_resource *res, submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0); - cmd = vmw_fifo_reserve(dev_priv, submit_size); + cmd = VMW_FIFO_RESERVE(dev_priv, submit_size); if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "unbinding.\n"); mutex_unlock(&dev_priv->binding_mutex); return -ENOMEM; } @@ -441,12 +431,9 @@ static int vmw_gb_context_destroy(struct vmw_resource *res) if (likely(res->id == -1)) return 0; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "destruction.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DESTROY_GB_CONTEXT; cmd->header.size = sizeof(cmd->body); @@ -487,10 +474,8 @@ static int vmw_dx_context_create(struct vmw_resource *res) goto out_no_fifo; } - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "creation.\n"); ret = -ENOMEM; goto out_no_fifo; } @@ -521,12 +506,9 @@ static int vmw_dx_context_bind(struct vmw_resource *res, BUG_ON(bo->mem.mem_type != VMW_PL_MOB); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "binding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_BIND_CONTEXT; cmd->header.size = sizeof(cmd->body); @@ -615,10 +597,8 @@ static int vmw_dx_context_unbind(struct vmw_resource *res, submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0); - cmd = vmw_fifo_reserve(dev_priv, submit_size); + cmd = VMW_FIFO_RESERVE(dev_priv, submit_size); if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "unbinding.\n"); mutex_unlock(&dev_priv->binding_mutex); return -ENOMEM; } @@ -665,12 +645,9 @@ static int vmw_dx_context_destroy(struct vmw_resource *res) if (likely(res->id == -1)) return 0; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for context " - "destruction.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_DESTROY_CONTEXT; cmd->header.size = sizeof(cmd->body); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c index 44f3f6f107d3..b4f6e1217c9d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c @@ -171,12 +171,9 @@ static int vmw_cotable_unscrub(struct vmw_resource *res) WARN_ON_ONCE(bo->mem.mem_type != VMW_PL_MOB); lockdep_assert_held(&bo->resv->lock.base); - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), SVGA3D_INVALID_ID); - if (!cmd) { - DRM_ERROR("Failed reserving FIFO space for cotable " - "binding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (!cmd) return -ENOMEM; - } WARN_ON(vcotbl->ctx->id == SVGA3D_INVALID_ID); WARN_ON(bo->mem.mem_type != VMW_PL_MOB); @@ -262,12 +259,9 @@ int vmw_cotable_scrub(struct vmw_resource *res, bool readback) if (readback) submit_size += sizeof(*cmd0); - cmd1 = vmw_fifo_reserve_dx(dev_priv, submit_size, SVGA3D_INVALID_ID); - if (!cmd1) { - DRM_ERROR("Failed reserving FIFO space for cotable " - "unbinding.\n"); + cmd1 = VMW_FIFO_RESERVE(dev_priv, submit_size); + if (!cmd1) return -ENOMEM; - } vcotbl->size_read_back = 0; if (readback) { @@ -351,13 +345,10 @@ static int vmw_cotable_readback(struct vmw_resource *res) struct vmw_fence_obj *fence; if (!vcotbl->scrubbed) { - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), - SVGA3D_INVALID_ID); - if (!cmd) { - DRM_ERROR("Failed reserving FIFO space for cotable " - "readback.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (!cmd) return -ENOMEM; - } + cmd->header.id = SVGA_3D_CMD_DX_READBACK_COTABLE; cmd->header.size = sizeof(cmd->body); cmd->body.cid = vcotbl->ctx->id; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 92367d4ebdf3..96983c47fb40 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -813,7 +813,6 @@ extern int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo); extern void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo); -extern void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes); extern void * vmw_fifo_reserve_dx(struct vmw_private *dev_priv, uint32_t bytes, int ctx_id); extern void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes); @@ -829,6 +828,18 @@ extern int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv, extern int vmw_fifo_flush(struct vmw_private *dev_priv, bool interruptible); +#define VMW_FIFO_RESERVE_DX(__priv, __bytes, __ctx_id) \ +({ \ + vmw_fifo_reserve_dx(__priv, __bytes, __ctx_id) ? : ({ \ + DRM_ERROR("FIFO reserve failed at %s for %u bytes\n", \ + __func__, (unsigned int) __bytes); \ + NULL; \ + }); \ +}) + +#define VMW_FIFO_RESERVE(__priv, __bytes) \ + VMW_FIFO_RESERVE_DX(__priv, __bytes, SVGA3D_INVALID_ID) + /** * TTM glue - vmwgfx_ttm_glue.c */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 0d703f431f1f..6cc9837b10ec 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -720,8 +720,7 @@ static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res) if (!dx_query_mob || dx_query_mob->dx_query_ctx) return 0; - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), ctx_res->id); - + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), ctx_res->id); if (cmd == NULL) return -ENOMEM; @@ -3468,14 +3467,13 @@ static int vmw_execbuf_submit_fifo(struct vmw_private *dev_priv, void *cmd; if (sw_context->dx_ctx_node) - cmd = vmw_fifo_reserve_dx(dev_priv, command_size, + cmd = VMW_FIFO_RESERVE_DX(dev_priv, command_size, sw_context->dx_ctx_node->ctx->id); else - cmd = vmw_fifo_reserve(dev_priv, command_size); - if (!cmd) { - VMW_DEBUG_USER("Failed reserving fifo space for commands.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, command_size); + + if (!cmd) return -ENOMEM; - } vmw_apply_relocations(sw_context); memcpy(cmd, kernel_commands, command_size); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index d0fd147ef75f..ff3586cb6851 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c @@ -395,12 +395,8 @@ void *vmw_fifo_reserve_dx(struct vmw_private *dev_priv, uint32_t bytes, WARN(1, "Command buffer has not been allocated.\n"); ret = NULL; } - if (IS_ERR_OR_NULL(ret)) { - DRM_ERROR("Fifo reserve failure of %u bytes.\n", - (unsigned) bytes); - dump_stack(); + if (IS_ERR_OR_NULL(ret)) return NULL; - } return ret; } @@ -544,7 +540,7 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *seqno) int ret = 0; uint32_t bytes = sizeof(u32) + sizeof(*cmd_fence); - fm = vmw_fifo_reserve(dev_priv, bytes); + fm = VMW_FIFO_RESERVE(dev_priv, bytes); if (unlikely(fm == NULL)) { *seqno = atomic_read(&dev_priv->marker_seq); ret = -ENOMEM; @@ -603,12 +599,9 @@ static int vmw_fifo_emit_dummy_legacy_query(struct vmw_private *dev_priv, SVGA3dCmdWaitForQuery body; } *cmd; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - - if (unlikely(cmd == NULL)) { - DRM_ERROR("Out of fifo space for dummy query.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_WAIT_FOR_QUERY; cmd->header.size = sizeof(cmd->body); @@ -652,12 +645,9 @@ static int vmw_fifo_emit_dummy_gb_query(struct vmw_private *dev_priv, SVGA3dCmdWaitForGBQuery body; } *cmd; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - - if (unlikely(cmd == NULL)) { - DRM_ERROR("Out of fifo space for dummy query.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY; cmd->header.size = sizeof(cmd->body); @@ -699,8 +689,3 @@ int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv, return vmw_fifo_emit_dummy_legacy_query(dev_priv, cid); } - -void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes) -{ - return vmw_fifo_reserve_dx(dev_priv, bytes, SVGA3D_INVALID_ID); -} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c index 007a0cc7f232..ae7acc6f3dda 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c @@ -51,7 +51,7 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv, uint32_t cmd_size = define_size + remap_size; uint32_t i; - cmd_orig = cmd = vmw_fifo_reserve(dev_priv, cmd_size); + cmd_orig = cmd = VMW_FIFO_RESERVE(dev_priv, cmd_size); if (unlikely(cmd == NULL)) return -ENOMEM; @@ -110,11 +110,10 @@ static void vmw_gmr2_unbind(struct vmw_private *dev_priv, uint32_t define_size = sizeof(define_cmd) + 4; uint32_t *cmd; - cmd = vmw_fifo_reserve(dev_priv, define_size); - if (unlikely(cmd == NULL)) { - DRM_ERROR("GMR2 unbind failed.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, define_size); + if (unlikely(cmd == NULL)) return; - } + define_cmd.gmrId = gmr_id; define_cmd.numPages = 0; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index de367e8612af..b97bc8e5944b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -64,11 +64,9 @@ static int vmw_cursor_update_image(struct vmw_private *dev_priv, if (!image) return -EINVAL; - cmd = vmw_fifo_reserve(dev_priv, cmd_size); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Fifo reserve failed.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, cmd_size); + if (unlikely(cmd == NULL)) return -ENOMEM; - } memset(cmd, 0, sizeof(*cmd)); @@ -2468,13 +2466,11 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv, dirty->unit = unit; if (dirty->fifo_reserve_size > 0) { - dirty->cmd = vmw_fifo_reserve(dev_priv, + dirty->cmd = VMW_FIFO_RESERVE(dev_priv, dirty->fifo_reserve_size); - if (!dirty->cmd) { - DRM_ERROR("Couldn't reserve fifo space " - "for dirty blits.\n"); + if (!dirty->cmd) return -ENOMEM; - } + memset(dirty->cmd, 0, dirty->fifo_reserve_size); } dirty->num_hits = 0; @@ -2604,12 +2600,9 @@ int vmw_kms_update_proxy(struct vmw_resource *res, if (!clips) return 0; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) * num_clips); - if (!cmd) { - DRM_ERROR("Couldn't reserve fifo space for proxy surface " - "update.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd) * num_clips); + if (!cmd) return -ENOMEM; - } for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) { box = &cmd->body.box; @@ -2839,7 +2832,7 @@ int vmw_du_helper_plane_update(struct vmw_du_update_plane *update) goto out_unref; reserved_size = update->calc_fifo_size(update, num_hits); - cmd_start = vmw_fifo_reserve(update->dev_priv, reserved_size); + cmd_start = VMW_FIFO_RESERVE(update->dev_priv, reserved_size); if (!cmd_start) { ret = -ENOMEM; goto out_revert; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 16be515c4c0f..25e6343bcf21 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -554,11 +554,9 @@ int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv, } *cmd; fifo_size = sizeof(*cmd) * num_clips; - cmd = vmw_fifo_reserve(dev_priv, fifo_size); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Fifo reserve failed.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, fifo_size); + if (unlikely(cmd == NULL)) return -ENOMEM; - } memset(cmd, 0, fifo_size); for (i = 0; i < num_clips; i++, clips += increment) { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index d83cc66e1210..406edc8cef35 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -146,9 +146,8 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1; } - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for OTable setup.\n"); ret = -ENOMEM; goto out_no_fifo; } @@ -202,12 +201,9 @@ static void vmw_takedown_otable_base(struct vmw_private *dev_priv, return; bo = otable->page_table->pt_bo; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for OTable " - "takedown.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return; - } memset(cmd, 0, sizeof(*cmd)); cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE; @@ -614,16 +610,14 @@ void vmw_mob_unbind(struct vmw_private *dev_priv, BUG_ON(ret != 0); } - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for Memory " - "Object unbinding.\n"); - } else { + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (cmd) { cmd->header.id = SVGA_3D_CMD_DESTROY_GB_MOB; cmd->header.size = sizeof(cmd->body); cmd->body.mobid = mob->id; vmw_fifo_commit(dev_priv, sizeof(*cmd)); } + if (bo) { vmw_bo_fence_single(bo, NULL); ttm_bo_unreserve(bo); @@ -683,12 +677,9 @@ int vmw_mob_bind(struct vmw_private *dev_priv, vmw_fifo_resource_inc(dev_priv); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for Memory " - "Object binding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) goto out_no_cmd_space; - } cmd->header.id = SVGA_3D_CMD_DEFINE_GB_MOB64; cmd->header.size = sizeof(cmd->body); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index 9f1b9d289bec..d5ef8cf802de 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -124,7 +124,7 @@ static int vmw_overlay_send_put(struct vmw_private *dev_priv, fifo_size = sizeof(*cmds) + sizeof(*flush) + sizeof(*items) * num_items; - cmds = vmw_fifo_reserve(dev_priv, fifo_size); + cmds = VMW_FIFO_RESERVE(dev_priv, fifo_size); /* hardware has hung, can't do anything here */ if (!cmds) return -ENOMEM; @@ -194,7 +194,7 @@ static int vmw_overlay_send_stop(struct vmw_private *dev_priv, int ret; for (;;) { - cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds)); + cmds = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmds)); if (cmds) break; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index c8feeaa85143..711f8fd0dd45 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -730,12 +730,9 @@ int vmw_query_readback_all(struct vmw_buffer_object *dx_query_mob) dx_query_ctx = dx_query_mob->dx_query_ctx; dev_priv = dx_query_ctx->dev_priv; - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), dx_query_ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for " - "query MOB read back.\n"); + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), dx_query_ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_READBACK_ALL_QUERY; cmd->header.size = sizeof(cmd->body); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 9c2bdb56a6d3..9a2a3836d89a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -130,12 +130,9 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv, BUG_ON(!sou->buffer); fifo_size = sizeof(*cmd); - cmd = vmw_fifo_reserve(dev_priv, fifo_size); - /* The hardware has hung, nothing we can do about it here. */ - if (unlikely(cmd == NULL)) { - DRM_ERROR("Fifo reserve failed.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, fifo_size); + if (unlikely(cmd == NULL)) return -ENOMEM; - } memset(cmd, 0, fifo_size); cmd->header.cmdType = SVGA_CMD_DEFINE_SCREEN; @@ -182,12 +179,9 @@ static int vmw_sou_fifo_destroy(struct vmw_private *dev_priv, return 0; fifo_size = sizeof(*cmd); - cmd = vmw_fifo_reserve(dev_priv, fifo_size); - /* the hardware has hung, nothing we can do about it here */ - if (unlikely(cmd == NULL)) { - DRM_ERROR("Fifo reserve failed.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, fifo_size); + if (unlikely(cmd == NULL)) return -ENOMEM; - } memset(cmd, 0, fifo_size); cmd->header.cmdType = SVGA_CMD_DESTROY_SCREEN; @@ -998,11 +992,9 @@ static int do_bo_define_gmrfb(struct vmw_private *dev_priv, if (depth == 32) depth = 24; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (!cmd) { - DRM_ERROR("Out of fifo space for dirty framebuffer command.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (!cmd) return -ENOMEM; - } cmd->header = SVGA_CMD_DEFINE_GMRFB; cmd->body.format.bitsPerPixel = framebuffer->base.format->cpp[0] * 8; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index bbc95743a381..d310d21f0d54 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c @@ -218,10 +218,8 @@ static int vmw_gb_shader_create(struct vmw_resource *res) goto out_no_fifo; } - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for shader " - "creation.\n"); ret = -ENOMEM; goto out_no_fifo; } @@ -254,12 +252,9 @@ static int vmw_gb_shader_bind(struct vmw_resource *res, BUG_ON(bo->mem.mem_type != VMW_PL_MOB); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for shader " - "binding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_BIND_GB_SHADER; cmd->header.size = sizeof(cmd->body); @@ -285,12 +280,9 @@ static int vmw_gb_shader_unbind(struct vmw_resource *res, BUG_ON(res->backup->base.mem.mem_type != VMW_PL_MOB); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for shader " - "unbinding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_BIND_GB_SHADER; cmd->header.size = sizeof(cmd->body); @@ -328,10 +320,8 @@ static int vmw_gb_shader_destroy(struct vmw_resource *res) mutex_lock(&dev_priv->binding_mutex); vmw_binding_res_list_scrub(&res->binding_head); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for shader " - "destruction.\n"); mutex_unlock(&dev_priv->binding_mutex); return -ENOMEM; } @@ -400,13 +390,9 @@ static int vmw_dx_shader_unscrub(struct vmw_resource *res) if (!list_empty(&shader->cotable_head) || !shader->committed) return 0; - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), - shader->ctx->id); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for shader " - "scrubbing.\n"); + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), shader->ctx->id); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_BIND_SHADER; cmd->header.size = sizeof(cmd->body); @@ -491,12 +477,9 @@ static int vmw_dx_shader_scrub(struct vmw_resource *res) return 0; WARN_ON_ONCE(!shader->committed); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - if (unlikely(cmd == NULL)) { - DRM_ERROR("Failed reserving FIFO space for shader " - "scrubbing.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DX_BIND_SHADER; cmd->header.size = sizeof(cmd->body); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c index c50002a3db27..63807361e16f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c @@ -170,13 +170,12 @@ static int vmw_view_create(struct vmw_resource *res) return 0; } - cmd = vmw_fifo_reserve_dx(res->dev_priv, view->cmd_size, - view->ctx->id); + cmd = VMW_FIFO_RESERVE_DX(res->dev_priv, view->cmd_size, view->ctx->id); if (!cmd) { - DRM_ERROR("Failed reserving FIFO space for view creation.\n"); mutex_unlock(&dev_priv->binding_mutex); return -ENOMEM; } + memcpy(cmd, &view->cmd, view->cmd_size); WARN_ON(cmd->body.view_id != view->view_id); /* Sid may have changed due to surface eviction. */ @@ -214,12 +213,9 @@ static int vmw_view_destroy(struct vmw_resource *res) if (!view->committed || res->id == -1) return 0; - cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), view->ctx->id); - if (!cmd) { - DRM_ERROR("Failed reserving FIFO space for view " - "destruction.\n"); + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), view->ctx->id); + if (!cmd) return -ENOMEM; - } cmd->header.id = vmw_view_destroy_cmds[view->view_type]; cmd->header.size = sizeof(cmd->body); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 1a65008a27b2..f803bb5e782b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -167,12 +167,9 @@ static int vmw_stdu_define_st(struct vmw_private *dev_priv, SVGA3dCmdDefineGBScreenTarget body; } *cmd; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - - if (unlikely(cmd == NULL)) { - DRM_ERROR("Out of FIFO space defining Screen Target\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DEFINE_GB_SCREENTARGET; cmd->header.size = sizeof(cmd->body); @@ -229,12 +226,9 @@ static int vmw_stdu_bind_st(struct vmw_private *dev_priv, memset(&image, 0, sizeof(image)); image.sid = res ? res->id : SVGA3D_INVALID_ID; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - - if (unlikely(cmd == NULL)) { - DRM_ERROR("Out of FIFO space binding a screen target\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_BIND_GB_SCREENTARGET; cmd->header.size = sizeof(cmd->body); @@ -296,12 +290,9 @@ static int vmw_stdu_update_st(struct vmw_private *dev_priv, return -EINVAL; } - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - - if (unlikely(cmd == NULL)) { - DRM_ERROR("Out of FIFO space updating a Screen Target\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } vmw_stdu_populate_update(cmd, stdu->base.unit, 0, stdu->display_width, @@ -335,12 +326,9 @@ static int vmw_stdu_destroy_st(struct vmw_private *dev_priv, if (unlikely(!stdu->defined)) return 0; - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - - if (unlikely(cmd == NULL)) { - DRM_ERROR("Out of FIFO space, screen target not destroyed\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (unlikely(cmd == NULL)) return -ENOMEM; - } cmd->header.id = SVGA_3D_CMD_DESTROY_GB_SCREENTARGET; cmd->header.size = sizeof(cmd->body); @@ -637,12 +625,9 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) dev_priv = vmw_priv(stdu->base.crtc.dev); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); - - if (!cmd) { - DRM_ERROR("Cannot reserve FIFO space to update STDU"); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); + if (!cmd) goto out_cleanup; - } vmw_stdu_populate_update(cmd, stdu->base.unit, region.x1, region.x2, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index b550f69578e8..219471903bc1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -342,12 +342,9 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) if (res->id != -1) { - cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size()); - if (unlikely(!cmd)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "destruction.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, vmw_surface_destroy_size()); + if (unlikely(!cmd)) return; - } vmw_surface_destroy_encode(res->id, cmd); vmw_fifo_commit(dev_priv, vmw_surface_destroy_size()); @@ -414,10 +411,8 @@ static int vmw_legacy_srf_create(struct vmw_resource *res) */ submit_size = vmw_surface_define_size(srf); - cmd = vmw_fifo_reserve(dev_priv, submit_size); + cmd = VMW_FIFO_RESERVE(dev_priv, submit_size); if (unlikely(!cmd)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "creation.\n"); ret = -ENOMEM; goto out_no_fifo; } @@ -468,12 +463,10 @@ static int vmw_legacy_srf_dma(struct vmw_resource *res, BUG_ON(!val_buf->bo); submit_size = vmw_surface_dma_size(srf); - cmd = vmw_fifo_reserve(dev_priv, submit_size); - if (unlikely(!cmd)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "DMA.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, submit_size); + if (unlikely(!cmd)) return -ENOMEM; - } + vmw_bo_get_guest_ptr(val_buf->bo, &ptr); vmw_surface_dma_encode(srf, cmd, &ptr, bind); @@ -556,12 +549,9 @@ static int vmw_legacy_srf_destroy(struct vmw_resource *res) */ submit_size = vmw_surface_destroy_size(); - cmd = vmw_fifo_reserve(dev_priv, submit_size); - if (unlikely(!cmd)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "eviction.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, submit_size); + if (unlikely(!cmd)) return -ENOMEM; - } vmw_surface_destroy_encode(res->id, cmd); vmw_fifo_commit(dev_priv, submit_size); @@ -1086,12 +1076,10 @@ static int vmw_gb_surface_create(struct vmw_resource *res) submit_len = sizeof(*cmd); } - cmd = vmw_fifo_reserve(dev_priv, submit_len); + cmd = VMW_FIFO_RESERVE(dev_priv, submit_len); cmd2 = (typeof(cmd2))cmd; cmd3 = (typeof(cmd3))cmd; if (unlikely(!cmd)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "creation.\n"); ret = -ENOMEM; goto out_no_fifo; } @@ -1169,12 +1157,9 @@ static int vmw_gb_surface_bind(struct vmw_resource *res, submit_size = sizeof(*cmd1) + (res->backup_dirty ? sizeof(*cmd2) : 0); - cmd1 = vmw_fifo_reserve(dev_priv, submit_size); - if (unlikely(!cmd1)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "binding.\n"); + cmd1 = VMW_FIFO_RESERVE(dev_priv, submit_size); + if (unlikely(!cmd1)) return -ENOMEM; - } cmd1->header.id = SVGA_3D_CMD_BIND_GB_SURFACE; cmd1->header.size = sizeof(cmd1->body); @@ -1219,12 +1204,9 @@ static int vmw_gb_surface_unbind(struct vmw_resource *res, BUG_ON(bo->mem.mem_type != VMW_PL_MOB); submit_size = sizeof(*cmd3) + (readback ? sizeof(*cmd1) : sizeof(*cmd2)); - cmd = vmw_fifo_reserve(dev_priv, submit_size); - if (unlikely(!cmd)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "unbinding.\n"); + cmd = VMW_FIFO_RESERVE(dev_priv, submit_size); + if (unlikely(!cmd)) return -ENOMEM; - } if (readback) { cmd1 = (void *) cmd; @@ -1278,10 +1260,8 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res) vmw_view_surface_list_destroy(dev_priv, &srf->view_list); vmw_binding_res_list_scrub(&res->binding_head); - cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); + cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd)); if (unlikely(!cmd)) { - DRM_ERROR("Failed reserving FIFO space for surface " - "destruction.\n"); mutex_unlock(&dev_priv->binding_mutex); return -ENOMEM; } -- cgit v1.2.3 From a5020f4f537ff1a0b73ea4eb78be185c34b261ae Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 11 Mar 2019 20:24:46 -0700 Subject: drm/vmwgfx: Zero initialize handle in vmw_execbuf_process When building with -Wsometimes-uninitialized, Clang warns: drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c:3964:7: warning: variable 'handle' is used uninitialized whenever '?:' condition is false [-Wsometimes-uninitialized] It's not wrong; however, in practice, this is never an issue because the value of handle isn't used when user_fence_rep is NULL because vmw_execbuf_copy_fence_user returns immediately when that is the case. Just zero initialize this variable so that Clang no longer warns. Link: https://github.com/ClangBuiltLinux/linux/issues/397 Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Deepak Rawat --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 6cc9837b10ec..2ff7ba04d8c8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -3620,7 +3620,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, struct vmw_sw_context *sw_context = &dev_priv->ctx; struct vmw_fence_obj *fence = NULL; struct vmw_cmdbuf_header *header; - uint32_t handle; + uint32_t handle = 0; int ret; int32_t out_fence_fd = -1; struct sync_file *sync_file = NULL; -- cgit v1.2.3 From c601b12fb634e2d0c2669706b38dba98a3c3a832 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 25 Mar 2019 10:32:17 -0700 Subject: drm/vmwgfx: Remove set but not used variable 'fb_offset, fb_depth' Fixes gcc '-Wunused-but-set-variable' warning: drivers/gpu/drm/vmwgfx/vmwgfx_fb.c: In function 'vmw_fb_init': drivers/gpu/drm/vmwgfx/vmwgfx_fb.c:645:29: warning: variable 'fb_offset' set but not used [-Wunused-but-set-variable] drivers/gpu/drm/vmwgfx/vmwgfx_fb.c:645:19: warning: variable 'fb_depth' set but not used [-Wunused-but-set-variable] They're not used any more, so can be removed. Signed-off-by: YueHaibing Reviewed-by: Deepak Rawat Signed-off-by: Deepak Rawat --- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 2a9112515f46..972e8fda6d35 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -642,12 +642,11 @@ int vmw_fb_init(struct vmw_private *vmw_priv) struct vmw_fb_par *par; struct fb_info *info; unsigned fb_width, fb_height; - unsigned fb_bpp, fb_depth, fb_offset, fb_pitch, fb_size; + unsigned int fb_bpp, fb_pitch, fb_size; struct drm_display_mode *init_mode; int ret; fb_bpp = 32; - fb_depth = 24; /* XXX As shouldn't these be as well. */ fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); @@ -655,7 +654,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv) fb_pitch = fb_width * fb_bpp / 8; fb_size = fb_pitch * fb_height; - fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET); info = framebuffer_alloc(sizeof(*par), device); if (!info) -- cgit v1.2.3 From 15b7dae0076befcce99cf843dca7af3c3bdf31e4 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 5 Apr 2019 17:51:09 -0700 Subject: drm/i915/psr: Update PSR2 SU corruption workaround comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turn out it is not a DMC bug it is actually a HW one, so this workaround will be needed for current gens, lets update the comment and remove the FIXME. BSpec: 7723 Cc: Dhinakaran Pandiyan Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20190406005112.27205-1-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index aacf5c6f6d95..361d231c888b 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -534,10 +534,8 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) val |= EDP_PSR2_TP2_TIME_2500us; /* - * FIXME: There is probably a issue in DMC firmwares(icl_dmc_ver1_07.bin - * and kbl_dmc_ver1_04.bin at least) that causes PSR2 SU to fail after - * exiting DC6 if EDP_PSR_TP1_TP3_SEL is kept in PSR_CTL, so for now - * lets workaround the issue by cleaning PSR_CTL before enable PSR2. + * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is + * recommending keep this bit unset while PSR2 is enabled. */ I915_WRITE(EDP_PSR_CTL, 0); -- cgit v1.2.3 From c0f6ffb2cd6a99ace18e7e195048381d6185cfcb Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 5 Apr 2019 17:51:10 -0700 Subject: drm/i915: Remove unused VLV/CHV PSR registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PSR support for VLV and CHV was dropped in commit ce3508fd2a77 ("drm/i915/psr: Nuke PSR support for VLV and CHV") so no need to keep this registers around. Cc: Dhinakaran Pandiyan Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20190406005112.27205-2-jose.souza@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c18caa76f27c..9c206e803ab3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4209,42 +4209,6 @@ enum { #define PIPESRC(trans) _MMIO_TRANS2(trans, _PIPEASRC) #define PIPE_MULT(trans) _MMIO_TRANS2(trans, _PIPE_MULT_A) -/* VLV eDP PSR registers */ -#define _PSRCTLA (VLV_DISPLAY_BASE + 0x60090) -#define _PSRCTLB (VLV_DISPLAY_BASE + 0x61090) -#define VLV_EDP_PSR_ENABLE (1 << 0) -#define VLV_EDP_PSR_RESET (1 << 1) -#define VLV_EDP_PSR_MODE_MASK (7 << 2) -#define VLV_EDP_PSR_MODE_HW_TIMER (1 << 3) -#define VLV_EDP_PSR_MODE_SW_TIMER (1 << 2) -#define VLV_EDP_PSR_SINGLE_FRAME_UPDATE (1 << 7) -#define VLV_EDP_PSR_ACTIVE_ENTRY (1 << 8) -#define VLV_EDP_PSR_SRC_TRANSMITTER_STATE (1 << 9) -#define VLV_EDP_PSR_DBL_FRAME (1 << 10) -#define VLV_EDP_PSR_FRAME_COUNT_MASK (0xff << 16) -#define VLV_EDP_PSR_IDLE_FRAME_SHIFT 16 -#define VLV_PSRCTL(pipe) _MMIO_PIPE(pipe, _PSRCTLA, _PSRCTLB) - -#define _VSCSDPA (VLV_DISPLAY_BASE + 0x600a0) -#define _VSCSDPB (VLV_DISPLAY_BASE + 0x610a0) -#define VLV_EDP_PSR_SDP_FREQ_MASK (3 << 30) -#define VLV_EDP_PSR_SDP_FREQ_ONCE (1 << 31) -#define VLV_EDP_PSR_SDP_FREQ_EVFRAME (1 << 30) -#define VLV_VSCSDP(pipe) _MMIO_PIPE(pipe, _VSCSDPA, _VSCSDPB) - -#define _PSRSTATA (VLV_DISPLAY_BASE + 0x60094) -#define _PSRSTATB (VLV_DISPLAY_BASE + 0x61094) -#define VLV_EDP_PSR_LAST_STATE_MASK (7 << 3) -#define VLV_EDP_PSR_CURR_STATE_MASK 7 -#define VLV_EDP_PSR_DISABLED (0 << 0) -#define VLV_EDP_PSR_INACTIVE (1 << 0) -#define VLV_EDP_PSR_IN_TRANS_TO_ACTIVE (2 << 0) -#define VLV_EDP_PSR_ACTIVE_NORFB_UP (3 << 0) -#define VLV_EDP_PSR_ACTIVE_SF_UPDATE (4 << 0) -#define VLV_EDP_PSR_EXIT (5 << 0) -#define VLV_EDP_PSR_IN_TRANS (1 << 7) -#define VLV_PSRSTAT(pipe) _MMIO_PIPE(pipe, _PSRSTATA, _PSRSTATB) - /* HSW+ eDP PSR registers */ #define HSW_EDP_PSR_BASE 0x64800 #define BDW_EDP_PSR_BASE 0x6f800 -- cgit v1.2.3 From 98c0d19ec72cd75ff85f9e84c52d11deb3c82032 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 5 Apr 2019 17:51:11 -0700 Subject: drm/i915/psr: Initialize PSR mutex even when sink is not reliable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Even when driver is reloaded and hits this scenario the PSR mutex should be initialized, otherwise reading PSR debugfs status will execute mutex_lock() over a mutex that was not initialized. Cc: Dhinakaran Pandiyan Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20190406005112.27205-3-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 361d231c888b..cc8b5be68e89 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -1230,7 +1230,6 @@ void intel_psr_init(struct drm_i915_private *dev_priv) if (val) { DRM_DEBUG_KMS("PSR interruption error set\n"); dev_priv->psr.sink_not_reliable = true; - return; } /* Set link_standby x link_off defaults */ -- cgit v1.2.3 From 7ae6ad6fbd83c74c37e70b7699248256eaa152a8 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Fri, 5 Apr 2019 17:51:12 -0700 Subject: drm/i915/psr: Do not enable PSR in interlaced mode for all GENs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This interlaced mode restriction applies to all gens, not only to Haswell. Also while at it updating the debug message to. Cc: Dhinakaran Pandiyan Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Reviewed-by: Dhinakaran Pandiyan Signed-off-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20190406005112.27205-4-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_psr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index cc8b5be68e89..963663ba0edf 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c @@ -630,9 +630,8 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, return; } - if (IS_HASWELL(dev_priv) && - adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { - DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n"); + if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { + DRM_DEBUG_KMS("PSR condition failed: Interlaced mode enabled\n"); return; } -- cgit v1.2.3 From 6484775766e37049883d49e7ee9c1a174f0d0524 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 7 Apr 2019 20:26:49 +0100 Subject: drm/i915/selftests: Mark live_forcewake_ops as unreliable A couple of machines in the farm show quite frequent errors in the powerwells not being released. Either there is an external agent interferring with the powerwells, or the powerwell doesn't quite behave as we anticipate -- either way, the test is not reliable enough to be enabled by default in CI. It has served its immediate purpose in providing coverage as we made tweaks to forcewake, so keep it available for future testing. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110210 Signed-off-by: Chris Wilson Cc: Daniele Ceraolo Spurio Cc: Mika Kuoppala Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20190407192649.14750-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/selftests/intel_uncore.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c index ee0bc91f7664..e0d7ebecb215 100644 --- a/drivers/gpu/drm/i915/selftests/intel_uncore.c +++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c @@ -155,6 +155,17 @@ static int live_forcewake_ops(void *arg) return 0; } + /* + * Not quite as reliable across the gen as one would hope. + * + * Either our theory of operation is incorrect, or there remain + * external parties interfering with the powerwells. + * + * https://bugs.freedesktop.org/show_bug.cgi?id=110210 + */ + if (!IS_ENABLED(CONFIG_DRM_I915_SELFTEST_BROKEN)) + return 0; + /* We have to pick carefully to get the exact behaviour we need */ for (r = registers; r->name; r++) if (r->platforms & INTEL_INFO(i915)->gen_mask) -- cgit v1.2.3 From bef42cb2029c0ec8cd8c9e0545589d81913dec4e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Sun, 7 Apr 2019 15:46:55 +0300 Subject: drm/i915: Get power refs in encoder->get_power_domains() Push getting the reference for the encoders' power domains into the encoder get_power_domains() hook instead of doing this from the caller. This way the encoder can store away the corresponding wakerefs. This fixes the DSI encoder disabling, which didn't release these power references it acquired during HW state readout. Note that longtime ownership for the corresponding wakerefs can be thus acquired / released in two ways. Nevertheless there is always only one owner for them: After HW readout (booting/system resume): - encoder->get_power_domains() acquires - encoder->disable*() releases After a modeset (calling intel_atomic_commit()): - encoder->enable*() acquires - encoder->disable*() releases * can be any of the encoder enable/disable hooks. v2: - Check that the DSI io_wakerefs are unset both during encoder HW readout and enabling. (Chris) Fixes: 0e6e0be4c9523 ("drm/i915: Markup paired operations on display power domains") Cc: Vandita Kulkarni Cc: Chris Wilson Signed-off-by: Imre Deak Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190407124655.31536-1-imre.deak@intel.com (cherry picked from commit 3a52fb7e7953f0b13df8c05d0d74b56a66888f30) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/icl_dsi.c | 40 ++++++++++++++++++------------------ drivers/gpu/drm/i915/intel_ddi.c | 17 ++++++++------- drivers/gpu/drm/i915/intel_display.c | 6 +----- drivers/gpu/drm/i915/intel_drv.h | 10 +++++---- 4 files changed, 35 insertions(+), 38 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 73a7bee24a66..83cd8284e807 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -323,6 +323,21 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) } } +static void get_dsi_io_power_domains(struct drm_i915_private *dev_priv, + struct intel_dsi *intel_dsi) +{ + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + WARN_ON(intel_dsi->io_wakeref[port]); + intel_dsi->io_wakeref[port] = + intel_display_power_get(dev_priv, + port == PORT_A ? + POWER_DOMAIN_PORT_DDI_A_IO : + POWER_DOMAIN_PORT_DDI_B_IO); + } +} + static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -336,13 +351,7 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) I915_WRITE(ICL_DSI_IO_MODECTL(port), tmp); } - for_each_dsi_port(port, intel_dsi->ports) { - intel_dsi->io_wakeref[port] = - intel_display_power_get(dev_priv, - port == PORT_A ? - POWER_DOMAIN_PORT_DDI_A_IO : - POWER_DOMAIN_PORT_DDI_B_IO); - } + get_dsi_io_power_domains(dev_priv, intel_dsi); } static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) @@ -1218,20 +1227,11 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder, return 0; } -static u64 gen11_dsi_get_power_domains(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state) +static void gen11_dsi_get_power_domains(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state) { - struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); - u64 domains = 0; - enum port port; - - for_each_dsi_port(port, intel_dsi->ports) - if (port == PORT_A) - domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO); - else - domains |= BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO); - - return domains; + get_dsi_io_power_domains(to_i915(encoder->base.dev), + enc_to_intel_dsi(&encoder->base)); } static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 14d580cdefd3..deba8e90360a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2075,12 +2075,11 @@ intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port) intel_aux_power_domain(dig_port); } -static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state) +static void intel_ddi_get_power_domains(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port; - u64 domains; /* * TODO: Add support for MST encoders. Atm, the following should never @@ -2088,10 +2087,10 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, * hook. */ if (WARN_ON(intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))) - return 0; + return; dig_port = enc_to_dig_port(&encoder->base); - domains = BIT_ULL(dig_port->ddi_io_power_domain); + intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); /* * AUX power is only needed for (e)DP mode, and for HDMI mode on TC @@ -2099,15 +2098,15 @@ static u64 intel_ddi_get_power_domains(struct intel_encoder *encoder, */ if (intel_crtc_has_dp_encoder(crtc_state) || intel_port_is_tc(dev_priv, encoder->port)) - domains |= BIT_ULL(intel_ddi_main_link_aux_domain(dig_port)); + intel_display_power_get(dev_priv, + intel_ddi_main_link_aux_domain(dig_port)); /* * VDSC power is needed when DSC is enabled */ if (crtc_state->dsc_params.compression_enable) - domains |= BIT_ULL(intel_dsc_power_domain(crtc_state)); - - return domains; + intel_display_power_get(dev_priv, + intel_dsc_power_domain(crtc_state)); } void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ccb616351bba..421aac80a838 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -15986,8 +15986,6 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) struct intel_encoder *encoder; for_each_intel_encoder(&dev_priv->drm, encoder) { - u64 get_domains; - enum intel_display_power_domain domain; struct intel_crtc_state *crtc_state; if (!encoder->get_power_domains) @@ -16001,9 +15999,7 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv) continue; crtc_state = to_intel_crtc_state(encoder->base.crtc->state); - get_domains = encoder->get_power_domains(encoder, crtc_state); - for_each_power_domain(domain, get_domains) - intel_display_power_get(dev_priv, domain); + encoder->get_power_domains(encoder, crtc_state); } } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 15db41394b9e..d5660ac1b0d6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -270,10 +270,12 @@ struct intel_encoder { * be set correctly before calling this function. */ void (*get_config)(struct intel_encoder *, struct intel_crtc_state *pipe_config); - /* Returns a mask of power domains that need to be referenced as part - * of the hardware state readout code. */ - u64 (*get_power_domains)(struct intel_encoder *encoder, - struct intel_crtc_state *crtc_state); + /* + * Acquires the power domains needed for an active encoder during + * hardware state readout. + */ + void (*get_power_domains)(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state); /* * Called during system suspend after all pending requests for the * encoder are flushed (for example for DP AUX transactions) and -- cgit v1.2.3 From 2ae2c3316fb77dcf64275d011596b60104c45426 Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Thu, 4 Apr 2019 00:04:09 +0800 Subject: drm/mediatek: fix possible object reference leak The call to of_parse_phandle returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage. Detected by coccinelle with the following warnings: drivers/gpu/drm/mediatek/mtk_hdmi.c:1521:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 1509, but without a corresponding object release within this function. drivers/gpu/drm/mediatek/mtk_hdmi.c:1524:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 1509, but without a corresponding object release within this function. Signed-off-by: Wen Yang Cc: CK Hu Cc: Philipp Zabel Cc: David Airlie Cc: Daniel Vetter Cc: Matthias Brugger Cc: dri-devel@lists.freedesktop.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-mediatek@lists.infradead.org Cc: linux-kernel@vger.kernel.org Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_hdmi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c index 543a25e5765e..e04e6c293d39 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1515,6 +1515,7 @@ static int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, of_node_put(remote); hdmi->ddc_adpt = of_find_i2c_adapter_by_node(i2c_np); + of_node_put(i2c_np); if (!hdmi->ddc_adpt) { dev_err(dev, "Failed to get ddc i2c adapter by node\n"); return -EINVAL; -- cgit v1.2.3 From 174221e8491588aa9d44ebfa3242bea11eacc64f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 8 Apr 2019 10:17:14 +0100 Subject: drm/i915/guc: Replace preempt_client lookup with engine->preempt_context Circumvent the dance we currently perform to find the preempt_client and lookup its HW context for this engine, as we know we have already pinned the preempt_context on the engine. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190408091728.20207-15-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_guc_submission.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index 42fcd622d7a3..dea87253d141 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -567,7 +567,7 @@ static void inject_preempt_context(struct work_struct *work) preempt_work[engine->id]); struct intel_guc_client *client = guc->preempt_client; struct guc_stage_desc *stage_desc = __get_stage_desc(client); - struct intel_context *ce = intel_context_lookup(client->owner, engine); + struct intel_context *ce = engine->preempt_context; u32 data[7]; if (!ce->ring->emit) { /* recreate upon load/resume */ -- cgit v1.2.3 From 0c24613cda163dedfa229afc8eff6072e57fac8d Mon Sep 17 00:00:00 2001 From: Wangyan Wang Date: Tue, 9 Apr 2019 14:53:04 +0800 Subject: drm/mediatek: fix the rate and divder of hdmi phy for MT2701 Due to a clerical error,there is one zero less for 12800000. Fix it for 128000000 Fixes: 0fc721b2968e ("drm/mediatek: add hdmi driver for MT2701 and MT7623") Signed-off-by: Wangyan Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c index fcc42dc6ea7f..0746fc887706 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c @@ -116,8 +116,8 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, if (rate <= 64000000) pos_div = 3; - else if (rate <= 12800000) - pos_div = 1; + else if (rate <= 128000000) + pos_div = 2; else pos_div = 1; -- cgit v1.2.3 From 321b628e6f5a3af999f75eadd373adbcb8b4cb1f Mon Sep 17 00:00:00 2001 From: Wangyan Wang Date: Tue, 9 Apr 2019 14:53:06 +0800 Subject: drm/mediatek: make implementation of recalc_rate() for MT2701 hdmi phy Recalculate the rate of this clock, by querying hardware to make implementation of recalc_rate() to match the definition. Signed-off-by: Wangyan Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 8 ------ drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 -- drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 38 +++++++++++++++++++++++--- drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 8 ++++++ 4 files changed, 42 insertions(+), 14 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c index 4ef9c57ffd44..efc400ebbb90 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c @@ -29,14 +29,6 @@ long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, return rate; } -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); - - return hdmi_phy->pll_rate; -} - void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, u32 bits) { diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h index f39b1fc66612..71430691ffe4 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h @@ -50,8 +50,6 @@ void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate); -unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate); extern struct platform_driver mtk_hdmi_phy_driver; extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c index 0746fc887706..feb6a7ed63d1 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c @@ -79,7 +79,6 @@ static int mtk_hdmi_pll_prepare(struct clk_hw *hw) mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); usleep_range(80, 100); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); - mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); @@ -94,7 +93,6 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); - mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); usleep_range(80, 100); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); @@ -123,6 +121,7 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK); + mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC), RG_HTPLL_IC_MASK); mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR), @@ -154,6 +153,39 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + unsigned long out_rate, val; + + val = (readl(hdmi_phy->regs + HDMI_CON6) + & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV; + switch (val) { + case 0x00: + out_rate = parent_rate; + break; + case 0x01: + out_rate = parent_rate / 2; + break; + default: + out_rate = parent_rate / 4; + break; + } + + val = (readl(hdmi_phy->regs + HDMI_CON6) + & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV; + out_rate *= (val + 1) * 2; + val = (readl(hdmi_phy->regs + HDMI_CON2) + & RG_HDMITX_TX_POSDIV_MASK); + out_rate >>= (val >> RG_HDMITX_TX_POSDIV); + + if (readl(hdmi_phy->regs + HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV) + out_rate /= 5; + + return out_rate; +} + static const struct clk_ops mtk_hdmi_phy_pll_ops = { .prepare = mtk_hdmi_pll_prepare, .unprepare = mtk_hdmi_pll_unprepare, @@ -174,7 +206,6 @@ static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); usleep_range(80, 100); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); - mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); @@ -186,7 +217,6 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK); - mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN); usleep_range(80, 100); mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK); diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c index ed5916b27658..83662a208491 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c @@ -285,6 +285,14 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + + return hdmi_phy->pll_rate; +} + static const struct clk_ops mtk_hdmi_phy_pll_ops = { .prepare = mtk_hdmi_pll_prepare, .unprepare = mtk_hdmi_pll_unprepare, -- cgit v1.2.3 From 827abdd024207146822f66ba3ba74867135866b9 Mon Sep 17 00:00:00 2001 From: Wangyan Wang Date: Tue, 9 Apr 2019 14:53:03 +0800 Subject: drm/mediatek: remove flag CLK_SET_RATE_PARENT for MT2701 hdmi phy This is the first step to make MT2701 hdmi stable. The parent rate of hdmi phy had set by DPI driver. We should not set or change the parent rate of MT2701 hdmi phy, as a result we should remove the flags of "CLK_SET_RATE_PARENT" from the clock of MT2701 hdmi phy. Signed-off-by: Wangyan Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 13 +++++-------- drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 1 + drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 1 + drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 1 + 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c index efc400ebbb90..08b029772c5a 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c @@ -102,13 +102,11 @@ mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) return NULL; } -static void mtk_hdmi_phy_clk_get_ops(struct mtk_hdmi_phy *hdmi_phy, - const struct clk_ops **ops) +static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy, + struct clk_init_data *clk_init) { - if (hdmi_phy && hdmi_phy->conf && hdmi_phy->conf->hdmi_phy_clk_ops) - *ops = hdmi_phy->conf->hdmi_phy_clk_ops; - else - dev_err(hdmi_phy->dev, "Failed to get clk ops of phy\n"); + clk_init->flags = hdmi_phy->conf->flags; + clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops; } static int mtk_hdmi_phy_probe(struct platform_device *pdev) @@ -121,7 +119,6 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) struct clk_init_data clk_init = { .num_parents = 1, .parent_names = (const char * const *)&ref_clk_name, - .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, }; struct phy *phy; @@ -159,7 +156,7 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev) hdmi_phy->dev = dev; hdmi_phy->conf = (struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev); - mtk_hdmi_phy_clk_get_ops(hdmi_phy, &clk_init.ops); + mtk_hdmi_phy_clk_get_data(hdmi_phy, &clk_init); hdmi_phy->pll_hw.init = &clk_init; hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw); if (IS_ERR(hdmi_phy->pll)) { diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h index 71430691ffe4..d28b8d5ed2b4 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h @@ -21,6 +21,7 @@ struct mtk_hdmi_phy; struct mtk_hdmi_phy_conf { bool tz_disabled; + unsigned long flags; const struct clk_ops *hdmi_phy_clk_ops; void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy); void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy); diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c index feb6a7ed63d1..31f3175f032b 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c @@ -232,6 +232,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf = { .tz_disabled = true, + .flags = CLK_SET_RATE_GATE, .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c index 83662a208491..37f9503d7643 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c @@ -317,6 +317,7 @@ static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) } struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = { + .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops, .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds, .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds, -- cgit v1.2.3 From 8eeb3946feeb00486ac0909e2309da87db8988a5 Mon Sep 17 00:00:00 2001 From: Wangyan Wang Date: Tue, 9 Apr 2019 14:53:05 +0800 Subject: drm/mediatek: using new factor for tvdpll for MT2701 hdmi phy This is the second step to make MT2701 HDMI stable. The factor depends on the divider of DPI in MT2701, therefore, we should fix this factor to the right and new one. Test: search ok Signed-off-by: Wangyan Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 22e68a100e7b..5d333138f913 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -662,13 +662,11 @@ static unsigned int mt8173_calculate_factor(int clock) static unsigned int mt2701_calculate_factor(int clock) { if (clock <= 64000) - return 16; - else if (clock <= 128000) - return 8; - else if (clock <= 256000) return 4; - else + else if (clock <= 128000) return 2; + else + return 1; } static const struct mtk_dpi_conf mt8173_conf = { -- cgit v1.2.3 From 9ee76098a1b8ae21cccac641b735ee4d3a77bccf Mon Sep 17 00:00:00 2001 From: Wangyan Wang Date: Tue, 9 Apr 2019 14:53:07 +0800 Subject: drm/mediatek: no change parent rate in round_rate() for MT2701 hdmi phy This is the third step to make MT2701 HDMI stable. We should not change the rate of parent for hdmi phy when doing round_rate for this clock. The parent clock of hdmi phy must be the same as it. We change it when doing set_rate only. Signed-off-by: Wangyan Wang Signed-off-by: CK Hu --- drivers/gpu/drm/mediatek/mtk_hdmi_phy.c | 14 -------------- drivers/gpu/drm/mediatek/mtk_hdmi_phy.h | 2 -- drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c | 6 ++++++ drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c | 14 ++++++++++++++ 4 files changed, 20 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c index 08b029772c5a..5223498502c4 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c @@ -15,20 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = { .owner = THIS_MODULE, }; -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); - - hdmi_phy->pll_rate = rate; - if (rate <= 74250000) - *parent_rate = rate; - else - *parent_rate = rate / 2; - - return rate; -} - void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, u32 bits) { diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h index d28b8d5ed2b4..2d8b3182470d 100644 --- a/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_phy.h @@ -49,8 +49,6 @@ void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset, void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset, u32 val, u32 mask); struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); -long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate); extern struct platform_driver mtk_hdmi_phy_driver; extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; diff --git a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c index 31f3175f032b..d3cc4022e988 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt2701_hdmi_phy.c @@ -106,6 +106,12 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) usleep_range(80, 100); } +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + return rate; +} + static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { diff --git a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c index 37f9503d7643..47f8a2951682 100644 --- a/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c +++ b/drivers/gpu/drm/mediatek/mtk_mt8173_hdmi_phy.c @@ -199,6 +199,20 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) usleep_range(100, 150); } +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + + hdmi_phy->pll_rate = rate; + if (rate <= 74250000) + *parent_rate = rate; + else + *parent_rate = rate / 2; + + return rate; +} + static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { -- cgit v1.2.3 From c5b81a325263a891d5811aabe938c87e03db4c37 Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Mon, 25 Mar 2019 16:56:41 +0530 Subject: drm/i915/icl: Ungate ddi clocks before IO enable IO enable sequencing needs ddi clocks enabled. These clocks will be gated at a later point in the enable sequence. v2: Fix the commit header (Uma) v3: Remove the redundant read (Ville) Fixes: 949fc52af19e ("drm/i915/icl: add pll mapping for DSI") Signed-off-by: Vandita Kulkarni Reviewed-by: Uma Shankar Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1553513202-13863-1-git-send-email-vandita.kulkarni@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 6fc48479c97b..be1cfbced8e9 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -602,6 +602,12 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder, val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); } I915_WRITE(DPCLKA_CFGCR0_ICL, val); + + for_each_dsi_port(port, intel_dsi->ports) { + val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port); + } + I915_WRITE(DPCLKA_CFGCR0_ICL, val); + POSTING_READ(DPCLKA_CFGCR0_ICL); mutex_unlock(&dev_priv->dpll_lock); -- cgit v1.2.3 From 942d1cf48eae3fcd7e973cfb708d5c4860f0c713 Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Mon, 25 Mar 2019 16:56:42 +0530 Subject: drm/i915/icl: Fix port disable sequence for mipi-dsi Re-enable clock gating of DDI clocks. v2: Fix the default ddi clk state for mipi-dsi (Imre) Fixes: 1026bea00381 ("drm/i915/icl: Ungate DSI clocks") Signed-off-by: Vandita Kulkarni Reviewed-by: Uma Shankar Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1553513202-13863-2-git-send-email-vandita.kulkarni@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 2 +- drivers/gpu/drm/i915/intel_ddi.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index be1cfbced8e9..9d962ea1e635 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1138,7 +1138,7 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder) DRM_ERROR("DDI port:%c buffer not idle\n", port_name(port)); } - gen11_dsi_ungate_clocks(encoder); + gen11_dsi_gate_clocks(encoder); } static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 0ab3a8a43848..3ae55274056c 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2802,10 +2802,10 @@ void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) return; } /* - * DSI ports should have their DDI clock ungated when disabled - * and gated when enabled. + * For DSI we keep the ddi clocks gated + * except during enable/disable sequence. */ - ddi_clk_needed = !encoder->base.crtc; + ddi_clk_needed = false; } val = I915_READ(DPCLKA_CFGCR0_ICL); -- cgit v1.2.3 From f11cb1c19ad0563b3c1ea5eb16a6bac0e401f428 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 10:52:20 +0300 Subject: drm/i915/dp: revert back to max link rate and lane count on eDP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 7769db588384 ("drm/i915/dp: optimize eDP 1.4+ link config fast and narrow") started to optize the eDP 1.4+ link config, both per spec and as preparation for display stream compression support. Sadly, we again face panels that flat out fail with parameters they claim to support. Revert, and go back to the drawing board. v2: Actually revert to max params instead of just wide-and-slow. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109959 Fixes: 7769db588384 ("drm/i915/dp: optimize eDP 1.4+ link config fast and narrow") Cc: Ville Syrjälä Cc: Manasi Navare Cc: Rodrigo Vivi Cc: Matt Atwood Cc: "Lee, Shawn C" Cc: Dave Airlie Cc: intel-gfx@lists.freedesktop.org Cc: # v5.0+ Reviewed-by: Rodrigo Vivi Reviewed-by: Manasi Navare Tested-by: Albert Astals Cid # v5.0 backport Tested-by: Emanuele Panigati # v5.0 backport Tested-by: Matteo Iervasi # v5.0 backport Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190405075220.9815-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_dp.c | 69 ++++++----------------------------------- 1 file changed, 10 insertions(+), 59 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c4e36759a756..0936d08aa982 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1868,42 +1868,6 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, return -EINVAL; } -/* Optimize link config in order: max bpp, min lanes, min clock */ -static int -intel_dp_compute_link_config_fast(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - const struct link_config_limits *limits) -{ - struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; - int bpp, clock, lane_count; - int mode_rate, link_clock, link_avail; - - for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { - mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, - bpp); - - for (lane_count = limits->min_lane_count; - lane_count <= limits->max_lane_count; - lane_count <<= 1) { - for (clock = limits->min_clock; clock <= limits->max_clock; clock++) { - link_clock = intel_dp->common_rates[clock]; - link_avail = intel_dp_max_data_rate(link_clock, - lane_count); - - if (mode_rate <= link_avail) { - pipe_config->lane_count = lane_count; - pipe_config->pipe_bpp = bpp; - pipe_config->port_clock = link_clock; - - return 0; - } - } - } - } - - return -EINVAL; -} - static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) { int i, num_bpc; @@ -2040,15 +2004,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, limits.min_bpp = 6 * 3; limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); - if (intel_dp_is_edp(intel_dp) && intel_dp->edp_dpcd[0] < DP_EDP_14) { + if (intel_dp_is_edp(intel_dp)) { /* * Use the maximum clock and number of lanes the eDP panel - * advertizes being capable of. The eDP 1.3 and earlier panels - * are generally designed to support only a single clock and - * lane configuration, and typically these values correspond to - * the native resolution of the panel. With eDP 1.4 rate select - * and DSC, this is decreasingly the case, and we need to be - * able to select less than maximum link config. + * advertizes being capable of. The panels are generally + * designed to support only a single clock and lane + * configuration, and typically these values correspond to the + * native resolution of the panel. */ limits.min_lane_count = limits.max_lane_count; limits.min_clock = limits.max_clock; @@ -2062,22 +2024,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, intel_dp->common_rates[limits.max_clock], limits.max_bpp, adjusted_mode->crtc_clock); - if (intel_dp_is_edp(intel_dp)) - /* - * Optimize for fast and narrow. eDP 1.3 section 3.3 and eDP 1.4 - * section A.1: "It is recommended that the minimum number of - * lanes be used, using the minimum link rate allowed for that - * lane configuration." - * - * Note that we use the max clock and lane count for eDP 1.3 and - * earlier, and fast vs. wide is irrelevant. - */ - ret = intel_dp_compute_link_config_fast(intel_dp, pipe_config, - &limits); - else - /* Optimize for slow and wide. */ - ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, - &limits); + /* + * Optimize for slow and wide. This is the place to add alternative + * optimization policy. + */ + ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits); /* enable compression if the mode doesn't fit available BW */ DRM_DEBUG_KMS("Force DSC en = %d\n", intel_dp->force_dsc_en); -- cgit v1.2.3 From a087bafeeac7ef317b1e44c615e162129c9c0ee2 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 10 Apr 2019 16:21:23 +0300 Subject: drm/i915/icl: Handle rps interrupts without irq lock Unlike previous gens, we already hold the irq_lock on entering the rps handler so we can't use it as it is. Make a gen11 specific rps interrupt handler without locking. v2: return early (Chris) Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190410132124.21795-1-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6454ddc37f8b..eb0eb96ac751 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1796,6 +1796,25 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, /* The RPS events need forcewake, so we add them to a work queue and mask their * IMR bits until the work is done. Other interrupts can be processed without * the work queue. */ +static void gen11_rps_irq_handler(struct drm_i915_private *i915, u32 pm_iir) +{ + struct intel_rps *rps = &i915->gt_pm.rps; + const u32 events = i915->pm_rps_events & pm_iir; + + lockdep_assert_held(&i915->irq_lock); + + if (unlikely(!events)) + return; + + gen6_mask_pm_irq(i915, events); + + if (!rps->interrupts_enabled) + return; + + rps->pm_iir |= events; + schedule_work(&rps->work); +} + static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) { struct intel_rps *rps = &dev_priv->gt_pm.rps; @@ -2949,7 +2968,7 @@ gen11_other_irq_handler(struct drm_i915_private * const i915, const u8 instance, const u16 iir) { if (instance == OTHER_GTPM_INSTANCE) - return gen6_rps_irq_handler(i915, iir); + return gen11_rps_irq_handler(i915, iir); WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n", instance, iir); -- cgit v1.2.3 From 8455dad7ba8ca846ebc4d03c2ca905c12fc6a455 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 10 Apr 2019 16:21:24 +0300 Subject: drm/i915/icl: Don't warn on spurious interrupts There is a chance we can see spurious interrupts in live now. We have more engines enabled and that with more elaborate access patterns with pm and display, increases the chances hardware just makes a social call, without anything to work on. Remove the error as we have tests to actually probe if we really miss interrupt, instead of getting spurious ones. Note that now we do write to intr_dw even with a zero value. This is considered advantegous as the write is an ack that sw is done. Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190410132124.21795-2-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index eb0eb96ac751..8d8935d71180 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3025,14 +3025,8 @@ gen11_gt_bank_handler(struct drm_i915_private * const i915, intr_dw = raw_reg_read(regs, GEN11_GT_INTR_DW(bank)); - if (unlikely(!intr_dw)) { - DRM_ERROR("GT_INTR_DW%u blank!\n", bank); - return; - } - for_each_set_bit(bit, &intr_dw, 32) { - const u32 ident = gen11_gt_engine_identity(i915, - bank, bit); + const u32 ident = gen11_gt_engine_identity(i915, bank, bit); gen11_gt_identity_handler(i915, ident); } -- cgit v1.2.3 From 20eea462bf2fbff3a4be375cc8424a544235a432 Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Mon, 25 Mar 2019 16:56:41 +0530 Subject: drm/i915/icl: Ungate ddi clocks before IO enable IO enable sequencing needs ddi clocks enabled. These clocks will be gated at a later point in the enable sequence. v2: Fix the commit header (Uma) v3: Remove the redundant read (Ville) Fixes: 949fc52af19e ("drm/i915/icl: add pll mapping for DSI") Signed-off-by: Vandita Kulkarni Reviewed-by: Uma Shankar Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1553513202-13863-1-git-send-email-vandita.kulkarni@intel.com (cherry picked from commit c5b81a325263a891d5811aabe938c87e03db4c37) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/icl_dsi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 83cd8284e807..43b7b80ffa21 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -598,6 +598,12 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder, val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port); } I915_WRITE(DPCLKA_CFGCR0_ICL, val); + + for_each_dsi_port(port, intel_dsi->ports) { + val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port); + } + I915_WRITE(DPCLKA_CFGCR0_ICL, val); + POSTING_READ(DPCLKA_CFGCR0_ICL); mutex_unlock(&dev_priv->dpll_lock); -- cgit v1.2.3 From 4690985e00ac38334d4a68f99c56ac310ef0527b Mon Sep 17 00:00:00 2001 From: Vandita Kulkarni Date: Mon, 25 Mar 2019 16:56:42 +0530 Subject: drm/i915/icl: Fix port disable sequence for mipi-dsi Re-enable clock gating of DDI clocks. v2: Fix the default ddi clk state for mipi-dsi (Imre) Fixes: 1026bea00381 ("drm/i915/icl: Ungate DSI clocks") Signed-off-by: Vandita Kulkarni Reviewed-by: Uma Shankar Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1553513202-13863-2-git-send-email-vandita.kulkarni@intel.com (cherry picked from commit 942d1cf48eae3fcd7e973cfb708d5c4860f0c713) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/icl_dsi.c | 2 +- drivers/gpu/drm/i915/intel_ddi.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 43b7b80ffa21..641e0778fa9c 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -1132,7 +1132,7 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder) DRM_ERROR("DDI port:%c buffer not idle\n", port_name(port)); } - gen11_dsi_ungate_clocks(encoder); + gen11_dsi_gate_clocks(encoder); } static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index deba8e90360a..ab4e60dfd6a3 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2824,10 +2824,10 @@ void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) return; } /* - * DSI ports should have their DDI clock ungated when disabled - * and gated when enabled. + * For DSI we keep the ddi clocks gated + * except during enable/disable sequence. */ - ddi_clk_needed = !encoder->base.crtc; + ddi_clk_needed = false; } val = I915_READ(DPCLKA_CFGCR0_ICL); -- cgit v1.2.3 From 21635d7311734d2d1b177f8a95e2f9386174b76d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 5 Apr 2019 10:52:20 +0300 Subject: drm/i915/dp: revert back to max link rate and lane count on eDP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 7769db588384 ("drm/i915/dp: optimize eDP 1.4+ link config fast and narrow") started to optize the eDP 1.4+ link config, both per spec and as preparation for display stream compression support. Sadly, we again face panels that flat out fail with parameters they claim to support. Revert, and go back to the drawing board. v2: Actually revert to max params instead of just wide-and-slow. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109959 Fixes: 7769db588384 ("drm/i915/dp: optimize eDP 1.4+ link config fast and narrow") Cc: Ville Syrjälä Cc: Manasi Navare Cc: Rodrigo Vivi Cc: Matt Atwood Cc: "Lee, Shawn C" Cc: Dave Airlie Cc: intel-gfx@lists.freedesktop.org Cc: # v5.0+ Reviewed-by: Rodrigo Vivi Reviewed-by: Manasi Navare Tested-by: Albert Astals Cid # v5.0 backport Tested-by: Emanuele Panigati # v5.0 backport Tested-by: Matteo Iervasi # v5.0 backport Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190405075220.9815-1-jani.nikula@intel.com (cherry picked from commit f11cb1c19ad0563b3c1ea5eb16a6bac0e401f428) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/intel_dp.c | 69 ++++++----------------------------------- 1 file changed, 10 insertions(+), 59 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cf709835fb9a..8891f29a8c7f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1859,42 +1859,6 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, return -EINVAL; } -/* Optimize link config in order: max bpp, min lanes, min clock */ -static int -intel_dp_compute_link_config_fast(struct intel_dp *intel_dp, - struct intel_crtc_state *pipe_config, - const struct link_config_limits *limits) -{ - struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; - int bpp, clock, lane_count; - int mode_rate, link_clock, link_avail; - - for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { - mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock, - bpp); - - for (lane_count = limits->min_lane_count; - lane_count <= limits->max_lane_count; - lane_count <<= 1) { - for (clock = limits->min_clock; clock <= limits->max_clock; clock++) { - link_clock = intel_dp->common_rates[clock]; - link_avail = intel_dp_max_data_rate(link_clock, - lane_count); - - if (mode_rate <= link_avail) { - pipe_config->lane_count = lane_count; - pipe_config->pipe_bpp = bpp; - pipe_config->port_clock = link_clock; - - return 0; - } - } - } - } - - return -EINVAL; -} - static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc) { int i, num_bpc; @@ -2031,15 +1995,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, limits.min_bpp = 6 * 3; limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); - if (intel_dp_is_edp(intel_dp) && intel_dp->edp_dpcd[0] < DP_EDP_14) { + if (intel_dp_is_edp(intel_dp)) { /* * Use the maximum clock and number of lanes the eDP panel - * advertizes being capable of. The eDP 1.3 and earlier panels - * are generally designed to support only a single clock and - * lane configuration, and typically these values correspond to - * the native resolution of the panel. With eDP 1.4 rate select - * and DSC, this is decreasingly the case, and we need to be - * able to select less than maximum link config. + * advertizes being capable of. The panels are generally + * designed to support only a single clock and lane + * configuration, and typically these values correspond to the + * native resolution of the panel. */ limits.min_lane_count = limits.max_lane_count; limits.min_clock = limits.max_clock; @@ -2053,22 +2015,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, intel_dp->common_rates[limits.max_clock], limits.max_bpp, adjusted_mode->crtc_clock); - if (intel_dp_is_edp(intel_dp)) - /* - * Optimize for fast and narrow. eDP 1.3 section 3.3 and eDP 1.4 - * section A.1: "It is recommended that the minimum number of - * lanes be used, using the minimum link rate allowed for that - * lane configuration." - * - * Note that we use the max clock and lane count for eDP 1.3 and - * earlier, and fast vs. wide is irrelevant. - */ - ret = intel_dp_compute_link_config_fast(intel_dp, pipe_config, - &limits); - else - /* Optimize for slow and wide. */ - ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, - &limits); + /* + * Optimize for slow and wide. This is the place to add alternative + * optimization policy. + */ + ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, &limits); /* enable compression if the mode doesn't fit available BW */ DRM_DEBUG_KMS("Force DSC en = %d\n", intel_dp->force_dsc_en); -- cgit v1.2.3 From feb8846b3a4f88c8807dbbb8176defd419371887 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Fri, 5 Apr 2019 15:48:21 -0700 Subject: drm/i915/dp: Expose force_dsc_enable through debugfs Currently we use force_dsc_enable to force DSC from IGT, but we dont expose this value to userspace through debugfs. This patch exposes this through the same dsc_fec_support debugfs node per connector so that we can restore its value back after the tests are completed. Suggested-by: Imre Deak Cc: Imre Deak Cc: Lyude Paul Cc: Anusha Srivatsa Signed-off-by: Manasi Navare Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20190405224821.32435-1-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4622afa22827..b88c62ea664d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4822,6 +4822,8 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data) yesno(crtc_state->dsc_params.compression_enable)); seq_printf(m, "DSC_Sink_Support: %s\n", yesno(drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd))); + seq_printf(m, "Force_DSC_Enable: %s\n", + yesno(intel_dp->force_dsc_en)); if (!intel_dp_is_edp(intel_dp)) seq_printf(m, "FEC_Sink_Support: %s\n", yesno(drm_dp_sink_supports_fec(intel_dp->fec_capable))); -- cgit v1.2.3 From 4825d8d6a0fe689bde668140600663f2c246e88f Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 8 Apr 2019 16:15:36 +0800 Subject: drm/amd/powerplay: optimization function of smu_update_table in fact, the firmware need 2 parameter: 1.table_id, 2.XferArg so change the function interface to match the firmware code Signed-off-by: Kevin Wang Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 7 +++++-- drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c index 7e8c74da6a74..c058c784180e 100644 --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -97,16 +97,19 @@ int smu_common_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, return ret; } -int smu_update_table(struct smu_context *smu, uint32_t table_id, +int smu_update_table_with_arg(struct smu_context *smu, uint16_t table_id, uint16_t exarg, void *table_data, bool drv2smu) { struct smu_table_context *smu_table = &smu->smu_table; struct smu_table *table = NULL; int ret = 0; + uint32_t table_index; if (!table_data || table_id >= smu_table->table_count) return -EINVAL; + table_index = (exarg << 16) | table_id; + table = &smu_table->tables[table_id]; if (drv2smu) @@ -123,7 +126,7 @@ int smu_update_table(struct smu_context *smu, uint32_t table_id, ret = smu_send_smc_msg_with_param(smu, drv2smu ? SMU_MSG_TransferTableDram2Smu : SMU_MSG_TransferTableSmu2Dram, - table_id); + table_index); if (ret) return ret; diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index 2083139533e9..c146b5e884f8 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -745,8 +745,11 @@ extern int smu_feature_set_enabled(struct smu_context *smu, int feature_id, bool extern int smu_feature_is_supported(struct smu_context *smu, int feature_id); extern int smu_feature_set_supported(struct smu_context *smu, int feature_id, bool enable); -int smu_update_table(struct smu_context *smu, uint32_t table_id, +int smu_update_table_with_arg(struct smu_context *smu, uint16_t table_id, uint16_t exarg, void *table_data, bool drv2smu); +#define smu_update_table(smu, table_id, table_data, drv2smu) \ + smu_update_table_with_arg((smu), (table_id), 0, (table_data), (drv2smu)) + bool is_support_sw_smu(struct amdgpu_device *adev); int smu_reset(struct smu_context *smu); int smu_common_read_sensor(struct smu_context *smu, enum amd_pp_sensors sensor, -- cgit v1.2.3 From 0e4f087ba2fe598a0add8b7cb2a3720e31ace1ed Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Mon, 8 Apr 2019 16:29:49 +0800 Subject: drm/amd/powerplay: simplify the code of [get|set]_activity_monitor_coeff use smu_update_table_with_arg to replace old code logic Signed-off-by: Kevin Wang Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 6 --- drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 75 +++----------------------- 2 files changed, 7 insertions(+), 74 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index c146b5e884f8..26a7d2c7f4fa 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -524,12 +524,6 @@ struct smu_funcs struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges); int (*set_od8_default_settings)(struct smu_context *smu, bool initialize); - int (*get_activity_monitor_coeff)(struct smu_context *smu, - uint8_t *table, - uint16_t workload_type); - int (*set_activity_monitor_coeff)(struct smu_context *smu, - uint8_t *table, - uint16_t workload_type); int (*conv_power_profile_to_pplib_workload)(int power_profile); int (*get_power_profile_mode)(struct smu_context *smu, char *buf); int (*set_power_profile_mode)(struct smu_context *smu, long *input, uint32_t size); diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index 0e4b4b88af24..d2e2a4e2d0eb 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -1460,62 +1460,6 @@ static int smu_v11_0_set_od8_default_settings(struct smu_context *smu, return 0; } -static int smu_v11_0_set_activity_monitor_coeff(struct smu_context *smu, - uint8_t *table, uint16_t workload_type) -{ - int ret = 0; - memcpy(smu->smu_table.tables[TABLE_ACTIVITY_MONITOR_COEFF].cpu_addr, - table, smu->smu_table.tables[TABLE_ACTIVITY_MONITOR_COEFF].size); - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrHigh, - upper_32_bits(smu->smu_table.tables[TABLE_ACTIVITY_MONITOR_COEFF].mc_address)); - if (ret) { - pr_err("[%s] Attempt to Set Dram Addr High Failed!", __func__); - return ret; - } - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrLow, - lower_32_bits(smu->smu_table.tables[TABLE_ACTIVITY_MONITOR_COEFF].mc_address)); - if (ret) { - pr_err("[%s] Attempt to Set Dram Addr Low Failed!", __func__); - return ret; - } - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_TransferTableSmu2Dram, - TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16)); - if (ret) { - pr_err("[%s] Attempt to Transfer Table From SMU Failed!", __func__); - return ret; - } - - return ret; -} - -static int smu_v11_0_get_activity_monitor_coeff(struct smu_context *smu, - uint8_t *table, uint16_t workload_type) -{ - int ret = 0; - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrHigh, - upper_32_bits(smu->smu_table.tables[TABLE_ACTIVITY_MONITOR_COEFF].mc_address)); - if (ret) { - pr_err("[%s] Attempt to Set Dram Addr High Failed!", __func__); - return ret; - } - - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetDriverDramAddrLow, - lower_32_bits(smu->smu_table.tables[TABLE_ACTIVITY_MONITOR_COEFF].mc_address)); - if (ret) { - pr_err("[%s] Attempt to Set Dram Addr Low Failed!", __func__); - return ret; - } - - ret = smu_send_smc_msg_with_param(smu, SMU_MSG_TransferTableSmu2Dram, - TABLE_ACTIVITY_MONITOR_COEFF | (workload_type << 16)); - if (ret) { - pr_err("[%s] Attempt to Transfer Table From SMU Failed!", __func__); - return ret; - } - - return ret; -} - static int smu_v11_0_conv_power_profile_to_pplib_workload(int power_profile) { int pplib_workload = 0; @@ -1584,9 +1528,8 @@ static int smu_v11_0_get_power_profile_mode(struct smu_context *smu, char *buf) for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ workload_type = smu_v11_0_conv_power_profile_to_pplib_workload(i); - result = smu_v11_0_get_activity_monitor_coeff(smu, - (uint8_t *)(&activity_monitor), - workload_type); + result = smu_update_table_with_arg(smu, TABLE_ACTIVITY_MONITOR_COEFF, + workload_type, &activity_monitor, false); if (result) { pr_err("[%s] Failed to get activity monitor!", __func__); return result; @@ -1658,7 +1601,7 @@ static int smu_v11_0_get_power_profile_mode(struct smu_context *smu, char *buf) static int smu_v11_0_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) { DpmActivityMonitorCoeffInt_t activity_monitor; - int workload_type, ret = 0; + int workload_type = 0, ret = 0; smu->power_profile_mode = input[size]; @@ -1668,9 +1611,8 @@ static int smu_v11_0_set_power_profile_mode(struct smu_context *smu, long *input } if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { - ret = smu_v11_0_get_activity_monitor_coeff(smu, - (uint8_t *)(&activity_monitor), - WORKLOAD_PPLIB_CUSTOM_BIT); + ret = smu_update_table_with_arg(smu, TABLE_ACTIVITY_MONITOR_COEFF, + WORKLOAD_PPLIB_CUSTOM_BIT, &activity_monitor, false); if (ret) { pr_err("[%s] Failed to get activity monitor!", __func__); return ret; @@ -1723,9 +1665,8 @@ static int smu_v11_0_set_power_profile_mode(struct smu_context *smu, long *input break; } - ret = smu_v11_0_set_activity_monitor_coeff(smu, - (uint8_t *)(&activity_monitor), - WORKLOAD_PPLIB_CUSTOM_BIT); + ret = smu_update_table_with_arg(smu, TABLE_ACTIVITY_MONITOR_COEFF, + WORKLOAD_PPLIB_COMPUTE_BIT, &activity_monitor, true); if (ret) { pr_err("[%s] Failed to set activity monitor!", __func__); return ret; @@ -1994,8 +1935,6 @@ static const struct smu_funcs smu_v11_0_funcs = { .get_sclk = smu_v11_0_dpm_get_sclk, .get_mclk = smu_v11_0_dpm_get_mclk, .set_od8_default_settings = smu_v11_0_set_od8_default_settings, - .get_activity_monitor_coeff = smu_v11_0_get_activity_monitor_coeff, - .set_activity_monitor_coeff = smu_v11_0_set_activity_monitor_coeff, .conv_power_profile_to_pplib_workload = smu_v11_0_conv_power_profile_to_pplib_workload, .get_power_profile_mode = smu_v11_0_get_power_profile_mode, .set_power_profile_mode = smu_v11_0_set_power_profile_mode, -- cgit v1.2.3 From 191051a1bef8257313d4bc4eafbf201e35e135e7 Mon Sep 17 00:00:00 2001 From: xinhui pan Date: Wed, 3 Apr 2019 09:52:59 +0800 Subject: drm/amdgpu: Make default ras error type to none Unless IP has implemented its own ras, use ERROR_NONE as the default type. Signed-off-by: xinhui pan Reviewed-by: Alex Deucher Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 469cb6477b8e..a0e34f62f110 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -558,11 +558,13 @@ static int amdgpu_ras_enable_all_features(struct amdgpu_device *adev, struct amdgpu_ras *con = amdgpu_ras_get_context(adev); int ras_block_count = AMDGPU_RAS_BLOCK_COUNT; int i; + const enum amdgpu_ras_error_type default_ras_type = + AMDGPU_RAS_ERROR__NONE; for (i = 0; i < ras_block_count; i++) { struct ras_common_if head = { .block = i, - .type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE, + .type = default_ras_type, .sub_block_index = 0, }; strcpy(head.name, ras_block_str(i)); @@ -1368,9 +1370,6 @@ int amdgpu_ras_init(struct amdgpu_device *adev) amdgpu_ras_mask &= AMDGPU_RAS_BLOCK_MASK; - if (con->flags & AMDGPU_RAS_FLAG_INIT_BY_VBIOS) - amdgpu_ras_enable_all_features(adev, 1); - if (amdgpu_ras_fs_init(adev)) goto fs_out; @@ -1398,18 +1397,25 @@ void amdgpu_ras_post_init(struct amdgpu_device *adev) if (!con) return; - /* We enable ras on all hw_supported block, but as boot parameter might - * disable some of them and one or more IP has not implemented yet. - * So we disable them on behalf. - */ if (con->flags & AMDGPU_RAS_FLAG_INIT_BY_VBIOS) { + /* Set up all other IPs which are not implemented. There is a + * tricky thing that IP's actual ras error type should be + * MULTI_UNCORRECTABLE, but as driver does not handle it, so + * ERROR_NONE make sense anyway. + */ + amdgpu_ras_enable_all_features(adev, 1); + + /* We enable ras on all hw_supported block, but as boot + * parameter might disable some of them and one or more IP has + * not implemented yet. So we disable them on behalf. + */ list_for_each_entry_safe(obj, tmp, &con->head, node) { if (!amdgpu_ras_is_supported(adev, obj->head.block)) { amdgpu_ras_feature_enable(adev, &obj->head, 0); /* there should be no any reference. */ WARN_ON(alive_obj(obj)); } - }; + } } } -- cgit v1.2.3 From 77de502b088fa4b9ed8060085d0c2d49b2e0a306 Mon Sep 17 00:00:00 2001 From: xinhui pan Date: Mon, 8 Apr 2019 14:49:37 +0800 Subject: drm/amdgpu: Introduce another ras enable function Many parts of the whole SW stack can program the ras enablement state during the boot. Now we handle that case by adding one function which check the ras flags and choose different code path. Reviewed-by: Evan Quan Signed-off-by: xinhui pan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 27 +++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 3 +++ 2 files changed, 30 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index a0e34f62f110..22bd21efe6b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -530,6 +530,33 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, return 0; } +/* Only used in device probe stage and called only once. */ +int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev, + struct ras_common_if *head, bool enable) +{ + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + int ret; + + if (!con) + return -EINVAL; + + if (con->flags & AMDGPU_RAS_FLAG_INIT_BY_VBIOS) { + /* If ras is enabled by vbios, we set up ras object first in + * both case. For enable, that is all what we need do. For + * disable, we need perform a ras TA disable cmd after that. + */ + ret = __amdgpu_ras_feature_enable(adev, head, 1); + if (ret) + return ret; + + if (!enable) + ret = amdgpu_ras_feature_enable(adev, head, 0); + } else + ret = amdgpu_ras_feature_enable(adev, head, enable); + + return ret; +} + static int amdgpu_ras_disable_all_features(struct amdgpu_device *adev, bool bypass) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h index 682f2be0d68c..eaef5edefc34 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h @@ -262,6 +262,9 @@ int amdgpu_ras_pre_fini(struct amdgpu_device *adev); int amdgpu_ras_feature_enable(struct amdgpu_device *adev, struct ras_common_if *head, bool enable); +int amdgpu_ras_feature_enable_on_boot(struct amdgpu_device *adev, + struct ras_common_if *head, bool enable); + int amdgpu_ras_sysfs_create(struct amdgpu_device *adev, struct ras_fs_if *head); -- cgit v1.2.3 From a170d49d084da50b98b840d4cea506559823cb54 Mon Sep 17 00:00:00 2001 From: xinhui pan Date: Mon, 8 Apr 2019 14:55:45 +0800 Subject: drm/amdgpu: gfx use amdgpu_ras_feature_enable_on_boot handle ras enable on boot. Signed-off-by: xinhui pan Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 3765d97b8512..58f5b1015de1 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -3568,7 +3568,7 @@ static int gfx_v9_0_ecc_late_init(void *handle) int r; if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) { - amdgpu_ras_feature_enable(adev, &ras_block, 0); + amdgpu_ras_feature_enable_on_boot(adev, &ras_block, 0); return 0; } @@ -3581,7 +3581,7 @@ static int gfx_v9_0_ecc_late_init(void *handle) **ras_if = ras_block; - r = amdgpu_ras_feature_enable(adev, *ras_if, 1); + r = amdgpu_ras_feature_enable_on_boot(adev, *ras_if, 1); if (r) goto feature; -- cgit v1.2.3 From 53d650548c386f1e9f246b05c40a1960dae37437 Mon Sep 17 00:00:00 2001 From: xinhui pan Date: Mon, 8 Apr 2019 14:56:46 +0800 Subject: drm/amdgpu: gmc use amdgpu_ras_feature_enable_on_boot handle ras enable on boot. Signed-off-by: xinhui pan Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 404875147ec3..f7de53335804 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -676,7 +676,7 @@ static int gmc_v9_0_ecc_late_init(void *handle) int r; if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) { - amdgpu_ras_feature_enable(adev, &ras_block, 0); + amdgpu_ras_feature_enable_on_boot(adev, &ras_block, 0); return 0; } /* handle resume path. */ @@ -689,7 +689,7 @@ static int gmc_v9_0_ecc_late_init(void *handle) **ras_if = ras_block; - r = amdgpu_ras_feature_enable(adev, *ras_if, 1); + r = amdgpu_ras_feature_enable_on_boot(adev, *ras_if, 1); if (r) goto feature; -- cgit v1.2.3 From 7dd609da9b4e8bc4a5725392c3e528ad65cfe100 Mon Sep 17 00:00:00 2001 From: xinhui pan Date: Mon, 8 Apr 2019 14:57:28 +0800 Subject: drm/amdgpu: sdma use amdgpu_ras_feature_enable_on_boot handle ras enable on boot. Signed-off-by: xinhui pan Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index e858043a3a0e..31d5b3fdd5cd 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -1518,7 +1518,7 @@ static int sdma_v4_0_late_init(void *handle) int r; if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) { - amdgpu_ras_feature_enable(adev, &ras_block, 0); + amdgpu_ras_feature_enable_on_boot(adev, &ras_block, 0); return 0; } @@ -1532,7 +1532,7 @@ static int sdma_v4_0_late_init(void *handle) **ras_if = ras_block; - r = amdgpu_ras_feature_enable(adev, *ras_if, 1); + r = amdgpu_ras_feature_enable_on_boot(adev, *ras_if, 1); if (r) goto feature; -- cgit v1.2.3 From 14cfde84e33e0c5bbb8c30e0c309c29e92d4118a Mon Sep 17 00:00:00 2001 From: xinhui pan Date: Tue, 9 Apr 2019 16:53:08 +0800 Subject: drm/amdgpu: Add a check to avoid panic because of unexpected irqs IP initialize ras in late_init, because of the BUGs of PSP or any other components, driver receives unexpected irqs. It is ok to add such check anyway. Signed-off-by: xinhui pan Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 8 +++++++- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 8 +++++++- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 58f5b1015de1..107756dd1b25 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -4840,10 +4840,16 @@ static int gfx_v9_0_cp_ecc_error_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { + struct ras_common_if *ras_if = adev->gfx.ras_if; struct ras_dispatch_if ih_data = { - .head = *adev->gfx.ras_if, .entry = entry, }; + + if (!ras_if) + return 0; + + ih_data.head = *ras_if; + DRM_ERROR("CP ECC ERROR IRQ\n"); amdgpu_ras_interrupt_dispatch(adev, &ih_data); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index f7de53335804..3fd79e07944d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -248,10 +248,16 @@ static int gmc_v9_0_process_ecc_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { + struct ras_common_if *ras_if = adev->gmc.ras_if; struct ras_dispatch_if ih_data = { - .head = *adev->gmc.ras_if, .entry = entry, }; + + if (!ras_if) + return 0; + + ih_data.head = *ras_if; + amdgpu_ras_interrupt_dispatch(adev, &ih_data); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 31d5b3fdd5cd..1ec60f54b992 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -1865,10 +1865,16 @@ static int sdma_v4_0_process_ecc_irq(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { + struct ras_common_if *ras_if = adev->sdma.ras_if; struct ras_dispatch_if ih_data = { - .head = *adev->sdma.ras_if, .entry = entry, }; + + if (!ras_if) + return 0; + + ih_data.head = *ras_if; + amdgpu_ras_interrupt_dispatch(adev, &ih_data); return 0; } -- cgit v1.2.3 From b0960c3592a39f1cc6fcab1793158f3850f72c77 Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Mon, 8 Apr 2019 18:28:22 -0400 Subject: drm/amdgpu: Always enable memory sharing within same XGMI hive XGMI Memory sharing will be disbaled by default for security reason after boot up, it depends on driver to enable the memory sharing Signed-off-by: shaoyunl Acked-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 2b3429d90690..b91df7bd1d98 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -674,7 +674,7 @@ static int psp_v11_0_xgmi_set_topology_info(struct psp_context *psp, for (i = 0; i < topology_info_input->num_nodes; i++) { topology_info_input->nodes[i].node_id = topology->nodes[i].node_id; topology_info_input->nodes[i].num_hops = topology->nodes[i].num_hops; - topology_info_input->nodes[i].is_sharing_enabled = topology->nodes[i].is_sharing_enabled; + topology_info_input->nodes[i].is_sharing_enabled = 1; topology_info_input->nodes[i].sdma_engine = topology->nodes[i].sdma_engine; } -- cgit v1.2.3 From bb5a2bdf36a8df79e1437b443299b7fe1ea3abfc Mon Sep 17 00:00:00 2001 From: Yintian Tao Date: Tue, 9 Apr 2019 20:33:20 +0800 Subject: drm/amdgpu: support dpm level modification under virtualization v3 Under vega10 virtualuzation, smu ip block will not be added. Therefore, we need add pp clk query and force dpm level function at amdgpu_virt_ops to support the feature. v2: add get_pp_clk existence check and use kzalloc to allocate buf v3: return -ENOMEM for allocation failure and correct the coding style Signed-off-by: Yintian Tao Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 16 ++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 49 +++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 11 +++++ drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c | 78 ++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h | 6 +++ 7 files changed, 165 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7cee269ec3e3..3f08be7a913e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2471,6 +2471,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->virt.vf_errors.lock); hash_init(adev->mn_hash); mutex_init(&adev->lock_reset); + mutex_init(&adev->virt.dpm_mutex); amdgpu_device_check_arguments(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 2e376064bad8..b17d0545728e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -696,6 +696,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file if (adev->pm.dpm_enabled) { dev_info.max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10; dev_info.max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10; + } else if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) && + adev->virt.ops->get_pp_clk) { + dev_info.max_engine_clock = amdgpu_virt_get_sclk(adev, false) * 10; + dev_info.max_memory_clock = amdgpu_virt_get_mclk(adev, false) * 10; } else { dev_info.max_engine_clock = adev->clock.default_sclk * 10; dev_info.max_memory_clock = adev->clock.default_mclk * 10; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 88362019d1dd..4b7a076eea9c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -327,6 +327,18 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, goto fail; } + if (amdgpu_sriov_vf(adev)) { + if (amdgim_is_hwperf(adev) && + adev->virt.ops->force_dpm_level) { + mutex_lock(&adev->pm.mutex); + adev->virt.ops->force_dpm_level(adev, level); + mutex_unlock(&adev->pm.mutex); + return count; + } else { + return -EINVAL; + } + } + if (current_level == level) return count; @@ -790,6 +802,10 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = ddev->dev_private; + if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) && + adev->virt.ops->get_pp_clk) + return adev->virt.ops->get_pp_clk(adev, PP_SCLK, buf); + if (is_support_sw_smu(adev)) return smu_print_clk_levels(&adev->smu, PP_SCLK, buf); else if (adev->powerplay.pp_funcs->print_clock_levels) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 462a04e0f5e6..7e7f9ed89ee1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -375,4 +375,53 @@ void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev) } } +static uint32_t parse_clk(char *buf, bool min) +{ + char *ptr = buf; + uint32_t clk = 0; + + do { + ptr = strchr(ptr, ':'); + if (!ptr) + break; + ptr+=2; + clk = simple_strtoul(ptr, NULL, 10); + } while (!min); + + return clk * 100; +} + +uint32_t amdgpu_virt_get_sclk(struct amdgpu_device *adev, bool lowest) +{ + char *buf = NULL; + uint32_t clk = 0; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + adev->virt.ops->get_pp_clk(adev, PP_SCLK, buf); + clk = parse_clk(buf, lowest); + + kfree(buf); + + return clk; +} + +uint32_t amdgpu_virt_get_mclk(struct amdgpu_device *adev, bool lowest) +{ + char *buf = NULL; + uint32_t clk = 0; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + adev->virt.ops->get_pp_clk(adev, PP_MCLK, buf); + clk = parse_clk(buf, lowest); + + kfree(buf); + + return clk; +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h index 722deefc0a7e..584947b7ccf3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h @@ -57,6 +57,8 @@ struct amdgpu_virt_ops { int (*reset_gpu)(struct amdgpu_device *adev); int (*wait_reset)(struct amdgpu_device *adev); void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); + int (*get_pp_clk)(struct amdgpu_device *adev, u32 type, char *buf); + int (*force_dpm_level)(struct amdgpu_device *adev, u32 level); }; /* @@ -83,6 +85,8 @@ enum AMDGIM_FEATURE_FLAG { AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2, /* VRAM LOST by GIM */ AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4, + /* HW PERF SIM in GIM */ + AMDGIM_FEATURE_HW_PERF_SIMULATION = (1 << 3), }; struct amd_sriov_msg_pf2vf_info_header { @@ -252,6 +256,8 @@ struct amdgpu_virt { struct amdgpu_vf_error_buffer vf_errors; struct amdgpu_virt_fw_reserve fw_reserve; uint32_t gim_feature; + /* protect DPM events to GIM */ + struct mutex dpm_mutex; }; #define amdgpu_sriov_enabled(adev) \ @@ -278,6 +284,9 @@ static inline bool is_virtual_machine(void) #endif } +#define amdgim_is_hwperf(adev) \ + ((adev)->virt.gim_feature & AMDGIM_FEATURE_HW_PERF_SIMULATION) + bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev); void amdgpu_virt_init_setting(struct amdgpu_device *adev); uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); @@ -295,5 +304,7 @@ int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size, unsigned int key, unsigned int chksum); void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); +uint32_t amdgpu_virt_get_sclk(struct amdgpu_device *adev, bool lowest); +uint32_t amdgpu_virt_get_mclk(struct amdgpu_device *adev, bool lowest); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c index 73851ebb3833..8dbad496b29f 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c @@ -157,6 +157,82 @@ static void xgpu_ai_mailbox_trans_msg (struct amdgpu_device *adev, xgpu_ai_mailbox_set_valid(adev, false); } +static int xgpu_ai_get_pp_clk(struct amdgpu_device *adev, u32 type, char *buf) +{ + int r = 0; + u32 req, val, size; + + if (!amdgim_is_hwperf(adev) || buf == NULL) + return -EBADRQC; + + switch(type) { + case PP_SCLK: + req = IDH_IRQ_GET_PP_SCLK; + break; + case PP_MCLK: + req = IDH_IRQ_GET_PP_MCLK; + break; + default: + return -EBADRQC; + } + + mutex_lock(&adev->virt.dpm_mutex); + + xgpu_ai_mailbox_trans_msg(adev, req, 0, 0, 0); + + r = xgpu_ai_poll_msg(adev, IDH_SUCCESS); + if (!r && adev->fw_vram_usage.va != NULL) { + val = RREG32_NO_KIQ( + SOC15_REG_OFFSET(NBIO, 0, + mmBIF_BX_PF0_MAILBOX_MSGBUF_RCV_DW1)); + size = strnlen((((char *)adev->virt.fw_reserve.p_pf2vf) + + val), PAGE_SIZE); + + if (size < PAGE_SIZE) + strcpy(buf,((char *)adev->virt.fw_reserve.p_pf2vf + val)); + else + size = 0; + + r = size; + goto out; + } + + r = xgpu_ai_poll_msg(adev, IDH_FAIL); + if(r) + pr_info("%s DPM request failed", + (type == PP_SCLK)? "SCLK" : "MCLK"); + +out: + mutex_unlock(&adev->virt.dpm_mutex); + return r; +} + +static int xgpu_ai_force_dpm_level(struct amdgpu_device *adev, u32 level) +{ + int r = 0; + u32 req = IDH_IRQ_FORCE_DPM_LEVEL; + + if (!amdgim_is_hwperf(adev)) + return -EBADRQC; + + mutex_lock(&adev->virt.dpm_mutex); + xgpu_ai_mailbox_trans_msg(adev, req, level, 0, 0); + + r = xgpu_ai_poll_msg(adev, IDH_SUCCESS); + if (!r) + goto out; + + r = xgpu_ai_poll_msg(adev, IDH_FAIL); + if (!r) + pr_info("DPM request failed"); + else + pr_info("Mailbox is broken"); + +out: + mutex_unlock(&adev->virt.dpm_mutex); + return r; +} + static int xgpu_ai_send_access_requests(struct amdgpu_device *adev, enum idh_request req) { @@ -375,4 +451,6 @@ const struct amdgpu_virt_ops xgpu_ai_virt_ops = { .reset_gpu = xgpu_ai_request_reset, .wait_reset = NULL, .trans_msg = xgpu_ai_mailbox_trans_msg, + .get_pp_clk = xgpu_ai_get_pp_clk, + .force_dpm_level = xgpu_ai_force_dpm_level, }; diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h index b4a9ceea334b..39d151b79153 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h @@ -35,6 +35,10 @@ enum idh_request { IDH_REL_GPU_FINI_ACCESS, IDH_REQ_GPU_RESET_ACCESS, + IDH_IRQ_FORCE_DPM_LEVEL = 10, + IDH_IRQ_GET_PP_SCLK, + IDH_IRQ_GET_PP_MCLK, + IDH_LOG_VF_ERROR = 200, }; @@ -43,6 +47,8 @@ enum idh_event { IDH_READY_TO_ACCESS_GPU, IDH_FLR_NOTIFICATION, IDH_FLR_NOTIFICATION_CMPL, + IDH_SUCCESS, + IDH_FAIL, IDH_EVENT_MAX }; -- cgit v1.2.3 From 3d12beb319c4efa18d55454096cc523108320d17 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 25 Mar 2019 15:27:01 -0400 Subject: drm/amd/display: Remove semicolon from to_dm_plane_state definition The extra ; in the macro definition creates an empty statement preventing any variable declarations from occuring after any use of to_dm_plane_state(...). Signed-off-by: Nicholas Kazlauskas Reviewed-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index add238fe4b57..2e9e3db778c6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -58,7 +58,7 @@ struct amdgpu_hpd; #define to_amdgpu_encoder(x) container_of(x, struct amdgpu_encoder, base) #define to_amdgpu_framebuffer(x) container_of(x, struct amdgpu_framebuffer, base) -#define to_dm_plane_state(x) container_of(x, struct dm_plane_state, base); +#define to_dm_plane_state(x) container_of(x, struct dm_plane_state, base) #define AMDGPU_MAX_HPD_PINS 6 #define AMDGPU_MAX_CRTCS 6 -- cgit v1.2.3 From 2aa632c5ffbedb2ee0e68857683466ea788f17eb Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 22 Mar 2019 09:59:32 -0400 Subject: drm/amd/display: Initialize stream_update with memset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The brace initialization used here generates warnings on some compilers. For example, on GCC 4.9: [...] In function ‘dm_determine_update_type_for_commit’: [...] error: missing braces around initializer [-Werror=missing-braces] struct dc_stream_update stream_update = { 0 }; ^ Use memset to make this more portable. v2: Specify the compiler / diagnostic in the commit message (Paul) Cc: Sun peng Li Cc: Harry Wentland Signed-off-by: Nicholas Kazlauskas Reviewed-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f2312f022b46..06f58cd9e984 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6123,7 +6123,9 @@ dm_determine_update_type_for_commit(struct dc *dc, } for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - struct dc_stream_update stream_update = { 0 }; + struct dc_stream_update stream_update; + + memset(&stream_update, 0, sizeof(stream_update)); new_dm_crtc_state = to_dm_crtc_state(new_crtc_state); old_dm_crtc_state = to_dm_crtc_state(old_crtc_state); -- cgit v1.2.3 From b62f95d1625100edfa473387fc250d666cf05998 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 22 Mar 2019 10:11:14 -0400 Subject: drm/amd/display: Add debugfs entry for amdgpu_dm_visual_confirm [Why] DC provides a few visual confirmation debug options that can be dynamically changed at runtime to help debug surface programming issues but we don't have any way to access it from userspace. [How] Add the amdgpu_dm_visual_confirm debugfs entry. It accepts a string containing the DC visual confirm enum value using the debugfs attribute helpers. The debugfs_create_file_unsafe can be used instead of debugfs_create_file as per the documentation. v2: Use debugfs helpers for getting and setting the value (Christian) Cc: Leo Li Cc: Harry Wentland Signed-off-by: Nicholas Kazlauskas Reviewed-by: Leo Li Signed-off-by: Alex Deucher --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 39 +++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 1a9e3d3dfa38..1d5fc5ad3bee 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -995,6 +995,35 @@ static const struct drm_info_list amdgpu_dm_debugfs_list[] = { {"amdgpu_target_backlight_pwm", &target_backlight_read}, }; +/* + * Sets the DC visual confirm debug option from the given string. + * Example usage: echo 1 > /sys/kernel/debug/dri/0/amdgpu_visual_confirm + */ +static int visual_confirm_set(void *data, u64 val) +{ + struct amdgpu_device *adev = data; + + adev->dm.dc->debug.visual_confirm = (enum visual_confirm)val; + + return 0; +} + +/* + * Reads the DC visual confirm debug option value into the given buffer. + * Example usage: cat /sys/kernel/debug/dri/0/amdgpu_dm_visual_confirm + */ +static int visual_confirm_get(void *data, u64 *val) +{ + struct amdgpu_device *adev = data; + + *val = adev->dm.dc->debug.visual_confirm; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(visual_confirm_fops, visual_confirm_get, + visual_confirm_set, "%llu\n"); + int dtn_debugfs_init(struct amdgpu_device *adev) { static const struct file_operations dtn_log_fops = { @@ -1020,5 +1049,13 @@ int dtn_debugfs_init(struct amdgpu_device *adev) adev, &dtn_log_fops); - return PTR_ERR_OR_ZERO(ent); + if (IS_ERR(ent)) + return PTR_ERR(ent); + + ent = debugfs_create_file_unsafe("amdgpu_dm_visual_confirm", 0644, root, + adev, &visual_confirm_fops); + if (IS_ERR(ent)) + return PTR_ERR(ent); + + return 0; } -- cgit v1.2.3 From e5490464f45db8b8006bc62d29ec9280debd0ef9 Mon Sep 17 00:00:00 2001 From: SivapiriyanKumarasamy Date: Tue, 19 Mar 2019 15:21:50 -0400 Subject: drm/amd/display: fix dp_hdmi_max_pixel_clk units [Why] We are incorrectly using dp_hdmi_max_pixel_clk because the units are not clear. [How] Rename to dp_hdmi_max_pixel_clk_in_khz, and change mode timing validation to use the value correctly. Signed-off-by: SivapiriyanKumarasamy Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 6 +++--- drivers/gpu/drm/amd/display/dc/dc_types.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index b39f76e61039..2f0117ceaafc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2150,7 +2150,7 @@ static bool dp_active_dongle_validate_timing( return false; } - if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk * 10)) + if (get_timing_pixel_clock_100hz(timing) > (dongle_caps->dp_hdmi_max_pixel_clk_in_khz * 10)) return false; return true; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 063d019a3f6f..528c9625b5c0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2304,8 +2304,8 @@ static void get_active_converter_info( hdmi_caps = {.raw = det_caps[3] }; union dwnstream_port_caps_byte2 hdmi_color_caps = {.raw = det_caps[2] }; - link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk = - det_caps[1] * 25000; + link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz = + det_caps[1] * 2500; link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter = hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK; @@ -2322,7 +2322,7 @@ static void get_active_converter_info( translate_dpcd_max_bpc( hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT); - if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk != 0) + if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0) link->dpcd_caps.dongle_caps.extendedCapValid = true; } diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index c8e2dc5ec62a..6c2a3d9a4c2e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -395,7 +395,7 @@ struct dc_dongle_caps { bool is_dp_hdmi_ycbcr422_converter; bool is_dp_hdmi_ycbcr420_converter; uint32_t dp_hdmi_max_bpc; - uint32_t dp_hdmi_max_pixel_clk; + uint32_t dp_hdmi_max_pixel_clk_in_khz; }; /* Scaling format */ enum scaling_transformation { -- cgit v1.2.3 From e49f69363adf8920883fff7e8ffecb802d897c6b Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Thu, 21 Mar 2019 13:05:36 -0400 Subject: drm/amd/display: use proper formula to calculate bandwidth from timing [why] The existing calculation uses a wrong formula to calculate bandwidth from timing. [how] Expose the existing proper function that calculates the bandwidth, so dc_link can use it to calculate timing bandwidth correctly. Signed-off-by: Wenjing Liu Reviewed-by: Jun Lei Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 48 +++++++++++++++++++++- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 51 +----------------------- drivers/gpu/drm/amd/display/dc/dc_link.h | 2 + 3 files changed, 51 insertions(+), 50 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 2f0117ceaafc..abf611538153 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2321,7 +2321,7 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx) uint32_t denominator; bpc = get_color_depth(pipe_ctx->stream_res.pix_clk_params.color_depth); - kbps = pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10 * bpc * 3; + kbps = dc_bandwidth_in_kbps_from_timing(&pipe_ctx->stream->timing); /* * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 @@ -2736,3 +2736,49 @@ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable) } } +uint32_t dc_bandwidth_in_kbps_from_timing( + const struct dc_crtc_timing *timing) +{ + uint32_t bits_per_channel = 0; + uint32_t kbps; + + switch (timing->display_color_depth) { + case COLOR_DEPTH_666: + bits_per_channel = 6; + break; + case COLOR_DEPTH_888: + bits_per_channel = 8; + break; + case COLOR_DEPTH_101010: + bits_per_channel = 10; + break; + case COLOR_DEPTH_121212: + bits_per_channel = 12; + break; + case COLOR_DEPTH_141414: + bits_per_channel = 14; + break; + case COLOR_DEPTH_161616: + bits_per_channel = 16; + break; + default: + break; + } + + ASSERT(bits_per_channel != 0); + + kbps = timing->pix_clk_100hz / 10; + kbps *= bits_per_channel; + + if (timing->flags.Y_ONLY != 1) { + /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/ + kbps *= 3; + if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + kbps /= 2; + else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) + kbps = kbps * 2 / 3; + } + + return kbps; + +} diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 528c9625b5c0..491d13d27e9e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1533,53 +1533,6 @@ static bool decide_fallback_link_setting( return true; } -static uint32_t bandwidth_in_kbps_from_timing( - const struct dc_crtc_timing *timing) -{ - uint32_t bits_per_channel = 0; - uint32_t kbps; - - switch (timing->display_color_depth) { - case COLOR_DEPTH_666: - bits_per_channel = 6; - break; - case COLOR_DEPTH_888: - bits_per_channel = 8; - break; - case COLOR_DEPTH_101010: - bits_per_channel = 10; - break; - case COLOR_DEPTH_121212: - bits_per_channel = 12; - break; - case COLOR_DEPTH_141414: - bits_per_channel = 14; - break; - case COLOR_DEPTH_161616: - bits_per_channel = 16; - break; - default: - break; - } - - ASSERT(bits_per_channel != 0); - - kbps = timing->pix_clk_100hz / 10; - kbps *= bits_per_channel; - - if (timing->flags.Y_ONLY != 1) { - /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/ - kbps *= 3; - if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) - kbps /= 2; - else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) - kbps = kbps * 2 / 3; - } - - return kbps; - -} - static uint32_t bandwidth_in_kbps_from_link_settings( const struct dc_link_settings *link_setting) { @@ -1620,7 +1573,7 @@ bool dp_validate_mode_timing( link_setting = &link->verified_link_cap; */ - req_bw = bandwidth_in_kbps_from_timing(timing); + req_bw = dc_bandwidth_in_kbps_from_timing(timing); max_bw = bandwidth_in_kbps_from_link_settings(link_setting); if (req_bw <= max_bw) { @@ -1739,7 +1692,7 @@ void decide_link_settings(struct dc_stream_state *stream, struct dc_link *link; uint32_t req_bw; - req_bw = bandwidth_in_kbps_from_timing(&stream->timing); + req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing); link = stream->link; diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 8fc223defed4..a83e1c60f9db 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -252,4 +252,6 @@ bool dc_submit_i2c( uint32_t link_index, struct i2c_command *cmd); +uint32_t dc_bandwidth_in_kbps_from_timing( + const struct dc_crtc_timing *timing); #endif /* DC_LINK_H_ */ -- cgit v1.2.3 From 0de34efc7b5f1f34676dcdd7ed8bb8a20038724d Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Wed, 20 Mar 2019 17:10:41 -0400 Subject: drm/amd/display: fix clk_mgr naming clk_mgr is called dccg in dc_state, this change fixes that Signed-off-by: Dmytro Laktyushkin Reviewed-by: Eric Bernstein Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 4 ++-- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index abf611538153..71a4dd63c4dc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1399,7 +1399,7 @@ static enum dc_status enable_link_dp( pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; - state->dccg->funcs->update_clocks(state->dccg, state, false); + state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); dp_enable_link_phy( link, diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index d0ed95eda508..f798fc28fb2a 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2064,7 +2064,7 @@ void dc_resource_state_construct( const struct dc *dc, struct dc_state *dst_ctx) { - dst_ctx->dccg = dc->res_pool->clk_mgr; + dst_ctx->clk_mgr = dc->res_pool->clk_mgr; } /** diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index a1c4d26c6747..7ac50ab1b762 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1166,8 +1166,8 @@ static void build_audio_output( if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { audio_output->pll_info.dp_dto_source_clock_in_khz = - state->dccg->funcs->get_dp_ref_clk_frequency( - state->dccg); + state->clk_mgr->funcs->get_dp_ref_clk_frequency( + state->clk_mgr); } audio_output->pll_info.feed_back_divider = diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index c3f820cc8287..827541e34ee2 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -301,7 +301,7 @@ struct dc_state { struct dcn_bw_internal_vars dcn_bw_vars; #endif - struct clk_mgr *dccg; + struct clk_mgr *clk_mgr; struct { bool full_update_needed : 1; -- cgit v1.2.3 From 332c11914a76200dfbafc6b46ae5e728216aac00 Mon Sep 17 00:00:00 2001 From: Nikola Cornij Date: Tue, 19 Mar 2019 19:47:32 -0400 Subject: drm/amd/display: Calculate link bandwidth in a common function [why] Currently link bandwidth is calculated in two places, using the same formula. They should be unified into calling one function. [how] Replace all implementations of link bandwidth calculation with a call to a function. Signed-off-by: Nikola Cornij Reviewed-by: Nikola Cornij Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 13 +++++++++++++ drivers/gpu/drm/amd/display/dc/core/dc_link.c | 16 +++++++--------- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 24 +++++------------------- drivers/gpu/drm/amd/display/dc/dc_link.h | 3 +++ 4 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 5f05e191f0ff..51b85a8ef9f2 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -584,6 +584,19 @@ void dc_link_set_test_pattern(struct dc_link *link, cust_pattern_size); } +uint32_t dc_link_bandwidth_kbps( + const struct dc_link *link, + const struct dc_link_settings *link_setting) +{ + uint32_t link_bw_kbps = link_setting->link_rate * LINK_RATE_REF_FREQ_IN_KHZ; /* bytes per sec */ + + link_bw_kbps *= 8; /* 8 bits per byte*/ + link_bw_kbps *= link_setting->lane_count; + + return link_bw_kbps; + +} + static void destruct(struct dc *dc) { dc_release_state(dc->current_state); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 71a4dd63c4dc..c0d1d83ae4c5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -58,7 +58,6 @@ ******************************************************************************/ enum { - LINK_RATE_REF_FREQ_IN_MHZ = 27, PEAK_FACTOR_X1000 = 1006, /* * Some receivers fail to train on first try and are good @@ -2289,14 +2288,13 @@ void core_link_resume(struct dc_link *link) static struct fixed31_32 get_pbn_per_slot(struct dc_stream_state *stream) { - struct dc_link_settings *link_settings = - &stream->link->cur_link_settings; - uint32_t link_rate_in_mbps = - link_settings->link_rate * LINK_RATE_REF_FREQ_IN_MHZ; - struct fixed31_32 mbps = dc_fixpt_from_int( - link_rate_in_mbps * link_settings->lane_count); - - return dc_fixpt_div_int(mbps, 54); + struct fixed31_32 mbytes_per_sec; + uint32_t link_rate_in_mbytes_per_sec = dc_link_bandwidth_kbps(stream->link, &stream->link->cur_link_settings); + link_rate_in_mbytes_per_sec /= 8000; /* Kbits to MBytes */ + + mbytes_per_sec = dc_fixpt_from_int(link_rate_in_mbytes_per_sec); + + return dc_fixpt_div_int(mbytes_per_sec, 54); } static int get_color_depth(enum dc_color_depth color_depth) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 491d13d27e9e..0d8ef8f7cb58 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1533,22 +1533,6 @@ static bool decide_fallback_link_setting( return true; } -static uint32_t bandwidth_in_kbps_from_link_settings( - const struct dc_link_settings *link_setting) -{ - uint32_t link_rate_in_kbps = link_setting->link_rate * - LINK_RATE_REF_FREQ_IN_KHZ; - - uint32_t lane_count = link_setting->lane_count; - uint32_t kbps = link_rate_in_kbps; - - kbps *= lane_count; - kbps *= 8; /* 8 bits per byte*/ - - return kbps; - -} - bool dp_validate_mode_timing( struct dc_link *link, const struct dc_crtc_timing *timing) @@ -1574,7 +1558,7 @@ bool dp_validate_mode_timing( */ req_bw = dc_bandwidth_in_kbps_from_timing(timing); - max_bw = bandwidth_in_kbps_from_link_settings(link_setting); + max_bw = dc_link_bandwidth_kbps(link, link_setting); if (req_bw <= max_bw) { /* remember the biggest mode here, during @@ -1609,7 +1593,8 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting */ while (current_link_setting.link_rate <= link->verified_link_cap.link_rate) { - link_bw = bandwidth_in_kbps_from_link_settings( + link_bw = dc_link_bandwidth_kbps( + link, ¤t_link_setting); if (req_bw <= link_bw) { *link_setting = current_link_setting; @@ -1660,7 +1645,8 @@ static bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settin */ while (current_link_setting.link_rate <= link->verified_link_cap.link_rate) { - link_bw = bandwidth_in_kbps_from_link_settings( + link_bw = dc_link_bandwidth_kbps( + link, ¤t_link_setting); if (req_bw <= link_bw) { *link_setting = current_link_setting; diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index a83e1c60f9db..7b61fb7b1bb7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -246,6 +246,9 @@ void dc_link_set_test_pattern(struct dc_link *link, const struct link_training_settings *p_link_settings, const unsigned char *p_custom_pattern, unsigned int cust_pattern_size); +uint32_t dc_link_bandwidth_kbps( + const struct dc_link *link, + const struct dc_link_settings *link_setting); bool dc_submit_i2c( struct dc *dc, -- cgit v1.2.3 From a1e07ba89d49581471d64c48152dbe03b42bd025 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 14 Mar 2019 13:46:44 -0400 Subject: drm/amd/display: Use plane->color_space for dpp if specified [Why] The input color space for the plane was previously ignored even if it was set. If a limited range YUV format was given to DC then the wrong color transformation matrix was being used since DC assumed that it was full range instead. [How] Respect the given color_space format for the plane if it isn't COLOR_SPACE_UNKNOWN. Otherwise, use the implicit default since DM didn't specify. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Sun peng Li Acked-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 6 +++++- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c index f91e4b49d211..6f4b24756323 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c @@ -385,6 +385,10 @@ void dpp1_cnv_setup ( default: break; } + + /* Set default color space based on format if none is given. */ + color_space = input_color_space ? input_color_space : color_space; + REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, CNVC_SURFACE_PIXEL_FORMAT, pixel_format); REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en); @@ -396,7 +400,7 @@ void dpp1_cnv_setup ( for (i = 0; i < 12; i++) tbl_entry.regval[i] = input_csc_color_matrix.matrix[i]; - tbl_entry.color_space = input_color_space; + tbl_entry.color_space = color_space; if (color_space >= COLOR_SPACE_YCBCR601) select = INPUT_CSC_SELECT_ICSC; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 4969fa5e6f1d..976812ae4ede 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1949,7 +1949,7 @@ static void update_dpp(struct dpp *dpp, struct dc_plane_state *plane_state) plane_state->format, EXPANSION_MODE_ZERO, plane_state->input_csc_color_matrix, - COLOR_SPACE_YCBCR601_LIMITED); + plane_state->color_space); //set scale and bias registers build_prescale_params(&bns_params, plane_state); -- cgit v1.2.3 From b4423fd9cf3e5ba0e36c42cee12db167dae6cf5e Mon Sep 17 00:00:00 2001 From: Su Sung Chung Date: Thu, 21 Mar 2019 15:40:44 -0400 Subject: drm/amd/display: return correct dc_status for dcn10_validate_global [Why] Before it was returning false in the case of failure even though return type should be enum dc_status [How] Return DC_FAIL_UNSUPPORTED_1 instead Signed-off-by: Su Sung Chung Reviewed-by: Eric Yang Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 +- drivers/gpu/drm/amd/display/dc/inc/core_status.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 7c37836bb9cc..79f4fbb8a145 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1146,7 +1146,7 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont continue; if (context->stream_status[i].plane_count > 2) - return false; + return DC_FAIL_UNSUPPORTED_1; for (j = 0; j < context->stream_status[i].plane_count; j++) { struct dc_plane_state *plane = diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_status.h b/drivers/gpu/drm/amd/display/dc/inc/core_status.h index 2e61a22ef4b2..8dca3b7700e5 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_status.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_status.h @@ -43,7 +43,7 @@ enum dc_status { DC_FAIL_BANDWIDTH_VALIDATE = 13, /* BW and Watermark validation */ DC_FAIL_SCALING = 14, DC_FAIL_DP_LINK_TRAINING = 15, - + DC_FAIL_UNSUPPORTED_1 = 18, DC_ERROR_UNEXPECTED = -1 }; -- cgit v1.2.3 From 2fbbd495e9fe0f6fffdf999833848bc2e928a1ea Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Fri, 22 Mar 2019 17:27:52 -0400 Subject: drm/amd/display: 3.2.25 Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 16483bf82c8f..dc6a2c236ba7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -39,7 +39,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.24" +#define DC_VER "3.2.25" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit v1.2.3 From e9164db72aa273a63a78f70b5d89a4509967551c Mon Sep 17 00:00:00 2001 From: Josip Pavic Date: Thu, 21 Mar 2019 15:04:32 -0400 Subject: drm/amd/display: remove min reduction for abm 2.2 level 3 [Why] Image brightness compensation for solid color full screen images is expected to be optimal for ABM 2.2 at level 3. The min reduction that is currently being enforced prevents this from being achieved. [How] Remove the min reduction for ABM 2.2 at level 3 Signed-off-by: Josip Pavic Reviewed-by: Anthony Koo Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/power/power_helpers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c index efd386f3ca53..b3810b864676 100644 --- a/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ b/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -43,10 +43,10 @@ static const unsigned char max_reduction_table[13] = { /* Possible ABM 2.2 Min Reduction configs from least aggressive to most aggressive * 0 1 2 3 4 5 6 7 8 9 10 11 12 - * 100 100 100 100 100 100 100 90.2 85.1 80.0 80.0 75.3 75.3 % + * 100 100 100 100 100 100 100 100 100 92.2 83.1 75.3 75.3 % */ static const unsigned char min_reduction_table_v_2_2[13] = { -0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xd9, 0xcc, 0xcc, 0xc0, 0xc0}; +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xd4, 0xc0, 0xc0}; /* Possible ABM 2.2 Max Reduction configs from least aggressive to most aggressive * 0 1 2 3 4 5 6 7 8 9 10 11 12 -- cgit v1.2.3 From 7ee3769a37d3f9d7352bb0182b0bf3a2beabe523 Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Fri, 22 Mar 2019 19:33:46 -0400 Subject: drm/amd/display: prefer preferred link cap over verified link settings [why] when preferred link cap is set, we should always use preferred in all validation. we should not use preferred for some validation but use verified for others. [how] create getter function that gets verified link cap. if preferred is set, return preferred link settings instead. Signed-off-by: Wenjing Liu Reviewed-by: Nikola Cornij Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 9 +++++++++ drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- drivers/gpu/drm/amd/display/dc/dc_link.h | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 51b85a8ef9f2..2b1cd8bd5e03 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -597,6 +597,15 @@ uint32_t dc_link_bandwidth_kbps( } +const struct dc_link_settings *dc_link_get_verified_link_cap( + const struct dc_link *link) +{ + if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN && + link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN) + return &link->preferred_link_setting; + return &link->verified_link_cap; +} + static void destruct(struct dc *dc) { dc_release_state(dc->current_state); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 0d8ef8f7cb58..acb4f829e042 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1549,7 +1549,7 @@ bool dp_validate_mode_timing( return true; /* We always use verified link settings */ - link_setting = &link->verified_link_cap; + link_setting = dc_link_get_verified_link_cap(link); /* TODO: DYNAMIC_VALIDATION needs to be implemented */ /*if (flags.DYNAMIC_VALIDATION == 1 && diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 7b61fb7b1bb7..4e26d6e93b31 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -250,6 +250,9 @@ uint32_t dc_link_bandwidth_kbps( const struct dc_link *link, const struct dc_link_settings *link_setting); +const struct dc_link_settings *dc_link_get_verified_link_cap( + const struct dc_link *link); + bool dc_submit_i2c( struct dc *dc, uint32_t link_index, -- cgit v1.2.3 From 004fefa385b42740a1773381bbf4795ec6b168f5 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 15 Mar 2019 10:31:50 -0400 Subject: drm/amd/display: Set surface color space from DRM plane state [Why] We need DC's color space to match the color encoding and color space specified by userspace to correctly render YUV surfaces. [How] Convert the DRM color encoding and color range properties to the appropriate DC colorspace option and update the color space when performing surface updates. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 53 ++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 06f58cd9e984..1db85cd8d0fb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2744,6 +2744,50 @@ fill_blending_from_plane_state(struct drm_plane_state *plane_state, } } +static int +fill_plane_color_attributes(const struct drm_plane_state *plane_state, + const struct dc_plane_state *dc_plane_state, + enum dc_color_space *color_space) +{ + bool full_range; + + *color_space = COLOR_SPACE_SRGB; + + /* DRM color properties only affect non-RGB formats. */ + if (dc_plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + return 0; + + full_range = (plane_state->color_range == DRM_COLOR_YCBCR_FULL_RANGE); + + switch (plane_state->color_encoding) { + case DRM_COLOR_YCBCR_BT601: + if (full_range) + *color_space = COLOR_SPACE_YCBCR601; + else + *color_space = COLOR_SPACE_YCBCR601_LIMITED; + break; + + case DRM_COLOR_YCBCR_BT709: + if (full_range) + *color_space = COLOR_SPACE_YCBCR709; + else + *color_space = COLOR_SPACE_YCBCR709_LIMITED; + break; + + case DRM_COLOR_YCBCR_BT2020: + if (full_range) + *color_space = COLOR_SPACE_2020_YCBCR; + else + return -EINVAL; + break; + + default: + return -EINVAL; + } + + return 0; +} + static int fill_plane_attributes(struct amdgpu_device *adev, struct dc_plane_state *dc_plane_state, struct drm_plane_state *plane_state, @@ -2765,6 +2809,11 @@ static int fill_plane_attributes(struct amdgpu_device *adev, if (ret) return ret; + ret = fill_plane_color_attributes(plane_state, dc_plane_state, + &dc_plane_state->color_space); + if (ret) + return ret; + /* * Always set input transfer function, since plane state is refreshed * every time. @@ -5015,8 +5064,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->scaling_infos[planes_count].clip_rect = dc_plane->clip_rect; bundle->surface_updates[planes_count].scaling_info = &bundle->scaling_infos[planes_count]; + fill_plane_color_attributes( + new_plane_state, dc_plane, + &bundle->plane_infos[planes_count].color_space); - bundle->plane_infos[planes_count].color_space = dc_plane->color_space; bundle->plane_infos[planes_count].format = dc_plane->format; bundle->plane_infos[planes_count].plane_size = dc_plane->plane_size; bundle->plane_infos[planes_count].rotation = dc_plane->rotation; -- cgit v1.2.3 From 86eb426a0f30ef538109a7b44f86051586390125 Mon Sep 17 00:00:00 2001 From: SivapiriyanKumarasamy Date: Mon, 25 Mar 2019 14:04:30 -0400 Subject: drm/amd/display: Call hwss.set_cursor_sdr_white_level, if available [Why] In HDR configurations, the cursor - in SDR - needs to have it's white level boosted. [How] Program the cursor boost in update_dchubp_dpp like the other cursor attributes. Signed-off-by: SivapiriyanKumarasamy Reviewed-by: Anthony Koo Acked-by: Leo Li Acked-by: Reza Amini Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 976812ae4ede..afa8648d88e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2138,6 +2138,9 @@ void update_dchubp_dpp( if (pipe_ctx->stream->cursor_attributes.address.quad_part != 0) { dc->hwss.set_cursor_position(pipe_ctx); dc->hwss.set_cursor_attribute(pipe_ctx); + + if (dc->hwss.set_cursor_sdr_white_level) + dc->hwss.set_cursor_sdr_white_level(pipe_ctx); } if (plane_state->update_flags.bits.full_update) { -- cgit v1.2.3 From c85fc65e2241bacbce35e3beb28ac4994e1e033a Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Sat, 23 Mar 2019 13:46:40 -0400 Subject: drm/amd/display: init dc_config before rest of DC init [Why] In some cases we want DC init to take in some config options [How] Init dc_config before rest of DC init Signed-off-by: Anthony Koo Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 2b1cd8bd5e03..4887d0611001 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -654,6 +654,8 @@ static bool construct(struct dc *dc, #endif enum dce_version dc_version = DCE_VERSION_UNKNOWN; + dc->config = init_params->flags; + memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides)); dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL); @@ -847,8 +849,6 @@ struct dc *dc_create(const struct dc_init_data *init_params) if (dc->res_pool->dmcu != NULL) dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version; - dc->config = init_params->flags; - dc->build_id = DC_BUILD_ID; DC_LOG_DC("Display Core initialized\n"); -- cgit v1.2.3 From 15ae3b28f8ca406b449d36d36021e96b66aedb5d Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Mon, 25 Mar 2019 14:30:12 -0400 Subject: drm/amd/display: disable link before changing link settings [Why] If link is already enabled at a different rate (for example 5.4 Gbps) then calling VBIOS command table to switch to a new rate (for example 2.7 Gbps) will not take effect. This can lead to link training failure to occur. [How] If the requested link rate is different than the current link rate, the link must be disabled in order to re-enable at the new link rate. In today's logic it is currently only impacting eDP since DP connection types will always disable the link during display detection, when initial link verification occurs. Signed-off-by: Anthony Koo Reviewed-by: Aric Cyr Acked-by: Leo Li Acked-by: Tony Cheng Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index c0d1d83ae4c5..3b1e38e110ee 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1396,6 +1396,15 @@ static enum dc_status enable_link_dp( /* get link settings for video mode timing */ decide_link_settings(stream, &link_settings); + /* If link settings are different than current and link already enabled + * then need to disable before programming to new rate. + */ + if (link->link_status.link_active && + (link->cur_link_settings.lane_count != link_settings.lane_count || + link->cur_link_settings.link_rate != link_settings.link_rate)) { + dp_disable_link_phy(link, pipe_ctx->stream->signal); + } + pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ; state->clk_mgr->funcs->update_clocks(state->clk_mgr, state, false); -- cgit v1.2.3 From d5ca5fdbeb76ef78af9a8291846d2c9f08ae414b Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Mon, 25 Mar 2019 16:11:43 -0400 Subject: drm/amd/display: fix underflow on boot [Why] New seamless boot sequence introduced a bug where front end is disabled without blanking otg. [How] Adjust the condition of blanking otg to match seamless boot. Signed-off-by: Eric Yang Reviewed-by: Anthony Koo Acked-by: Leo Li Acked-by: Tony Cheng Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index afa8648d88e1..f6591488ef9b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -979,16 +979,14 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context) * to non-preferred front end. If pipe_ctx->stream is not NULL, * we will use the pipe, so don't disable */ - if (pipe_ctx->stream != NULL) + if (pipe_ctx->stream != NULL && can_apply_seamless_boot) continue; - if (tg->funcs->is_tg_enabled(tg)) - tg->funcs->lock(tg); - /* Blank controller using driver code instead of * command table. */ if (tg->funcs->is_tg_enabled(tg)) { + tg->funcs->lock(tg); tg->funcs->set_blank(tg, true); hwss_wait_for_blank_complete(tg); } -- cgit v1.2.3 From fbd06ec492fc6e078a62664c5b4a0d74b90285be Mon Sep 17 00:00:00 2001 From: Murton Liu Date: Mon, 25 Mar 2019 14:51:28 -0400 Subject: drm/amd/display: HDR visual confirmation incorrectly reports black color [Why] Checking against a TF that is unused causes us to default to black [How] Check against PQ instead Signed-off-by: Murton Liu Reviewed-by: Aric Cyr Acked-by: Leo Li Acked-by: Tony Cheng Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index f6591488ef9b..c2b93a851dc6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1852,7 +1852,7 @@ void dcn10_get_hdr_visual_confirm_color( switch (top_pipe_ctx->plane_res.scl_data.format) { case PIXEL_FORMAT_ARGB2101010: - if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_UNITY) { + if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { /* HDR10, ARGB2101010 - set boarder color to red */ color->color_r_cr = color_value; } -- cgit v1.2.3 From 113b7a010872117e90b16a3e411558db5cb5979e Mon Sep 17 00:00:00 2001 From: Leo Li Date: Tue, 19 Mar 2019 19:29:16 -0400 Subject: drm/amd/display: Recreate private_obj->state during S3 resume [Why] When entering S3, amdgpu first calls DRM to cache the current atomic state, then commit the 'all-disabled' state. This sets dc->current_state to point at the private atomic object's dm_atomic_state->context, as any regular atomic commit would. Afterwards, amdgpu_dm calls dc_set_power_state() with S3 power state. This invalidates dc->current_state by wiping it to 0, consequently wiping dm_atomic_state->context. During resume, the cached atomic state is restored. When getting the private object however, the dm_atomic_state - containing the wiped context - is duplicated into the atomic state. This causes DC validation to fail during atomic check, as necessary function pointers in dc_state are now NULL. [How] Recreate the private object's dm_atomic_state->context during resume, restoring any static values such as function pointers. A TODO item is added to move static read-only values out of dc_state - they shouldn't be there anyways. Signed-off-by: Leo Li Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 1db85cd8d0fb..0ea715c747bb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -983,9 +983,16 @@ static int dm_resume(void *handle) struct drm_plane *plane; struct drm_plane_state *new_plane_state; struct dm_plane_state *dm_new_plane_state; + struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state); enum dc_connection_type new_connection_type = dc_connection_none; int i; + /* Recreate dc_state - DC invalidates it when setting power state to S3. */ + dc_release_state(dm_state->context); + dm_state->context = dc_create_state(dm->dc); + /* TODO: Remove dc_state->dccg, use dc->dccg directly. */ + dc_resource_state_construct(dm->dc, dm_state->context); + /* power on hardware */ dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0); -- cgit v1.2.3 From c7e557ab46a7395fd28936c24e12e06f1841279c Mon Sep 17 00:00:00 2001 From: Leo Li Date: Wed, 20 Mar 2019 09:52:14 -0400 Subject: drm/amd/display: Clean up locking in dcn*_apply_ctx_for_surface() [Why] dcn*_disable_plane() doesn't unlock the pipe anymore, making the extra lock unnecessary. In addition - during full plane updates - all necessary pipes should be locked/unlocked together when modifying hubp to avoid tearing in pipesplit setups. [How] Remove redundant locks, and add function to lock all pipes. If an interdependent pipe update is required, lock down all pipes. Otherwise, lock only the top pipe for the updated pipe tree. Signed-off-by: Leo Li Reviewed-by: Tony Cheng Acked-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 66 +++++++++++++++------- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h | 4 ++ 2 files changed, 49 insertions(+), 21 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index c2b93a851dc6..dab370676bfa 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2329,6 +2329,7 @@ static void dcn10_apply_ctx_for_surface( int i; struct timing_generator *tg; bool removed_pipe[4] = { false }; + bool interdependent_update = false; struct pipe_ctx *top_pipe_to_program = find_top_pipe_for_stream(dc, context, stream); DC_LOGGER_INIT(dc->ctx->logger); @@ -2338,7 +2339,13 @@ static void dcn10_apply_ctx_for_surface( tg = top_pipe_to_program->stream_res.tg; - dcn10_pipe_control_lock(dc, top_pipe_to_program, true); + interdependent_update = top_pipe_to_program->plane_state && + top_pipe_to_program->plane_state->update_flags.bits.full_update; + + if (interdependent_update) + lock_all_pipes(dc, context, true); + else + dcn10_pipe_control_lock(dc, top_pipe_to_program, true); if (num_planes == 0) { /* OTG blank before remove all front end */ @@ -2358,15 +2365,9 @@ static void dcn10_apply_ctx_for_surface( */ if (pipe_ctx->plane_state && !old_pipe_ctx->plane_state) { if (old_pipe_ctx->stream_res.tg == tg && - old_pipe_ctx->plane_res.hubp && - old_pipe_ctx->plane_res.hubp->opp_id != 0xf) { + old_pipe_ctx->plane_res.hubp && + old_pipe_ctx->plane_res.hubp->opp_id != 0xf) dcn10_disable_plane(dc, old_pipe_ctx); - /* - * power down fe will unlock when calling reset, need - * to lock it back here. Messy, need rework. - */ - pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg); - } } if ((!pipe_ctx->plane_state || @@ -2385,29 +2386,25 @@ static void dcn10_apply_ctx_for_surface( if (num_planes > 0) program_all_pipe_in_tree(dc, top_pipe_to_program, context); - dcn10_pipe_control_lock(dc, top_pipe_to_program, false); - - if (top_pipe_to_program->plane_state && - top_pipe_to_program->plane_state->update_flags.bits.full_update) + if (interdependent_update) for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - tg = pipe_ctx->stream_res.tg; /* Skip inactive pipes and ones already updated */ - if (!pipe_ctx->stream || pipe_ctx->stream == stream - || !pipe_ctx->plane_state - || !tg->funcs->is_tg_enabled(tg)) + if (!pipe_ctx->stream || pipe_ctx->stream == stream || + !pipe_ctx->plane_state || !tg->funcs->is_tg_enabled(tg)) continue; - tg->funcs->lock(tg); - pipe_ctx->plane_res.hubp->funcs->hubp_setup_interdependent( pipe_ctx->plane_res.hubp, &pipe_ctx->dlg_regs, &pipe_ctx->ttu_regs); - - tg->funcs->unlock(tg); } + if (interdependent_update) + lock_all_pipes(dc, context, false); + else + dcn10_pipe_control_lock(dc, top_pipe_to_program, false); + if (num_planes == 0) false_optc_underflow_wa(dc, stream, tg); @@ -2814,6 +2811,33 @@ int get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx) return vertical_line_start; } +void lock_all_pipes(struct dc *dc, + struct dc_state *context, + bool lock) +{ + struct pipe_ctx *pipe_ctx; + struct timing_generator *tg; + int i; + + for (i = 0; i < dc->res_pool->pipe_count; i++) { + pipe_ctx = &context->res_ctx.pipe_ctx[i]; + tg = pipe_ctx->stream_res.tg; + /* + * Only lock the top pipe's tg to prevent redundant + * (un)locking. Also skip if pipe is disabled. + */ + if (pipe_ctx->top_pipe || + !pipe_ctx->stream || !pipe_ctx->plane_state || + !tg->funcs->is_tg_enabled(tg)) + continue; + + if (lock) + tg->funcs->lock(tg); + else + tg->funcs->unlock(tg); + } +} + static void calc_vupdate_position( struct pipe_ctx *pipe_ctx, uint32_t *start_line, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index 6d66084df55f..4b3b27a5d23b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -83,4 +83,8 @@ struct pipe_ctx *find_top_pipe_for_stream( int get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx); +void lock_all_pipes(struct dc *dc, + struct dc_state *context, + bool lock); + #endif /* __DC_HWSS_DCN10_H__ */ -- cgit v1.2.3 From cc1fec5724d16295979c8bb7cf27ac2f4696b19c Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 14 Mar 2019 15:58:51 -0400 Subject: drm/amd/display: Pass plane caps into amdgpu_dm_plane_init [Why] When deciding to add properties or expose formats on DRM planes we should be querying the caps for the DC plane it's supposed to represent. [How] Pass plane caps down into plane initialization, refactoring overlay plane initialization to have the overlay plane be represented by the first overlay capable DC plane. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 63 ++++++++++++----------- 1 file changed, 34 insertions(+), 29 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 0ea715c747bb..fd5646c11bb2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -111,7 +111,8 @@ amdgpu_dm_update_connector_after_detect(struct amdgpu_dm_connector *aconnector); static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, struct drm_plane *plane, - unsigned long possible_crtcs); + unsigned long possible_crtcs, + const struct dc_plane_cap *plane_cap); static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, struct drm_plane *plane, uint32_t link_index); @@ -1961,7 +1962,8 @@ amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm) static int initialize_plane(struct amdgpu_display_manager *dm, struct amdgpu_mode_info *mode_info, int plane_id, - enum drm_plane_type plane_type) + enum drm_plane_type plane_type, + const struct dc_plane_cap *plane_cap) { struct drm_plane *plane; unsigned long possible_crtcs; @@ -1984,7 +1986,7 @@ static int initialize_plane(struct amdgpu_display_manager *dm, if (plane_id >= dm->dc->caps.max_streams) possible_crtcs = 0xff; - ret = amdgpu_dm_plane_init(dm, plane, possible_crtcs); + ret = amdgpu_dm_plane_init(dm, plane, possible_crtcs, plane_cap); if (ret) { DRM_ERROR("KMS: Failed to initialize plane\n"); @@ -2037,8 +2039,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) struct amdgpu_encoder *aencoder = NULL; struct amdgpu_mode_info *mode_info = &adev->mode_info; uint32_t link_cnt; - int32_t overlay_planes, primary_planes; + int32_t primary_planes; enum dc_connection_type new_connection_type = dc_connection_none; + const struct dc_plane_cap *plane; link_cnt = dm->dc->caps.max_links; if (amdgpu_dm_mode_config_init(dm->adev)) { @@ -2046,24 +2049,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) return -EINVAL; } - /* - * Determine the number of overlay planes supported. - * Only support DCN for now, and cap so we don't encourage - * userspace to use up all the planes. - */ - overlay_planes = 0; - - for (i = 0; i < dm->dc->caps.max_planes; ++i) { - struct dc_plane_cap *plane = &dm->dc->caps.planes[i]; - - if (plane->type == DC_PLANE_TYPE_DCN_UNIVERSAL && - plane->blends_with_above && plane->blends_with_below && - plane->supports_argb8888) - overlay_planes += 1; - } - - overlay_planes = min(overlay_planes, 1); - /* There is one primary plane per CRTC */ primary_planes = dm->dc->caps.max_streams; ASSERT(primary_planes <= AMDGPU_MAX_PLANES); @@ -2073,8 +2058,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) * Order is reversed to match iteration order in atomic check. */ for (i = (primary_planes - 1); i >= 0; i--) { + plane = &dm->dc->caps.planes[i]; + if (initialize_plane(dm, mode_info, i, - DRM_PLANE_TYPE_PRIMARY)) { + DRM_PLANE_TYPE_PRIMARY, plane)) { DRM_ERROR("KMS: Failed to initialize primary plane\n"); goto fail; } @@ -2085,13 +2072,30 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) * These planes have a higher DRM index than the primary planes since * they should be considered as having a higher z-order. * Order is reversed to match iteration order in atomic check. + * + * Only support DCN for now, and only expose one so we don't encourage + * userspace to use up all the pipes. */ - for (i = (overlay_planes - 1); i >= 0; i--) { + for (i = 0; i < dm->dc->caps.max_planes; ++i) { + struct dc_plane_cap *plane = &dm->dc->caps.planes[i]; + + if (plane->type != DC_PLANE_TYPE_DCN_UNIVERSAL) + continue; + + if (!plane->blends_with_above || !plane->blends_with_below) + continue; + + if (!plane->supports_argb8888) + continue; + if (initialize_plane(dm, NULL, primary_planes + i, - DRM_PLANE_TYPE_OVERLAY)) { + DRM_PLANE_TYPE_OVERLAY, plane)) { DRM_ERROR("KMS: Failed to initialize overlay plane\n"); goto fail; } + + /* Only create one overlay plane. */ + break; } for (i = 0; i < dm->dc->caps.max_streams; i++) @@ -4119,7 +4123,8 @@ static const u32 cursor_formats[] = { static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, struct drm_plane *plane, - unsigned long possible_crtcs) + unsigned long possible_crtcs, + const struct dc_plane_cap *plane_cap) { int res = -EPERM; @@ -4156,8 +4161,8 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, break; } - /* TODO: Check DC plane caps explicitly here for adding propertes */ - if (plane->type == DRM_PLANE_TYPE_OVERLAY) { + if (plane->type == DRM_PLANE_TYPE_OVERLAY && + plane_cap && plane_cap->per_pixel_alpha) { unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | BIT(DRM_MODE_BLEND_PREMULTI); @@ -4189,7 +4194,7 @@ static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, goto fail; cursor_plane->type = DRM_PLANE_TYPE_CURSOR; - res = amdgpu_dm_plane_init(dm, cursor_plane, 0); + res = amdgpu_dm_plane_init(dm, cursor_plane, 0, NULL); acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); if (!acrtc) -- cgit v1.2.3 From fe6382cd69de98802455e77040c6e00d9e12cc47 Mon Sep 17 00:00:00 2001 From: Dmytro Laktyushkin Date: Tue, 26 Mar 2019 13:26:37 -0400 Subject: drm/amd/display: fix is odm head pipe logic Simply return true/false, don't iterate up the tree. Signed-off-by: Dmytro Laktyushkin Reviewed-by: Nikola Cornij Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index f798fc28fb2a..3830e6ce1355 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1305,18 +1305,13 @@ struct pipe_ctx *dc_res_get_odm_bottom_pipe(struct pipe_ctx *pipe_ctx) bool dc_res_is_odm_head_pipe(struct pipe_ctx *pipe_ctx) { struct pipe_ctx *top_pipe = pipe_ctx->top_pipe; - bool result = false; + if (!top_pipe) + return false; if (top_pipe && top_pipe->stream_res.opp == pipe_ctx->stream_res.opp) return false; - while (top_pipe) { - if (!top_pipe->top_pipe && top_pipe->stream_res.opp != pipe_ctx->stream_res.opp) - result = true; - top_pipe = top_pipe->top_pipe; - } - - return result; + return true; } bool dc_remove_plane_from_context( -- cgit v1.2.3 From 9726920b7ea287673eead69e5276b3abff91fd8c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 10 Apr 2019 20:01:20 +0100 Subject: drm/i915: Only reset the pinned kernel contexts on resume On resume, we know that the only pinned contexts in danger of seeing corruption are the kernel context, and so we do not need to walk the list of all GEM contexts as we tracked them on each engine. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190410190120.830-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_gem.c | 9 ++---- drivers/gpu/drm/i915/intel_context_types.h | 1 + drivers/gpu/drm/i915/intel_engine_cs.c | 24 +++++++++++++++ drivers/gpu/drm/i915/intel_lrc.c | 49 +++++++++++++++--------------- drivers/gpu/drm/i915/intel_lrc.h | 1 - drivers/gpu/drm/i915/intel_ringbuffer.c | 17 +++++------ drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +- 8 files changed, 60 insertions(+), 45 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 63eca3061d10..35d0782c077e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1995,7 +1995,6 @@ struct drm_i915_private { /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ struct { - void (*resume)(struct drm_i915_private *); void (*cleanup_engine)(struct intel_engine_cs *engine); struct i915_gt_timelines { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf3d12f94365..0a818a60ad31 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4513,7 +4513,7 @@ void i915_gem_resume(struct drm_i915_private *i915) * guarantee that the context image is complete. So let's just reset * it and start again. */ - i915->gt.resume(i915); + intel_gt_resume(i915); if (i915_gem_init_hw(i915)) goto err_wedged; @@ -4853,13 +4853,10 @@ int i915_gem_init(struct drm_i915_private *dev_priv) dev_priv->mm.unordered_timeline = dma_fence_context_alloc(1); - if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) { - dev_priv->gt.resume = intel_lr_context_resume; + if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) dev_priv->gt.cleanup_engine = intel_logical_ring_cleanup; - } else { - dev_priv->gt.resume = intel_legacy_submission_resume; + else dev_priv->gt.cleanup_engine = intel_engine_cleanup; - } i915_timelines_init(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_context_types.h b/drivers/gpu/drm/i915/intel_context_types.h index 624729a35875..68b4ca1611e0 100644 --- a/drivers/gpu/drm/i915/intel_context_types.h +++ b/drivers/gpu/drm/i915/intel_context_types.h @@ -24,6 +24,7 @@ struct intel_context_ops { int (*pin)(struct intel_context *ce); void (*unpin)(struct intel_context *ce); + void (*reset)(struct intel_context *ce); void (*destroy)(struct kref *kref); }; diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index d0427c2e3997..f29a667cad52 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -753,6 +753,30 @@ err_unpin: return ret; } +void intel_gt_resume(struct drm_i915_private *i915) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + + /* + * After resume, we may need to poke into the pinned kernel + * contexts to paper over any damage caused by the sudden suspend. + * Only the kernel contexts should remain pinned over suspend, + * allowing us to fixup the user contexts on their first pin. + */ + for_each_engine(engine, i915, id) { + struct intel_context *ce; + + ce = engine->kernel_context; + if (ce) + ce->ops->reset(ce); + + ce = engine->preempt_context; + if (ce) + ce->ops->reset(ce); + } +} + /** * intel_engines_cleanup_common - cleans up the engine state created by * the common initiailizers. diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6931dbb2888c..b54dbf36197e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1379,9 +1379,33 @@ static int execlists_context_pin(struct intel_context *ce) return __execlists_context_pin(ce, ce->engine); } +static void execlists_context_reset(struct intel_context *ce) +{ + /* + * Because we emit WA_TAIL_DWORDS there may be a disparity + * between our bookkeeping in ce->ring->head and ce->ring->tail and + * that stored in context. As we only write new commands from + * ce->ring->tail onwards, everything before that is junk. If the GPU + * starts reading from its RING_HEAD from the context, it may try to + * execute that junk and die. + * + * The contexts that are stilled pinned on resume belong to the + * kernel, and are local to each engine. All other contexts will + * have their head/tail sanitized upon pinning before use, so they + * will never see garbage, + * + * So to avoid that we reset the context images upon resume. For + * simplicity, we just zero everything out. + */ + intel_ring_reset(ce->ring, 0); + __execlists_update_reg_state(ce, ce->engine); +} + static const struct intel_context_ops execlists_context_ops = { .pin = execlists_context_pin, .unpin = execlists_context_unpin, + + .reset = execlists_context_reset, .destroy = execlists_context_destroy, }; @@ -2895,31 +2919,6 @@ error_deref_obj: return ret; } -void intel_lr_context_resume(struct drm_i915_private *i915) -{ - struct i915_gem_context *ctx; - struct intel_context *ce; - - /* - * Because we emit WA_TAIL_DWORDS there may be a disparity - * between our bookkeeping in ce->ring->head and ce->ring->tail and - * that stored in context. As we only write new commands from - * ce->ring->tail onwards, everything before that is junk. If the GPU - * starts reading from its RING_HEAD from the context, it may try to - * execute that junk and die. - * - * So to avoid that we reset the context images upon resume. For - * simplicity, we just zero everything out. - */ - list_for_each_entry(ctx, &i915->contexts.list, link) { - list_for_each_entry(ce, &ctx->active_engines, active_link) { - GEM_BUG_ON(!ce->ring); - intel_ring_reset(ce->ring, 0); - __execlists_update_reg_state(ce, ce->engine); - } - } -} - void intel_execlists_show_requests(struct intel_engine_cs *engine, struct drm_printer *m, void (*show_request)(struct drm_printer *m, diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 92642ab91472..4d0b7736cb6d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -102,7 +102,6 @@ struct drm_printer; struct drm_i915_private; struct i915_gem_context; -void intel_lr_context_resume(struct drm_i915_private *dev_priv); void intel_execlists_set_default_submission(struct intel_engine_cs *engine); void intel_execlists_show_requests(struct intel_engine_cs *engine, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 8a19eee9c5d4..af35f99c5940 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1508,9 +1508,16 @@ err_unpin: return err; } +static void ring_context_reset(struct intel_context *ce) +{ + intel_ring_reset(ce->ring, 0); +} + static const struct intel_context_ops ring_context_ops = { .pin = ring_context_pin, .unpin = ring_context_unpin, + + .reset = ring_context_reset, .destroy = ring_context_destroy, }; @@ -1581,16 +1588,6 @@ void intel_engine_cleanup(struct intel_engine_cs *engine) kfree(engine); } -void intel_legacy_submission_resume(struct drm_i915_private *dev_priv) -{ - struct intel_engine_cs *engine; - enum intel_engine_id id; - - /* Restart from the beginning of the rings for convenience */ - for_each_engine(engine, dev_priv, id) - intel_ring_reset(engine->buffer, 0); -} - static int load_pd_dir(struct i915_request *rq, const struct i915_hw_ppgtt *ppgtt) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index e58d6f04177b..0dea6c7fd438 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -268,8 +268,6 @@ static inline void intel_ring_put(struct intel_ring *ring) void intel_engine_stop(struct intel_engine_cs *engine); void intel_engine_cleanup(struct intel_engine_cs *engine); -void intel_legacy_submission_resume(struct drm_i915_private *dev_priv); - int __must_check intel_ring_cacheline_align(struct i915_request *rq); u32 __must_check *intel_ring_begin(struct i915_request *rq, unsigned int n); @@ -463,6 +461,7 @@ static inline void intel_engine_reset(struct intel_engine_cs *engine, } void intel_engines_sanitize(struct drm_i915_private *i915, bool force); +void intel_gt_resume(struct drm_i915_private *i915); bool intel_engine_is_idle(struct intel_engine_cs *engine); bool intel_engines_are_idle(struct drm_i915_private *dev_priv); -- cgit v1.2.3 From cd7879f79f83aec4bb13f0f823f323911dc5397b Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Wed, 10 Apr 2019 12:16:33 +0800 Subject: drm/i915/gvt: Roundup fb->height into tile's height at calucation fb->size When fb is tiled and fb->height isn't the multiple of tile's height, the format fb->size = fb->stride * fb->height, will get a smaller size than the actual size. As the memory height of tiled fb should be multiple of tile's height. Fixes: 7f1a93b1f1d1 ("drm/i915/gvt: Correct the calculation of plane size") Reviewed-by: Zhenyu Wang Signed-off-by: Xiong Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/dmabuf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 5d887f7cc0d5..69a9a1b2ea4a 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -209,7 +209,7 @@ static int vgpu_get_plane_info(struct drm_device *dev, struct drm_i915_private *dev_priv = to_i915(dev); struct intel_vgpu_primary_plane_format p; struct intel_vgpu_cursor_plane_format c; - int ret; + int ret, tile_height = 1; if (plane_id == DRM_PLANE_TYPE_PRIMARY) { ret = intel_vgpu_decode_primary_plane(vgpu, &p); @@ -228,12 +228,15 @@ static int vgpu_get_plane_info(struct drm_device *dev, break; case PLANE_CTL_TILED_X: info->drm_format_mod = I915_FORMAT_MOD_X_TILED; + tile_height = 8; break; case PLANE_CTL_TILED_Y: info->drm_format_mod = I915_FORMAT_MOD_Y_TILED; + tile_height = 32; break; case PLANE_CTL_TILED_YF: info->drm_format_mod = I915_FORMAT_MOD_Yf_TILED; + tile_height = 32; break; default: gvt_vgpu_err("invalid tiling mode: %x\n", p.tiled); @@ -264,8 +267,8 @@ static int vgpu_get_plane_info(struct drm_device *dev, return -EINVAL; } - info->size = (info->stride * info->height + PAGE_SIZE - 1) - >> PAGE_SHIFT; + info->size = (info->stride * roundup(info->height, tile_height) + + PAGE_SIZE - 1) >> PAGE_SHIFT; if (info->size == 0) { gvt_vgpu_err("fb size is zero\n"); return -EINVAL; -- cgit v1.2.3 From b7404c7ecb38b66f103cec694e23a8e99252829e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 9 Apr 2019 16:29:22 +0100 Subject: drm/i915: Bump ready tasks ahead of busywaits Consider two tasks that are running in parallel on a pair of engines (vcs0, vcs1), but then must complete on a shared engine (rcs0). To maximise throughput, we want to run the first ready task on rcs0 (i.e. the first task that completes on either of vcs0 or vcs1). When using semaphores, however, we will instead queue onto rcs in submission order. To resolve this incorrect ordering, we want to re-evaluate the priority queue when each of the request is ready. Normally this happens because we only insert into the priority queue requests that are ready, but with semaphores we are inserting ahead of their readiness and to compensate we penalize those tasks with reduced priority (so that tasks that do not need to busywait should naturally be run first). However, given a series of tasks that each use semaphores, the queue degrades into submission fifo rather than readiness fifo, and so to counter this we give a small boost to semaphore users as their dependent tasks are completed (and so we no longer require any busywait prior to running the user task as they are then ready themselves). v2: Fixup irqsave for schedule_lock (Tvrtko) Testcase: igt/gem_exec_schedule/semaphore-codependency Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Dmitry Rogozhkin Cc: Dmitry Ermilov Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190409152922.23894-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_request.c | 40 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_request.h | 1 + drivers/gpu/drm/i915/i915_scheduler.c | 21 +++++++++--------- 3 files changed, 52 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 96a9e8bcd805..a7d87cfaabcb 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -552,6 +552,36 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) return NOTIFY_DONE; } +static int __i915_sw_fence_call +semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) +{ + struct i915_request *request = + container_of(fence, typeof(*request), semaphore); + + switch (state) { + case FENCE_COMPLETE: + /* + * We only check a small portion of our dependencies + * and so cannot guarantee that there remains no + * semaphore chain across all. Instead of opting + * for the full NOSEMAPHORE boost, we go for the + * smaller (but still preempting) boost of + * NEWCLIENT. This will be enough to boost over + * a busywaiting request (as that cannot be + * NEWCLIENT) without accidentally boosting + * a busywait over real work elsewhere. + */ + i915_schedule_bump_priority(request, I915_PRIORITY_NEWCLIENT); + break; + + case FENCE_FREE: + i915_request_put(request); + break; + } + + return NOTIFY_DONE; +} + static void ring_retire_requests(struct intel_ring *ring) { struct i915_request *rq, *rn; @@ -702,6 +732,7 @@ i915_request_alloc(struct intel_engine_cs *engine, struct i915_gem_context *ctx) /* We bump the ref for the fence chain */ i915_sw_fence_init(&i915_request_get(rq)->submit, submit_notify); + i915_sw_fence_init(&i915_request_get(rq)->semaphore, semaphore_notify); i915_sched_node_init(&rq->sched); @@ -784,6 +815,12 @@ emit_semaphore_wait(struct i915_request *to, &from->fence, 0, I915_FENCE_GFP); + err = i915_sw_fence_await_dma_fence(&to->semaphore, + &from->fence, 0, + I915_FENCE_GFP); + if (err < 0) + return err; + /* We need to pin the signaler's HWSP until we are finished reading. */ err = i915_timeline_read_hwsp(from, to, &hwsp_offset); if (err) @@ -1114,6 +1151,7 @@ void i915_request_add(struct i915_request *request) * run at the earliest possible convenience. */ local_bh_disable(); + i915_sw_fence_commit(&request->semaphore); rcu_read_lock(); /* RCU serialisation for set-wedged protection */ if (engine->schedule) { struct i915_sched_attr attr = request->gem_context->sched; @@ -1320,7 +1358,9 @@ long i915_request_wait(struct i915_request *rq, if (flags & I915_WAIT_PRIORITY) { if (!i915_request_started(rq) && INTEL_GEN(rq->i915) >= 6) gen6_rps_boost(rq); + local_bh_disable(); /* suspend tasklets for reprioritisation */ i915_schedule_bump_priority(rq, I915_PRIORITY_WAIT); + local_bh_enable(); /* kick tasklets en masse */ } wait.tsk = current; diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h index 875be6f71412..a982664618c2 100644 --- a/drivers/gpu/drm/i915/i915_request.h +++ b/drivers/gpu/drm/i915/i915_request.h @@ -143,6 +143,7 @@ struct i915_request { struct i915_sw_dma_fence_cb dmaq; }; struct list_head execute_cb; + struct i915_sw_fence semaphore; /* * A list of everyone we wait upon, and everyone who waits upon us. diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index 77dbf7d74e12..39bc4f54e272 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -64,7 +64,7 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node, { bool ret = false; - spin_lock(&schedule_lock); + spin_lock_irq(&schedule_lock); if (!node_signaled(signal)) { INIT_LIST_HEAD(&dep->dfs_link); @@ -81,7 +81,7 @@ bool __i915_sched_node_add_dependency(struct i915_sched_node *node, ret = true; } - spin_unlock(&schedule_lock); + spin_unlock_irq(&schedule_lock); return ret; } @@ -108,7 +108,7 @@ void i915_sched_node_fini(struct i915_sched_node *node) GEM_BUG_ON(!list_empty(&node->link)); - spin_lock(&schedule_lock); + spin_lock_irq(&schedule_lock); /* * Everyone we depended upon (the fences we wait to be signaled) @@ -135,7 +135,7 @@ void i915_sched_node_fini(struct i915_sched_node *node) i915_dependency_free(dep); } - spin_unlock(&schedule_lock); + spin_unlock_irq(&schedule_lock); } static inline struct i915_priolist *to_priolist(struct rb_node *rb) @@ -356,7 +356,7 @@ static void __i915_schedule(struct i915_request *rq, memset(&cache, 0, sizeof(cache)); engine = rq->engine; - spin_lock_irq(&engine->timeline.lock); + spin_lock(&engine->timeline.lock); /* Fifo and depth-first replacement ensure our deps execute before us */ list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) { @@ -407,32 +407,33 @@ static void __i915_schedule(struct i915_request *rq, tasklet_hi_schedule(&engine->execlists.tasklet); } - spin_unlock_irq(&engine->timeline.lock); + spin_unlock(&engine->timeline.lock); } void i915_schedule(struct i915_request *rq, const struct i915_sched_attr *attr) { - spin_lock(&schedule_lock); + spin_lock_irq(&schedule_lock); __i915_schedule(rq, attr); - spin_unlock(&schedule_lock); + spin_unlock_irq(&schedule_lock); } void i915_schedule_bump_priority(struct i915_request *rq, unsigned int bump) { struct i915_sched_attr attr; + unsigned long flags; GEM_BUG_ON(bump & ~I915_PRIORITY_MASK); if (READ_ONCE(rq->sched.attr.priority) == I915_PRIORITY_INVALID) return; - spin_lock_bh(&schedule_lock); + spin_lock_irqsave(&schedule_lock, flags); attr = rq->sched.attr; attr.priority |= bump; __i915_schedule(rq, &attr); - spin_unlock_bh(&schedule_lock); + spin_unlock_irqrestore(&schedule_lock, flags); } void __i915_priolist_free(struct i915_priolist *p) -- cgit v1.2.3 From a79208de65fe78d684eae529a7a3d606599744a6 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 10 Apr 2019 13:59:17 +0300 Subject: drm/i915: Use dedicated rc6 enabling sequence for gen11 In order not to inflate gen9 rc6 enabling sequence with gen11 specifics, use a separate function for it. Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190410105923.18546-1-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index bba477e62a12..4d87790aefa1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7120,6 +7120,76 @@ static void gen9_enable_rps(struct drm_i915_private *dev_priv) intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); } +static void gen11_enable_rc6(struct drm_i915_private *dev_priv) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + + /* 1a: Software RC state - RC0 */ + I915_WRITE(GEN6_RC_STATE, 0); + + /* + * 1b: Get forcewake during program sequence. Although the driver + * hasn't enabled a state yet where we need forcewake, BIOS may have. + */ + intel_uncore_forcewake_get(&dev_priv->uncore, FORCEWAKE_ALL); + + /* 2a: Disable RC states. */ + I915_WRITE(GEN6_RC_CONTROL, 0); + + /* 2b: Program RC6 thresholds.*/ + I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 54 << 16 | 85); + I915_WRITE(GEN10_MEDIA_WAKE_RATE_LIMIT, 150); + + I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); /* 12500 * 1280ns */ + I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); /* 25 * 1280ns */ + for_each_engine(engine, dev_priv, id) + I915_WRITE(RING_MAX_IDLE(engine->mmio_base), 10); + + if (HAS_GUC(dev_priv)) + I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA); + + I915_WRITE(GEN6_RC_SLEEP, 0); + + /* + * 2c: Program Coarse Power Gating Policies. + * + * Bspec's guidance is to use 25us (really 25 * 1280ns) here. What we + * use instead is a more conservative estimate for the maximum time + * it takes us to service a CS interrupt and submit a new ELSP - that + * is the time which the GPU is idle waiting for the CPU to select the + * next request to execute. If the idle hysteresis is less than that + * interrupt service latency, the hardware will automatically gate + * the power well and we will then incur the wake up cost on top of + * the service latency. A similar guide from intel_pstate is that we + * do not want the enable hysteresis to less than the wakeup latency. + * + * igt/gem_exec_nop/sequential provides a rough estimate for the + * service latency, and puts it around 10us for Broadwell (and other + * big core) and around 40us for Broxton (and other low power cores). + * [Note that for legacy ringbuffer submission, this is less than 1us!] + * However, the wakeup latency on Broxton is closer to 100us. To be + * conservative, we have to factor in a context switch on top (due + * to ksoftirqd). + */ + I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 250); + I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 250); + + /* 3a: Enable RC6 */ + I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ + + I915_WRITE(GEN6_RC_CONTROL, + GEN6_RC_CTL_HW_ENABLE | + GEN6_RC_CTL_RC6_ENABLE | + GEN6_RC_CTL_EI_MODE(1)); + + /* 3b: Enable Coarse Power Gating only when RC6 is enabled. */ + I915_WRITE(GEN9_PG_ENABLE, + GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE); + + intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); +} + static void gen9_enable_rc6(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; @@ -8596,6 +8666,8 @@ static void intel_enable_rc6(struct drm_i915_private *dev_priv) cherryview_enable_rc6(dev_priv); else if (IS_VALLEYVIEW(dev_priv)) valleyview_enable_rc6(dev_priv); + else if (INTEL_GEN(dev_priv) >= 11) + gen11_enable_rc6(dev_priv); else if (INTEL_GEN(dev_priv) >= 9) gen9_enable_rc6(dev_priv); else if (IS_BROADWELL(dev_priv)) -- cgit v1.2.3 From d105e9ad548daabf641d377fb4c963a1aa2d8127 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 10 Apr 2019 13:59:18 +0300 Subject: drm/i915/icl: Apply a recommended rc6 threshold On gen11 the recommended rc6 threshold differs from previous gens, apply it. Move the write to a correct spot in sequence. v2: do write in 2b, fix bspec ref (Michal) Bspec: 33149 Cc: Michal Wajdeczko Signed-off-by: Mika Kuoppala Acked-by: Chris Wilson Reviewed-by: Michal Wajdeczko Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190410105923.18546-2-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4d87790aefa1..b7946a73cea3 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7151,6 +7151,8 @@ static void gen11_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC_SLEEP, 0); + I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */ + /* * 2c: Program Coarse Power Gating Policies. * @@ -7176,8 +7178,6 @@ static void gen11_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN9_RENDER_PG_IDLE_HYSTERESIS, 250); /* 3a: Enable RC6 */ - I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */ - I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | GEN6_RC_CTL_RC6_ENABLE | -- cgit v1.2.3 From 2ea7414159cdbbab76b55f01b4ff560ff2018a4f Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 10 Apr 2019 13:59:19 +0300 Subject: drm/i915/icl: Enable media sampler powergate Enable media sampler powergate as recommended. v2: use REG_BIT (Chris) Cc: Chris Wilson Signed-off-by: Mika Kuoppala Acked-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190410105923.18546-3-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 5 +++-- drivers/gpu/drm/i915/intel_pm.c | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9c206e803ab3..3c243025ea3e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8687,8 +8687,9 @@ enum { #define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4) #define GEN9_RENDER_PG_IDLE_HYSTERESIS _MMIO(0xA0C8) #define GEN9_PG_ENABLE _MMIO(0xA210) -#define GEN9_RENDER_PG_ENABLE (1 << 0) -#define GEN9_MEDIA_PG_ENABLE (1 << 1) +#define GEN9_RENDER_PG_ENABLE REG_BIT(0) +#define GEN9_MEDIA_PG_ENABLE REG_BIT(1) +#define GEN11_MEDIA_SAMPLER_PG_ENABLE REG_BIT(2) #define GEN8_PUSHBUS_CONTROL _MMIO(0xA248) #define GEN8_PUSHBUS_ENABLE _MMIO(0xA250) #define GEN8_PUSHBUS_SHIFT _MMIO(0xA25C) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index b7946a73cea3..2f0204c2be16 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -7185,7 +7185,9 @@ static void gen11_enable_rc6(struct drm_i915_private *dev_priv) /* 3b: Enable Coarse Power Gating only when RC6 is enabled. */ I915_WRITE(GEN9_PG_ENABLE, - GEN9_RENDER_PG_ENABLE | GEN9_MEDIA_PG_ENABLE); + GEN9_RENDER_PG_ENABLE | + GEN9_MEDIA_PG_ENABLE | + GEN11_MEDIA_SAMPLER_PG_ENABLE); intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); } -- cgit v1.2.3 From 1071d0f6877e63d3354bac7fb4b1e6c740b388f0 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 10 Apr 2019 16:24:36 +0300 Subject: drm/i915/icl: Disable video turbo mode for rp control There is no video turbo mode for gen11, so don't set it. v2: inline (Chris) v3: brackets (Chris) Cc: Chris Wilson Signed-off-by: Mika Kuoppala Acked-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190410132436.23679-1-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2f0204c2be16..8e826a6ab62e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6606,7 +6606,7 @@ static void rps_set_power(struct drm_i915_private *dev_priv, int new_power) ei_down * threshold_down / 100)); I915_WRITE(GEN6_RP_CONTROL, - GEN6_RP_MEDIA_TURBO | + (INTEL_GEN(dev_priv) > 9 ? 0 : GEN6_RP_MEDIA_TURBO) | GEN6_RP_MEDIA_HW_NORMAL_MODE | GEN6_RP_MEDIA_IS_GFX | GEN6_RP_ENABLE | -- cgit v1.2.3 From 917dc6b53c273dd7e026f158ad4894ae366da326 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Wed, 10 Apr 2019 13:59:22 +0300 Subject: drm/i915: Use Engine1 instance for gen11 pm interrupts With gen11 the interrupt registers are shared between 2 engines, with Engine1 instance being upper word and Engine0 instance being lower. Annoyingly gen11 selected the pm interrupts to be in the Engine1 instance. Rectify the situation by shifting the access accordingly, based on gen. v2: comments, warn on overzealous rps_events Bugzilla: https://bugzilla.freedesktop.org/show_bug.cgi?id=108059 Testcase: igt/i915_pm_rps@min-max-config-loaded Cc: Chris Wilson Signed-off-by: Mika Kuoppala Acked-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190410105923.18546-6-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_irq.c | 56 ++++++++++++++++++++++++++++------------- drivers/gpu/drm/i915/i915_reg.h | 5 ++++ 2 files changed, 43 insertions(+), 18 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8d8935d71180..d934545445e1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -369,24 +369,41 @@ static i915_reg_t gen6_pm_iir(struct drm_i915_private *dev_priv) return INTEL_GEN(dev_priv) >= 8 ? GEN8_GT_IIR(2) : GEN6_PMIIR; } -static i915_reg_t gen6_pm_imr(struct drm_i915_private *dev_priv) +static void write_pm_imr(struct drm_i915_private *dev_priv) { - if (INTEL_GEN(dev_priv) >= 11) - return GEN11_GPM_WGBOXPERF_INTR_MASK; - else if (INTEL_GEN(dev_priv) >= 8) - return GEN8_GT_IMR(2); - else - return GEN6_PMIMR; + i915_reg_t reg; + u32 mask = dev_priv->pm_imr; + + if (INTEL_GEN(dev_priv) >= 11) { + reg = GEN11_GPM_WGBOXPERF_INTR_MASK; + /* pm is in upper half */ + mask = mask << 16; + } else if (INTEL_GEN(dev_priv) >= 8) { + reg = GEN8_GT_IMR(2); + } else { + reg = GEN6_PMIMR; + } + + I915_WRITE(reg, mask); + POSTING_READ(reg); } -static i915_reg_t gen6_pm_ier(struct drm_i915_private *dev_priv) +static void write_pm_ier(struct drm_i915_private *dev_priv) { - if (INTEL_GEN(dev_priv) >= 11) - return GEN11_GPM_WGBOXPERF_INTR_ENABLE; - else if (INTEL_GEN(dev_priv) >= 8) - return GEN8_GT_IER(2); - else - return GEN6_PMIER; + i915_reg_t reg; + u32 mask = dev_priv->pm_ier; + + if (INTEL_GEN(dev_priv) >= 11) { + reg = GEN11_GPM_WGBOXPERF_INTR_ENABLE; + /* pm is in upper half */ + mask = mask << 16; + } else if (INTEL_GEN(dev_priv) >= 8) { + reg = GEN8_GT_IER(2); + } else { + reg = GEN6_PMIER; + } + + I915_WRITE(reg, mask); } /** @@ -411,8 +428,7 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv, if (new_val != dev_priv->pm_imr) { dev_priv->pm_imr = new_val; - I915_WRITE(gen6_pm_imr(dev_priv), dev_priv->pm_imr); - POSTING_READ(gen6_pm_imr(dev_priv)); + write_pm_imr(dev_priv); } } @@ -453,7 +469,7 @@ static void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, u32 enable_mas lockdep_assert_held(&dev_priv->irq_lock); dev_priv->pm_ier |= enable_mask; - I915_WRITE(gen6_pm_ier(dev_priv), dev_priv->pm_ier); + write_pm_ier(dev_priv); gen6_unmask_pm_irq(dev_priv, enable_mask); /* unmask_pm_irq provides an implicit barrier (POSTING_READ) */ } @@ -464,7 +480,7 @@ static void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, u32 disable_m dev_priv->pm_ier &= ~disable_mask; __gen6_mask_pm_irq(dev_priv, disable_mask); - I915_WRITE(gen6_pm_ier(dev_priv), dev_priv->pm_ier); + write_pm_ier(dev_priv); /* though a barrier is missing here, but don't really need a one */ } @@ -4639,6 +4655,10 @@ void intel_irq_init(struct drm_i915_private *dev_priv) GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT); + /* We share the register with other engine */ + if (INTEL_GEN(dev_priv) > 9) + GEM_WARN_ON(dev_priv->pm_rps_events & 0xffff0000); + rps->pm_intrmsk_mbz = 0; /* diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3c243025ea3e..8ad2f0a03f28 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8704,6 +8704,11 @@ enum { #define GEN6_PMIER _MMIO(0x4402C) #define GEN6_PM_MBOX_EVENT (1 << 25) #define GEN6_PM_THERMAL_EVENT (1 << 24) + +/* + * For Gen11 these are in the upper word of the GPM_WGBOXPERF + * registers. Shifting is handled on accessing the imr and ier. + */ #define GEN6_PM_RP_DOWN_TIMEOUT (1 << 6) #define GEN6_PM_RP_UP_THRESHOLD (1 << 5) #define GEN6_PM_RP_DOWN_THRESHOLD (1 << 4) -- cgit v1.2.3 From 7d4c75d9097a0031b0aabf0bbc127ae7dcf93de3 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 5 Apr 2019 21:46:56 +0100 Subject: drm/i915: Prepare for larger CSB status FIFO size Make csb entry count variable in preparation for larger CSB status FIFO size found on gen11+ hardware. v2: adapt to hwsp access only (Chris) non continuous mmio (Daniele) v3: entries (Chris), fix macro for checkpatch v4: num_entries (Chris) v5: consistency on num_entries Cc: Daniele Ceraolo Spurio Cc: Chris Wilson Cc: Joonas Lahtinen Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190405204657.12887-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_engine_cs.c | 29 +++++++++++------------------ drivers/gpu/drm/i915/intel_engine_types.h | 5 +++++ drivers/gpu/drm/i915/intel_lrc.c | 7 +++++-- drivers/gpu/drm/i915/intel_lrc.h | 13 ++++++------- 4 files changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index f29a667cad52..eea9bec04f1b 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1405,40 +1405,33 @@ static void intel_engine_print_registers(const struct intel_engine_cs *engine, if (HAS_EXECLISTS(dev_priv)) { const u32 *hws = &engine->status_page.addr[I915_HWS_CSB_BUF0_INDEX]; + const u8 num_entries = execlists->csb_size; unsigned int idx; u8 read, write; - drm_printf(m, "\tExeclist status: 0x%08x %08x\n", + drm_printf(m, "\tExeclist status: 0x%08x %08x, entries %u\n", ENGINE_READ(engine, RING_EXECLIST_STATUS_LO), - ENGINE_READ(engine, RING_EXECLIST_STATUS_HI)); + ENGINE_READ(engine, RING_EXECLIST_STATUS_HI), + num_entries); read = execlists->csb_head; write = READ_ONCE(*execlists->csb_write); - drm_printf(m, "\tExeclist CSB read %d, write %d [mmio:%d], tasklet queued? %s (%s)\n", + drm_printf(m, "\tExeclist CSB read %d, write %d, tasklet queued? %s (%s)\n", read, write, - GEN8_CSB_WRITE_PTR(ENGINE_READ(engine, RING_CONTEXT_STATUS_PTR)), yesno(test_bit(TASKLET_STATE_SCHED, &engine->execlists.tasklet.state)), enableddisabled(!atomic_read(&engine->execlists.tasklet.count))); - if (read >= GEN8_CSB_ENTRIES) + if (read >= num_entries) read = 0; - if (write >= GEN8_CSB_ENTRIES) + if (write >= num_entries) write = 0; if (read > write) - write += GEN8_CSB_ENTRIES; + write += num_entries; while (read < write) { - idx = ++read % GEN8_CSB_ENTRIES; - drm_printf(m, "\tExeclist CSB[%d]: 0x%08x [mmio:0x%08x], context: %d [mmio:%d]\n", - idx, - hws[idx * 2], - ENGINE_READ_IDX(engine, - RING_CONTEXT_STATUS_BUF_LO, - idx), - hws[idx * 2 + 1], - ENGINE_READ_IDX(engine, - RING_CONTEXT_STATUS_BUF_HI, - idx)); + idx = ++read % num_entries; + drm_printf(m, "\tExeclist CSB[%d]: 0x%08x, context: %d\n", + idx, hws[idx * 2], hws[idx * 2 + 1]); } rcu_read_lock(); diff --git a/drivers/gpu/drm/i915/intel_engine_types.h b/drivers/gpu/drm/i915/intel_engine_types.h index 6c6d8a9aca94..1f970c76b6a6 100644 --- a/drivers/gpu/drm/i915/intel_engine_types.h +++ b/drivers/gpu/drm/i915/intel_engine_types.h @@ -246,6 +246,11 @@ struct intel_engine_execlists { */ u32 preempt_complete_status; + /** + * @csb_size: context status buffer FIFO size + */ + u8 csb_size; + /** * @csb_head: context status buffer head */ diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index b54dbf36197e..6a104ce3291e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -895,7 +895,7 @@ invalidate_csb_entries(const u32 *first, const u32 *last) static void reset_csb_pointers(struct intel_engine_execlists *execlists) { - const unsigned int reset_value = GEN8_CSB_ENTRIES - 1; + const unsigned int reset_value = execlists->csb_size - 1; /* * After a reset, the HW starts writing into CSB entry [0]. We @@ -994,6 +994,7 @@ static void process_csb(struct intel_engine_cs *engine) struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port *port = execlists->port; const u32 * const buf = execlists->csb_status; + const u8 num_entries = execlists->csb_size; u8 head, tail; lockdep_assert_held(&engine->timeline.lock); @@ -1029,7 +1030,7 @@ static void process_csb(struct intel_engine_cs *engine) unsigned int status; unsigned int count; - if (++head == GEN8_CSB_ENTRIES) + if (++head == num_entries) head = 0; /* @@ -2476,6 +2477,8 @@ static int logical_ring_init(struct intel_engine_cs *engine) execlists->csb_write = &engine->status_page.addr[intel_hws_csb_write_index(i915)]; + execlists->csb_size = GEN8_CSB_ENTRIES; + reset_csb_pointers(execlists); return 0; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 4d0b7736cb6d..1e343a4af442 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -36,12 +36,10 @@ #define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT (1 << 0) #define CTX_CTRL_RS_CTX_ENABLE (1 << 1) #define CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT (1 << 2) -#define RING_CONTEXT_STATUS_BUF_BASE(base) _MMIO((base) + 0x370) -#define RING_CONTEXT_STATUS_BUF_LO(base, i) _MMIO((base) + 0x370 + (i) * 8) -#define RING_CONTEXT_STATUS_BUF_HI(base, i) _MMIO((base) + 0x370 + (i) * 8 + 4) #define RING_CONTEXT_STATUS_PTR(base) _MMIO((base) + 0x3a0) #define RING_EXECLIST_SQ_CONTENTS(base) _MMIO((base) + 0x510) #define RING_EXECLIST_CONTROL(base) _MMIO((base) + 0x550) + #define EL_CTRL_LOAD (1 << 0) /* The docs specify that the write pointer wraps around after 5h, "After status @@ -55,10 +53,11 @@ #define GEN8_CSB_PTR_MASK 0x7 #define GEN8_CSB_READ_PTR_MASK (GEN8_CSB_PTR_MASK << 8) #define GEN8_CSB_WRITE_PTR_MASK (GEN8_CSB_PTR_MASK << 0) -#define GEN8_CSB_WRITE_PTR(csb_status) \ - (((csb_status) & GEN8_CSB_WRITE_PTR_MASK) >> 0) -#define GEN8_CSB_READ_PTR(csb_status) \ - (((csb_status) & GEN8_CSB_READ_PTR_MASK) >> 8) + +#define GEN11_CSB_ENTRIES 12 +#define GEN11_CSB_PTR_MASK 0xf +#define GEN11_CSB_READ_PTR_MASK (GEN11_CSB_PTR_MASK << 8) +#define GEN11_CSB_WRITE_PTR_MASK (GEN11_CSB_PTR_MASK << 0) enum { INTEL_CONTEXT_SCHEDULE_IN = 0, -- cgit v1.2.3 From 632c7ad6f4509767fcbe76ac034747b4a30a13d9 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 5 Apr 2019 21:46:57 +0100 Subject: drm/i915/icl: Switch to using 12 deep CSB status FIFO Now when we can support variable csb fifo sizes, disable legacy mode. By disabling legacy we hope to get better hw testing coverage by assuming everyone else have switched over. v2: rebase References: https://bugs.freedesktop.org/show_bug.cgi?id=110338 Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Daniele Ceraolo Spurio Cc: Kelvin Gardiner Cc: Paulo Zanoni Signed-off-by: Mika Kuoppala Acked-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190405204657.12887-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6a104ce3291e..75446e4b983a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1849,17 +1849,9 @@ static void enable_execlists(struct intel_engine_cs *engine) intel_engine_set_hwsp_writemask(engine, ~0u); /* HWSTAM */ - /* - * Make sure we're not enabling the new 12-deep CSB - * FIFO as that requires a slightly updated handling - * in the ctx switch irq. Since we're currently only - * using only 2 elements of the enhanced execlists the - * deeper FIFO it's not needed and it's not worth adding - * more statements to the irq handler to support it. - */ if (INTEL_GEN(dev_priv) >= 11) I915_WRITE(RING_MODE_GEN7(engine), - _MASKED_BIT_DISABLE(GEN11_GFX_DISABLE_LEGACY_MODE)); + _MASKED_BIT_ENABLE(GEN11_GFX_DISABLE_LEGACY_MODE)); else I915_WRITE(RING_MODE_GEN7(engine), _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); @@ -2477,7 +2469,10 @@ static int logical_ring_init(struct intel_engine_cs *engine) execlists->csb_write = &engine->status_page.addr[intel_hws_csb_write_index(i915)]; - execlists->csb_size = GEN8_CSB_ENTRIES; + if (INTEL_GEN(engine->i915) < 11) + execlists->csb_size = GEN8_CSB_ENTRIES; + else + execlists->csb_size = GEN11_CSB_ENTRIES; reset_csb_pointers(execlists); -- cgit v1.2.3 From e154592a1d25fa1f50ac1bd8d132d0e1103442ba Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 11 Apr 2019 00:47:46 +0200 Subject: gpu: host1x: Fix compile error when IOMMU API is not available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case the IOMMU API is not available compiling host1x fails with the following error: In file included from drivers/gpu/host1x/hw/host1x06.c:27: drivers/gpu/host1x/hw/channel_hw.c: In function ‘host1x_channel_set_streamid’: drivers/gpu/host1x/hw/channel_hw.c:118:30: error: implicit declaration of function ‘dev_iommu_fwspec_get’; did you mean ‘iommu_fwspec_free’? [-Werror=implicit-function-declaration] struct iommu_fwspec *spec = dev_iommu_fwspec_get(channel->dev->parent); ^~~~~~~~~~~~~~~~~~~~ iommu_fwspec_free Fixes: de5469c21ff9 ("gpu: host1x: Program the channel stream ID") Signed-off-by: Stefan Agner Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/channel_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c index 27101c04a827..4030d64916f0 100644 --- a/drivers/gpu/host1x/hw/channel_hw.c +++ b/drivers/gpu/host1x/hw/channel_hw.c @@ -114,7 +114,7 @@ static inline void synchronize_syncpt_base(struct host1x_job *job) static void host1x_channel_set_streamid(struct host1x_channel *channel) { -#if HOST1X_HW >= 6 +#if IS_ENABLED(CONFIG_IOMMU_API) && HOST1X_HW >= 6 struct iommu_fwspec *spec = dev_iommu_fwspec_get(channel->dev->parent); u32 sid = spec ? spec->ids[0] & 0xffff : 0x7f; -- cgit v1.2.3 From 4e2056e05e6eb646d37e310c11f6ac97a266b355 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 26 Mar 2019 16:25:56 +0200 Subject: drm/i915: Set DP min_bpp to 8*3 for non-RGB output formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6bpc is only legal for RGB and RAW pixel encodings. For the rest the minimum is 8bpc. Set our lower limit accordingly. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190326142556.21176-6-ville.syrjala@linux.intel.com Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/i915/intel_dp.c | 10 +++++++++- drivers/gpu/drm/i915/intel_dp.h | 1 + drivers/gpu/drm/i915/intel_dp_mst.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0936d08aa982..6f1babe911df 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1978,6 +1978,14 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, return 0; } +int intel_dp_min_bpp(const struct intel_crtc_state *crtc_state) +{ + if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) + return 6 * 3; + else + return 8 * 3; +} + static int intel_dp_compute_link_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, @@ -2001,7 +2009,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, limits.min_lane_count = 1; limits.max_lane_count = intel_dp_max_lane_count(intel_dp); - limits.min_bpp = 6 * 3; + limits.min_bpp = intel_dp_min_bpp(pipe_config); limits.max_bpp = intel_dp_compute_bpp(intel_dp, pipe_config); if (intel_dp_is_edp(intel_dp)) { diff --git a/drivers/gpu/drm/i915/intel_dp.h b/drivers/gpu/drm/i915/intel_dp.h index 5c152ca6f9ed..5e9e8d13de6e 100644 --- a/drivers/gpu/drm/i915/intel_dp.h +++ b/drivers/gpu/drm/i915/intel_dp.h @@ -34,6 +34,7 @@ void intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, struct link_config_limits *limits); bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); +int intel_dp_min_bpp(const struct intel_crtc_state *crtc_state); bool intel_dp_port_enabled(struct drm_i915_private *dev_priv, i915_reg_t dp_reg, enum port port, enum pipe *pipe); diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 9c4c0589c0fc..8839eaea8371 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -124,7 +124,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, limits.min_lane_count = limits.max_lane_count = intel_dp_max_lane_count(intel_dp); - limits.min_bpp = 6 * 3; + limits.min_bpp = intel_dp_min_bpp(pipe_config); limits.max_bpp = pipe_config->pipe_bpp; intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits); -- cgit v1.2.3 From aefa95bacfbe65c3abcd8832575af023bc21cce8 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 26 Mar 2019 16:49:03 +0200 Subject: drm/i915: Clean up DSC vs. not bpp handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No point in duplicating all this code when we can just use a variable to hold the output bpp (the only thing that differs between the two branches). Cc: Anusha Srivatsa Cc: Manasi Navare Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190326144903.6617-2-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/intel_dp.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6f1babe911df..e0c59383d11e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2111,7 +2111,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, to_intel_digital_connector_state(conn_state); bool constant_n = drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_CONSTANT_N); - int ret; + int ret, output_bpp; if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A) pipe_config->has_pch_encoder = true; @@ -2166,25 +2166,22 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->limited_color_range = intel_dp_limited_color_range(pipe_config, conn_state); - if (!pipe_config->dsc_params.compression_enable) - intel_link_compute_m_n(pipe_config->pipe_bpp, - pipe_config->lane_count, - adjusted_mode->crtc_clock, - pipe_config->port_clock, - &pipe_config->dp_m_n, - constant_n); + if (pipe_config->dsc_params.compression_enable) + output_bpp = pipe_config->dsc_params.compressed_bpp; else - intel_link_compute_m_n(pipe_config->dsc_params.compressed_bpp, - pipe_config->lane_count, - adjusted_mode->crtc_clock, - pipe_config->port_clock, - &pipe_config->dp_m_n, - constant_n); + output_bpp = pipe_config->pipe_bpp; + + intel_link_compute_m_n(output_bpp, + pipe_config->lane_count, + adjusted_mode->crtc_clock, + pipe_config->port_clock, + &pipe_config->dp_m_n, + constant_n); if (intel_connector->panel.downclock_mode != NULL && dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) { pipe_config->has_drrs = true; - intel_link_compute_m_n(pipe_config->pipe_bpp, + intel_link_compute_m_n(output_bpp, pipe_config->lane_count, intel_connector->panel.downclock_mode->clock, pipe_config->port_clock, -- cgit v1.2.3 From 0c441cb6f3eeed8ac07fd8c3fd5a0dd2ac568362 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 11 Apr 2019 13:24:45 +0100 Subject: drm/i915: Call i915_sw_fence_fini on request cleanup As i915_requests are put into an RCU-freelist, they may get reused before debugobjects notice them as being freed. On cleanup, explicitly call i915_sw_fence_fini() so that the debugobject is properly tracked. Reported-by: Mika Kuoppala Fixes: b7404c7ecb38 ("drm/i915: Bump ready tasks ahead of busywaits") Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20190411122445.20060-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_request.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index a7d87cfaabcb..b836721d3b13 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -101,6 +101,7 @@ static void i915_fence_release(struct dma_fence *fence) * caught trying to reuse dead objects. */ i915_sw_fence_fini(&rq->submit); + i915_sw_fence_fini(&rq->semaphore); kmem_cache_free(global.slab_requests, rq); } -- cgit v1.2.3 From 3936867dbc1eb8790aa5985a68d53e4303b3616f Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Thu, 11 Apr 2019 11:30:34 +0300 Subject: drm/i915: Disable read only ppgtt support for gen11 On gen11 writing to read only ppgtt page causes a gpu hang. This behaviour is different than with previous gen where read only ppgtt access is supported. On those, the write is just dropped without visible side effects. Disable ro ppgtt support on gen11 until a solution can be found to bring it into line with its predecessors. References: HSDES#1807136187 References: https://bugzilla.freedesktop.org/show_bug.cgi?id=108569 Cc: Chris Wilson Signed-off-by: Mika Kuoppala Acked-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190411083034.28311-1-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_gem_gtt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 736c845eb77f..8f460cc4cc1f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1228,7 +1228,7 @@ static int gen8_init_scratch(struct i915_address_space *vm) vm->scratch_pte = gen8_pte_encode(vm->scratch_page.daddr, I915_CACHE_LLC, - PTE_READ_ONLY); + vm->has_read_only); vm->scratch_pt = alloc_pt(vm); if (IS_ERR(vm->scratch_pt)) { @@ -1548,8 +1548,13 @@ static struct i915_hw_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915) ppgtt_init(i915, ppgtt); - /* From bdw, there is support for read-only pages in the PPGTT. */ - ppgtt->vm.has_read_only = true; + /* + * From bdw, there is hw support for read-only pages in the PPGTT. + * + * Gen11 has HSDES#:1807136187 unresolved. Disable ro support + * for now. + */ + ppgtt->vm.has_read_only = INTEL_GEN(i915) != 11; /* There are only few exceptions for gen >=6. chv and bxt. * And we are not sure about the latter so play safe for now. -- cgit v1.2.3 From 292ad25c22d96583b76ce714b7a06941d54bd939 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 11 Apr 2019 14:05:14 +0100 Subject: drm/i915/guc: Implement reset locally Before causing guc and execlists to diverge further (breaking guc in the process), take a copy of the current reset procedure and make it local to the guc submission backend Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20190411130515.20716-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_guc_submission.c | 102 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.c | 37 +++++++++- drivers/gpu/drm/i915/intel_lrc.h | 5 ++ drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 4 files changed, 143 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index dea87253d141..37f60cb8e9e1 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -872,6 +872,104 @@ static void guc_reset_prepare(struct intel_engine_cs *engine) flush_workqueue(engine->i915->guc.preempt_wq); } +static void guc_reset(struct intel_engine_cs *engine, bool stalled) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + struct i915_request *rq; + unsigned long flags; + + spin_lock_irqsave(&engine->timeline.lock, flags); + + execlists_cancel_port_requests(execlists); + + /* Push back any incomplete requests for replay after the reset. */ + rq = execlists_unwind_incomplete_requests(execlists); + if (!rq) + goto out_unlock; + + if (!i915_request_started(rq)) + stalled = false; + + i915_reset_request(rq, stalled); + intel_lr_context_reset(engine, rq->hw_context, rq->head, stalled); + +out_unlock: + spin_unlock_irqrestore(&engine->timeline.lock, flags); +} + +static void guc_cancel_requests(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + struct i915_request *rq, *rn; + struct rb_node *rb; + unsigned long flags; + + GEM_TRACE("%s\n", engine->name); + + /* + * Before we call engine->cancel_requests(), we should have exclusive + * access to the submission state. This is arranged for us by the + * caller disabling the interrupt generation, the tasklet and other + * threads that may then access the same state, giving us a free hand + * to reset state. However, we still need to let lockdep be aware that + * we know this state may be accessed in hardirq context, so we + * disable the irq around this manipulation and we want to keep + * the spinlock focused on its duties and not accidentally conflate + * coverage to the submission's irq state. (Similarly, although we + * shouldn't need to disable irq around the manipulation of the + * submission's irq state, we also wish to remind ourselves that + * it is irq state.) + */ + spin_lock_irqsave(&engine->timeline.lock, flags); + + /* Cancel the requests on the HW and clear the ELSP tracker. */ + execlists_cancel_port_requests(execlists); + + /* Mark all executing requests as skipped. */ + list_for_each_entry(rq, &engine->timeline.requests, link) { + if (!i915_request_signaled(rq)) + dma_fence_set_error(&rq->fence, -EIO); + + i915_request_mark_complete(rq); + } + + /* Flush the queued requests to the timeline list (for retiring). */ + while ((rb = rb_first_cached(&execlists->queue))) { + struct i915_priolist *p = to_priolist(rb); + int i; + + priolist_for_each_request_consume(rq, rn, p, i) { + list_del_init(&rq->sched.link); + __i915_request_submit(rq); + dma_fence_set_error(&rq->fence, -EIO); + i915_request_mark_complete(rq); + } + + rb_erase_cached(&p->node, &execlists->queue); + i915_priolist_free(p); + } + + /* Remaining _unready_ requests will be nop'ed when submitted */ + + execlists->queue_priority_hint = INT_MIN; + execlists->queue = RB_ROOT_CACHED; + GEM_BUG_ON(port_isset(execlists->port)); + + spin_unlock_irqrestore(&engine->timeline.lock, flags); +} + +static void guc_reset_finish(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + if (__tasklet_enable(&execlists->tasklet)) + /* And kick in case we missed a new request submission. */ + tasklet_hi_schedule(&execlists->tasklet); + + GEM_TRACE("%s: depth->%d\n", engine->name, + atomic_read(&execlists->tasklet.count)); +} + /* * Everything below here is concerned with setup & teardown, and is * therefore not part of the somewhat time-critical batch-submission @@ -1293,6 +1391,10 @@ static void guc_set_default_submission(struct intel_engine_cs *engine) engine->unpark = guc_submission_unpark; engine->reset.prepare = guc_reset_prepare; + engine->reset.reset = guc_reset; + engine->reset.finish = guc_reset_finish; + + engine->cancel_requests = guc_cancel_requests; engine->flags &= ~I915_ENGINE_SUPPORTS_STATS; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 75446e4b983a..95ec4f7ad083 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -429,13 +429,13 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine) return active; } -void +struct i915_request * execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists) { struct intel_engine_cs *engine = container_of(execlists, typeof(*engine), execlists); - __unwind_incomplete_requests(engine); + return __unwind_incomplete_requests(engine); } static inline void @@ -2345,6 +2345,8 @@ void intel_execlists_set_default_submission(struct intel_engine_cs *engine) engine->execlists.tasklet.func = execlists_submission_tasklet; engine->reset.prepare = execlists_reset_prepare; + engine->reset.reset = execlists_reset; + engine->reset.finish = execlists_reset_finish; engine->park = NULL; engine->unpark = NULL; @@ -2977,6 +2979,37 @@ void intel_execlists_show_requests(struct intel_engine_cs *engine, spin_unlock_irqrestore(&engine->timeline.lock, flags); } +void intel_lr_context_reset(struct intel_engine_cs *engine, + struct intel_context *ce, + u32 head, + bool scrub) +{ + /* + * We want a simple context + ring to execute the breadcrumb update. + * We cannot rely on the context being intact across the GPU hang, + * so clear it and rebuild just what we need for the breadcrumb. + * All pending requests for this context will be zapped, and any + * future request will be after userspace has had the opportunity + * to recreate its own state. + */ + if (scrub) { + u32 *regs = ce->lrc_reg_state; + + if (engine->pinned_default_state) { + memcpy(regs, /* skip restoring the vanilla PPHWSP */ + engine->pinned_default_state + LRC_STATE_PN * PAGE_SIZE, + engine->context_size - PAGE_SIZE); + } + execlists_init_reg_state(regs, ce, engine, ce->ring); + } + + /* Rerun the request; its payload has been neutered (if guilty). */ + ce->ring->head = head; + intel_ring_update_space(ce->ring); + + __execlists_update_reg_state(ce, engine); +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/intel_lrc.c" #endif diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 1e343a4af442..84aa230ea27b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -103,6 +103,11 @@ struct i915_gem_context; void intel_execlists_set_default_submission(struct intel_engine_cs *engine); +void intel_lr_context_reset(struct intel_engine_cs *engine, + struct intel_context *ce, + u32 head, + bool scrub); + void intel_execlists_show_requests(struct intel_engine_cs *engine, struct drm_printer *m, void (*show_request)(struct drm_printer *m, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 0dea6c7fd438..4b33e88eabb1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -165,7 +165,7 @@ void execlists_user_end(struct intel_engine_execlists *execlists); void execlists_cancel_port_requests(struct intel_engine_execlists * const execlists); -void +struct i915_request * execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists); static inline unsigned int -- cgit v1.2.3 From 1863e3020ab50bd5f68d85719ba26356cc282643 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 11 Apr 2019 14:05:15 +0100 Subject: drm/i915/execlists: Always reset the context's RING registers During reset, we try and stop the active ring. This has the consequence that we often clobber the RING registers within the context image. When we find an active request, we update the context image to rerun that request (if it was guilty, we replace the hanging user payload with NOPs). However, we were ignoring an active context if the request had completed, with the consequence that the next submission on that request would start with RING_HEAD==0 and not the tail of the previous request, causing all requests still in the ring to be rerun. Rare, but occasionally seen within CI where we would spot that the context seqno would reverse and complain that we were retiring an incomplete request. <0> [412.390350] -0 3d.s2 408373352us : __i915_request_submit: rcs0 fence 1e95b:3640 -> current 3638 <0> [412.390350] -0 3d.s2 408373353us : __i915_request_submit: rcs0 fence 1e95b:3642 -> current 3638 <0> [412.390350] -0 3d.s2 408373354us : __i915_request_submit: rcs0 fence 1e95b:3644 -> current 3638 <0> [412.390350] -0 3d.s2 408373354us : __i915_request_submit: rcs0 fence 1e95b:3646 -> current 3638 <0> [412.390350] -0 3d.s2 408373356us : __execlists_submission_tasklet: rcs0 in[0]: ctx=2.1, fence 1e95b:3646 (current 3638), prio=4 <0> [412.390350] i915_sel-4613 0.... 408373374us : __i915_request_commit: rcs0 fence 1e95b:3648 <0> [412.390350] i915_sel-4613 0d..1 408373377us : process_csb: rcs0 cs-irq head=2, tail=3 <0> [412.390350] i915_sel-4613 0d..1 408373377us : process_csb: rcs0 csb[3]: status=0x00000001:0x00000000, active=0x1 <0> [412.390350] i915_sel-4613 0d..1 408373378us : __i915_request_submit: rcs0 fence 1e95b:3648 -> current 3638 <0> [412.390350] -0 3..s1 408373378us : execlists_submission_tasklet: rcs0 awake?=1, active=5 <0> [412.390350] i915_sel-4613 0d..1 408373379us : __execlists_submission_tasklet: rcs0 in[0]: ctx=2.2, fence 1e95b:3648 (current 3638), prio=4 <0> [412.390350] i915_sel-4613 0.... 408373381us : i915_reset_engine: rcs0 flags=4 <0> [412.390350] i915_sel-4613 0.... 408373382us : execlists_reset_prepare: rcs0: depth<-0 <0> [412.390350] -0 3d.s2 408373390us : process_csb: rcs0 cs-irq head=3, tail=4 <0> [412.390350] -0 3d.s2 408373390us : process_csb: rcs0 csb[4]: status=0x00008002:0x00000002, active=0x1 <0> [412.390350] -0 3d.s2 408373390us : process_csb: rcs0 out[0]: ctx=2.2, fence 1e95b:3648 (current 3640), prio=4 <0> [412.390350] i915_sel-4613 0.... 408373401us : intel_engine_stop_cs: rcs0 <0> [412.390350] i915_sel-4613 0d..1 408373402us : process_csb: rcs0 cs-irq head=4, tail=4 <0> [412.390350] i915_sel-4613 0.... 408373403us : intel_gpu_reset: engine_mask=1 <0> [412.390350] i915_sel-4613 0d..1 408373408us : execlists_cancel_port_requests: rcs0:port0 fence 1e95b:3648, (current 3648) <0> [412.390350] i915_sel-4613 0.... 408373442us : intel_engine_cancel_stop_cs: rcs0 <0> [412.390350] i915_sel-4613 0.... 408373442us : execlists_reset_finish: rcs0: depth->0 <0> [412.390350] ksoftirq-26 3..s. 408373442us : execlists_submission_tasklet: rcs0 awake?=1, active=0 <0> [412.390350] ksoftirq-26 3d.s1 408373443us : process_csb: rcs0 cs-irq head=5, tail=5 <0> [412.390350] i915_sel-4613 0.... 408373475us : i915_request_retire: rcs0 fence 1e95b:3640, current 3648 <0> [412.390350] i915_sel-4613 0.... 408373476us : i915_request_retire: __retire_engine_request(rcs0) fence 1e95b:3640, current 3648 <0> [412.390350] i915_sel-4613 0.... 408373494us : __i915_request_commit: rcs0 fence 1e95b:3650 <0> [412.390350] i915_sel-4613 0d..1 408373496us : process_csb: rcs0 cs-irq head=5, tail=5 <0> [412.390350] i915_sel-4613 0d..1 408373496us : __i915_request_submit: rcs0 fence 1e95b:3650 -> current 3648 <0> [412.390350] i915_sel-4613 0d..1 408373498us : __execlists_submission_tasklet: rcs0 in[0]: ctx=2.1, fence 1e95b:3650 (current 3648), prio=6 <0> [412.390350] i915_sel-4613 0.... 408373500us : i915_request_retire_upto: rcs0 fence 1e95b:3648, current 3648 <0> [412.390350] i915_sel-4613 0.... 408373500us : i915_request_retire: rcs0 fence 1e95b:3642, current 3648 <0> [412.390350] i915_sel-4613 0.... 408373501us : i915_request_retire: __retire_engine_request(rcs0) fence 1e95b:3642, current 3648 <0> [412.390350] i915_sel-4613 0.... 408373514us : i915_request_retire: rcs0 fence 1e95b:3644, current 3648 <0> [412.390350] i915_sel-4613 0.... 408373515us : i915_request_retire: __retire_engine_request(rcs0) fence 1e95b:3644, current 3648 <0> [412.390350] i915_sel-4613 0.... 408373527us : i915_request_retire: rcs0 fence 1e95b:3646, current 3640 <0> [412.390350] -0 3..s1 408373569us : execlists_submission_tasklet: rcs0 awake?=1, active=1 <0> [412.390350] -0 3d.s2 408373569us : process_csb: rcs0 cs-irq head=5, tail=1 <0> [412.390350] -0 3d.s2 408373570us : process_csb: rcs0 csb[0]: status=0x00000001:0x00000000, active=0x1 <0> [412.390350] -0 3d.s2 408373570us : process_csb: rcs0 csb[1]: status=0x00000018:0x00000002, active=0x5 <0> [412.390350] -0 3d.s2 408373570us : process_csb: rcs0 out[0]: ctx=2.1, fence 1e95b:3650 (current 3650), prio=6 <0> [412.390350] -0 3d.s2 408373571us : process_csb: rcs0 completed ctx=2 <0> [412.390350] i915_sel-4613 0.... 408373621us : i915_request_retire: i915_request_retire:253 GEM_BUG_ON(!i915_request_completed(request)) v2: Fixup the cancellation path to drain the CSB and reset the pointers. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20190411130515.20716-2-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 241 +++++++++++++++++++++------------------ 1 file changed, 133 insertions(+), 108 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 95ec4f7ad083..3cb788a223ef 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -893,96 +893,6 @@ invalidate_csb_entries(const u32 *first, const u32 *last) clflush((void *)last); } -static void reset_csb_pointers(struct intel_engine_execlists *execlists) -{ - const unsigned int reset_value = execlists->csb_size - 1; - - /* - * After a reset, the HW starts writing into CSB entry [0]. We - * therefore have to set our HEAD pointer back one entry so that - * the *first* entry we check is entry 0. To complicate this further, - * as we don't wait for the first interrupt after reset, we have to - * fake the HW write to point back to the last entry so that our - * inline comparison of our cached head position against the last HW - * write works even before the first interrupt. - */ - execlists->csb_head = reset_value; - WRITE_ONCE(*execlists->csb_write, reset_value); - - invalidate_csb_entries(&execlists->csb_status[0], - &execlists->csb_status[GEN8_CSB_ENTRIES - 1]); -} - -static void nop_submission_tasklet(unsigned long data) -{ - /* The driver is wedged; don't process any more events. */ -} - -static void execlists_cancel_requests(struct intel_engine_cs *engine) -{ - struct intel_engine_execlists * const execlists = &engine->execlists; - struct i915_request *rq, *rn; - struct rb_node *rb; - unsigned long flags; - - GEM_TRACE("%s\n", engine->name); - - /* - * Before we call engine->cancel_requests(), we should have exclusive - * access to the submission state. This is arranged for us by the - * caller disabling the interrupt generation, the tasklet and other - * threads that may then access the same state, giving us a free hand - * to reset state. However, we still need to let lockdep be aware that - * we know this state may be accessed in hardirq context, so we - * disable the irq around this manipulation and we want to keep - * the spinlock focused on its duties and not accidentally conflate - * coverage to the submission's irq state. (Similarly, although we - * shouldn't need to disable irq around the manipulation of the - * submission's irq state, we also wish to remind ourselves that - * it is irq state.) - */ - spin_lock_irqsave(&engine->timeline.lock, flags); - - /* Cancel the requests on the HW and clear the ELSP tracker. */ - execlists_cancel_port_requests(execlists); - execlists_user_end(execlists); - - /* Mark all executing requests as skipped. */ - list_for_each_entry(rq, &engine->timeline.requests, link) { - if (!i915_request_signaled(rq)) - dma_fence_set_error(&rq->fence, -EIO); - - i915_request_mark_complete(rq); - } - - /* Flush the queued requests to the timeline list (for retiring). */ - while ((rb = rb_first_cached(&execlists->queue))) { - struct i915_priolist *p = to_priolist(rb); - int i; - - priolist_for_each_request_consume(rq, rn, p, i) { - list_del_init(&rq->sched.link); - __i915_request_submit(rq); - dma_fence_set_error(&rq->fence, -EIO); - i915_request_mark_complete(rq); - } - - rb_erase_cached(&p->node, &execlists->queue); - i915_priolist_free(p); - } - - /* Remaining _unready_ requests will be nop'ed when submitted */ - - execlists->queue_priority_hint = INT_MIN; - execlists->queue = RB_ROOT_CACHED; - GEM_BUG_ON(port_isset(execlists->port)); - - GEM_BUG_ON(__tasklet_is_enabled(&execlists->tasklet)); - execlists->tasklet.func = nop_submission_tasklet; - - spin_unlock_irqrestore(&engine->timeline.lock, flags); -} - static inline bool reset_in_progress(const struct intel_engine_execlists *execlists) { @@ -1152,7 +1062,7 @@ static void process_csb(struct intel_engine_cs *engine) * the wash as hardware, working or not, will need to do the * invalidation before. */ - invalidate_csb_entries(&buf[0], &buf[GEN8_CSB_ENTRIES - 1]); + invalidate_csb_entries(&buf[0], &buf[num_entries - 1]); } static void __execlists_submission_tasklet(struct intel_engine_cs *const engine) @@ -1921,7 +1831,6 @@ static void execlists_reset_prepare(struct intel_engine_cs *engine) /* And flush any current direct submission. */ spin_lock_irqsave(&engine->timeline.lock, flags); - process_csb(engine); /* drain preemption events */ spin_unlock_irqrestore(&engine->timeline.lock, flags); } @@ -1942,14 +1851,47 @@ static bool lrc_regs_ok(const struct i915_request *rq) return true; } -static void execlists_reset(struct intel_engine_cs *engine, bool stalled) +static void reset_csb_pointers(struct intel_engine_execlists *execlists) +{ + const unsigned int reset_value = execlists->csb_size - 1; + + /* + * After a reset, the HW starts writing into CSB entry [0]. We + * therefore have to set our HEAD pointer back one entry so that + * the *first* entry we check is entry 0. To complicate this further, + * as we don't wait for the first interrupt after reset, we have to + * fake the HW write to point back to the last entry so that our + * inline comparison of our cached head position against the last HW + * write works even before the first interrupt. + */ + execlists->csb_head = reset_value; + WRITE_ONCE(*execlists->csb_write, reset_value); + + invalidate_csb_entries(&execlists->csb_status[0], + &execlists->csb_status[reset_value]); +} + +static void __execlists_reset(struct intel_engine_cs *engine, bool stalled) { struct intel_engine_execlists * const execlists = &engine->execlists; + struct intel_context *ce; struct i915_request *rq; - unsigned long flags; u32 *regs; - spin_lock_irqsave(&engine->timeline.lock, flags); + process_csb(engine); /* drain preemption events */ + + /* Following the reset, we need to reload the CSB read/write pointers */ + reset_csb_pointers(&engine->execlists); + + /* + * Save the currently executing context, even if we completed + * its request, it was still running at the time of the + * reset and will have been clobbered. + */ + if (!port_isset(execlists->port)) + goto out_clear; + + ce = port_request(execlists->port)->hw_context; /* * Catch up with any missed context-switch interrupts. @@ -1964,12 +1906,13 @@ static void execlists_reset(struct intel_engine_cs *engine, bool stalled) /* Push back any incomplete requests for replay after the reset. */ rq = __unwind_incomplete_requests(engine); - - /* Following the reset, we need to reload the CSB read/write pointers */ - reset_csb_pointers(&engine->execlists); - if (!rq) - goto out_unlock; + goto out_replay; + + if (rq->hw_context != ce) { /* caught just before a CS event */ + rq = NULL; + goto out_replay; + } /* * If this request hasn't started yet, e.g. it is waiting on a @@ -1984,7 +1927,7 @@ static void execlists_reset(struct intel_engine_cs *engine, bool stalled) * perfectly and we do not need to flag the result as being erroneous. */ if (!i915_request_started(rq) && lrc_regs_ok(rq)) - goto out_unlock; + goto out_replay; /* * If the request was innocent, we leave the request in the ELSP @@ -1999,7 +1942,7 @@ static void execlists_reset(struct intel_engine_cs *engine, bool stalled) */ i915_reset_request(rq, stalled); if (!stalled && lrc_regs_ok(rq)) - goto out_unlock; + goto out_replay; /* * We want a simple context + ring to execute the breadcrumb update. @@ -2009,21 +1952,103 @@ static void execlists_reset(struct intel_engine_cs *engine, bool stalled) * future request will be after userspace has had the opportunity * to recreate its own state. */ - regs = rq->hw_context->lrc_reg_state; + regs = ce->lrc_reg_state; if (engine->pinned_default_state) { memcpy(regs, /* skip restoring the vanilla PPHWSP */ engine->pinned_default_state + LRC_STATE_PN * PAGE_SIZE, engine->context_size - PAGE_SIZE); } + execlists_init_reg_state(regs, ce, engine, ce->ring); /* Rerun the request; its payload has been neutered (if guilty). */ - rq->ring->head = intel_ring_wrap(rq->ring, rq->head); - intel_ring_update_space(rq->ring); +out_replay: + ce->ring->head = + rq ? intel_ring_wrap(ce->ring, rq->head) : ce->ring->tail; + intel_ring_update_space(ce->ring); + __execlists_update_reg_state(ce, engine); + +out_clear: + execlists_clear_all_active(execlists); +} + +static void execlists_reset(struct intel_engine_cs *engine, bool stalled) +{ + unsigned long flags; + + GEM_TRACE("%s\n", engine->name); + + spin_lock_irqsave(&engine->timeline.lock, flags); + + __execlists_reset(engine, stalled); + + spin_unlock_irqrestore(&engine->timeline.lock, flags); +} + +static void nop_submission_tasklet(unsigned long data) +{ + /* The driver is wedged; don't process any more events. */ +} + +static void execlists_cancel_requests(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + struct i915_request *rq, *rn; + struct rb_node *rb; + unsigned long flags; - execlists_init_reg_state(regs, rq->hw_context, engine, rq->ring); - __execlists_update_reg_state(rq->hw_context, engine); + GEM_TRACE("%s\n", engine->name); + + /* + * Before we call engine->cancel_requests(), we should have exclusive + * access to the submission state. This is arranged for us by the + * caller disabling the interrupt generation, the tasklet and other + * threads that may then access the same state, giving us a free hand + * to reset state. However, we still need to let lockdep be aware that + * we know this state may be accessed in hardirq context, so we + * disable the irq around this manipulation and we want to keep + * the spinlock focused on its duties and not accidentally conflate + * coverage to the submission's irq state. (Similarly, although we + * shouldn't need to disable irq around the manipulation of the + * submission's irq state, we also wish to remind ourselves that + * it is irq state.) + */ + spin_lock_irqsave(&engine->timeline.lock, flags); + + __execlists_reset(engine, true); + + /* Mark all executing requests as skipped. */ + list_for_each_entry(rq, &engine->timeline.requests, link) { + if (!i915_request_signaled(rq)) + dma_fence_set_error(&rq->fence, -EIO); + + i915_request_mark_complete(rq); + } + + /* Flush the queued requests to the timeline list (for retiring). */ + while ((rb = rb_first_cached(&execlists->queue))) { + struct i915_priolist *p = to_priolist(rb); + int i; + + priolist_for_each_request_consume(rq, rn, p, i) { + list_del_init(&rq->sched.link); + __i915_request_submit(rq); + dma_fence_set_error(&rq->fence, -EIO); + i915_request_mark_complete(rq); + } + + rb_erase_cached(&p->node, &execlists->queue); + i915_priolist_free(p); + } + + /* Remaining _unready_ requests will be nop'ed when submitted */ + + execlists->queue_priority_hint = INT_MIN; + execlists->queue = RB_ROOT_CACHED; + GEM_BUG_ON(port_isset(execlists->port)); + + GEM_BUG_ON(__tasklet_is_enabled(&execlists->tasklet)); + execlists->tasklet.func = nop_submission_tasklet; -out_unlock: spin_unlock_irqrestore(&engine->timeline.lock, flags); } -- cgit v1.2.3 From 2e1e5c5532ffe14ff48811ffe96a40f7dce8645c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 9 Apr 2019 18:41:08 +0100 Subject: drm/i915: Avoid reclaim taints from runtime-pm debug As intel_runtime_pm_get/_put may be called from any blockable context, we need to avoid allowing reclaim from our mallocs, as we need to avoid tainting any mutexes held by the callers (as they may themselves not allow for allocations as they are taken in the shrinker). <4> [435.339331] WARNING: possible circular locking dependency detected <4> [435.339364] 5.1.0-rc4-CI-Trybot_4116+ #1 Tainted: G U <4> [435.339395] ------------------------------------------------------ <4> [435.339426] gem_caching/1334 is trying to acquire lock: <4> [435.339456] 000000004505c39b (wakeref#3){+.+.}, at: intel_engine_pm_put+0x1b/0x40 [i915] <4> [435.339788] but task is already holding lock: <4> [435.339819] 00000000ee77b4ed (fs_reclaim){+.+.}, at: fs_reclaim_acquire.part.24+0x0/0x30 <4> [435.339879] which lock already depends on the new lock. <4> [435.339918] the existing dependency chain (in reverse order) is: <4> [435.339952] -> #1 (fs_reclaim){+.+.}: <4> [435.339998] fs_reclaim_acquire.part.24+0x24/0x30 <4> [435.340035] kmem_cache_alloc_trace+0x2a/0x290 <4> [435.340311] __print_intel_runtime_pm_wakeref+0x24/0x160 [i915] <4> [435.340590] untrack_intel_runtime_pm_wakeref+0x16e/0x1d0 [i915] <4> [435.340869] intel_runtime_pm_put_unchecked+0xd/0x30 [i915] <4> [435.341147] __intel_wakeref_put_once+0x22/0x40 [i915] <4> [435.341508] i915_request_retire+0x477/0xaf0 [i915] <4> [435.341871] ring_retire_requests+0x86/0x160 [i915] <4> [435.342226] i915_retire_requests+0x58/0xc0 [i915] <4> [435.342576] retire_work_handler+0x5b/0x70 [i915] <4> [435.342615] process_one_work+0x245/0x610 <4> [435.342646] worker_thread+0x37/0x380 <4> [435.342679] kthread+0x119/0x130 <4> [435.342714] ret_from_fork+0x3a/0x50 <4> [435.342739] -> #0 (wakeref#3){+.+.}: <4> [435.342788] lock_acquire+0xa6/0x1c0 <4> [435.342822] __mutex_lock+0x8c/0x960 <4> [435.342853] atomic_dec_and_mutex_lock+0x33/0x50 <4> [435.343151] intel_engine_pm_put+0x1b/0x40 [i915] <4> [435.343501] i915_request_retire+0x477/0xaf0 [i915] <4> [435.343851] ring_retire_requests+0x86/0x160 [i915] <4> [435.344202] i915_retire_requests+0x58/0xc0 [i915] <4> [435.344543] i915_gem_shrink+0xd8/0x5b0 [i915] <4> [435.344835] i915_drop_caches_set+0x17b/0x250 [i915] <4> [435.344877] simple_attr_write+0xb0/0xd0 <4> [435.344911] full_proxy_write+0x51/0x80 <4> [435.344943] vfs_write+0xbd/0x1b0 <4> [435.344972] ksys_write+0x55/0xe0 <4> [435.345002] do_syscall_64+0x55/0x190 <4> [435.345040] entry_SYSCALL_64_after_hwframe+0x49/0xbe Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20190409174108.19396-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_runtime_pm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index e6d1e592225b..3107a742d8ad 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -162,7 +162,7 @@ static void cancel_intel_runtime_pm_wakeref(struct drm_i915_private *i915, rpm->debug.count, atomic_read(&rpm->wakeref_count))) { char *buf; - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN); if (!buf) return; @@ -198,7 +198,7 @@ __print_intel_runtime_pm_wakeref(struct drm_printer *p, unsigned long i; char *buf; - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + buf = kmalloc(PAGE_SIZE, GFP_NOWAIT | __GFP_NOWARN); if (!buf) return; @@ -282,7 +282,9 @@ void print_intel_runtime_pm_wakeref(struct drm_i915_private *i915, if (dbg.count <= alloc) break; - s = krealloc(dbg.owners, dbg.count * sizeof(*s), GFP_KERNEL); + s = krealloc(dbg.owners, + dbg.count * sizeof(*s), + GFP_NOWAIT | __GFP_NOWARN); if (!s) goto out; -- cgit v1.2.3 From 6fd3134ae3551d4802a04669c0f39f2f5c56f77d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 26 Mar 2019 16:49:02 +0200 Subject: drm/i915: Do not enable FEC without DSC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we enable FEC even when DSC is no used. While that is theoretically valid supposedly there isn't much of a benefit from this. But more importantly we do not account for the FEC link bandwidth overhead (2.4%) in the non-DSC link bandwidth computations. So the code may think we have enough bandwidth when we in fact do not. Cc: stable@vger.kernel.org Cc: Anusha Srivatsa Cc: Manasi Navare Fixes: 240999cf339f ("i915/dp/fec: Add fec_enable to the crtc state.") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190326144903.6617-1-ville.syrjala@linux.intel.com Reviewed-by: Manasi Navare --- drivers/gpu/drm/i915/intel_dp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e0c59383d11e..560274d1c50b 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1895,6 +1895,9 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, int pipe_bpp; int ret; + pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && + intel_dp_supports_fec(intel_dp, pipe_config); + if (!intel_dp_supports_dsc(intel_dp, pipe_config)) return -EINVAL; @@ -2156,9 +2159,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) return -EINVAL; - pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) && - intel_dp_supports_fec(intel_dp, pipe_config); - ret = intel_dp_compute_link_config(encoder, pipe_config, conn_state); if (ret < 0) return ret; -- cgit v1.2.3 From 2474028e4b9abde6cc63ce0e3e3a045040b7815c Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Fri, 29 Mar 2019 18:19:19 -0700 Subject: drm/i915: Rename skl_wa_clkgating to the actual WA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functional change. Renaming the function to reflect the specific WA. Suggested-by: Ville Syrjala Cc: Anusha Srivatsa Signed-off-by: Radhakrishna Sripada Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190330011921.10397-1-radhakrishna.sripada@intel.com --- drivers/gpu/drm/i915/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f29a348e8d71..bf8565b98e44 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -477,7 +477,7 @@ static const struct intel_limit intel_limits_bxt = { }; static void -skl_wa_clkgate(struct drm_i915_private *dev_priv, int pipe, bool enable) +skl_wa_827(struct drm_i915_private *dev_priv, int pipe, bool enable) { if (enable) I915_WRITE(CLKGATE_DIS_PSL(pipe), @@ -5540,7 +5540,7 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) /* Display WA 827 */ if (needs_nv12_wa(dev_priv, old_crtc_state) && !needs_nv12_wa(dev_priv, pipe_config)) { - skl_wa_clkgate(dev_priv, crtc->pipe, false); + skl_wa_827(dev_priv, crtc->pipe, false); } } @@ -5579,7 +5579,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state, /* Display WA 827 */ if (!needs_nv12_wa(dev_priv, old_crtc_state) && needs_nv12_wa(dev_priv, pipe_config)) { - skl_wa_clkgate(dev_priv, crtc->pipe, true); + skl_wa_827(dev_priv, crtc->pipe, true); } /* -- cgit v1.2.3 From fa9d38f65d3976d8594e84edb0edcdfc75054b17 Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Fri, 29 Mar 2019 18:19:20 -0700 Subject: drm/i915: Fix the inconsistent RMW in WA 827 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RMW is used only in the disable path. Using it in enable path for consistency. Suggested-by: Ville Syrjala Cc: Anusha Srivatsa Signed-off-by: Radhakrishna Sripada Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190330011921.10397-2-radhakrishna.sripada@intel.com --- drivers/gpu/drm/i915/intel_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bf8565b98e44..c780ca6cd667 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -481,6 +481,7 @@ skl_wa_827(struct drm_i915_private *dev_priv, int pipe, bool enable) { if (enable) I915_WRITE(CLKGATE_DIS_PSL(pipe), + I915_READ(CLKGATE_DIS_PSL(pipe)) | DUPS1_GATING_DIS | DUPS2_GATING_DIS); else I915_WRITE(CLKGATE_DIS_PSL(pipe), -- cgit v1.2.3 From 0edda1d6813b7ac30593b93edea2daeb2c47ef91 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Apr 2019 12:01:59 +0100 Subject: drm/i915: Flush the CSB pointer reset The HW resets it CSB tail pointer on resetting the engine. Most of the time. In case it doesn't (and for system resume) we write the expected value anyway. For extra paranoia, flush the write before we invalidate the cacheline. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Acked-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20190412110159.10495-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 3cb788a223ef..4e0a351bfbca 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1866,6 +1866,7 @@ static void reset_csb_pointers(struct intel_engine_execlists *execlists) */ execlists->csb_head = reset_value; WRITE_ONCE(*execlists->csb_write, reset_value); + wmb(); /* Make sure this is visible to HW (paranoia?) */ invalidate_csb_entries(&execlists->csb_status[0], &execlists->csb_status[reset_value]); -- cgit v1.2.3 From 7a412b8f60cd57ab7dcb72ab701fde2bf81752eb Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 11 Apr 2019 19:49:25 +0300 Subject: drm/i915: Restore correct bxt_ddi_phy_calc_lane_lat_optim_mask() calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We are no longer calling bxt_ddi_phy_calc_lane_lat_optim_mask() when intel{hdmi,dp}_compute_config() succeeds, and instead only call it when those fail. This is fallout from the bool->int .compute_config() conversion which failed to invert the return value check before calling bxt_ddi_phy_calc_lane_lat_optim_mask(). Let's just replace it with an early bailout so that it's harder to miss. This restores the correct latency optim setting calculation (which could fix some real failures), and avoids the MISSING_CASE() from bxt_ddi_phy_calc_lane_lat_optim_mask() after intel{hdmi,dp}_compute_config() has failed. Cc: Lyude Paul Fixes: 204474a6b859 ("drm/i915: Pass down rc in intel_encoder->compute_config()") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109373 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190411164925.28491-1-ville.syrjala@linux.intel.com Reviewed-by: Lyude Paul --- drivers/gpu/drm/i915/intel_ddi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3ae55274056c..24f9106efcc6 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3857,14 +3857,16 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder, ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); else ret = intel_dp_compute_config(encoder, pipe_config, conn_state); + if (ret) + return ret; - if (IS_GEN9_LP(dev_priv) && ret) + if (IS_GEN9_LP(dev_priv)) pipe_config->lane_lat_optim_mask = bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); - return ret; + return 0; } -- cgit v1.2.3 From e5604e2fb6d440d91f8f729fa5424cc93c802c76 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 11 Apr 2019 17:33:49 +0300 Subject: drm/i915: Suppress spurious combo PHY B warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On ICL the DMC doesn't reinit combo PHY B so we should not warn about its state being bogus during the display core uninit. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190411143349.17934-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/intel_combo_phy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_combo_phy.c b/drivers/gpu/drm/i915/intel_combo_phy.c index 3d0271cebf99..2bf4359d7e41 100644 --- a/drivers/gpu/drm/i915/intel_combo_phy.c +++ b/drivers/gpu/drm/i915/intel_combo_phy.c @@ -239,7 +239,8 @@ void icl_combo_phys_uninit(struct drm_i915_private *dev_priv) for_each_combo_port_reverse(dev_priv, port) { u32 val; - if (!icl_combo_phy_verify_state(dev_priv, port)) + if (port == PORT_A && + !icl_combo_phy_verify_state(dev_priv, port)) DRM_WARN("Port %c combo PHY HW state changed unexpectedly\n", port_name(port)); -- cgit v1.2.3 From 2624dd154bcc53ac2de16ecae9746ba867b6ca70 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Mon, 1 Apr 2019 17:51:00 +0800 Subject: drm/amdgpu: add timeline support in amdgpu CS v3 syncobj wait/signal operation is appending in command submission. v2: separate to two kinds in/out_deps functions v3: fix checking for timeline syncobj Signed-off-by: Chunming Zhou Cc: Tobias Hector Cc: Jason Ekstrand Cc: Dave Airlie Cc: Chris Wilson Cc: Lionel Landwerlin Reviewed-by: Lionel Landwerlin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 10 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 152 +++++++++++++++++++++++++++------ include/uapi/drm/amdgpu_drm.h | 8 ++ 3 files changed, 144 insertions(+), 26 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6294316f24c7..14398f55f602 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -436,6 +436,12 @@ struct amdgpu_cs_chunk { void *kdata; }; +struct amdgpu_cs_post_dep { + struct drm_syncobj *syncobj; + struct dma_fence_chain *chain; + u64 point; +}; + struct amdgpu_cs_parser { struct amdgpu_device *adev; struct drm_file *filp; @@ -465,8 +471,8 @@ struct amdgpu_cs_parser { /* user fence */ struct amdgpu_bo_list_entry uf_entry; - unsigned num_post_dep_syncobjs; - struct drm_syncobj **post_dep_syncobjs; + unsigned num_post_deps; + struct amdgpu_cs_post_dep *post_deps; }; static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 52a5e4fdc95b..2f6239b6be6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -215,6 +215,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs case AMDGPU_CHUNK_ID_SYNCOBJ_IN: case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES: + case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT: + case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL: break; default: @@ -804,9 +806,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, ttm_eu_backoff_reservation(&parser->ticket, &parser->validated); - for (i = 0; i < parser->num_post_dep_syncobjs; i++) - drm_syncobj_put(parser->post_dep_syncobjs[i]); - kfree(parser->post_dep_syncobjs); + for (i = 0; i < parser->num_post_deps; i++) { + drm_syncobj_put(parser->post_deps[i].syncobj); + kfree(parser->post_deps[i].chain); + } + kfree(parser->post_deps); dma_fence_put(parser->fence); @@ -1117,13 +1121,18 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, } static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, - uint32_t handle) + uint32_t handle, u64 point, + u64 flags) { - int r; struct dma_fence *fence; - r = drm_syncobj_find_fence(p->filp, handle, 0, 0, &fence); - if (r) + int r; + + r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence); + if (r) { + DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n", + handle, point, r); return r; + } r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true); dma_fence_put(fence); @@ -1134,46 +1143,118 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p, struct amdgpu_cs_chunk *chunk) { + struct drm_amdgpu_cs_chunk_sem *deps; unsigned num_deps; int i, r; - struct drm_amdgpu_cs_chunk_sem *deps; deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; num_deps = chunk->length_dw * 4 / sizeof(struct drm_amdgpu_cs_chunk_sem); + for (i = 0; i < num_deps; ++i) { + r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle, + 0, 0); + if (r) + return r; + } + + return 0; +} + +static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser *p, + struct amdgpu_cs_chunk *chunk) +{ + struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps; + unsigned num_deps; + int i, r; + + syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata; + num_deps = chunk->length_dw * 4 / + sizeof(struct drm_amdgpu_cs_chunk_syncobj); for (i = 0; i < num_deps; ++i) { - r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle); + r = amdgpu_syncobj_lookup_and_add_to_sync(p, + syncobj_deps[i].handle, + syncobj_deps[i].point, + syncobj_deps[i].flags); if (r) return r; } + return 0; } static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p, struct amdgpu_cs_chunk *chunk) { + struct drm_amdgpu_cs_chunk_sem *deps; unsigned num_deps; int i; - struct drm_amdgpu_cs_chunk_sem *deps; + deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; num_deps = chunk->length_dw * 4 / sizeof(struct drm_amdgpu_cs_chunk_sem); - p->post_dep_syncobjs = kmalloc_array(num_deps, - sizeof(struct drm_syncobj *), - GFP_KERNEL); - p->num_post_dep_syncobjs = 0; + p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps), + GFP_KERNEL); + p->num_post_deps = 0; - if (!p->post_dep_syncobjs) + if (!p->post_deps) return -ENOMEM; + for (i = 0; i < num_deps; ++i) { - p->post_dep_syncobjs[i] = drm_syncobj_find(p->filp, deps[i].handle); - if (!p->post_dep_syncobjs[i]) + p->post_deps[i].syncobj = + drm_syncobj_find(p->filp, deps[i].handle); + if (!p->post_deps[i].syncobj) return -EINVAL; - p->num_post_dep_syncobjs++; + p->post_deps[i].chain = NULL; + p->post_deps[i].point = 0; + p->num_post_deps++; } + + return 0; +} + + +static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p, + struct amdgpu_cs_chunk + *chunk) +{ + struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps; + unsigned num_deps; + int i; + + syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata; + num_deps = chunk->length_dw * 4 / + sizeof(struct drm_amdgpu_cs_chunk_syncobj); + + p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps), + GFP_KERNEL); + p->num_post_deps = 0; + + if (!p->post_deps) + return -ENOMEM; + + for (i = 0; i < num_deps; ++i) { + struct amdgpu_cs_post_dep *dep = &p->post_deps[i]; + + dep->chain = NULL; + if (syncobj_deps[i].point) { + dep->chain = kmalloc(sizeof(*dep->chain), GFP_KERNEL); + if (!dep->chain) + return -ENOMEM; + } + + dep->syncobj = drm_syncobj_find(p->filp, + syncobj_deps[i].handle); + if (!dep->syncobj) { + kfree(dep->chain); + return -EINVAL; + } + dep->point = syncobj_deps[i].point; + p->num_post_deps++; + } + return 0; } @@ -1187,19 +1268,33 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, chunk = &p->chunks[i]; - if (chunk->chunk_id == AMDGPU_CHUNK_ID_DEPENDENCIES || - chunk->chunk_id == AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES) { + switch (chunk->chunk_id) { + case AMDGPU_CHUNK_ID_DEPENDENCIES: + case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES: r = amdgpu_cs_process_fence_dep(p, chunk); if (r) return r; - } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_IN) { + break; + case AMDGPU_CHUNK_ID_SYNCOBJ_IN: r = amdgpu_cs_process_syncobj_in_dep(p, chunk); if (r) return r; - } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_OUT) { + break; + case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: r = amdgpu_cs_process_syncobj_out_dep(p, chunk); if (r) return r; + break; + case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT: + r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk); + if (r) + return r; + break; + case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL: + r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk); + if (r) + return r; + break; } } @@ -1210,8 +1305,17 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) { int i; - for (i = 0; i < p->num_post_dep_syncobjs; ++i) - drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence); + for (i = 0; i < p->num_post_deps; ++i) { + if (p->post_deps[i].chain && p->post_deps[i].point) { + drm_syncobj_add_point(p->post_deps[i].syncobj, + p->post_deps[i].chain, + p->fence, p->post_deps[i].point); + p->post_deps[i].chain = NULL; + } else { + drm_syncobj_replace_fence(p->post_deps[i].syncobj, + p->fence); + } + } } static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index e3a97da4add9..4788730dbe78 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -528,6 +528,8 @@ struct drm_amdgpu_gem_va { #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05 #define AMDGPU_CHUNK_ID_BO_HANDLES 0x06 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07 +#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT 0x08 +#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x09 struct drm_amdgpu_cs_chunk { __u32 chunk_id; @@ -608,6 +610,12 @@ struct drm_amdgpu_cs_chunk_sem { __u32 handle; }; +struct drm_amdgpu_cs_chunk_syncobj { + __u32 handle; + __u32 flags; + __u64 point; +}; + #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2 -- cgit v1.2.3 From 1afeb3144344e303547a211ff29d1e18ba9a9994 Mon Sep 17 00:00:00 2001 From: Chunming Zhou Date: Mon, 1 Apr 2019 17:51:03 +0800 Subject: drm/amdgpu: update version for timeline syncobj support in amdgpu v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: update version for amd-staging-drm-next merge Signed-off-by: Chunming Zhou Reviewed-by: Lionel Landwerlin Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index f34e3ab5a9f3..1e2cc9d68a05 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -75,9 +75,10 @@ * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID * - 3.30.0 - Add AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE. * - 3.31.0 - Add support for per-flip tiling attribute changes with DC + * - 3.32.0 - Add syncobj timeline support to AMDGPU_CS. */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 31 +#define KMS_DRIVER_MINOR 32 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; -- cgit v1.2.3 From 3d2aca8c8620346abdba96c6300d2c0b90a1d0cc Mon Sep 17 00:00:00 2001 From: Christian König Date: Fri, 29 Mar 2019 19:30:23 +0100 Subject: drm/amdgpu: fix old fence check in amdgpu_fence_emit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't hold a reference to the old fence, so it can go away any time we are waiting for it to signal. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index ee47c11e92ce..4dee2326b29c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -136,8 +136,9 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, { struct amdgpu_device *adev = ring->adev; struct amdgpu_fence *fence; - struct dma_fence *old, **ptr; + struct dma_fence __rcu **ptr; uint32_t seq; + int r; fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); if (fence == NULL) @@ -153,15 +154,24 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, seq, flags | AMDGPU_FENCE_FLAG_INT); ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask]; + if (unlikely(rcu_dereference_protected(*ptr, 1))) { + struct dma_fence *old; + + rcu_read_lock(); + old = dma_fence_get_rcu_safe(ptr); + rcu_read_unlock(); + + if (old) { + r = dma_fence_wait(old, false); + dma_fence_put(old); + if (r) + return r; + } + } + /* This function can't be called concurrently anyway, otherwise * emitting the fence would mess up the hardware ring buffer. */ - old = rcu_dereference_protected(*ptr, 1); - if (old && !dma_fence_is_signaled(old)) { - DRM_INFO("rcu slot is busy\n"); - dma_fence_wait(old, false); - } - rcu_assign_pointer(*ptr, dma_fence_get(&fence->base)); *f = &fence->base; -- cgit v1.2.3 From e911671cd027e21f576a3b90bc76cc5c18ccaa4b Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Thu, 11 Apr 2019 11:01:07 -0400 Subject: drm/powerplay: Add smu set xgmi pstate interface XGMI pstate is controlled by SMU, driver need this interface to communicate with SMU Signed-off-by: shaoyunl Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 4 ++++ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index 26a7d2c7f4fa..c8b168b3413b 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -540,6 +540,8 @@ struct smu_funcs int (*get_fan_speed_percent)(struct smu_context *smu, uint32_t *speed); int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed); int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed); + int (*set_xgmi_pstate)(struct smu_context *smu, uint32_t pstate); + }; #define smu_init_microcode(smu) \ @@ -723,6 +725,8 @@ struct smu_funcs ((smu)->funcs->get_sclk ? (smu)->funcs->get_sclk((smu), (low)) : 0) #define smu_get_mclk(smu, low) \ ((smu)->funcs->get_mclk ? (smu)->funcs->get_mclk((smu), (low)) : 0) +#define smu_set_xgmi_pstate(smu, pstate) \ + ((smu)->funcs->set_xgmi_pstate ? (smu)->funcs->set_xgmi_pstate((smu), (pstate)) : 0) extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index d2e2a4e2d0eb..c478b38662d0 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -1893,6 +1893,13 @@ set_fan_speed_rpm_failed: return ret; } +static int smu_v11_0_set_xgmi_pstate(struct smu_context *smu, + uint32_t pstate) +{ + /* send msg to SMU to set pstate */ + return 0; +} + static const struct smu_funcs smu_v11_0_funcs = { .init_microcode = smu_v11_0_init_microcode, .load_microcode = smu_v11_0_load_microcode, @@ -1947,6 +1954,7 @@ static const struct smu_funcs smu_v11_0_funcs = { .get_fan_speed_percent = smu_v11_0_get_fan_speed_percent, .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm, + .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, }; void smu_v11_0_set_smu_funcs(struct smu_context *smu) @@ -1954,7 +1962,6 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu) struct amdgpu_device *adev = smu->adev; smu->funcs = &smu_v11_0_funcs; - switch (adev->asic_type) { case CHIP_VEGA20: vega20_set_ppt_funcs(smu); -- cgit v1.2.3 From 93abb05fd5d6f3042320ae3c485b034d7c5e8e54 Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Fri, 5 Apr 2019 11:55:27 -0400 Subject: drm/amdgpu: Set proper function to set xgmi pstate Driver need to call SMU to set xgmi pstate Signed-off-by: shaoyunl Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 336834797af3..a48c84c51775 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -24,6 +24,7 @@ #include #include "amdgpu.h" #include "amdgpu_xgmi.h" +#include "amdgpu_smu.h" static DEFINE_MUTEX(xgmi_mutex); @@ -216,7 +217,17 @@ int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate) if (hive->pstate == pstate) return 0; - /* Todo : sent the message to SMU for pstate change */ + + dev_dbg(adev->dev, "Set xgmi pstate %d.\n", pstate); + + if (is_support_sw_smu(adev)) + ret = smu_set_xgmi_pstate(&adev->smu, pstate); + if (ret) + dev_err(adev->dev, + "XGMI: Set pstate failure on device %llx, hive %llx, ret %d", + adev->gmc.xgmi.node_id, + adev->gmc.xgmi.hive_id, ret); + return ret; } -- cgit v1.2.3 From 019d26004ebad73a5aedaedab958ea8a381c2ffc Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 12 Apr 2019 19:53:35 +0300 Subject: drm/i915: Shortcut readiness to reset check If the engine says it is ready for reset, it is ready so avoid further dancing and proceed. v2: reg (Chris) v3: request, ack, mask from following patch (Chris) Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190412165335.16347-1-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_reset.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c index 68875ba43b8d..8ce819bbd8ff 100644 --- a/drivers/gpu/drm/i915/i915_reset.c +++ b/drivers/gpu/drm/i915/i915_reset.c @@ -490,20 +490,26 @@ static int gen11_reset_engines(struct drm_i915_private *i915, static int gen8_engine_reset_prepare(struct intel_engine_cs *engine) { struct intel_uncore *uncore = engine->uncore; + const i915_reg_t reg = RING_RESET_CTL(engine->mmio_base); + u32 request, mask, ack; int ret; - intel_uncore_write_fw(uncore, - RING_RESET_CTL(engine->mmio_base), - _MASKED_BIT_ENABLE(RESET_CTL_REQUEST_RESET)); + ack = intel_uncore_read_fw(uncore, reg); + if (!(ack & RESET_CTL_READY_TO_RESET)) { + request = RESET_CTL_REQUEST_RESET; + mask = RESET_CTL_READY_TO_RESET; + ack = RESET_CTL_READY_TO_RESET; + } else { + return 0; + } - ret = __intel_wait_for_register_fw(uncore, - RING_RESET_CTL(engine->mmio_base), - RESET_CTL_READY_TO_RESET, - RESET_CTL_READY_TO_RESET, - 700, 0, - NULL); + intel_uncore_write_fw(uncore, reg, _MASKED_BIT_ENABLE(request)); + ret = __intel_wait_for_register_fw(uncore, reg, mask, ack, + 700, 0, NULL); if (ret) - DRM_ERROR("%s: reset request timeout\n", engine->name); + DRM_ERROR("%s reset request timed out: {request: %08x, RESET_CTL: %08x}\n", + engine->name, request, + intel_uncore_read_fw(uncore, reg)); return ret; } -- cgit v1.2.3 From 5ce5f61b70f97bd664f7a20aeffd9574d17ab350 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 12 Apr 2019 19:53:53 +0300 Subject: drm/i915: Handle catastrophic error on engine reset If cat error is set, we need to clear it by acking it. Further, if it is set, we must not do a normal request for reset. v2: avoid goto (Chris) v3: comment, error format, direct assign (Chris) Bspec: 12567 Cc: Chris Wilson Signed-off-by: Mika Kuoppala Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190412165353.16432-1-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 6 ++++-- drivers/gpu/drm/i915/i915_reset.c | 12 +++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 8ad2f0a03f28..c1c0f7ab03e9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2446,8 +2446,10 @@ enum i915_power_well_id { #define RING_HWS_PGA(base) _MMIO((base) + 0x80) #define RING_HWS_PGA_GEN6(base) _MMIO((base) + 0x2080) #define RING_RESET_CTL(base) _MMIO((base) + 0xd0) -#define RESET_CTL_REQUEST_RESET (1 << 0) -#define RESET_CTL_READY_TO_RESET (1 << 1) +#define RESET_CTL_CAT_ERROR REG_BIT(2) +#define RESET_CTL_READY_TO_RESET REG_BIT(1) +#define RESET_CTL_REQUEST_RESET REG_BIT(0) + #define RING_SEMA_WAIT_POLL(base) _MMIO((base) + 0x24c) #define HSW_GTT_CACHE_EN _MMIO(0x4024) diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c index 8ce819bbd8ff..bc5f9c69895e 100644 --- a/drivers/gpu/drm/i915/i915_reset.c +++ b/drivers/gpu/drm/i915/i915_reset.c @@ -495,7 +495,17 @@ static int gen8_engine_reset_prepare(struct intel_engine_cs *engine) int ret; ack = intel_uncore_read_fw(uncore, reg); - if (!(ack & RESET_CTL_READY_TO_RESET)) { + if (ack & RESET_CTL_CAT_ERROR) { + /* + * For catastrophic errors, ready-for-reset sequence + * needs to be bypassed: HAS#396813 + */ + request = RESET_CTL_CAT_ERROR; + mask = RESET_CTL_CAT_ERROR; + + /* Catastrophic errors need to be cleared by HW */ + ack = 0; + } else if (!(ack & RESET_CTL_READY_TO_RESET)) { request = RESET_CTL_REQUEST_RESET; mask = RESET_CTL_READY_TO_RESET; ack = RESET_CTL_READY_TO_RESET; -- cgit v1.2.3 From 39564ae86d51ada75759c859770c8d973b458eec Mon Sep 17 00:00:00 2001 From: Bob Paauwe Date: Fri, 12 Apr 2019 11:09:20 -0700 Subject: drm/i915/ehl: Inherit Ice Lake conditional code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of the conditional code for ICELAKE also applies to ELKHARTLAKE so use IS_GEN(dev_priv, 11) even for PM and Workarounds for now. v2: - Rename commit (Jose) - Include a wm workaround (Jose and Lucas) - Include display core init (Jose and Lucas) v3: Add a missing case of gen greater-than 11 (Jose) Cc: José Roberto de Souza Cc: Lucas De Marchi Signed-off-by: Bob Paauwe Signed-off-by: Rodrigo Vivi Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20190412180920.22347-1-rodrigo.vivi@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 6 +++--- drivers/gpu/drm/i915/intel_runtime_pm.c | 6 +++--- drivers/gpu/drm/i915/intel_workarounds.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 8e826a6ab62e..7357bddf9ad9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4530,10 +4530,10 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, memset(&wm->wm[level], 0, sizeof(wm->wm[level])); /* - * Wa_1408961008:icl + * Wa_1408961008:icl, ehl * Underruns with WM1+ disabled */ - if (IS_ICELAKE(dev_priv) && + if (IS_GEN(dev_priv, 11) && level == 1 && wm->wm[0].plane_en) { wm->wm[level].plane_res_b = wm->wm[0].plane_res_b; wm->wm[level].plane_res_l = wm->wm[0].plane_res_l; @@ -9573,7 +9573,7 @@ static void nop_init_clock_gating(struct drm_i915_private *dev_priv) */ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) { - if (IS_ICELAKE(dev_priv)) + if (IS_GEN(dev_priv, 11)) dev_priv->display.init_clock_gating = icl_init_clock_gating; else if (IS_CANNONLAKE(dev_priv)) dev_priv->display.init_clock_gating = cnl_init_clock_gating; diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 3107a742d8ad..d4f4262d0fee 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -3448,7 +3448,7 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) * The enabling order will be from lower to higher indexed wells, * the disabling order is reversed. */ - if (IS_ICELAKE(dev_priv)) { + if (IS_GEN(dev_priv, 11)) { err = set_power_wells(power_domains, icl_power_wells); } else if (IS_CANNONLAKE(dev_priv)) { err = set_power_wells(power_domains, cnl_power_wells); @@ -4061,7 +4061,7 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume) power_domains->initializing = true; - if (IS_ICELAKE(i915)) { + if (INTEL_GEN(i915) >= 11) { icl_display_core_init(i915, resume); } else if (IS_CANNONLAKE(i915)) { cnl_display_core_init(i915, resume); @@ -4209,7 +4209,7 @@ void intel_power_domains_suspend(struct drm_i915_private *i915, intel_power_domains_verify_state(i915); } - if (IS_ICELAKE(i915)) + if (INTEL_GEN(i915) >= 11) icl_display_core_uninit(i915); else if (IS_CANNONLAKE(i915)) cnl_display_core_uninit(i915); diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c index a04dbc58ec1c..c0977036db79 100644 --- a/drivers/gpu/drm/i915/intel_workarounds.c +++ b/drivers/gpu/drm/i915/intel_workarounds.c @@ -569,7 +569,7 @@ void intel_engine_init_ctx_wa(struct intel_engine_cs *engine) wa_init_start(wal, "context"); - if (IS_ICELAKE(i915)) + if (IS_GEN(i915, 11)) icl_ctx_workarounds_init(engine); else if (IS_CANNONLAKE(i915)) cnl_ctx_workarounds_init(engine); @@ -867,7 +867,7 @@ icl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) static void gt_init_workarounds(struct drm_i915_private *i915, struct i915_wa_list *wal) { - if (IS_ICELAKE(i915)) + if (IS_GEN(i915, 11)) icl_gt_workarounds_init(i915, wal); else if (IS_CANNONLAKE(i915)) cnl_gt_workarounds_init(i915, wal); @@ -1064,7 +1064,7 @@ void intel_engine_init_whitelist(struct intel_engine_cs *engine) wa_init_start(w, "whitelist"); - if (IS_ICELAKE(i915)) + if (IS_GEN(i915, 11)) icl_whitelist_build(w); else if (IS_CANNONLAKE(i915)) cnl_whitelist_build(w); @@ -1112,7 +1112,7 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) { struct drm_i915_private *i915 = engine->i915; - if (IS_ICELAKE(i915)) { + if (IS_GEN(i915, 11)) { /* This is not an Wa. Enable for better image quality */ wa_masked_en(wal, _3D_CHICKEN3, -- cgit v1.2.3 From 5d75dc2b08102d82f50cca21963eb718bc1ea802 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Apr 2019 21:24:57 +0100 Subject: drm/i915: Teach intel_workarounds to use uncore mmio access Start weaning ourselves off the implicit I915_WRITE macro madness and start using the explicit intel_uncore mmio access. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Daniele Ceraolo Spurio Cc: Paulo Zanoni Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20190412202458.10653-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_workarounds.c | 65 +++++++++++----------- drivers/gpu/drm/i915/intel_workarounds.h | 6 +- drivers/gpu/drm/i915/selftests/intel_workarounds.c | 5 +- 3 files changed, 38 insertions(+), 38 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c index c0977036db79..ccaf63679435 100644 --- a/drivers/gpu/drm/i915/intel_workarounds.c +++ b/drivers/gpu/drm/i915/intel_workarounds.c @@ -729,9 +729,9 @@ cfl_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal) } static void -wa_init_mcr(struct drm_i915_private *dev_priv, struct i915_wa_list *wal) +wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal) { - const struct sseu_dev_info *sseu = &RUNTIME_INFO(dev_priv)->sseu; + const struct sseu_dev_info *sseu = &RUNTIME_INFO(i915)->sseu; u32 mcr_slice_subslice_mask; /* @@ -747,14 +747,15 @@ wa_init_mcr(struct drm_i915_private *dev_priv, struct i915_wa_list *wal) * something more complex that requires checking the range of every * MMIO read). */ - if (INTEL_GEN(dev_priv) >= 10 && + if (INTEL_GEN(i915) >= 10 && is_power_of_2(sseu->slice_mask)) { /* * read FUSE3 for enabled L3 Bank IDs, if L3 Bank matches * enabled subslice, no need to redirect MCR packet */ u32 slice = fls(sseu->slice_mask); - u32 fuse3 = I915_READ(GEN10_MIRROR_FUSE3); + u32 fuse3 = + intel_uncore_read(&i915->uncore, GEN10_MIRROR_FUSE3); u8 ss_mask = sseu->subslice_mask[slice]; u8 enabled_mask = (ss_mask | ss_mask >> @@ -768,7 +769,7 @@ wa_init_mcr(struct drm_i915_private *dev_priv, struct i915_wa_list *wal) WARN_ON((enabled_mask & disabled_mask) != enabled_mask); } - if (INTEL_GEN(dev_priv) >= 11) + if (INTEL_GEN(i915) >= 11) mcr_slice_subslice_mask = GEN11_MCR_SLICE_MASK | GEN11_MCR_SUBSLICE_MASK; else @@ -788,7 +789,7 @@ wa_init_mcr(struct drm_i915_private *dev_priv, struct i915_wa_list *wal) wa_write_masked_or(wal, GEN8_MCR_SELECTOR, mcr_slice_subslice_mask, - intel_calculate_mcr_s_ss_select(dev_priv)); + intel_calculate_mcr_s_ss_select(i915)); } static void @@ -897,15 +898,14 @@ void intel_gt_init_workarounds(struct drm_i915_private *i915) } static enum forcewake_domains -wal_get_fw_for_rmw(struct drm_i915_private *dev_priv, - const struct i915_wa_list *wal) +wal_get_fw_for_rmw(struct intel_uncore *uncore, const struct i915_wa_list *wal) { enum forcewake_domains fw = 0; struct i915_wa *wa; unsigned int i; for (i = 0, wa = wal->list; i < wal->count; i++, wa++) - fw |= intel_uncore_forcewake_for_reg(&dev_priv->uncore, + fw |= intel_uncore_forcewake_for_reg(uncore, wa->reg, FW_REG_READ | FW_REG_WRITE); @@ -914,7 +914,7 @@ wal_get_fw_for_rmw(struct drm_i915_private *dev_priv, } static void -wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal) +wa_list_apply(struct intel_uncore *uncore, const struct i915_wa_list *wal) { enum forcewake_domains fw; unsigned long flags; @@ -924,27 +924,22 @@ wa_list_apply(struct drm_i915_private *dev_priv, const struct i915_wa_list *wal) if (!wal->count) return; - fw = wal_get_fw_for_rmw(dev_priv, wal); + fw = wal_get_fw_for_rmw(uncore, wal); - spin_lock_irqsave(&dev_priv->uncore.lock, flags); - intel_uncore_forcewake_get__locked(&dev_priv->uncore, fw); + spin_lock_irqsave(&uncore->lock, flags); + intel_uncore_forcewake_get__locked(uncore, fw); for (i = 0, wa = wal->list; i < wal->count; i++, wa++) { - u32 val = I915_READ_FW(wa->reg); - - val &= ~wa->mask; - val |= wa->val; - - I915_WRITE_FW(wa->reg, val); + intel_uncore_rmw_fw(uncore, wa->reg, wa->mask, wa->val); } - intel_uncore_forcewake_put__locked(&dev_priv->uncore, fw); - spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); + intel_uncore_forcewake_put__locked(uncore, fw); + spin_unlock_irqrestore(&uncore->lock, flags); } -void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv) +void intel_gt_apply_workarounds(struct drm_i915_private *i915) { - wa_list_apply(dev_priv, &dev_priv->gt_wa_list); + wa_list_apply(&i915->uncore, &i915->gt_wa_list); } static bool @@ -961,7 +956,7 @@ wa_verify(const struct i915_wa *wa, u32 cur, const char *name, const char *from) return true; } -static bool wa_list_verify(struct drm_i915_private *dev_priv, +static bool wa_list_verify(struct intel_uncore *uncore, const struct i915_wa_list *wal, const char *from) { @@ -970,15 +965,17 @@ static bool wa_list_verify(struct drm_i915_private *dev_priv, bool ok = true; for (i = 0, wa = wal->list; i < wal->count; i++, wa++) - ok &= wa_verify(wa, I915_READ(wa->reg), wal->name, from); + ok &= wa_verify(wa, + intel_uncore_read(uncore, wa->reg), + wal->name, from); return ok; } -bool intel_gt_verify_workarounds(struct drm_i915_private *dev_priv, +bool intel_gt_verify_workarounds(struct drm_i915_private *i915, const char *from) { - return wa_list_verify(dev_priv, &dev_priv->gt_wa_list, from); + return wa_list_verify(&i915->uncore, &i915->gt_wa_list, from); } static void @@ -1088,8 +1085,8 @@ void intel_engine_init_whitelist(struct intel_engine_cs *engine) void intel_engine_apply_whitelist(struct intel_engine_cs *engine) { - struct drm_i915_private *dev_priv = engine->i915; const struct i915_wa_list *wal = &engine->whitelist; + struct intel_uncore *uncore = engine->uncore; const u32 base = engine->mmio_base; struct i915_wa *wa; unsigned int i; @@ -1098,13 +1095,15 @@ void intel_engine_apply_whitelist(struct intel_engine_cs *engine) return; for (i = 0, wa = wal->list; i < wal->count; i++, wa++) - I915_WRITE(RING_FORCE_TO_NONPRIV(base, i), - i915_mmio_reg_offset(wa->reg)); + intel_uncore_write(uncore, + RING_FORCE_TO_NONPRIV(base, i), + i915_mmio_reg_offset(wa->reg)); /* And clear the rest just in case of garbage */ for (; i < RING_MAX_NONPRIV_SLOTS; i++) - I915_WRITE(RING_FORCE_TO_NONPRIV(base, i), - i915_mmio_reg_offset(RING_NOPID(base))); + intel_uncore_write(uncore, + RING_FORCE_TO_NONPRIV(base, i), + i915_mmio_reg_offset(RING_NOPID(base))); } static void @@ -1253,7 +1252,7 @@ void intel_engine_init_workarounds(struct intel_engine_cs *engine) void intel_engine_apply_workarounds(struct intel_engine_cs *engine) { - wa_list_apply(engine->i915, &engine->wa_list); + wa_list_apply(engine->uncore, &engine->wa_list); } #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) diff --git a/drivers/gpu/drm/i915/intel_workarounds.h b/drivers/gpu/drm/i915/intel_workarounds.h index a1bf51c611a9..34eee5ec511e 100644 --- a/drivers/gpu/drm/i915/intel_workarounds.h +++ b/drivers/gpu/drm/i915/intel_workarounds.h @@ -20,9 +20,9 @@ static inline void intel_wa_list_free(struct i915_wa_list *wal) void intel_engine_init_ctx_wa(struct intel_engine_cs *engine); int intel_engine_emit_ctx_wa(struct i915_request *rq); -void intel_gt_init_workarounds(struct drm_i915_private *dev_priv); -void intel_gt_apply_workarounds(struct drm_i915_private *dev_priv); -bool intel_gt_verify_workarounds(struct drm_i915_private *dev_priv, +void intel_gt_init_workarounds(struct drm_i915_private *i915); +void intel_gt_apply_workarounds(struct drm_i915_private *i915); +bool intel_gt_verify_workarounds(struct drm_i915_private *i915, const char *from); void intel_engine_init_whitelist(struct intel_engine_cs *engine); diff --git a/drivers/gpu/drm/i915/selftests/intel_workarounds.c b/drivers/gpu/drm/i915/selftests/intel_workarounds.c index 3baed59008d7..567b6f8dae86 100644 --- a/drivers/gpu/drm/i915/selftests/intel_workarounds.c +++ b/drivers/gpu/drm/i915/selftests/intel_workarounds.c @@ -750,10 +750,11 @@ static bool verify_gt_engine_wa(struct drm_i915_private *i915, enum intel_engine_id id; bool ok = true; - ok &= wa_list_verify(i915, &lists->gt_wa_list, str); + ok &= wa_list_verify(&i915->uncore, &lists->gt_wa_list, str); for_each_engine(engine, i915, id) - ok &= wa_list_verify(i915, &lists->engine[id].wa_list, str); + ok &= wa_list_verify(engine->uncore, + &lists->engine[id].wa_list, str); return ok; } -- cgit v1.2.3 From 3be0a0b8501585120f8de68e9077ca143024139b Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Thu, 28 Mar 2019 12:39:48 -0400 Subject: drm/amd/display: Add switch for Fractional PWM on or off [Why] Some LED Driver might not like Fractional PWM especially at extreme ranges near 0% or 100%. For example, backlight flashing could be observed. We want a way to switch fractional PWM on/off either for debug, or possibly production. [How] Add DC code that can send new FW command to enable/disable fractional PWM. Signed-off-by: Anthony Koo Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index dc6a2c236ba7..704e5430d4dc 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -183,6 +183,7 @@ struct dc_config { bool disable_disp_pll_sharing; bool fbc_support; bool optimize_edp_link_rate; + bool disable_fractional_pwm; bool allow_seamless_boot_optimization; }; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index da96229db53a..855360b1414f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -50,6 +50,7 @@ #define MCP_ABM_LEVEL_SET 0x65 #define MCP_ABM_PIPE_SET 0x66 #define MCP_BL_SET 0x67 +#define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ #define MCP_DISABLE_ABM_IMMEDIATELY 255 @@ -390,6 +391,23 @@ static bool dce_abm_init_backlight(struct abm *abm) REG_UPDATE(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, 0); + /* Wait until microcontroller is ready to process interrupt */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800); + + /* Set PWM fractional enable/disable */ + value = (abm->ctx->dc->config.disable_fractional_pwm == false) ? 1 : 0; + REG_WRITE(MASTER_COMM_DATA_REG1, value); + + /* Set command to enable or disable fractional PWM microcontroller */ + REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, + MCP_BL_SET_PWM_FRAC); + + /* Notify microcontroller of new command */ + REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); + + /* Ensure command has been executed before continuing */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800); + return true; } -- cgit v1.2.3 From 37c6a93b7e535e4269af3e85bfce3955a635c750 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 15 Mar 2019 15:45:34 -0400 Subject: drm/amd/display: Expose support for NV12 on suitable planes [Why] Hardware can support video surfaces and DC tells us which planes are suitable via DC plane caps. [How] The supported formats array will now vary based on what DC tells us, so create an array and fill it dynamically based on plane types and caps. Ideally we'd query support for every format via DC plane caps, but for the framework is in place to do so later with this. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Sun peng Li Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 86 +++++++++++++++-------- 1 file changed, 55 insertions(+), 31 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fd5646c11bb2..dfc28b7433bf 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4121,46 +4121,71 @@ static const u32 cursor_formats[] = { DRM_FORMAT_ARGB8888 }; -static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, - struct drm_plane *plane, - unsigned long possible_crtcs, - const struct dc_plane_cap *plane_cap) +static int get_plane_formats(const struct drm_plane *plane, + const struct dc_plane_cap *plane_cap, + uint32_t *formats, int max_formats) { - int res = -EPERM; + int i, num_formats = 0; + + /* + * TODO: Query support for each group of formats directly from + * DC plane caps. This will require adding more formats to the + * caps list. + */ switch (plane->type) { case DRM_PLANE_TYPE_PRIMARY: - res = drm_universal_plane_init( - dm->adev->ddev, - plane, - possible_crtcs, - &dm_plane_funcs, - rgb_formats, - ARRAY_SIZE(rgb_formats), - NULL, plane->type, NULL); + for (i = 0; i < ARRAY_SIZE(rgb_formats); ++i) { + if (num_formats >= max_formats) + break; + + formats[num_formats++] = rgb_formats[i]; + } + + if (plane_cap && plane_cap->supports_nv12) + formats[num_formats++] = DRM_FORMAT_NV12; break; + case DRM_PLANE_TYPE_OVERLAY: - res = drm_universal_plane_init( - dm->adev->ddev, - plane, - possible_crtcs, - &dm_plane_funcs, - overlay_formats, - ARRAY_SIZE(overlay_formats), - NULL, plane->type, NULL); + for (i = 0; i < ARRAY_SIZE(overlay_formats); ++i) { + if (num_formats >= max_formats) + break; + + formats[num_formats++] = overlay_formats[i]; + } break; + case DRM_PLANE_TYPE_CURSOR: - res = drm_universal_plane_init( - dm->adev->ddev, - plane, - possible_crtcs, - &dm_plane_funcs, - cursor_formats, - ARRAY_SIZE(cursor_formats), - NULL, plane->type, NULL); + for (i = 0; i < ARRAY_SIZE(cursor_formats); ++i) { + if (num_formats >= max_formats) + break; + + formats[num_formats++] = cursor_formats[i]; + } break; } + return num_formats; +} + +static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, + struct drm_plane *plane, + unsigned long possible_crtcs, + const struct dc_plane_cap *plane_cap) +{ + uint32_t formats[32]; + int num_formats; + int res = -EPERM; + + num_formats = get_plane_formats(plane, plane_cap, formats, + ARRAY_SIZE(formats)); + + res = drm_universal_plane_init(dm->adev->ddev, plane, possible_crtcs, + &dm_plane_funcs, formats, num_formats, + NULL, plane->type, NULL); + if (res) + return res; + if (plane->type == DRM_PLANE_TYPE_OVERLAY && plane_cap && plane_cap->per_pixel_alpha) { unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | @@ -4176,8 +4201,7 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, if (plane->funcs->reset) plane->funcs->reset(plane); - - return res; + return 0; } static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, -- cgit v1.2.3 From fc8e5230dca9dfe0dae0a9d5ce92c6a3199decb1 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 15 Mar 2019 15:55:43 -0400 Subject: drm/amd/display: Add DRM color properties for primary planes [Why] We need DC's color space to match the color encoding and color space specified by userspace to correctly render YUV surfaces. [How] Add the DRM color properties when the DC plane supports NV12. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Sun peng Li Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index dfc28b7433bf..89d30eeea057 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4195,6 +4195,18 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, drm_plane_create_blend_mode_property(plane, blend_caps); } + if (plane->type == DRM_PLANE_TYPE_PRIMARY && + plane_cap && plane_cap->supports_nv12) { + /* This only affects YUV formats. */ + drm_plane_create_color_properties( + plane, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), + DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); + } + drm_plane_helper_add(plane, &dm_plane_helper_funcs); /* Create (reset) the plane state */ -- cgit v1.2.3 From ea36ad34c5b2d6d2e079efc20fb0784e63dad438 Mon Sep 17 00:00:00 2001 From: Jun Lei Date: Tue, 26 Mar 2019 17:32:59 -0400 Subject: drm/amd/display: expand plane caps to include fp16 and scaling capability [why] there are some scaling capabilities such as fp16 which are known to be unsupported on a given ASIC. exposing these static capabilities allows much simpler implementation for OS interfaces which require to report such static capabilities to reduce the number of dynamic validation calls [how] refactor the existing plane caps to be more extensible, and add fp16 and scaling capabilities Signed-off-by: Jun Lei Reviewed-by: Tony Cheng Acked-by: Bhawanpreet Lakha Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++-- drivers/gpu/drm/amd/display/dc/dc.h | 23 +++++++++++-- .../drm/amd/display/dc/dce100/dce100_resource.c | 19 ++++++++++- .../drm/amd/display/dc/dce110/dce110_resource.c | 38 ++++++++++++++++++++-- .../drm/amd/display/dc/dce112/dce112_resource.c | 19 ++++++++++- .../drm/amd/display/dc/dce120/dce120_resource.c | 19 ++++++++++- .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 19 ++++++++++- .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 20 ++++++++++-- 8 files changed, 150 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 89d30eeea057..dd93f7d854ac 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2085,7 +2085,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) if (!plane->blends_with_above || !plane->blends_with_below) continue; - if (!plane->supports_argb8888) + if (!plane->pixel_format_support.argb8888) continue; if (initialize_plane(dm, NULL, primary_planes + i, @@ -4142,7 +4142,7 @@ static int get_plane_formats(const struct drm_plane *plane, formats[num_formats++] = rgb_formats[i]; } - if (plane_cap && plane_cap->supports_nv12) + if (plane_cap && plane_cap->pixel_format_support.nv12) formats[num_formats++] = DRM_FORMAT_NV12; break; @@ -4196,7 +4196,7 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, } if (plane->type == DRM_PLANE_TYPE_PRIMARY && - plane_cap && plane_cap->supports_nv12) { + plane_cap && plane_cap->pixel_format_support.nv12) { /* This only affects YUV formats. */ drm_plane_create_color_properties( plane, diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 704e5430d4dc..ced53db1a1be 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -66,8 +66,27 @@ struct dc_plane_cap { uint32_t blends_with_above : 1; uint32_t blends_with_below : 1; uint32_t per_pixel_alpha : 1; - uint32_t supports_argb8888 : 1; - uint32_t supports_nv12 : 1; + struct { + uint32_t argb8888 : 1; + uint32_t nv12 : 1; + uint32_t fp16 : 1; + } pixel_format_support; + // max upscaling factor x1000 + // upscaling factors are always >= 1 + // for example, 1080p -> 8K is 4.0, or 4000 raw value + struct { + uint32_t argb8888; + uint32_t nv12; + uint32_t fp16; + } max_upscale_factor; + // max downscale factor x1000 + // downscale factors are always <= 1 + // for example, 8K -> 1080p is 0.25, or 250 raw value + struct { + uint32_t argb8888; + uint32_t nv12; + uint32_t fp16; + } max_downscale_factor; }; struct dc_caps { diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 767d37c6d942..f38ea29b3377 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -380,7 +380,24 @@ static const struct resource_caps res_cap = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCE_RGB, - .supports_argb8888 = true, + + .pixel_format_support = { + .argb8888 = true, + .nv12 = false, + .fp16 = false + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 1, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 1, + .fp16 = 1 + } }; #define CTX ctx diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 7c4914b2b524..d5ebc4538711 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -397,14 +397,48 @@ static const struct dc_plane_cap plane_cap = { .blends_with_below = true, .blends_with_above = true, .per_pixel_alpha = 1, - .supports_argb8888 = true, + + .pixel_format_support = { + .argb8888 = true, + .nv12 = false, + .fp16 = false + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 1, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 1, + .fp16 = 1 + } }; static const struct dc_plane_cap underlay_plane_cap = { .type = DC_PLANE_TYPE_DCE_UNDERLAY, .blends_with_above = true, .per_pixel_alpha = 1, - .supports_nv12 = true + + .pixel_format_support = { + .argb8888 = false, + .nv12 = true, + .fp16 = false + }, + + .max_upscale_factor = { + .argb8888 = 1, + .nv12 = 16000, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 1, + .nv12 = 250, + .fp16 = 1 + } }; #define CTX ctx diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 2f28a74383f5..afbc82b87982 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -399,7 +399,24 @@ static const struct resource_caps polaris_11_resource_cap = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCE_RGB, - .supports_argb8888 = true, + + .pixel_format_support = { + .argb8888 = true, + .nv12 = false, + .fp16 = false + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 1, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 1, + .fp16 = 1 + } }; #define CTX ctx diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 01ea503faa12..6d49c7143c67 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -456,7 +456,24 @@ static const struct resource_caps res_cap = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCE_RGB, - .supports_argb8888 = true, + + .pixel_format_support = { + .argb8888 = true, + .nv12 = false, + .fp16 = false + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 1, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 1, + .fp16 = 1 + } }; static const struct dc_debug_options debug_defaults = { diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index c7899ec96287..9569f3af12a3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -389,7 +389,24 @@ static const struct resource_caps res_cap_83 = { static const struct dc_plane_cap plane_cap = { .type = DC_PLANE_TYPE_DCE_RGB, - .supports_argb8888 = true, + + .pixel_format_support = { + .argb8888 = true, + .nv12 = false, + .fp16 = false + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 1, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 1, + .fp16 = 1 + } }; static const struct dce_dmcu_registers dmcu_regs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c index 79f4fbb8a145..7eccb54c421d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -521,8 +521,24 @@ static const struct dc_plane_cap plane_cap = { .blends_with_above = true, .blends_with_below = true, .per_pixel_alpha = true, - .supports_argb8888 = true, - .supports_nv12 = true + + .pixel_format_support = { + .argb8888 = true, + .nv12 = true, + .fp16 = true + }, + + .max_upscale_factor = { + .argb8888 = 16000, + .nv12 = 16000, + .fp16 = 1 + }, + + .max_downscale_factor = { + .argb8888 = 250, + .nv12 = 250, + .fp16 = 1 + } }; static const struct dc_debug_options debug_defaults_drv = { -- cgit v1.2.3 From 623588b8ee601c4e15e717ea5cbea838cd9723ac Mon Sep 17 00:00:00 2001 From: David Francis Date: Mon, 25 Mar 2019 09:44:04 -0400 Subject: drm/amd/display: Handle get crtc position error [Why] dc_stream_get_crtc_position can return false. This was unhandled in delay_cursor_until_vupdate [How] If dc_stream_get_crtc_position returns false, something is weird. Don't delay. Signed-off-by: David Francis Reviewed-by: Sun peng Li Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index f7a293902234..e10479d58c11 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -211,7 +211,8 @@ static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc) ASIC_REV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) { vupdate_line = get_vupdate_offset_from_vsync(pipe_ctx); - dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos); + if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos)) + return; if (vpos >= vupdate_line) return; -- cgit v1.2.3 From e54ae524294f0fe66f5fbbde4cdcb4a52e89bdd5 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Thu, 28 Mar 2019 16:49:42 -0400 Subject: drm/amd/display: define HUBP_MASK_SH_LIST_DCN for Raven Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h index 3268ab089363..db98ba361686 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h @@ -247,7 +247,7 @@ .field_name = reg_name ## __ ## field_name ## post_fix /* Mask/shift struct generation macro for all ASICs (including those with reduced functionality) */ -#define HUBP_MASK_SH_LIST_DCN(mask_sh)\ +#define HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)\ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\ @@ -331,7 +331,6 @@ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, META_CHUNK_SIZE, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MIN_META_CHUNK_SIZE, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, DPTE_GROUP_SIZE, mask_sh),\ - HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, SWATH_HEIGHT, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, PTE_ROW_HEIGHT_LINEAR, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, CHUNK_SIZE_C, mask_sh),\ @@ -339,7 +338,6 @@ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, META_CHUNK_SIZE_C, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MIN_META_CHUNK_SIZE_C, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, DPTE_GROUP_SIZE_C, mask_sh),\ - HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, SWATH_HEIGHT_C, mask_sh),\ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, PTE_ROW_HEIGHT_LINEAR_C, mask_sh),\ HUBP_SF(HUBPREQ0_BLANK_OFFSET_0, REFCYC_H_BLANK_END, mask_sh),\ @@ -373,6 +371,11 @@ HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\ HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh) +#define HUBP_MASK_SH_LIST_DCN(mask_sh)\ + HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh),\ + HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\ + HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh) + /* Mask/shift struct generation macro for ASICs with VM */ #define HUBP_MASK_SH_LIST_DCN_VM(mask_sh)\ HUBP_SF(HUBPREQ0_NOM_PARAMETERS_0, DST_Y_PER_PTE_ROW_NOM_L, mask_sh),\ -- cgit v1.2.3 From 32a5b542a6c6c7b175b9a37dd5e155667cbb2e7b Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Mon, 25 Mar 2019 20:33:35 -0400 Subject: drm/amd/display: Read eDP link settings on detection [Why] Unlike external DP panels, internal eDP does not perform verify link caps because the panel connection is fixed. So if GOP enabled the eDP at boot, we can retain its trained link settings to optimize. [How] Read the lane count and link rate by reading this information from DPCD 100h, 101h, 115h Signed-off-by: Anthony Koo Reviewed-by: Aric Cyr Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index acb4f829e042..ba7502f3d0eb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2587,6 +2587,9 @@ void detect_edp_sink_caps(struct dc_link *link) uint32_t entry; uint32_t link_rate_in_khz; enum dc_link_rate link_rate = LINK_RATE_UNKNOWN; + union lane_count_set lane_count_set = { {0} }; + uint8_t link_bw_set; + uint8_t link_rate_set; retrieve_link_cap(link); link->dpcd_caps.edp_supported_link_rates_count = 0; @@ -2612,6 +2615,33 @@ void detect_edp_sink_caps(struct dc_link *link) } } link->verified_link_cap = link->reported_link_cap; + + // Read DPCD 00101h to find out the number of lanes currently set + core_link_read_dpcd(link, DP_LANE_COUNT_SET, + &lane_count_set.raw, sizeof(lane_count_set)); + link->cur_link_settings.lane_count = lane_count_set.bits.LANE_COUNT_SET; + + // Read DPCD 00100h to find if standard link rates are set + core_link_read_dpcd(link, DP_LINK_BW_SET, + &link_bw_set, sizeof(link_bw_set)); + + if (link_bw_set == 0) { + /* If standard link rates are not being used, + * Read DPCD 00115h to find the link rate set used + */ + core_link_read_dpcd(link, DP_LINK_RATE_SET, + &link_rate_set, sizeof(link_rate_set)); + + if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { + link->cur_link_settings.link_rate = + link->dpcd_caps.edp_supported_link_rates[link_rate_set]; + link->cur_link_settings.link_rate_set = link_rate_set; + link->cur_link_settings.use_link_rate_set = true; + } + } else { + link->cur_link_settings.link_rate = link_bw_set; + link->cur_link_settings.use_link_rate_set = false; + } } void dc_link_dp_enable_hpd(const struct dc_link *link) -- cgit v1.2.3 From 0a8d85e0a16051c06aa8ae6286dd434e719c55c6 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Fri, 29 Mar 2019 16:27:50 -0400 Subject: drm/amd/display: 3.2.26 Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ced53db1a1be..c0b1defde65e 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -39,7 +39,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.25" +#define DC_VER "3.2.26" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit v1.2.3 From 7817183227798d32e0f49f2bfe865da05e48623a Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 25 Mar 2019 12:06:23 -0400 Subject: drm/amd/display: Update plane scaling parameters for fast updates [Why] Plane scaling parameters are not correctly filled or updated when performing fast updates. They're filled when creating the dc plane state and during atomic check. While the atomic check code path happens for the plane even during fast updates, the issue is that they're done in place on the dc_plane_state directly. This dc_plane_state may be the current state plane state being used by the hardware, so these parameters won't be correctly programmed. The new scaling parameters should instead be passed as an update to the plane. [How] Update fill_rects_from_plane_state to not modify dc_plane_state directly. Update the call sites that use this to fill in the appropriate values. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Sun peng Li Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 63 ++++++++++++++--------- 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index dd93f7d854ac..c4d0c4eee036 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2386,50 +2386,53 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { }; static bool fill_rects_from_plane_state(const struct drm_plane_state *state, - struct dc_plane_state *plane_state) + struct rect *src_rect, + struct rect *dst_rect, + struct rect *clip_rect, + enum dc_rotation_angle *rotation) { - plane_state->src_rect.x = state->src_x >> 16; - plane_state->src_rect.y = state->src_y >> 16; + src_rect->x = state->src_x >> 16; + src_rect->y = state->src_y >> 16; /* we ignore the mantissa for now and do not deal with floating pixels :( */ - plane_state->src_rect.width = state->src_w >> 16; + src_rect->width = state->src_w >> 16; - if (plane_state->src_rect.width == 0) + if (src_rect->width == 0) return false; - plane_state->src_rect.height = state->src_h >> 16; - if (plane_state->src_rect.height == 0) + src_rect->height = state->src_h >> 16; + if (src_rect->height == 0) return false; - plane_state->dst_rect.x = state->crtc_x; - plane_state->dst_rect.y = state->crtc_y; + dst_rect->x = state->crtc_x; + dst_rect->y = state->crtc_y; if (state->crtc_w == 0) return false; - plane_state->dst_rect.width = state->crtc_w; + dst_rect->width = state->crtc_w; if (state->crtc_h == 0) return false; - plane_state->dst_rect.height = state->crtc_h; + dst_rect->height = state->crtc_h; - plane_state->clip_rect = plane_state->dst_rect; + *clip_rect = *dst_rect; switch (state->rotation & DRM_MODE_ROTATE_MASK) { case DRM_MODE_ROTATE_0: - plane_state->rotation = ROTATION_ANGLE_0; + *rotation = ROTATION_ANGLE_0; break; case DRM_MODE_ROTATE_90: - plane_state->rotation = ROTATION_ANGLE_90; + *rotation = ROTATION_ANGLE_90; break; case DRM_MODE_ROTATE_180: - plane_state->rotation = ROTATION_ANGLE_180; + *rotation = ROTATION_ANGLE_180; break; case DRM_MODE_ROTATE_270: - plane_state->rotation = ROTATION_ANGLE_270; + *rotation = ROTATION_ANGLE_270; break; default: - plane_state->rotation = ROTATION_ANGLE_0; + *rotation = ROTATION_ANGLE_0; break; } @@ -2809,7 +2812,11 @@ static int fill_plane_attributes(struct amdgpu_device *adev, const struct drm_crtc *crtc = plane_state->crtc; int ret = 0; - if (!fill_rects_from_plane_state(plane_state, dc_plane_state)) + if (!fill_rects_from_plane_state(plane_state, + &dc_plane_state->src_rect, + &dc_plane_state->dst_rect, + &dc_plane_state->clip_rect, + &dc_plane_state->rotation)) return -EINVAL; ret = fill_plane_attributes_from_fb( @@ -4028,12 +4035,17 @@ static int dm_plane_atomic_check(struct drm_plane *plane, { struct amdgpu_device *adev = plane->dev->dev_private; struct dc *dc = adev->dm.dc; - struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); + struct dm_plane_state *dm_plane_state; + struct rect src_rect, dst_rect, clip_rect; + enum dc_rotation_angle rotation; + + dm_plane_state = to_dm_plane_state(state); if (!dm_plane_state->dc_state) return 0; - if (!fill_rects_from_plane_state(state, dm_plane_state->dc_state)) + if (!fill_rects_from_plane_state(state, &src_rect, &dst_rect, + &clip_rect, &rotation)) return -EINVAL; if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) @@ -5107,9 +5119,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->scaling_infos[planes_count].scaling_quality = dc_plane->scaling_quality; - bundle->scaling_infos[planes_count].src_rect = dc_plane->src_rect; - bundle->scaling_infos[planes_count].dst_rect = dc_plane->dst_rect; - bundle->scaling_infos[planes_count].clip_rect = dc_plane->clip_rect; + + fill_rects_from_plane_state(new_plane_state, + &bundle->scaling_infos[planes_count].src_rect, + &bundle->scaling_infos[planes_count].dst_rect, + &bundle->scaling_infos[planes_count].clip_rect, + &bundle->plane_infos[planes_count].rotation); + bundle->surface_updates[planes_count].scaling_info = &bundle->scaling_infos[planes_count]; fill_plane_color_attributes( @@ -5118,7 +5134,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->plane_infos[planes_count].format = dc_plane->format; bundle->plane_infos[planes_count].plane_size = dc_plane->plane_size; - bundle->plane_infos[planes_count].rotation = dc_plane->rotation; bundle->plane_infos[planes_count].horizontal_mirror = dc_plane->horizontal_mirror; bundle->plane_infos[planes_count].stereo_format = dc_plane->stereo_format; bundle->plane_infos[planes_count].tiling_info = dc_plane->tiling_info; -- cgit v1.2.3 From f6ff2a08f49d565e38300f1a9d2f13359c7efc54 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 25 Mar 2019 12:17:14 -0400 Subject: drm/amd/display: Maintain z-ordering when creating planes [Why] The overlay will be incorrectly placed *below* the primary plane for commits with state->allow_modeset = true because the primary plane won't be removed and recreated in the same commit. [How] Add the should_reset_plane helper to determine if the plane should be reset or not. If we need to add or force reset any plane in the context then we'll need to do the same for every plane on the stream. Unfortunately we need to do the remove / recreate routine for removing planes as well since DC currently isn't well equipped to handle the plane with the top pipe being removed with other planes still active. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Sun peng Li Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 74 +++++++++++++++++++++-- 1 file changed, 69 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c4d0c4eee036..66b3bb14d127 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6064,6 +6064,69 @@ fail: return ret; } +static bool should_reset_plane(struct drm_atomic_state *state, + struct drm_plane *plane, + struct drm_plane_state *old_plane_state, + struct drm_plane_state *new_plane_state) +{ + struct drm_plane *other; + struct drm_plane_state *old_other_state, *new_other_state; + struct drm_crtc_state *new_crtc_state; + int i; + + /* + * TODO: Remove this hack once the checks below are sufficient + * enough to determine when we need to reset all the planes on + * the stream. + */ + if (state->allow_modeset) + return true; + + /* Exit early if we know that we're adding or removing the plane. */ + if (old_plane_state->crtc != new_plane_state->crtc) + return true; + + /* old crtc == new_crtc == NULL, plane not in context. */ + if (!new_plane_state->crtc) + return false; + + new_crtc_state = + drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); + + if (!new_crtc_state) + return true; + + if (drm_atomic_crtc_needs_modeset(new_crtc_state)) + return true; + + /* + * If there are any new primary or overlay planes being added or + * removed then the z-order can potentially change. To ensure + * correct z-order and pipe acquisition the current DC architecture + * requires us to remove and recreate all existing planes. + * + * TODO: Come up with a more elegant solution for this. + */ + for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) { + if (other->type == DRM_PLANE_TYPE_CURSOR) + continue; + + if (old_other_state->crtc != new_plane_state->crtc && + new_other_state->crtc != new_plane_state->crtc) + continue; + + if (old_other_state->crtc != new_other_state->crtc) + return true; + + /* TODO: Remove this once we can handle fast format changes. */ + if (old_other_state->fb && new_other_state->fb && + old_other_state->fb->format != new_other_state->fb->format) + return true; + } + + return false; +} + static int dm_update_plane_state(struct dc *dc, struct drm_atomic_state *state, struct drm_plane *plane, @@ -6078,8 +6141,7 @@ static int dm_update_plane_state(struct dc *dc, struct drm_crtc_state *old_crtc_state, *new_crtc_state; struct dm_crtc_state *dm_new_crtc_state, *dm_old_crtc_state; struct dm_plane_state *dm_new_plane_state, *dm_old_plane_state; - /* TODO return page_flip_needed() function */ - bool pflip_needed = !state->allow_modeset; + bool needs_reset; int ret = 0; @@ -6092,10 +6154,12 @@ static int dm_update_plane_state(struct dc *dc, if (plane->type == DRM_PLANE_TYPE_CURSOR) return 0; + needs_reset = should_reset_plane(state, plane, old_plane_state, + new_plane_state); + /* Remove any changed/removed planes */ if (!enable) { - if (pflip_needed && - plane->type != DRM_PLANE_TYPE_OVERLAY) + if (!needs_reset) return 0; if (!old_plane_crtc) @@ -6146,7 +6210,7 @@ static int dm_update_plane_state(struct dc *dc, if (!dm_new_crtc_state->stream) return 0; - if (pflip_needed && plane->type != DRM_PLANE_TYPE_OVERLAY) + if (!needs_reset) return 0; WARN_ON(dm_new_plane_state->dc_state); -- cgit v1.2.3 From 320932bfd9e30222f427811079323b6c86edf4da Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 28 Mar 2019 09:46:23 -0400 Subject: drm/amd/display: Recalculate pitch when buffers change [Why] Pitch was only calculated based on format whenever the plane state was recreated. This could result in surface corruption due to the incorrect pitch being programmed when the surface pitch changed during commits where state->allow_modeset = false. [How] Recalculate pitch at the same time we update the buffer address and other buffer attributes. This function was previously called fill_plane_tiling_attributes but I've also renamed it to fill_plane_buffer_attributes to clarify the actual intent of the function now that it's handling most buffer related attributes. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++++++++++------------ 1 file changed, 34 insertions(+), 39 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 66b3bb14d127..f04f966c7787 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2528,28 +2528,53 @@ static int fill_plane_dcc_attributes(struct amdgpu_device *adev, } static int -fill_plane_tiling_attributes(struct amdgpu_device *adev, +fill_plane_buffer_attributes(struct amdgpu_device *adev, const struct amdgpu_framebuffer *afb, const struct dc_plane_state *plane_state, union dc_tiling_info *tiling_info, + union plane_size *plane_size, struct dc_plane_dcc_param *dcc, struct dc_plane_address *address, uint64_t tiling_flags) { + const struct drm_framebuffer *fb = &afb->base; int ret; memset(tiling_info, 0, sizeof(*tiling_info)); + memset(plane_size, 0, sizeof(*plane_size)); memset(dcc, 0, sizeof(*dcc)); memset(address, 0, sizeof(*address)); if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { + plane_size->grph.surface_size.x = 0; + plane_size->grph.surface_size.y = 0; + plane_size->grph.surface_size.width = fb->width; + plane_size->grph.surface_size.height = fb->height; + plane_size->grph.surface_pitch = + fb->pitches[0] / fb->format->cpp[0]; + address->type = PLN_ADDR_TYPE_GRAPHICS; address->grph.addr.low_part = lower_32_bits(afb->address); address->grph.addr.high_part = upper_32_bits(afb->address); } else { - const struct drm_framebuffer *fb = &afb->base; uint64_t chroma_addr = afb->address + fb->offsets[1]; + plane_size->video.luma_size.x = 0; + plane_size->video.luma_size.y = 0; + plane_size->video.luma_size.width = fb->width; + plane_size->video.luma_size.height = fb->height; + plane_size->video.luma_pitch = + fb->pitches[0] / fb->format->cpp[0]; + + plane_size->video.chroma_size.x = 0; + plane_size->video.chroma_size.y = 0; + /* TODO: set these based on surface format */ + plane_size->video.chroma_size.width = fb->width / 2; + plane_size->video.chroma_size.height = fb->height / 2; + + plane_size->video.chroma_pitch = + fb->pitches[1] / fb->format->cpp[1]; + address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; address->video_progressive.luma_addr.low_part = lower_32_bits(afb->address); @@ -2670,41 +2695,9 @@ static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, return -EINVAL; } - memset(&plane_state->address, 0, sizeof(plane_state->address)); - - if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { - plane_state->plane_size.grph.surface_size.x = 0; - plane_state->plane_size.grph.surface_size.y = 0; - plane_state->plane_size.grph.surface_size.width = fb->width; - plane_state->plane_size.grph.surface_size.height = fb->height; - plane_state->plane_size.grph.surface_pitch = - fb->pitches[0] / fb->format->cpp[0]; - /* TODO: unhardcode */ - plane_state->color_space = COLOR_SPACE_SRGB; - - } else { - plane_state->plane_size.video.luma_size.x = 0; - plane_state->plane_size.video.luma_size.y = 0; - plane_state->plane_size.video.luma_size.width = fb->width; - plane_state->plane_size.video.luma_size.height = fb->height; - plane_state->plane_size.video.luma_pitch = - fb->pitches[0] / fb->format->cpp[0]; - - plane_state->plane_size.video.chroma_size.x = 0; - plane_state->plane_size.video.chroma_size.y = 0; - /* TODO: set these based on surface format */ - plane_state->plane_size.video.chroma_size.width = fb->width / 2; - plane_state->plane_size.video.chroma_size.height = fb->height / 2; - - plane_state->plane_size.video.chroma_pitch = - fb->pitches[1] / fb->format->cpp[1]; - - /* TODO: unhardcode */ - plane_state->color_space = COLOR_SPACE_YCBCR709; - } - - fill_plane_tiling_attributes(adev, amdgpu_fb, plane_state, + fill_plane_buffer_attributes(adev, amdgpu_fb, plane_state, &plane_state->tiling_info, + &plane_state->plane_size, &plane_state->dcc, &plane_state->address, tiling_flags); @@ -4001,9 +3994,10 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; - fill_plane_tiling_attributes( + fill_plane_buffer_attributes( adev, afb, plane_state, &plane_state->tiling_info, - &plane_state->dcc, &plane_state->address, tiling_flags); + &plane_state->plane_size, &plane_state->dcc, + &plane_state->address, tiling_flags); } return 0; @@ -5174,8 +5168,9 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, amdgpu_bo_unreserve(abo); - fill_plane_tiling_attributes(dm->adev, afb, dc_plane, + fill_plane_buffer_attributes(dm->adev, afb, dc_plane, &bundle->plane_infos[planes_count].tiling_info, + &bundle->plane_infos[planes_count].plane_size, &bundle->plane_infos[planes_count].dcc, &bundle->flip_addrs[planes_count].address, tiling_flags); -- cgit v1.2.3 From 695af5f9a51914030eb2d9e3ba923d38180a8199 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 28 Mar 2019 14:45:19 -0400 Subject: drm/amd/display: Rework DC plane filling and surface updates [Why] We currently don't do DC validation for medium or full updates where the plane state isn't created. There are some medium and full updates that can cause bandwidth or clock changes to occur resulting in underflow or corruption. We need to be able to fill surface and plane info updates during atomic commit for dm_determine_update_type for commit. Since we already do this during atomic commit tail it would be good if we had the same logic in both places for creating these structures. [How] Introduce fill_dc_scaling_info and fill_dc_plane_info_and_addr. These two functions cover the following three update structures: - struct dc_scaling_info - struct dc_plane_info - struct dc_plane_address Cleanup and adapter the existing fill_plane_* helpers to work with these functions. Update call sites that used most of these sub helpers directly to work with the new functions. The exception being prepare_fb - we just want the new buffer attributes specifically in the case where we're creating the plane. This is needed for dc_commit_state in the case where the FB hasn't been previously been used. This isn't quite a refactor, but functionally driver behavior should be mostly the smae as before. The one exception is that we now check the return code for fill_plane_buffer_attributes which means that commits will be rejected that try to enable DCC with erroneous parameters. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 406 +++++++++++----------- 1 file changed, 204 insertions(+), 202 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f04f966c7787..5bf71a65f056 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2385,59 +2385,48 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { .destroy = amdgpu_dm_encoder_destroy, }; -static bool fill_rects_from_plane_state(const struct drm_plane_state *state, - struct rect *src_rect, - struct rect *dst_rect, - struct rect *clip_rect, - enum dc_rotation_angle *rotation) -{ - src_rect->x = state->src_x >> 16; - src_rect->y = state->src_y >> 16; - /* we ignore the mantissa for now and do not deal with floating pixels :( */ - src_rect->width = state->src_w >> 16; - - if (src_rect->width == 0) - return false; - src_rect->height = state->src_h >> 16; - if (src_rect->height == 0) - return false; +static int fill_dc_scaling_info(const struct drm_plane_state *state, + struct dc_scaling_info *scaling_info) +{ + memset(scaling_info, 0, sizeof(*scaling_info)); - dst_rect->x = state->crtc_x; - dst_rect->y = state->crtc_y; + /* Source is fixed 16.16 but we ignore mantissa for now... */ + scaling_info->src_rect.x = state->src_x >> 16; + scaling_info->src_rect.y = state->src_y >> 16; + + scaling_info->src_rect.width = state->src_w >> 16; + if (scaling_info->src_rect.width == 0) + return -EINVAL; + + scaling_info->src_rect.height = state->src_h >> 16; + if (scaling_info->src_rect.height == 0) + return -EINVAL; + + scaling_info->dst_rect.x = state->crtc_x; + scaling_info->dst_rect.y = state->crtc_y; if (state->crtc_w == 0) - return false; + return -EINVAL; - dst_rect->width = state->crtc_w; + scaling_info->dst_rect.width = state->crtc_w; if (state->crtc_h == 0) - return false; + return -EINVAL; - dst_rect->height = state->crtc_h; + scaling_info->dst_rect.height = state->crtc_h; - *clip_rect = *dst_rect; + /* DRM doesn't specify clipping on destination output. */ + scaling_info->clip_rect = scaling_info->dst_rect; - switch (state->rotation & DRM_MODE_ROTATE_MASK) { - case DRM_MODE_ROTATE_0: - *rotation = ROTATION_ANGLE_0; - break; - case DRM_MODE_ROTATE_90: - *rotation = ROTATION_ANGLE_90; - break; - case DRM_MODE_ROTATE_180: - *rotation = ROTATION_ANGLE_180; - break; - case DRM_MODE_ROTATE_270: - *rotation = ROTATION_ANGLE_270; - break; - default: - *rotation = ROTATION_ANGLE_0; - break; - } + /* + * The "scaling_quality" can be ignored for now, quality = 0 has DC + * assume reasonable defaults based on the format. + */ - return true; + return 0; } + static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb, uint64_t *tiling_flags) { @@ -2466,12 +2455,16 @@ static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags) return offset ? (address + offset * 256) : 0; } -static int fill_plane_dcc_attributes(struct amdgpu_device *adev, - const struct amdgpu_framebuffer *afb, - const struct dc_plane_state *plane_state, - struct dc_plane_dcc_param *dcc, - struct dc_plane_address *address, - uint64_t info) +static int +fill_plane_dcc_attributes(struct amdgpu_device *adev, + const struct amdgpu_framebuffer *afb, + const enum surface_pixel_format format, + const enum dc_rotation_angle rotation, + const union plane_size *plane_size, + const union dc_tiling_info *tiling_info, + const uint64_t info, + struct dc_plane_dcc_param *dcc, + struct dc_plane_address *address) { struct dc *dc = adev->dm.dc; struct dc_dcc_surface_param input; @@ -2486,24 +2479,20 @@ static int fill_plane_dcc_attributes(struct amdgpu_device *adev, if (!offset) return 0; - if (plane_state->address.type != PLN_ADDR_TYPE_GRAPHICS) + if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) return 0; if (!dc->cap_funcs.get_dcc_compression_cap) return -EINVAL; - input.format = plane_state->format; - input.surface_size.width = - plane_state->plane_size.grph.surface_size.width; - input.surface_size.height = - plane_state->plane_size.grph.surface_size.height; - input.swizzle_mode = plane_state->tiling_info.gfx9.swizzle; + input.format = format; + input.surface_size.width = plane_size->grph.surface_size.width; + input.surface_size.height = plane_size->grph.surface_size.height; + input.swizzle_mode = tiling_info->gfx9.swizzle; - if (plane_state->rotation == ROTATION_ANGLE_0 || - plane_state->rotation == ROTATION_ANGLE_180) + if (rotation == ROTATION_ANGLE_0 || rotation == ROTATION_ANGLE_180) input.scan = SCAN_DIRECTION_HORIZONTAL; - else if (plane_state->rotation == ROTATION_ANGLE_90 || - plane_state->rotation == ROTATION_ANGLE_270) + else if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) input.scan = SCAN_DIRECTION_VERTICAL; if (!dc->cap_funcs.get_dcc_compression_cap(dc, &input, &output)) @@ -2530,12 +2519,13 @@ static int fill_plane_dcc_attributes(struct amdgpu_device *adev, static int fill_plane_buffer_attributes(struct amdgpu_device *adev, const struct amdgpu_framebuffer *afb, - const struct dc_plane_state *plane_state, + const enum surface_pixel_format format, + const enum dc_rotation_angle rotation, + const uint64_t tiling_flags, union dc_tiling_info *tiling_info, union plane_size *plane_size, struct dc_plane_dcc_param *dcc, - struct dc_plane_address *address, - uint64_t tiling_flags) + struct dc_plane_address *address) { const struct drm_framebuffer *fb = &afb->base; int ret; @@ -2545,7 +2535,7 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, memset(dcc, 0, sizeof(*dcc)); memset(address, 0, sizeof(*address)); - if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { + if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { plane_size->grph.surface_size.x = 0; plane_size->grph.surface_size.y = 0; plane_size->grph.surface_size.width = fb->width; @@ -2635,8 +2625,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE); tiling_info->gfx9.shaderEnable = 1; - ret = fill_plane_dcc_attributes(adev, afb, plane_state, dcc, - address, tiling_flags); + ret = fill_plane_dcc_attributes(adev, afb, format, rotation, + plane_size, tiling_info, + tiling_flags, dcc, address); if (ret) return ret; } @@ -2644,80 +2635,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, return 0; } -static int fill_plane_attributes_from_fb(struct amdgpu_device *adev, - struct dc_plane_state *plane_state, - const struct amdgpu_framebuffer *amdgpu_fb) -{ - uint64_t tiling_flags; - const struct drm_framebuffer *fb = &amdgpu_fb->base; - int ret = 0; - struct drm_format_name_buf format_name; - - ret = get_fb_info( - amdgpu_fb, - &tiling_flags); - - if (ret) - return ret; - - switch (fb->format->format) { - case DRM_FORMAT_C8: - plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS; - break; - case DRM_FORMAT_RGB565: - plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_RGB565; - break; - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_ARGB8888: - plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888; - break; - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_ARGB2101010: - plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010; - break; - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_ABGR2101010: - plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010; - break; - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_ABGR8888: - plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR8888; - break; - case DRM_FORMAT_NV21: - plane_state->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr; - break; - case DRM_FORMAT_NV12: - plane_state->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb; - break; - default: - DRM_ERROR("Unsupported screen format %s\n", - drm_get_format_name(fb->format->format, &format_name)); - return -EINVAL; - } - - fill_plane_buffer_attributes(adev, amdgpu_fb, plane_state, - &plane_state->tiling_info, - &plane_state->plane_size, - &plane_state->dcc, - &plane_state->address, - tiling_flags); - - plane_state->visible = true; - plane_state->scaling_quality.h_taps_c = 0; - plane_state->scaling_quality.v_taps_c = 0; - - /* is this needed? is plane_state zeroed at allocation? */ - plane_state->scaling_quality.h_taps = 0; - plane_state->scaling_quality.v_taps = 0; - plane_state->stereo_format = PLANE_STEREO_FORMAT_NONE; - - return ret; - -} - static void -fill_blending_from_plane_state(struct drm_plane_state *plane_state, - const struct dc_plane_state *dc_plane_state, +fill_blending_from_plane_state(const struct drm_plane_state *plane_state, bool *per_pixel_alpha, bool *global_alpha, int *global_alpha_value) { @@ -2753,7 +2672,7 @@ fill_blending_from_plane_state(struct drm_plane_state *plane_state, static int fill_plane_color_attributes(const struct drm_plane_state *plane_state, - const struct dc_plane_state *dc_plane_state, + const enum surface_pixel_format format, enum dc_color_space *color_space) { bool full_range; @@ -2761,7 +2680,7 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state, *color_space = COLOR_SPACE_SRGB; /* DRM color properties only affect non-RGB formats. */ - if (dc_plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) + if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) return 0; full_range = (plane_state->color_range == DRM_COLOR_YCBCR_FULL_RANGE); @@ -2795,36 +2714,144 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state, return 0; } -static int fill_plane_attributes(struct amdgpu_device *adev, - struct dc_plane_state *dc_plane_state, - struct drm_plane_state *plane_state, - struct drm_crtc_state *crtc_state) +static int +fill_dc_plane_info_and_addr(struct amdgpu_device *adev, + const struct drm_plane_state *plane_state, + const uint64_t tiling_flags, + struct dc_plane_info *plane_info, + struct dc_plane_address *address) +{ + const struct drm_framebuffer *fb = plane_state->fb; + const struct amdgpu_framebuffer *afb = + to_amdgpu_framebuffer(plane_state->fb); + struct drm_format_name_buf format_name; + int ret; + + memset(plane_info, 0, sizeof(*plane_info)); + + switch (fb->format->format) { + case DRM_FORMAT_C8: + plane_info->format = + SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS; + break; + case DRM_FORMAT_RGB565: + plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_RGB565; + break; + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888; + break; + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010; + break; + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010; + break; + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_ABGR8888: + plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR8888; + break; + case DRM_FORMAT_NV21: + plane_info->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr; + break; + case DRM_FORMAT_NV12: + plane_info->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb; + break; + default: + DRM_ERROR( + "Unsupported screen format %s\n", + drm_get_format_name(fb->format->format, &format_name)); + return -EINVAL; + } + + switch (plane_state->rotation & DRM_MODE_ROTATE_MASK) { + case DRM_MODE_ROTATE_0: + plane_info->rotation = ROTATION_ANGLE_0; + break; + case DRM_MODE_ROTATE_90: + plane_info->rotation = ROTATION_ANGLE_90; + break; + case DRM_MODE_ROTATE_180: + plane_info->rotation = ROTATION_ANGLE_180; + break; + case DRM_MODE_ROTATE_270: + plane_info->rotation = ROTATION_ANGLE_270; + break; + default: + plane_info->rotation = ROTATION_ANGLE_0; + break; + } + + plane_info->visible = true; + plane_info->stereo_format = PLANE_STEREO_FORMAT_NONE; + + ret = fill_plane_color_attributes(plane_state, plane_info->format, + &plane_info->color_space); + if (ret) + return ret; + + ret = fill_plane_buffer_attributes(adev, afb, plane_info->format, + plane_info->rotation, tiling_flags, + &plane_info->tiling_info, + &plane_info->plane_size, + &plane_info->dcc, address); + if (ret) + return ret; + + fill_blending_from_plane_state( + plane_state, &plane_info->per_pixel_alpha, + &plane_info->global_alpha, &plane_info->global_alpha_value); + + return 0; +} + +static int fill_dc_plane_attributes(struct amdgpu_device *adev, + struct dc_plane_state *dc_plane_state, + struct drm_plane_state *plane_state, + struct drm_crtc_state *crtc_state) { const struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(plane_state->fb); - const struct drm_crtc *crtc = plane_state->crtc; - int ret = 0; + struct dc_scaling_info scaling_info; + struct dc_plane_info plane_info; + uint64_t tiling_flags; + int ret; - if (!fill_rects_from_plane_state(plane_state, - &dc_plane_state->src_rect, - &dc_plane_state->dst_rect, - &dc_plane_state->clip_rect, - &dc_plane_state->rotation)) - return -EINVAL; + ret = fill_dc_scaling_info(plane_state, &scaling_info); + if (ret) + return ret; - ret = fill_plane_attributes_from_fb( - crtc->dev->dev_private, - dc_plane_state, - amdgpu_fb); + dc_plane_state->src_rect = scaling_info.src_rect; + dc_plane_state->dst_rect = scaling_info.dst_rect; + dc_plane_state->clip_rect = scaling_info.clip_rect; + dc_plane_state->scaling_quality = scaling_info.scaling_quality; + ret = get_fb_info(amdgpu_fb, &tiling_flags); if (ret) return ret; - ret = fill_plane_color_attributes(plane_state, dc_plane_state, - &dc_plane_state->color_space); + ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, + &plane_info, + &dc_plane_state->address); if (ret) return ret; + dc_plane_state->format = plane_info.format; + dc_plane_state->color_space = plane_info.color_space; + dc_plane_state->format = plane_info.format; + dc_plane_state->plane_size = plane_info.plane_size; + dc_plane_state->rotation = plane_info.rotation; + dc_plane_state->horizontal_mirror = plane_info.horizontal_mirror; + dc_plane_state->stereo_format = plane_info.stereo_format; + dc_plane_state->tiling_info = plane_info.tiling_info; + dc_plane_state->visible = plane_info.visible; + dc_plane_state->per_pixel_alpha = plane_info.per_pixel_alpha; + dc_plane_state->global_alpha = plane_info.global_alpha; + dc_plane_state->global_alpha_value = plane_info.global_alpha_value; + dc_plane_state->dcc = plane_info.dcc; + /* * Always set input transfer function, since plane state is refreshed * every time. @@ -2835,11 +2862,6 @@ static int fill_plane_attributes(struct amdgpu_device *adev, dc_plane_state->in_transfer_func = NULL; } - fill_blending_from_plane_state(plane_state, dc_plane_state, - &dc_plane_state->per_pixel_alpha, - &dc_plane_state->global_alpha, - &dc_plane_state->global_alpha_value); - return ret; } @@ -3995,9 +4017,10 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; fill_plane_buffer_attributes( - adev, afb, plane_state, &plane_state->tiling_info, + adev, afb, plane_state->format, plane_state->rotation, + tiling_flags, &plane_state->tiling_info, &plane_state->plane_size, &plane_state->dcc, - &plane_state->address, tiling_flags); + &plane_state->address); } return 0; @@ -4030,17 +4053,17 @@ static int dm_plane_atomic_check(struct drm_plane *plane, struct amdgpu_device *adev = plane->dev->dev_private; struct dc *dc = adev->dm.dc; struct dm_plane_state *dm_plane_state; - struct rect src_rect, dst_rect, clip_rect; - enum dc_rotation_angle rotation; + struct dc_scaling_info scaling_info; + int ret; dm_plane_state = to_dm_plane_state(state); if (!dm_plane_state->dc_state) return 0; - if (!fill_rects_from_plane_state(state, &src_rect, &dst_rect, - &clip_rect, &rotation)) - return -EINVAL; + ret = fill_dc_scaling_info(state, &scaling_info); + if (ret) + return ret; if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) return 0; @@ -5087,7 +5110,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct drm_crtc *crtc = new_plane_state->crtc; struct drm_crtc_state *new_crtc_state; struct drm_framebuffer *fb = new_plane_state->fb; - struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(fb); bool plane_needs_flip; struct dc_plane_state *dc_plane; struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state); @@ -5111,32 +5133,11 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func; } + fill_dc_scaling_info(new_plane_state, + &bundle->scaling_infos[planes_count]); - bundle->scaling_infos[planes_count].scaling_quality = dc_plane->scaling_quality; - - fill_rects_from_plane_state(new_plane_state, - &bundle->scaling_infos[planes_count].src_rect, - &bundle->scaling_infos[planes_count].dst_rect, - &bundle->scaling_infos[planes_count].clip_rect, - &bundle->plane_infos[planes_count].rotation); - - bundle->surface_updates[planes_count].scaling_info = &bundle->scaling_infos[planes_count]; - - fill_plane_color_attributes( - new_plane_state, dc_plane, - &bundle->plane_infos[planes_count].color_space); - - bundle->plane_infos[planes_count].format = dc_plane->format; - bundle->plane_infos[planes_count].plane_size = dc_plane->plane_size; - bundle->plane_infos[planes_count].horizontal_mirror = dc_plane->horizontal_mirror; - bundle->plane_infos[planes_count].stereo_format = dc_plane->stereo_format; - bundle->plane_infos[planes_count].tiling_info = dc_plane->tiling_info; - bundle->plane_infos[planes_count].visible = dc_plane->visible; - bundle->plane_infos[planes_count].global_alpha = dc_plane->global_alpha; - bundle->plane_infos[planes_count].global_alpha_value = dc_plane->global_alpha_value; - bundle->plane_infos[planes_count].per_pixel_alpha = dc_plane->per_pixel_alpha; - bundle->plane_infos[planes_count].dcc = dc_plane->dcc; - bundle->surface_updates[planes_count].plane_info = &bundle->plane_infos[planes_count]; + bundle->surface_updates[planes_count].scaling_info = + &bundle->scaling_infos[planes_count]; plane_needs_flip = old_plane_state->fb && new_plane_state->fb; @@ -5168,12 +5169,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, amdgpu_bo_unreserve(abo); - fill_plane_buffer_attributes(dm->adev, afb, dc_plane, - &bundle->plane_infos[planes_count].tiling_info, - &bundle->plane_infos[planes_count].plane_size, - &bundle->plane_infos[planes_count].dcc, - &bundle->flip_addrs[planes_count].address, - tiling_flags); + fill_dc_plane_info_and_addr( + dm->adev, new_plane_state, tiling_flags, + &bundle->plane_infos[planes_count], + &bundle->flip_addrs[planes_count].address); + + bundle->surface_updates[planes_count].plane_info = + &bundle->plane_infos[planes_count]; bundle->flip_addrs[planes_count].flip_immediate = (crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0; @@ -6217,7 +6219,7 @@ static int dm_update_plane_state(struct dc *dc, DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n", plane->base.id, new_plane_crtc->base.id); - ret = fill_plane_attributes( + ret = fill_dc_plane_attributes( new_plane_crtc->dev->dev_private, dc_new_plane_state, new_plane_state, -- cgit v1.2.3 From 5ac4619b9d2fdbb54ef4b247db774637e347d46e Mon Sep 17 00:00:00 2001 From: Samson Tam Date: Mon, 1 Apr 2019 17:07:21 -0400 Subject: drm/amd/display: change name from dc_link_get_verified_link_cap to dc_link_get_link_cap [Why] DM doesn't need to know which link cap is being retrieved ( verified or preferred ). Let DC figure it out. [How] Change name. Signed-off-by: Samson Tam Reviewed-by: Tony Cheng Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 3 +-- drivers/gpu/drm/amd/display/dc/dc_link.h | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 4887d0611001..dda10b1f8574 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -597,7 +597,7 @@ uint32_t dc_link_bandwidth_kbps( } -const struct dc_link_settings *dc_link_get_verified_link_cap( +const struct dc_link_settings *dc_link_get_link_cap( const struct dc_link *link) { if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN && diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index ba7502f3d0eb..a6424c70f4c5 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1548,8 +1548,7 @@ bool dp_validate_mode_timing( timing->v_addressable == (uint32_t) 480) return true; - /* We always use verified link settings */ - link_setting = dc_link_get_verified_link_cap(link); + link_setting = dc_link_get_link_cap(link); /* TODO: DYNAMIC_VALIDATION needs to be implemented */ /*if (flags.DYNAMIC_VALIDATION == 1 && diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 4e26d6e93b31..cc7ffac64c96 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -250,7 +250,7 @@ uint32_t dc_link_bandwidth_kbps( const struct dc_link *link, const struct dc_link_settings *link_setting); -const struct dc_link_settings *dc_link_get_verified_link_cap( +const struct dc_link_settings *dc_link_get_link_cap( const struct dc_link *link); bool dc_submit_i2c( -- cgit v1.2.3 From 6491f0c05abd009631e0d0a33d671bb5a685847a Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 1 Apr 2019 09:43:34 -0400 Subject: drm/amd/display: Add basic downscale and upscale valdiation [Why] Planes have downscaling limits and upscaling limits per format and DM is expected to validate these using DC caps. We should fail atomic check validation if we aren't capable of doing the scaling. [How] We don't currently create store which DC plane maps to which DRM plane so we can't easily check the caps directly. For now add basic constraints that cover the absolute min and max downscale / upscale limits for most RGB and YUV formats across ASICs. Leave a TODO indicating that these should really be done with DC caps. We'll probably need to subclass DRM planes again in order to correctly identify which DC plane maps to it. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Harry Wentland Reviewed-by: Tony Cheng Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 5bf71a65f056..752179b359f1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -2389,6 +2389,8 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { static int fill_dc_scaling_info(const struct drm_plane_state *state, struct dc_scaling_info *scaling_info) { + int scale_w, scale_h; + memset(scaling_info, 0, sizeof(*scaling_info)); /* Source is fixed 16.16 but we ignore mantissa for now... */ @@ -2419,6 +2421,19 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, /* DRM doesn't specify clipping on destination output. */ scaling_info->clip_rect = scaling_info->dst_rect; + /* TODO: Validate scaling per-format with DC plane caps */ + scale_w = scaling_info->dst_rect.width * 1000 / + scaling_info->src_rect.width; + + if (scale_w < 250 || scale_w > 16000) + return -EINVAL; + + scale_h = scaling_info->dst_rect.height * 1000 / + scaling_info->src_rect.height; + + if (scale_h < 250 || scale_h > 16000) + return -EINVAL; + /* * The "scaling_quality" can be ignored for now, quality = 0 has DC * assume reasonable defaults based on the format. -- cgit v1.2.3 From f843b308adb2c412da611351acbe29292190cae8 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 10 Jan 2019 09:32:31 -0500 Subject: drm/amd/display: Use surface directly when checking update type [Why] DC expects the surface memory address to identify the surface. This doesn't work with what we're doing with the temporary surfaces, it will always assume this is a full update because the surface isn't in the current context. [How] Use the surface directly. This doesn't give us much improvement yet, since we always create a new dc_plane_state when state->allow_modeset is true. The call into dc_check_update_surfaces_for_stream also needs to be locked, for two reasons: 1. It checks the current DC state 2. It modifies the surface update flags Both of which could be currently in the middle of commit work from commit tail. A TODO here is to pass the context explicitly into this function and find a way to get the surface update flags out of it without modifying the surface in place. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 ++++++++++------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 752179b359f1..5c0b3bbfd18f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6282,10 +6282,11 @@ static int dm_update_plane_state(struct dc *dc, } static int -dm_determine_update_type_for_commit(struct dc *dc, +dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, struct drm_atomic_state *state, enum surface_update_type *out_type) { + struct dc *dc = dm->dc; struct dm_atomic_state *dm_state = NULL, *old_dm_state = NULL; int i, j, num_plane, ret = 0; struct drm_plane_state *old_plane_state, *new_plane_state; @@ -6299,14 +6300,12 @@ dm_determine_update_type_for_commit(struct dc *dc, struct dc_stream_status *status = NULL; struct dc_surface_update *updates; - struct dc_plane_state *surface; enum surface_update_type update_type = UPDATE_TYPE_FAST; updates = kcalloc(MAX_SURFACES, sizeof(*updates), GFP_KERNEL); - surface = kcalloc(MAX_SURFACES, sizeof(*surface), GFP_KERNEL); - if (!updates || !surface) { - DRM_ERROR("Plane or surface update failed to allocate"); + if (!updates) { + DRM_ERROR("Failed to allocate plane updates\n"); /* Set type to FULL to avoid crashing in DC*/ update_type = UPDATE_TYPE_FULL; goto cleanup; @@ -6349,17 +6348,9 @@ dm_determine_update_type_for_commit(struct dc *dc, if (crtc != new_plane_crtc) continue; - updates[num_plane].surface = &surface[num_plane]; + updates[num_plane].surface = new_dm_plane_state->dc_state; if (new_crtc_state->mode_changed) { - updates[num_plane].surface->src_rect = - new_dm_plane_state->dc_state->src_rect; - updates[num_plane].surface->dst_rect = - new_dm_plane_state->dc_state->dst_rect; - updates[num_plane].surface->rotation = - new_dm_plane_state->dc_state->rotation; - updates[num_plane].surface->in_transfer_func = - new_dm_plane_state->dc_state->in_transfer_func; stream_update.dst = new_dm_crtc_state->stream->dst; stream_update.src = new_dm_crtc_state->stream->src; } @@ -6394,8 +6385,14 @@ dm_determine_update_type_for_commit(struct dc *dc, status = dc_stream_get_status_from_state(old_dm_state->context, new_dm_crtc_state->stream); + /* + * TODO: DC modifies the surface during this call so we need + * to lock here - find a way to do this without locking. + */ + mutex_lock(&dm->dc_lock); update_type = dc_check_update_surfaces_for_stream(dc, updates, num_plane, &stream_update, status); + mutex_unlock(&dm->dc_lock); if (update_type > UPDATE_TYPE_MED) { update_type = UPDATE_TYPE_FULL; @@ -6405,7 +6402,6 @@ dm_determine_update_type_for_commit(struct dc *dc, cleanup: kfree(updates); - kfree(surface); *out_type = update_type; return ret; @@ -6589,7 +6585,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, lock_and_validation_needed = true; } - ret = dm_determine_update_type_for_commit(dc, state, &update_type); + ret = dm_determine_update_type_for_commit(&adev->dm, state, &update_type); if (ret) goto fail; -- cgit v1.2.3 From 6e8dc7b0a7a4d5532c2e0706795a95b7beb9592e Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 29 Mar 2019 11:40:43 -0400 Subject: drm/amd/display: Don't warn when DC update type > DM guess [Why] DM thinks that the update type should be full whenever a stream or plane is added or removed (including recreations). This won't match in the case where DC thinks what looks like a fast update to DM is actually a medium or full - like scaling changes that affect bandwidth and clocks. [How] Drop this warning. DC knows better than the DM does for determining cases like this. The other warning can be kept for now since it would warn on a pretty serious DC or DM bug. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 5c0b3bbfd18f..409979f8bf0b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6600,9 +6600,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, */ if (lock_and_validation_needed && overall_update_type <= UPDATE_TYPE_FAST) WARN(1, "Global lock should be Set, overall_update_type should be UPDATE_TYPE_MED or UPDATE_TYPE_FULL"); - else if (!lock_and_validation_needed && overall_update_type > UPDATE_TYPE_FAST) - WARN(1, "Global lock should NOT be set, overall_update_type should be UPDATE_TYPE_FAST"); - if (overall_update_type > UPDATE_TYPE_FAST) { ret = dm_atomic_get_state(state, &dm_state); -- cgit v1.2.3 From 004b3938e6374f39d43cc32bd4953f2fe8b8905b Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 28 Mar 2019 15:50:06 -0400 Subject: drm/amd/display: Check scaling info when determing update type [Why] Surface scaling info updates can affect bandwidth and blocks. We need to be checking these with global validation to avoid underflow or corruption. [How] Drop the state->allow_modeset early exit in dm_determine_update_type_for_commit. Most of those should be considered fast now anyway. Fill in scaling info and it to the surface update in atomic check. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 409979f8bf0b..ea63accc9f1f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6312,6 +6312,7 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, } for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + struct dc_scaling_info scaling_info; struct dc_stream_update stream_update; memset(&stream_update, 0, sizeof(stream_update)); @@ -6342,9 +6343,6 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, goto cleanup; } - if (!state->allow_modeset) - continue; - if (crtc != new_plane_crtc) continue; @@ -6366,6 +6364,13 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, new_dm_crtc_state->stream->out_transfer_func; } + ret = fill_dc_scaling_info(new_plane_state, + &scaling_info); + if (ret) + goto cleanup; + + updates[num_plane].scaling_info = &scaling_info; + num_plane++; } -- cgit v1.2.3 From c14a005c1621c3b995ac9df8bf93bb4de8a3e446 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 29 Mar 2019 14:58:32 -0400 Subject: drm/amd/display: Relax requirements for CRTCs to be enabled [Why] As long as we have at least one non-cursor plane enabled on a CRTC then the CRTC itself can remain enabled. This will allow for commits where there's an overlay plane enabled but no primary plane enabled. [How] Remove existing primary plane fb != NULL checks and replace them with the new does_crtc_have_active_plane helper. This will be called from atomic check when validating the CRTC. Since the primary plane state can now potentially be NULL we'll need to guard for that when accessing it in some of the cursor logic. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 56 ++++++++++++++++++----- 1 file changed, 44 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ea63accc9f1f..42e643c9b6bc 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3862,6 +3862,38 @@ static void dm_crtc_helper_disable(struct drm_crtc *crtc) { } +static bool does_crtc_have_active_plane(struct drm_crtc_state *new_crtc_state) +{ + struct drm_atomic_state *state = new_crtc_state->state; + struct drm_plane *plane; + int num_active = 0; + + drm_for_each_plane_mask(plane, state->dev, new_crtc_state->plane_mask) { + struct drm_plane_state *new_plane_state; + + /* Cursor planes are "fake". */ + if (plane->type == DRM_PLANE_TYPE_CURSOR) + continue; + + new_plane_state = drm_atomic_get_new_plane_state(state, plane); + + if (!new_plane_state) { + /* + * The plane is enable on the CRTC and hasn't changed + * state. This means that it previously passed + * validation and is therefore enabled. + */ + num_active += 1; + continue; + } + + /* We need a framebuffer to be considered enabled. */ + num_active += (new_plane_state->fb != NULL); + } + + return num_active > 0; +} + static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -3880,6 +3912,11 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, if (!dm_crtc_state->stream) return 0; + /* We want at least one hardware plane enabled to use the stream. */ + if (state->enable && state->active && + !does_crtc_have_active_plane(state)) + return -EINVAL; + if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK) return 0; @@ -4849,9 +4886,13 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, x = plane->state->crtc_x; y = plane->state->crtc_y; - /* avivo cursor are offset into the total surface */ - x += crtc->primary->state->src_x >> 16; - y += crtc->primary->state->src_y >> 16; + + if (crtc->primary->state) { + /* avivo cursor are offset into the total surface */ + x += crtc->primary->state->src_x >> 16; + y += crtc->primary->state->src_y >> 16; + } + if (x < 0) { xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1); x = 0; @@ -5872,21 +5913,12 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, struct amdgpu_dm_connector *aconnector = NULL; struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL; struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL; - struct drm_plane_state *new_plane_state = NULL; new_stream = NULL; dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); acrtc = to_amdgpu_crtc(crtc); - - new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary); - - if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) { - ret = -EINVAL; - goto fail; - } - aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc); /* TODO This hack should go away */ -- cgit v1.2.3 From afcd526b1ba9dbc5707f9bd8d2d032ae62e337dc Mon Sep 17 00:00:00 2001 From: Joshua Aberback Date: Mon, 1 Apr 2019 15:18:29 -0400 Subject: drm/amd/display: Add fast_validate parameter Add a fast_validate parameter in dc_validate_global_state for future use Signed-off-by: Joshua Aberback Reviewed-by: Tony Cheng Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 6 ++++-- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 6 ++++-- drivers/gpu/drm/amd/display/dc/dc.h | 7 ++++++- drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h | 3 ++- drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | 3 ++- drivers/gpu/drm/amd/display/dc/inc/core_types.h | 3 ++- drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h | 3 ++- 11 files changed, 29 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 42e643c9b6bc..054681113d71 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -6647,7 +6647,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, if (ret) goto fail; - if (dc_validate_global_state(dc, dm_state->context) != DC_OK) { + if (dc_validate_global_state(dc, dm_state->context, false) != DC_OK) { ret = -EINVAL; goto fail; } diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index 8843361e842d..d7aece82e4fe 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -701,7 +701,8 @@ static void hack_bounding_box(struct dcn_bw_internal_vars *v, bool dcn_validate_bandwidth( struct dc *dc, - struct dc_state *context) + struct dc_state *context, + bool fast_validate) { const struct resource_pool *pool = dc->res_pool; struct dcn_bw_internal_vars *v = &context->dcn_bw_vars; @@ -1013,8 +1014,9 @@ bool dcn_validate_bandwidth( mode_support_and_system_configuration(v); } - if (v->voltage_level != 5) { + if (v->voltage_level != number_of_states_plus_one && !fast_validate) { float bw_consumed = v->total_bandwidth_consumed_gbyte_per_second; + if (bw_consumed < v->fabric_and_dram_bandwidth_vmin0p65) bw_consumed = v->fabric_and_dram_bandwidth_vmin0p65; else if (bw_consumed < v->fabric_and_dram_bandwidth_vmid0p72) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 3830e6ce1355..eac7186e4f08 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2067,12 +2067,14 @@ void dc_resource_state_construct( * Checks HW resource availability and bandwidth requirement. * @dc: dc struct for this driver * @new_ctx: state to be validated + * @fast_validate: set to true if only yes/no to support matters * * Return: DC_OK if the result can be programmed. Otherwise, an error code. */ enum dc_status dc_validate_global_state( struct dc *dc, - struct dc_state *new_ctx) + struct dc_state *new_ctx, + bool fast_validate) { enum dc_status result = DC_ERROR_UNEXPECTED; int i, j; @@ -2127,7 +2129,7 @@ enum dc_status dc_validate_global_state( result = resource_build_scaling_params_for_context(dc, new_ctx); if (result == DC_OK) - if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx)) + if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate)) result = DC_FAIL_BANDWIDTH_VALIDATE; return result; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c0b1defde65e..978ce365b4a7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -658,9 +658,14 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info); +/* + * fast_validate: we return after determining if we can support the new state, + * but before we populate the programming info + */ enum dc_status dc_validate_global_state( struct dc *dc, - struct dc_state *new_ctx); + struct dc_state *new_ctx, + bool fast_validate); void dc_resource_state_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index f38ea29b3377..e938bf9986d3 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -778,7 +778,8 @@ static enum dc_status build_mapped_resource( bool dce100_validate_bandwidth( struct dc *dc, - struct dc_state *context) + struct dc_state *context, + bool fast_validate) { int i; bool at_least_one_pipe = false; diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index d5ebc4538711..dcd04e9ea76b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -903,7 +903,8 @@ static enum dc_status build_mapped_resource( static bool dce110_validate_bandwidth( struct dc *dc, - struct dc_state *context) + struct dc_state *context, + bool fast_validate) { bool result = false; diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index afbc82b87982..a480b15f6885 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -826,7 +826,8 @@ static enum dc_status build_mapped_resource( bool dce112_validate_bandwidth( struct dc *dc, - struct dc_state *context) + struct dc_state *context, + bool fast_validate) { bool result = false; diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h index 95a403396219..1f57ebc6f9b4 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h @@ -44,7 +44,8 @@ enum dc_status dce112_validate_with_context( bool dce112_validate_bandwidth( struct dc *dc, - struct dc_state *context); + struct dc_state *context, + bool fast_validate); enum dc_status dce112_add_stream_to_ctx( struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 9569f3af12a3..27d0cc394963 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -812,7 +812,8 @@ static void destruct(struct dce110_resource_pool *pool) bool dce80_validate_bandwidth( struct dc *dc, - struct dc_state *context) + struct dc_state *context, + bool fast_validate) { int i; bool at_least_one_pipe = false; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 827541e34ee2..88a82a23d259 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -97,7 +97,8 @@ struct resource_funcs { const struct encoder_init_data *init); bool (*validate_bandwidth)( struct dc *dc, - struct dc_state *context); + struct dc_state *context, + bool fast_validate); enum dc_status (*validate_global)( struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h index 86ec3f69c765..263c09630c06 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h @@ -621,7 +621,8 @@ extern const struct dcn_ip_params dcn10_ip_defaults; bool dcn_validate_bandwidth( struct dc *dc, - struct dc_state *context); + struct dc_state *context, + bool fast_validate); unsigned int dcn_find_dcfclk_suits_all( const struct dc *dc, -- cgit v1.2.3 From f55be0be5b7296e73f1634e2839a1953dc12d11e Mon Sep 17 00:00:00 2001 From: Joshua Aberback Date: Mon, 1 Apr 2019 15:21:24 -0400 Subject: drm/amd/display: Add profiling tools for bandwidth validation [Why] We used this change to investigate the performance of bandwidth validation, it will be useful to have if we need to investigate further. [How] We use performance counter tick numbers to profile performance, they live at dc->debug.bw_val_profile (set .enable in debugger to turn on measuring). Signed-off-by: Joshua Aberback Reviewed-by: Tony Cheng Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 18 ++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 52 ++++++++++++++++++++++++ 2 files changed, 70 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c index d7aece82e4fe..1b4b51657f5e 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -704,6 +704,12 @@ bool dcn_validate_bandwidth( struct dc_state *context, bool fast_validate) { + /* + * we want a breakdown of the various stages of validation, which the + * perf_trace macro doesn't support + */ + BW_VAL_TRACE_SETUP(); + const struct resource_pool *pool = dc->res_pool; struct dcn_bw_internal_vars *v = &context->dcn_bw_vars; int i, input_idx; @@ -712,6 +718,9 @@ bool dcn_validate_bandwidth( float bw_limit; PERFORMANCE_TRACE_START(); + + BW_VAL_TRACE_COUNT(); + if (dcn_bw_apply_registry_override(dc)) dcn_bw_sync_calcs_and_dml(dc); @@ -1014,6 +1023,8 @@ bool dcn_validate_bandwidth( mode_support_and_system_configuration(v); } + BW_VAL_TRACE_END_VOLTAGE_LEVEL(); + if (v->voltage_level != number_of_states_plus_one && !fast_validate) { float bw_consumed = v->total_bandwidth_consumed_gbyte_per_second; @@ -1089,6 +1100,8 @@ bool dcn_validate_bandwidth( break; } + BW_VAL_TRACE_END_WATERMARKS(); + for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -1179,6 +1192,10 @@ bool dcn_validate_bandwidth( input_idx++; } + } else if (v->voltage_level == number_of_states_plus_one) { + BW_VAL_TRACE_SKIP(fail); + } else if (fast_validate) { + BW_VAL_TRACE_SKIP(fast); } if (v->voltage_level == 0) { @@ -1198,6 +1215,7 @@ bool dcn_validate_bandwidth( kernel_fpu_end(); PERFORMANCE_TRACE_END(); + BW_VAL_TRACE_FINISH(); if (bw_limit_pass && v->voltage_level != 5) return true; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 978ce365b4a7..3459e39714bc 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -246,6 +246,57 @@ struct dc_clocks { bool p_state_change_support; }; +struct dc_bw_validation_profile { + bool enable; + + unsigned long long total_ticks; + unsigned long long voltage_level_ticks; + unsigned long long watermark_ticks; + unsigned long long rq_dlg_ticks; + + unsigned long long total_count; + unsigned long long skip_fast_count; + unsigned long long skip_pass_count; + unsigned long long skip_fail_count; +}; + +#define BW_VAL_TRACE_SETUP() \ + unsigned long long end_tick = 0; \ + unsigned long long voltage_level_tick = 0; \ + unsigned long long watermark_tick = 0; \ + unsigned long long start_tick = dc->debug.bw_val_profile.enable ? \ + dm_get_timestamp(dc->ctx) : 0 + +#define BW_VAL_TRACE_COUNT() \ + if (dc->debug.bw_val_profile.enable) \ + dc->debug.bw_val_profile.total_count++ + +#define BW_VAL_TRACE_SKIP(status) \ + if (dc->debug.bw_val_profile.enable) { \ + if (!voltage_level_tick) \ + voltage_level_tick = dm_get_timestamp(dc->ctx); \ + dc->debug.bw_val_profile.skip_ ## status ## _count++; \ + } + +#define BW_VAL_TRACE_END_VOLTAGE_LEVEL() \ + if (dc->debug.bw_val_profile.enable) \ + voltage_level_tick = dm_get_timestamp(dc->ctx) + +#define BW_VAL_TRACE_END_WATERMARKS() \ + if (dc->debug.bw_val_profile.enable) \ + watermark_tick = dm_get_timestamp(dc->ctx) + +#define BW_VAL_TRACE_FINISH() \ + if (dc->debug.bw_val_profile.enable) { \ + end_tick = dm_get_timestamp(dc->ctx); \ + dc->debug.bw_val_profile.total_ticks += end_tick - start_tick; \ + dc->debug.bw_val_profile.voltage_level_ticks += voltage_level_tick - start_tick; \ + if (watermark_tick) { \ + dc->debug.bw_val_profile.watermark_ticks += watermark_tick - voltage_level_tick; \ + dc->debug.bw_val_profile.rq_dlg_ticks += end_tick - watermark_tick; \ + } \ + } + struct dc_debug_options { enum visual_confirm visual_confirm; bool sanity_checks; @@ -299,6 +350,7 @@ struct dc_debug_options { unsigned int force_odm_combine; //bit vector based on otg inst unsigned int force_fclk_khz; bool disable_tri_buf; + struct dc_bw_validation_profile bw_val_profile; }; struct dc_debug_data { -- cgit v1.2.3 From 1ab494cc405ce597beec88145488648e59234924 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 13 Apr 2019 13:58:20 +0100 Subject: drm/i915/selftests: Skip live timeline/suspend tests if wedged If the driver is wedged, we can not issue the requests to exercise the timelines or the system across suspend, so skip the tests. live_hangcheck is there to fail if we cannot recover. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190413125820.14112-4-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/selftests/i915_gem.c | 3 +++ drivers/gpu/drm/i915/selftests/i915_timeline.c | 3 +++ 2 files changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c index 50bb7bbd26d3..6fd70d326468 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem.c @@ -215,5 +215,8 @@ int i915_gem_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_gem_hibernate), }; + if (i915_terminally_wedged(i915)) + return 0; + return i915_subtests(tests, i915); } diff --git a/drivers/gpu/drm/i915/selftests/i915_timeline.c b/drivers/gpu/drm/i915/selftests/i915_timeline.c index 8e7bcaa1eb66..bd96afcadfe7 100644 --- a/drivers/gpu/drm/i915/selftests/i915_timeline.c +++ b/drivers/gpu/drm/i915/selftests/i915_timeline.c @@ -838,5 +838,8 @@ int i915_timeline_live_selftests(struct drm_i915_private *i915) SUBTEST(live_hwsp_wrap), }; + if (i915_terminally_wedged(i915)) + return 0; + return i915_subtests(tests, i915); } -- cgit v1.2.3 From c856dbc887aa5b6674a565dbe227164958103a51 Mon Sep 17 00:00:00 2001 From: Manasi Navare Date: Mon, 15 Apr 2019 11:22:10 -0700 Subject: drm/i915: Nuke drm_crtc_state and use intel_atomic_state instead This is one of the patches to start replacing drm pointers and use the intel_atomic_state and intel_crtc to derive the necessary intel state variables required for the intel modeset functions. v3: * Remove the unwanted newline (Ville) v2: * Flip the function arguments (Ville) * Remove some remaining instances of drm pointers (Ville) * Use old_crtc_state and new_crtc_state (Ville) Suggested-by: Ville Syrjala Cc: Ville Syrjala Signed-off-by: Manasi Navare Reviewed-by: Ville Syrjala Link: https://patchwork.freedesktop.org/patch/msgid/20190415182210.13347-1-manasi.d.navare@intel.com --- drivers/gpu/drm/i915/intel_display.c | 61 +++++++++++++++++------------------- 1 file changed, 28 insertions(+), 33 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c780ca6cd667..3bd40a4a6739 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -125,8 +125,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, const struct intel_crtc_state *pipe_config); static void chv_prepare_pll(struct intel_crtc *crtc, const struct intel_crtc_state *pipe_config); -static void intel_begin_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); -static void intel_finish_crtc_commit(struct drm_crtc *, struct drm_crtc_state *); +static void intel_begin_crtc_commit(struct intel_atomic_state *, struct intel_crtc *); +static void intel_finish_crtc_commit(struct intel_atomic_state *, struct intel_crtc *); static void intel_crtc_init_scalers(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state); static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state); @@ -13274,14 +13274,14 @@ static void intel_update_crtc(struct drm_crtc *crtc, else if (new_plane_state) intel_fbc_enable(intel_crtc, pipe_config, new_plane_state); - intel_begin_crtc_commit(crtc, old_crtc_state); + intel_begin_crtc_commit(to_intel_atomic_state(state), intel_crtc); if (INTEL_GEN(dev_priv) >= 9) skl_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc); else i9xx_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc); - intel_finish_crtc_commit(crtc, old_crtc_state); + intel_finish_crtc_commit(to_intel_atomic_state(state), intel_crtc); } static void intel_update_crtcs(struct drm_atomic_state *state) @@ -14071,39 +14071,35 @@ skl_max_scale(const struct intel_crtc_state *crtc_state, return max_scale; } -static void intel_begin_crtc_commit(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) +static void intel_begin_crtc_commit(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *old_intel_cstate = - to_intel_crtc_state(old_crtc_state); - struct intel_atomic_state *old_intel_state = - to_intel_atomic_state(old_crtc_state->state); - struct intel_crtc_state *intel_cstate = - intel_atomic_get_new_crtc_state(old_intel_state, intel_crtc); - bool modeset = needs_modeset(&intel_cstate->base); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + struct intel_crtc_state *new_crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + bool modeset = needs_modeset(&new_crtc_state->base); /* Perform vblank evasion around commit operation */ - intel_pipe_update_start(intel_cstate); + intel_pipe_update_start(new_crtc_state); if (modeset) goto out; - if (intel_cstate->base.color_mgmt_changed || - intel_cstate->update_pipe) - intel_color_commit(intel_cstate); + if (new_crtc_state->base.color_mgmt_changed || + new_crtc_state->update_pipe) + intel_color_commit(new_crtc_state); - if (intel_cstate->update_pipe) - intel_update_pipe_config(old_intel_cstate, intel_cstate); + if (new_crtc_state->update_pipe) + intel_update_pipe_config(old_crtc_state, new_crtc_state); else if (INTEL_GEN(dev_priv) >= 9) - skl_detach_scalers(intel_cstate); + skl_detach_scalers(new_crtc_state); out: if (dev_priv->display.atomic_update_watermarks) - dev_priv->display.atomic_update_watermarks(old_intel_state, - intel_cstate); + dev_priv->display.atomic_update_watermarks(state, + new_crtc_state); } void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, @@ -14122,21 +14118,20 @@ void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, } } -static void intel_finish_crtc_commit(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) +static void intel_finish_crtc_commit(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_atomic_state *old_intel_state = - to_intel_atomic_state(old_crtc_state->state); + struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = - intel_atomic_get_new_crtc_state(old_intel_state, intel_crtc); + intel_atomic_get_new_crtc_state(state, crtc); intel_pipe_update_end(new_crtc_state); if (new_crtc_state->update_pipe && !needs_modeset(&new_crtc_state->base) && - old_crtc_state->mode.private_flags & I915_MODE_FLAG_INHERITED) - intel_crtc_arm_fifo_underrun(intel_crtc, new_crtc_state); + old_crtc_state->base.mode.private_flags & I915_MODE_FLAG_INHERITED) + intel_crtc_arm_fifo_underrun(crtc, new_crtc_state); } /** -- cgit v1.2.3 From ac071578286ee9abd0243480631510d9f818144d Mon Sep 17 00:00:00 2001 From: Xiaolin Zhang Date: Wed, 3 Apr 2019 16:28:04 +0800 Subject: drm/i915/gvt: addressed guest GPU hang with HWS index mode with the introduce of "switch to use HWS indices rather than address", guest GPU hang observed when running workloads which will update the seqno to the real HW HWSP, not vitural GPU HWSP and then cause GPU hang. this patch is to revoke index mode in PIPE_CTRL and MI_FLUSH_DW and patch guest GPU HWSP address value to these commands. Fixes: 54939ea0bd85 ("drm/i915: Switch to use HWS indices rather than addresses") Reviewed-by: Zhenyu Wang Signed-off-by: Xiaolin Zhang Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 57a92a86c63e..5a767180e430 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -1077,6 +1077,7 @@ static int cmd_handler_pipe_control(struct parser_exec_state *s) bool index_mode = false; unsigned int post_sync; int ret = 0; + u32 hws_pga, val; post_sync = (cmd_val(s, 1) & PIPE_CONTROL_POST_SYNC_OP_MASK) >> 14; @@ -1100,6 +1101,15 @@ static int cmd_handler_pipe_control(struct parser_exec_state *s) index_mode = true; ret |= cmd_address_audit(s, gma, sizeof(u64), index_mode); + if (ret) + return ret; + if (index_mode) { + hws_pga = s->vgpu->hws_pga[s->ring_id]; + gma = hws_pga + gma; + patch_value(s, cmd_ptr(s, 2), gma); + val = cmd_val(s, 1) & (~(1 << 21)); + patch_value(s, cmd_ptr(s, 1), val); + } } } } @@ -1569,6 +1579,7 @@ static int cmd_handler_mi_flush_dw(struct parser_exec_state *s) unsigned long gma; bool index_mode = false; int ret = 0; + u32 hws_pga, val; /* Check post-sync and ppgtt bit */ if (((cmd_val(s, 0) >> 14) & 0x3) && (cmd_val(s, 1) & (1 << 2))) { @@ -1579,6 +1590,15 @@ static int cmd_handler_mi_flush_dw(struct parser_exec_state *s) if (cmd_val(s, 0) & (1 << 21)) index_mode = true; ret = cmd_address_audit(s, gma, sizeof(u64), index_mode); + if (ret) + return ret; + if (index_mode) { + hws_pga = s->vgpu->hws_pga[s->ring_id]; + gma = hws_pga + gma; + patch_value(s, cmd_ptr(s, 1), gma); + val = cmd_val(s, 0) & (~(1 << 21)); + patch_value(s, cmd_ptr(s, 0), val); + } } /* Check notify bit */ if ((cmd_val(s, 0) & (1 << 8))) -- cgit v1.2.3 From 2bfc4975083ace0e5777116514c3a75e59b3dbcd Mon Sep 17 00:00:00 2001 From: Colin Xu Date: Mon, 1 Apr 2019 14:13:53 +0800 Subject: drm/i915/gvt: Fix incorrect mask of mmio 0x22028 in gen8/9 mmio list According to GFX PRM on 01.org, bit 31:16 of mmio 0x22028 should be masks. Fixes: 178657139307 ("drm/i915/gvt: vGPU context switch") Reviewed-by: Zhenyu Wang Signed-off-by: Colin Xu Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/gvt/mmio_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c index 76630fbe51b6..e7e14c842be4 100644 --- a/drivers/gpu/drm/i915/gvt/mmio_context.c +++ b/drivers/gpu/drm/i915/gvt/mmio_context.c @@ -68,7 +68,7 @@ static struct engine_mmio gen8_engine_mmio_list[] __cacheline_aligned = { {BCS0, RING_MI_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2209c */ {BCS0, RING_INSTPM(BLT_RING_BASE), 0xffff, false}, /* 0x220c0 */ {BCS0, RING_HWSTAM(BLT_RING_BASE), 0x0, false}, /* 0x22098 */ - {BCS0, RING_EXCC(BLT_RING_BASE), 0x0, false}, /* 0x22028 */ + {BCS0, RING_EXCC(BLT_RING_BASE), 0xffff, false}, /* 0x22028 */ {RCS0, INVALID_MMIO_REG, 0, false } /* Terminated */ }; @@ -119,7 +119,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = { {BCS0, RING_MI_MODE(BLT_RING_BASE), 0xffff, false}, /* 0x2209c */ {BCS0, RING_INSTPM(BLT_RING_BASE), 0xffff, false}, /* 0x220c0 */ {BCS0, RING_HWSTAM(BLT_RING_BASE), 0x0, false}, /* 0x22098 */ - {BCS0, RING_EXCC(BLT_RING_BASE), 0x0, false}, /* 0x22028 */ + {BCS0, RING_EXCC(BLT_RING_BASE), 0xffff, false}, /* 0x22028 */ {VCS1, RING_EXCC(GEN8_BSD2_RING_BASE), 0xffff, false}, /* 0x1c028 */ -- cgit v1.2.3 From 7a2a519a899b44fec5c37ce4bb2b624f9ad1eff5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 16 Apr 2019 09:52:18 +0100 Subject: drm/i915: Drop bool return from breadcrumbs signaler Since removal of the "missed interrupt detection" nobody used the result of whether or not we signaled anybody during that invocation, so now remove the return value. References: 789659f4307a ("drm/i915: Drop fake breadcrumb irq") Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190416085218.431-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 14 +++----------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 ++-- 2 files changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 09ed90c0ba00..3cbffd400b1b 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -27,8 +27,6 @@ #include "i915_drv.h" -#define task_asleep(tsk) ((tsk)->state & TASK_NORMAL && !(tsk)->on_rq) - static void irq_enable(struct intel_engine_cs *engine) { if (!engine->irq_enable) @@ -82,7 +80,7 @@ static inline bool __request_completed(const struct i915_request *rq) return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno); } -bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) +void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; struct intel_context *ce, *cn; @@ -146,19 +144,13 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine) dma_fence_signal(&rq->fence); i915_request_put(rq); } - - return !list_empty(&signal); } -bool intel_engine_signal_breadcrumbs(struct intel_engine_cs *engine) +void intel_engine_signal_breadcrumbs(struct intel_engine_cs *engine) { - bool result; - local_irq_disable(); - result = intel_engine_breadcrumbs_irq(engine); + intel_engine_breadcrumbs_irq(engine); local_irq_enable(); - - return result; } static void signal_irq_work(struct irq_work *work) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 4b33e88eabb1..72c7c337ace9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -388,7 +388,7 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine); void intel_engine_pin_breadcrumbs_irq(struct intel_engine_cs *engine); void intel_engine_unpin_breadcrumbs_irq(struct intel_engine_cs *engine); -bool intel_engine_signal_breadcrumbs(struct intel_engine_cs *engine); +void intel_engine_signal_breadcrumbs(struct intel_engine_cs *engine); void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine); static inline void @@ -397,7 +397,7 @@ intel_engine_queue_breadcrumbs(struct intel_engine_cs *engine) irq_work_queue(&engine->breadcrumbs.irq_work); } -bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine); +void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine); void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine); void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine); -- cgit v1.2.3 From adc674cebba7253dc4b4eeb1e4c1710082ee0f4a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Apr 2019 09:53:22 +0100 Subject: drm/i915: Mark up ips for RCU protection drivers/gpu/drm/i915/intel_pm.c:8352:9: error: incompatible types in comparison expression (different address spaces) drivers/gpu/drm/i915/intel_pm.c:8359:9: error: incompatible types in comparison expression (different address spaces) Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20190412085410.10392-3-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7357bddf9ad9..44be676fabd6 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -8263,14 +8263,14 @@ unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) return val; } -static struct drm_i915_private *i915_mch_dev; +static struct drm_i915_private __rcu *i915_mch_dev; static struct drm_i915_private *mchdev_get(void) { struct drm_i915_private *i915; rcu_read_lock(); - i915 = i915_mch_dev; + i915 = rcu_dereference(i915_mch_dev); if (!kref_get_unless_zero(&i915->drm.ref)) i915 = NULL; rcu_read_unlock(); -- cgit v1.2.3 From 68eb49b140c380866ee918d378ae1a798aab9983 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 10 Apr 2019 16:53:40 -0700 Subject: drm/i915: refactor the IRQ init/reset macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The whole point of having macros here is for the token pasting necessary to automatically have IMR, IIR and IER selected. We don't really need or want all the inlining that happens as a consequence. The good thing about the current code is that it works regardless of the relative offsets between these registers (they change after gen4, with the usual VLV/CHV exceptions). One thing which we can do is to split the logic of what we do with imr/ier/iir to functions separate from the macros that pick them. That's what we do in this commit. This allows us to get rid of the gen8 duplicates and also all the inlining: add/remove: 2/0 grow/shrink: 0/21 up/down: 384/-5949 (-5565) Function old new delta gen3_irq_reset - 233 +233 gen3_irq_init - 151 +151 i8xx_irq_postinstall 459 442 -17 gen11_irq_postinstall 804 744 -60 ironlake_irq_postinstall 450 353 -97 vlv_display_irq_postinstall 348 245 -103 i965_irq_postinstall 378 272 -106 i915_irq_postinstall 333 227 -106 gen8_irq_power_well_post_enable 374 240 -134 ironlake_irq_reset 397 218 -179 vlv_display_irq_reset 616 433 -183 i965_irq_reset 374 180 -194 cherryview_irq_reset 379 185 -194 i915_irq_reset 407 209 -198 ibx_irq_reset 332 133 -199 gen5_gt_irq_postinstall 533 332 -201 gen8_irq_power_well_pre_disable 434 204 -230 gen8_gt_irq_postinstall 469 196 -273 gen8_de_irq_postinstall 1200 836 -364 gen5_gt_irq_reset 471 76 -395 gen8_gt_irq_reset 775 99 -676 gen8_irq_reset 1100 333 -767 gen11_irq_reset 1959 686 -1273 Total: Before=2259222, After=2253657, chg -0.25% v2: - Make checkpatch happy with a temporary which_ (Checkpatch). - Reorder the arguments for the INIT macros (Ville). - Correctly explain when the register offsets change in the commit message (Ville). - Use more line breaks in the macro calls to make the arguments look a little more organized/readable. - Update the bloat-o-meter output (minor change only). Reviewed-by: Ville Syrjälä (v1) Signed-off-by: Paulo Zanoni Link: https://patchwork.freedesktop.org/patch/msgid/20190410235344.31199-2-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 136 +++++++++++++++++++++++++--------------- 1 file changed, 86 insertions(+), 50 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index d934545445e1..e6bbcaf6e27c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -136,36 +136,48 @@ static const u32 hpd_icp[HPD_NUM_PINS] = { [HPD_PORT_F] = SDE_TC4_HOTPLUG_ICP }; -/* IIR can theoretically queue up two events. Be paranoid. */ -#define GEN8_IRQ_RESET_NDX(type, which) do { \ - I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ - POSTING_READ(GEN8_##type##_IMR(which)); \ - I915_WRITE(GEN8_##type##_IER(which), 0); \ - I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ - POSTING_READ(GEN8_##type##_IIR(which)); \ - I915_WRITE(GEN8_##type##_IIR(which), 0xffffffff); \ - POSTING_READ(GEN8_##type##_IIR(which)); \ -} while (0) - -#define GEN3_IRQ_RESET(type) do { \ - I915_WRITE(type##IMR, 0xffffffff); \ - POSTING_READ(type##IMR); \ - I915_WRITE(type##IER, 0); \ - I915_WRITE(type##IIR, 0xffffffff); \ - POSTING_READ(type##IIR); \ - I915_WRITE(type##IIR, 0xffffffff); \ - POSTING_READ(type##IIR); \ -} while (0) - -#define GEN2_IRQ_RESET(type) do { \ - I915_WRITE16(type##IMR, 0xffff); \ - POSTING_READ16(type##IMR); \ - I915_WRITE16(type##IER, 0); \ - I915_WRITE16(type##IIR, 0xffff); \ - POSTING_READ16(type##IIR); \ - I915_WRITE16(type##IIR, 0xffff); \ - POSTING_READ16(type##IIR); \ -} while (0) +static void gen3_irq_reset(struct drm_i915_private *dev_priv, i915_reg_t imr, + i915_reg_t iir, i915_reg_t ier) +{ + I915_WRITE(imr, 0xffffffff); + POSTING_READ(imr); + + I915_WRITE(ier, 0); + + /* IIR can theoretically queue up two events. Be paranoid. */ + I915_WRITE(iir, 0xffffffff); + POSTING_READ(iir); + I915_WRITE(iir, 0xffffffff); + POSTING_READ(iir); +} + +static void gen2_irq_reset(struct drm_i915_private *dev_priv, i915_reg_t imr, + i915_reg_t iir, i915_reg_t ier) +{ + I915_WRITE16(imr, 0xffff); + POSTING_READ16(imr); + + I915_WRITE16(ier, 0); + + /* IIR can theoretically queue up two events. Be paranoid. */ + I915_WRITE16(iir, 0xffff); + POSTING_READ16(iir); + I915_WRITE16(iir, 0xffff); + POSTING_READ16(iir); +} + +#define GEN8_IRQ_RESET_NDX(type, which) \ +({ \ + unsigned int which_ = which; \ + gen3_irq_reset(dev_priv, GEN8_##type##_IMR(which_), \ + GEN8_##type##_IIR(which_), GEN8_##type##_IER(which_)); \ +}) + +#define GEN3_IRQ_RESET(type) \ + gen3_irq_reset(dev_priv, type##IMR, type##IIR, type##IER) + +#define GEN2_IRQ_RESET(type) \ + gen2_irq_reset(dev_priv, type##IMR, type##IIR, type##IER) /* * We should clear IMR at preinstall/uninstall, and just check at postinstall. @@ -202,26 +214,50 @@ static void gen2_assert_iir_is_zero(struct drm_i915_private *dev_priv, POSTING_READ16(reg); } -#define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) do { \ - gen3_assert_iir_is_zero(dev_priv, GEN8_##type##_IIR(which)); \ - I915_WRITE(GEN8_##type##_IER(which), (ier_val)); \ - I915_WRITE(GEN8_##type##_IMR(which), (imr_val)); \ - POSTING_READ(GEN8_##type##_IMR(which)); \ -} while (0) - -#define GEN3_IRQ_INIT(type, imr_val, ier_val) do { \ - gen3_assert_iir_is_zero(dev_priv, type##IIR); \ - I915_WRITE(type##IER, (ier_val)); \ - I915_WRITE(type##IMR, (imr_val)); \ - POSTING_READ(type##IMR); \ -} while (0) - -#define GEN2_IRQ_INIT(type, imr_val, ier_val) do { \ - gen2_assert_iir_is_zero(dev_priv, type##IIR); \ - I915_WRITE16(type##IER, (ier_val)); \ - I915_WRITE16(type##IMR, (imr_val)); \ - POSTING_READ16(type##IMR); \ -} while (0) +static void gen3_irq_init(struct drm_i915_private *dev_priv, + i915_reg_t imr, u32 imr_val, + i915_reg_t ier, u32 ier_val, + i915_reg_t iir) +{ + gen3_assert_iir_is_zero(dev_priv, iir); + + I915_WRITE(ier, ier_val); + I915_WRITE(imr, imr_val); + POSTING_READ(imr); +} + +static void gen2_irq_init(struct drm_i915_private *dev_priv, + i915_reg_t imr, u32 imr_val, + i915_reg_t ier, u32 ier_val, + i915_reg_t iir) +{ + gen2_assert_iir_is_zero(dev_priv, iir); + + I915_WRITE16(ier, ier_val); + I915_WRITE16(imr, imr_val); + POSTING_READ16(imr); +} + +#define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) \ +({ \ + unsigned int which_ = which; \ + gen3_irq_init(dev_priv, \ + GEN8_##type##_IMR(which_), imr_val, \ + GEN8_##type##_IER(which_), ier_val, \ + GEN8_##type##_IIR(which_)); \ +}) + +#define GEN3_IRQ_INIT(type, imr_val, ier_val) \ + gen3_irq_init(dev_priv, \ + type##IMR, imr_val, \ + type##IER, ier_val, \ + type##IIR) + +#define GEN2_IRQ_INIT(type, imr_val, ier_val) \ + gen2_irq_init(dev_priv, \ + type##IMR, imr_val, \ + type##IER, ier_val, \ + type##IIR) static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); -- cgit v1.2.3 From 2918c3caefc1589350f1aeb18b853bda94b5bc96 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 10 Apr 2019 16:53:41 -0700 Subject: drm/i915: don't specify the IRQ register in the gen2 macros Like the gen3+ macros, the gen2 versions of the IRQ initialization macros take the register name in the 'type' argument. But gen2 only has one set of registers, so there's really no need to specify the type. This commit removes the type argument and uses the registers directly instead of passing them through variables. Signed-off-by: Paulo Zanoni Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20190410235344.31199-3-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 57 ++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 32 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e6bbcaf6e27c..e76cb62dc072 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -151,19 +151,18 @@ static void gen3_irq_reset(struct drm_i915_private *dev_priv, i915_reg_t imr, POSTING_READ(iir); } -static void gen2_irq_reset(struct drm_i915_private *dev_priv, i915_reg_t imr, - i915_reg_t iir, i915_reg_t ier) +static void gen2_irq_reset(struct drm_i915_private *dev_priv) { - I915_WRITE16(imr, 0xffff); - POSTING_READ16(imr); + I915_WRITE16(IMR, 0xffff); + POSTING_READ16(IMR); - I915_WRITE16(ier, 0); + I915_WRITE16(IER, 0); /* IIR can theoretically queue up two events. Be paranoid. */ - I915_WRITE16(iir, 0xffff); - POSTING_READ16(iir); - I915_WRITE16(iir, 0xffff); - POSTING_READ16(iir); + I915_WRITE16(IIR, 0xffff); + POSTING_READ16(IIR); + I915_WRITE16(IIR, 0xffff); + POSTING_READ16(IIR); } #define GEN8_IRQ_RESET_NDX(type, which) \ @@ -176,8 +175,8 @@ static void gen2_irq_reset(struct drm_i915_private *dev_priv, i915_reg_t imr, #define GEN3_IRQ_RESET(type) \ gen3_irq_reset(dev_priv, type##IMR, type##IIR, type##IER) -#define GEN2_IRQ_RESET(type) \ - gen2_irq_reset(dev_priv, type##IMR, type##IIR, type##IER) +#define GEN2_IRQ_RESET() \ + gen2_irq_reset(dev_priv) /* * We should clear IMR at preinstall/uninstall, and just check at postinstall. @@ -198,20 +197,19 @@ static void gen3_assert_iir_is_zero(struct drm_i915_private *dev_priv, POSTING_READ(reg); } -static void gen2_assert_iir_is_zero(struct drm_i915_private *dev_priv, - i915_reg_t reg) +static void gen2_assert_iir_is_zero(struct drm_i915_private *dev_priv) { - u16 val = I915_READ16(reg); + u16 val = I915_READ16(IIR); if (val == 0) return; WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", - i915_mmio_reg_offset(reg), val); - I915_WRITE16(reg, 0xffff); - POSTING_READ16(reg); - I915_WRITE16(reg, 0xffff); - POSTING_READ16(reg); + i915_mmio_reg_offset(IIR), val); + I915_WRITE16(IIR, 0xffff); + POSTING_READ16(IIR); + I915_WRITE16(IIR, 0xffff); + POSTING_READ16(IIR); } static void gen3_irq_init(struct drm_i915_private *dev_priv, @@ -227,15 +225,13 @@ static void gen3_irq_init(struct drm_i915_private *dev_priv, } static void gen2_irq_init(struct drm_i915_private *dev_priv, - i915_reg_t imr, u32 imr_val, - i915_reg_t ier, u32 ier_val, - i915_reg_t iir) + u32 imr_val, u32 ier_val) { - gen2_assert_iir_is_zero(dev_priv, iir); + gen2_assert_iir_is_zero(dev_priv); - I915_WRITE16(ier, ier_val); - I915_WRITE16(imr, imr_val); - POSTING_READ16(imr); + I915_WRITE16(IER, ier_val); + I915_WRITE16(IMR, imr_val); + POSTING_READ16(IMR); } #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) \ @@ -253,11 +249,8 @@ static void gen2_irq_init(struct drm_i915_private *dev_priv, type##IER, ier_val, \ type##IIR) -#define GEN2_IRQ_INIT(type, imr_val, ier_val) \ - gen2_irq_init(dev_priv, \ - type##IMR, imr_val, \ - type##IER, ier_val, \ - type##IIR) +#define GEN2_IRQ_INIT(imr_val, ier_val) \ + gen2_irq_init(dev_priv, imr_val, ier_val) static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); @@ -4263,7 +4256,7 @@ static int i8xx_irq_postinstall(struct drm_device *dev) I915_MASTER_ERROR_INTERRUPT | I915_USER_INTERRUPT; - GEN2_IRQ_INIT(, dev_priv->irq_mask, enable_mask); + GEN2_IRQ_INIT(dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ -- cgit v1.2.3 From 9d9523d8c12295d69e9ff3693d61e0d36eb00709 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 10 Apr 2019 16:53:42 -0700 Subject: drm/i915: add GEN2_ prefix to the I{E, I, M, S}R registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This discussion started because we use token pasting in the GEN{2,3}_IRQ_INIT and GEN{2,3}_IRQ_RESET macros, so gen2-4 passes an empty argument to those macros, making the code a little weird. The original proposal was to just add a comment as the empty argument, but Ville suggested we just add a prefix to the registers, and that indeed sounds like a more elegant solution. Now doing this is kinda against our rules for register naming since we only add gens or platform names as register prefixes when the given gen/platform changes a register that already existed before. On the other hand, we have so many instances of IIR/IMR in comments that adding a prefix would make the users of these register more easily findable, in addition to make our token pasting macros actually readable. So IMHO opening an exception here is worth it. Cc: Ville Syrjälä Signed-off-by: Paulo Zanoni Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190410235344.31199-4-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++-- drivers/gpu/drm/i915/i915_gpu_error.c | 4 +-- drivers/gpu/drm/i915/i915_irq.c | 52 ++++++++++++++++----------------- drivers/gpu/drm/i915/i915_reg.h | 8 ++--- drivers/gpu/drm/i915/i915_reset.c | 3 +- drivers/gpu/drm/i915/intel_overlay.c | 4 +-- drivers/gpu/drm/i915/intel_ringbuffer.c | 10 +++---- 7 files changed, 44 insertions(+), 43 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index b88c62ea664d..e0bfdf31032c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -833,11 +833,11 @@ static int i915_interrupt_info(struct seq_file *m, void *data) } else if (!HAS_PCH_SPLIT(dev_priv)) { seq_printf(m, "Interrupt enable: %08x\n", - I915_READ(IER)); + I915_READ(GEN2_IER)); seq_printf(m, "Interrupt identity: %08x\n", - I915_READ(IIR)); + I915_READ(GEN2_IIR)); seq_printf(m, "Interrupt mask: %08x\n", - I915_READ(IMR)); + I915_READ(GEN2_IMR)); for_each_pipe(dev_priv, pipe) seq_printf(m, "Pipe %c stat: %08x\n", pipe_name(pipe), diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 43b68fdc8967..f51ff683dd2e 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1635,9 +1635,9 @@ static void capture_reg_state(struct i915_gpu_state *error) error->gtier[0] = I915_READ(GTIER); error->ngtier = 1; } else if (IS_GEN(dev_priv, 2)) { - error->ier = I915_READ16(IER); + error->ier = I915_READ16(GEN2_IER); } else if (!IS_VALLEYVIEW(dev_priv)) { - error->ier = I915_READ(IER); + error->ier = I915_READ(GEN2_IER); } error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e76cb62dc072..19a24b2b31e7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -153,16 +153,16 @@ static void gen3_irq_reset(struct drm_i915_private *dev_priv, i915_reg_t imr, static void gen2_irq_reset(struct drm_i915_private *dev_priv) { - I915_WRITE16(IMR, 0xffff); - POSTING_READ16(IMR); + I915_WRITE16(GEN2_IMR, 0xffff); + POSTING_READ16(GEN2_IMR); - I915_WRITE16(IER, 0); + I915_WRITE16(GEN2_IER, 0); /* IIR can theoretically queue up two events. Be paranoid. */ - I915_WRITE16(IIR, 0xffff); - POSTING_READ16(IIR); - I915_WRITE16(IIR, 0xffff); - POSTING_READ16(IIR); + I915_WRITE16(GEN2_IIR, 0xffff); + POSTING_READ16(GEN2_IIR); + I915_WRITE16(GEN2_IIR, 0xffff); + POSTING_READ16(GEN2_IIR); } #define GEN8_IRQ_RESET_NDX(type, which) \ @@ -199,17 +199,17 @@ static void gen3_assert_iir_is_zero(struct drm_i915_private *dev_priv, static void gen2_assert_iir_is_zero(struct drm_i915_private *dev_priv) { - u16 val = I915_READ16(IIR); + u16 val = I915_READ16(GEN2_IIR); if (val == 0) return; WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", - i915_mmio_reg_offset(IIR), val); - I915_WRITE16(IIR, 0xffff); - POSTING_READ16(IIR); - I915_WRITE16(IIR, 0xffff); - POSTING_READ16(IIR); + i915_mmio_reg_offset(GEN2_IIR), val); + I915_WRITE16(GEN2_IIR, 0xffff); + POSTING_READ16(GEN2_IIR); + I915_WRITE16(GEN2_IIR, 0xffff); + POSTING_READ16(GEN2_IIR); } static void gen3_irq_init(struct drm_i915_private *dev_priv, @@ -229,9 +229,9 @@ static void gen2_irq_init(struct drm_i915_private *dev_priv, { gen2_assert_iir_is_zero(dev_priv); - I915_WRITE16(IER, ier_val); - I915_WRITE16(IMR, imr_val); - POSTING_READ16(IMR); + I915_WRITE16(GEN2_IER, ier_val); + I915_WRITE16(GEN2_IMR, imr_val); + POSTING_READ16(GEN2_IMR); } #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) \ @@ -4360,7 +4360,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) u16 eir = 0, eir_stuck = 0; u16 iir; - iir = I915_READ16(IIR); + iir = I915_READ16(GEN2_IIR); if (iir == 0) break; @@ -4373,7 +4373,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) if (iir & I915_MASTER_ERROR_INTERRUPT) i8xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - I915_WRITE16(IIR, iir); + I915_WRITE16(GEN2_IIR, iir); if (iir & I915_USER_INTERRUPT) intel_engine_breadcrumbs_irq(dev_priv->engine[RCS0]); @@ -4400,7 +4400,7 @@ static void i915_irq_reset(struct drm_device *dev) i9xx_pipestat_irq_reset(dev_priv); - GEN3_IRQ_RESET(); + GEN3_IRQ_RESET(GEN2_); } static int i915_irq_postinstall(struct drm_device *dev) @@ -4432,7 +4432,7 @@ static int i915_irq_postinstall(struct drm_device *dev) dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; } - GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); + GEN3_IRQ_INIT(GEN2_, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -4464,7 +4464,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) u32 hotplug_status = 0; u32 iir; - iir = I915_READ(IIR); + iir = I915_READ(GEN2_IIR); if (iir == 0) break; @@ -4481,7 +4481,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) if (iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - I915_WRITE(IIR, iir); + I915_WRITE(GEN2_IIR, iir); if (iir & I915_USER_INTERRUPT) intel_engine_breadcrumbs_irq(dev_priv->engine[RCS0]); @@ -4509,7 +4509,7 @@ static void i965_irq_reset(struct drm_device *dev) i9xx_pipestat_irq_reset(dev_priv); - GEN3_IRQ_RESET(); + GEN3_IRQ_RESET(GEN2_); } static int i965_irq_postinstall(struct drm_device *dev) @@ -4552,7 +4552,7 @@ static int i965_irq_postinstall(struct drm_device *dev) if (IS_G4X(dev_priv)) enable_mask |= I915_BSD_USER_INTERRUPT; - GEN3_IRQ_INIT(, dev_priv->irq_mask, enable_mask); + GEN3_IRQ_INIT(GEN2_, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -4610,7 +4610,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) u32 hotplug_status = 0; u32 iir; - iir = I915_READ(IIR); + iir = I915_READ(GEN2_IIR); if (iir == 0) break; @@ -4626,7 +4626,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) if (iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); - I915_WRITE(IIR, iir); + I915_WRITE(GEN2_IIR, iir); if (iir & I915_USER_INTERRUPT) intel_engine_breadcrumbs_irq(dev_priv->engine[RCS0]); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c1c0f7ab03e9..b74824f0b5b1 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2715,10 +2715,10 @@ enum i915_power_well_id { #define VLV_GU_CTL0 _MMIO(VLV_DISPLAY_BASE + 0x2030) #define VLV_GU_CTL1 _MMIO(VLV_DISPLAY_BASE + 0x2034) #define SCPD0 _MMIO(0x209c) /* 915+ only */ -#define IER _MMIO(0x20a0) -#define IIR _MMIO(0x20a4) -#define IMR _MMIO(0x20a8) -#define ISR _MMIO(0x20ac) +#define GEN2_IER _MMIO(0x20a0) +#define GEN2_IIR _MMIO(0x20a4) +#define GEN2_IMR _MMIO(0x20a8) +#define GEN2_ISR _MMIO(0x20ac) #define VLV_GUNIT_CLOCK_GATE _MMIO(VLV_DISPLAY_BASE + 0x2060) #define GINT_DIS (1 << 22) #define GCFG_DIS (1 << 8) diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c index bc5f9c69895e..677d59304e78 100644 --- a/drivers/gpu/drm/i915/i915_reset.c +++ b/drivers/gpu/drm/i915/i915_reset.c @@ -1239,7 +1239,8 @@ void i915_clear_error_registers(struct drm_i915_private *i915) */ DRM_DEBUG_DRIVER("EIR stuck: 0x%08x, masking\n", eir); rmw_set(uncore, EMR, eir); - intel_uncore_write(uncore, IIR, I915_MASTER_ERROR_INTERRUPT); + intel_uncore_write(uncore, GEN2_IIR, + I915_MASTER_ERROR_INTERRUPT); } if (INTEL_GEN(i915) >= 8) { diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index a882b8d42bd9..eb317759b5d3 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -446,7 +446,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) if (!overlay->old_vma) return 0; - if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { + if (I915_READ(GEN2_ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { /* synchronous slowpath */ struct i915_request *rq; @@ -1430,7 +1430,7 @@ intel_overlay_capture_error_state(struct drm_i915_private *dev_priv) return NULL; error->dovsta = I915_READ(DOVSTA); - error->isr = I915_READ(ISR); + error->isr = I915_READ(GEN2_ISR); error->base = overlay->flip_addr; memcpy_fromio(&error->regs, overlay->regs, sizeof(error->regs)); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index af35f99c5940..029fd8ec1857 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -977,15 +977,15 @@ static void i9xx_irq_enable(struct intel_engine_cs *engine) { engine->i915->irq_mask &= ~engine->irq_enable_mask; - intel_uncore_write(engine->uncore, IMR, engine->i915->irq_mask); - intel_uncore_posting_read_fw(engine->uncore, IMR); + intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask); + intel_uncore_posting_read_fw(engine->uncore, GEN2_IMR); } static void i9xx_irq_disable(struct intel_engine_cs *engine) { engine->i915->irq_mask |= engine->irq_enable_mask; - intel_uncore_write(engine->uncore, IMR, engine->i915->irq_mask); + intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask); } static void @@ -994,7 +994,7 @@ i8xx_irq_enable(struct intel_engine_cs *engine) struct drm_i915_private *dev_priv = engine->i915; dev_priv->irq_mask &= ~engine->irq_enable_mask; - I915_WRITE16(IMR, dev_priv->irq_mask); + I915_WRITE16(GEN2_IMR, dev_priv->irq_mask); POSTING_READ16(RING_IMR(engine->mmio_base)); } @@ -1004,7 +1004,7 @@ i8xx_irq_disable(struct intel_engine_cs *engine) struct drm_i915_private *dev_priv = engine->i915; dev_priv->irq_mask |= engine->irq_enable_mask; - I915_WRITE16(IMR, dev_priv->irq_mask); + I915_WRITE16(GEN2_IMR, dev_priv->irq_mask); } static int -- cgit v1.2.3 From 65f42cdc6e654543a769a5f4df060ae00096a334 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 10 Apr 2019 16:53:43 -0700 Subject: drm/i915: convert the IRQ initialization functions to intel_uncore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IRQ initialization helpers are simple and self-contained. Continue the transition started in the recent uncore rework to get us rid of I915_READ/WRITE and the implicit dev_priv variables. While the implicit dev_priv is removed from the IRQ initialization helpers, we didn't get rid of them in the macro callers. Doing that should be very simple now. v2: Rebase on top of the new patches. Reviewed-by: Ville Syrjälä (v1) Signed-off-by: Paulo Zanoni Link: https://patchwork.freedesktop.org/patch/msgid/20190410235344.31199-5-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 97 ++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 49 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 19a24b2b31e7..2f34304ee637 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -136,121 +136,120 @@ static const u32 hpd_icp[HPD_NUM_PINS] = { [HPD_PORT_F] = SDE_TC4_HOTPLUG_ICP }; -static void gen3_irq_reset(struct drm_i915_private *dev_priv, i915_reg_t imr, +static void gen3_irq_reset(struct intel_uncore *uncore, i915_reg_t imr, i915_reg_t iir, i915_reg_t ier) { - I915_WRITE(imr, 0xffffffff); - POSTING_READ(imr); + intel_uncore_write(uncore, imr, 0xffffffff); + intel_uncore_posting_read(uncore, imr); - I915_WRITE(ier, 0); + intel_uncore_write(uncore, ier, 0); /* IIR can theoretically queue up two events. Be paranoid. */ - I915_WRITE(iir, 0xffffffff); - POSTING_READ(iir); - I915_WRITE(iir, 0xffffffff); - POSTING_READ(iir); + intel_uncore_write(uncore, iir, 0xffffffff); + intel_uncore_posting_read(uncore, iir); + intel_uncore_write(uncore, iir, 0xffffffff); + intel_uncore_posting_read(uncore, iir); } -static void gen2_irq_reset(struct drm_i915_private *dev_priv) +static void gen2_irq_reset(struct intel_uncore *uncore) { - I915_WRITE16(GEN2_IMR, 0xffff); - POSTING_READ16(GEN2_IMR); + intel_uncore_write16(uncore, GEN2_IMR, 0xffff); + intel_uncore_posting_read16(uncore, GEN2_IMR); - I915_WRITE16(GEN2_IER, 0); + intel_uncore_write16(uncore, GEN2_IER, 0); /* IIR can theoretically queue up two events. Be paranoid. */ - I915_WRITE16(GEN2_IIR, 0xffff); - POSTING_READ16(GEN2_IIR); - I915_WRITE16(GEN2_IIR, 0xffff); - POSTING_READ16(GEN2_IIR); + intel_uncore_write16(uncore, GEN2_IIR, 0xffff); + intel_uncore_posting_read16(uncore, GEN2_IIR); + intel_uncore_write16(uncore, GEN2_IIR, 0xffff); + intel_uncore_posting_read16(uncore, GEN2_IIR); } #define GEN8_IRQ_RESET_NDX(type, which) \ ({ \ unsigned int which_ = which; \ - gen3_irq_reset(dev_priv, GEN8_##type##_IMR(which_), \ + gen3_irq_reset(&dev_priv->uncore, GEN8_##type##_IMR(which_), \ GEN8_##type##_IIR(which_), GEN8_##type##_IER(which_)); \ }) #define GEN3_IRQ_RESET(type) \ - gen3_irq_reset(dev_priv, type##IMR, type##IIR, type##IER) + gen3_irq_reset(&dev_priv->uncore, type##IMR, type##IIR, type##IER) #define GEN2_IRQ_RESET() \ - gen2_irq_reset(dev_priv) + gen2_irq_reset(&dev_priv->uncore) /* * We should clear IMR at preinstall/uninstall, and just check at postinstall. */ -static void gen3_assert_iir_is_zero(struct drm_i915_private *dev_priv, - i915_reg_t reg) +static void gen3_assert_iir_is_zero(struct intel_uncore *uncore, i915_reg_t reg) { - u32 val = I915_READ(reg); + u32 val = intel_uncore_read(uncore, reg); if (val == 0) return; WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", i915_mmio_reg_offset(reg), val); - I915_WRITE(reg, 0xffffffff); - POSTING_READ(reg); - I915_WRITE(reg, 0xffffffff); - POSTING_READ(reg); + intel_uncore_write(uncore, reg, 0xffffffff); + intel_uncore_posting_read(uncore, reg); + intel_uncore_write(uncore, reg, 0xffffffff); + intel_uncore_posting_read(uncore, reg); } -static void gen2_assert_iir_is_zero(struct drm_i915_private *dev_priv) +static void gen2_assert_iir_is_zero(struct intel_uncore *uncore) { - u16 val = I915_READ16(GEN2_IIR); + u16 val = intel_uncore_read16(uncore, GEN2_IIR); if (val == 0) return; WARN(1, "Interrupt register 0x%x is not zero: 0x%08x\n", i915_mmio_reg_offset(GEN2_IIR), val); - I915_WRITE16(GEN2_IIR, 0xffff); - POSTING_READ16(GEN2_IIR); - I915_WRITE16(GEN2_IIR, 0xffff); - POSTING_READ16(GEN2_IIR); + intel_uncore_write16(uncore, GEN2_IIR, 0xffff); + intel_uncore_posting_read16(uncore, GEN2_IIR); + intel_uncore_write16(uncore, GEN2_IIR, 0xffff); + intel_uncore_posting_read16(uncore, GEN2_IIR); } -static void gen3_irq_init(struct drm_i915_private *dev_priv, +static void gen3_irq_init(struct intel_uncore *uncore, i915_reg_t imr, u32 imr_val, i915_reg_t ier, u32 ier_val, i915_reg_t iir) { - gen3_assert_iir_is_zero(dev_priv, iir); + gen3_assert_iir_is_zero(uncore, iir); - I915_WRITE(ier, ier_val); - I915_WRITE(imr, imr_val); - POSTING_READ(imr); + intel_uncore_write(uncore, ier, ier_val); + intel_uncore_write(uncore, imr, imr_val); + intel_uncore_posting_read(uncore, imr); } -static void gen2_irq_init(struct drm_i915_private *dev_priv, +static void gen2_irq_init(struct intel_uncore *uncore, u32 imr_val, u32 ier_val) { - gen2_assert_iir_is_zero(dev_priv); + gen2_assert_iir_is_zero(uncore); - I915_WRITE16(GEN2_IER, ier_val); - I915_WRITE16(GEN2_IMR, imr_val); - POSTING_READ16(GEN2_IMR); + intel_uncore_write16(uncore, GEN2_IER, ier_val); + intel_uncore_write16(uncore, GEN2_IMR, imr_val); + intel_uncore_posting_read16(uncore, GEN2_IMR); } #define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) \ ({ \ unsigned int which_ = which; \ - gen3_irq_init(dev_priv, \ + gen3_irq_init(&dev_priv->uncore, \ GEN8_##type##_IMR(which_), imr_val, \ GEN8_##type##_IER(which_), ier_val, \ GEN8_##type##_IIR(which_)); \ }) #define GEN3_IRQ_INIT(type, imr_val, ier_val) \ - gen3_irq_init(dev_priv, \ + gen3_irq_init(&dev_priv->uncore, \ type##IMR, imr_val, \ type##IER, ier_val, \ type##IIR) #define GEN2_IRQ_INIT(imr_val, ier_val) \ - gen2_irq_init(dev_priv, imr_val, ier_val) + gen2_irq_init(&dev_priv->uncore, imr_val, ier_val) static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); @@ -3884,7 +3883,7 @@ static void ibx_irq_postinstall(struct drm_device *dev) else mask = SDE_GMBUS_CPT; - gen3_assert_iir_is_zero(dev_priv, SDEIIR); + gen3_assert_iir_is_zero(&dev_priv->uncore, SDEIIR); I915_WRITE(SDEIMR, ~mask); if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv) || @@ -3953,7 +3952,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) } if (IS_HASWELL(dev_priv)) { - gen3_assert_iir_is_zero(dev_priv, EDP_PSR_IIR); + gen3_assert_iir_is_zero(&dev_priv->uncore, EDP_PSR_IIR); intel_psr_irq_control(dev_priv, dev_priv->psr.debug); display_mask |= DE_EDP_PSR_INT_HSW; } @@ -4099,7 +4098,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) else if (IS_BROADWELL(dev_priv)) de_port_enables |= GEN8_PORT_DP_A_HOTPLUG; - gen3_assert_iir_is_zero(dev_priv, EDP_PSR_IIR); + gen3_assert_iir_is_zero(&dev_priv->uncore, EDP_PSR_IIR); intel_psr_irq_control(dev_priv, dev_priv->psr.debug); for_each_pipe(dev_priv, pipe) { @@ -4183,7 +4182,7 @@ static void icp_irq_postinstall(struct drm_device *dev) I915_WRITE(SDEIER, 0xffffffff); POSTING_READ(SDEIER); - gen3_assert_iir_is_zero(dev_priv, SDEIIR); + gen3_assert_iir_is_zero(&dev_priv->uncore, SDEIIR); I915_WRITE(SDEIMR, ~mask); icp_hpd_detection_setup(dev_priv); -- cgit v1.2.3 From b16b2a2f70b16089ff460c53471af7c0b33ce37a Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 10 Apr 2019 16:53:44 -0700 Subject: drm/i915: fully convert the IRQ initialization macros to intel_uncore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make them take the uncore argument from the caller instead of passing the implicit &dev_priv->uncore directly. This will allow us to finally pass something that's not dev_priv->uncore in the future, and gets rid of the implicit variables in register macros. v2: Rebase on top of the newer patches. Reviewed-by: Ville Syrjälä (v1) Signed-off-by: Paulo Zanoni Link: https://patchwork.freedesktop.org/patch/msgid/20190410235344.31199-6-paulo.r.zanoni@intel.com --- drivers/gpu/drm/i915/i915_irq.c | 144 ++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 56 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2f34304ee637..b92cfd69134b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -165,18 +165,18 @@ static void gen2_irq_reset(struct intel_uncore *uncore) intel_uncore_posting_read16(uncore, GEN2_IIR); } -#define GEN8_IRQ_RESET_NDX(type, which) \ +#define GEN8_IRQ_RESET_NDX(uncore, type, which) \ ({ \ unsigned int which_ = which; \ - gen3_irq_reset(&dev_priv->uncore, GEN8_##type##_IMR(which_), \ + gen3_irq_reset((uncore), GEN8_##type##_IMR(which_), \ GEN8_##type##_IIR(which_), GEN8_##type##_IER(which_)); \ }) -#define GEN3_IRQ_RESET(type) \ - gen3_irq_reset(&dev_priv->uncore, type##IMR, type##IIR, type##IER) +#define GEN3_IRQ_RESET(uncore, type) \ + gen3_irq_reset((uncore), type##IMR, type##IIR, type##IER) -#define GEN2_IRQ_RESET() \ - gen2_irq_reset(&dev_priv->uncore) +#define GEN2_IRQ_RESET(uncore) \ + gen2_irq_reset(uncore) /* * We should clear IMR at preinstall/uninstall, and just check at postinstall. @@ -233,23 +233,23 @@ static void gen2_irq_init(struct intel_uncore *uncore, intel_uncore_posting_read16(uncore, GEN2_IMR); } -#define GEN8_IRQ_INIT_NDX(type, which, imr_val, ier_val) \ +#define GEN8_IRQ_INIT_NDX(uncore, type, which, imr_val, ier_val) \ ({ \ unsigned int which_ = which; \ - gen3_irq_init(&dev_priv->uncore, \ + gen3_irq_init((uncore), \ GEN8_##type##_IMR(which_), imr_val, \ GEN8_##type##_IER(which_), ier_val, \ GEN8_##type##_IIR(which_)); \ }) -#define GEN3_IRQ_INIT(type, imr_val, ier_val) \ - gen3_irq_init(&dev_priv->uncore, \ +#define GEN3_IRQ_INIT(uncore, type, imr_val, ier_val) \ + gen3_irq_init((uncore), \ type##IMR, imr_val, \ type##IER, ier_val, \ type##IIR) -#define GEN2_IRQ_INIT(imr_val, ier_val) \ - gen2_irq_init(&dev_priv->uncore, imr_val, ier_val) +#define GEN2_IRQ_INIT(uncore, imr_val, ier_val) \ + gen2_irq_init((uncore), imr_val, ier_val) static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir); @@ -3365,10 +3365,12 @@ static void i945gm_vblank_work_fini(struct drm_i915_private *dev_priv) static void ibx_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_uncore *uncore = &dev_priv->uncore; + if (HAS_PCH_NOP(dev_priv)) return; - GEN3_IRQ_RESET(SDE); + GEN3_IRQ_RESET(uncore, SDE); if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) I915_WRITE(SERR_INT, 0xffffffff); @@ -3396,13 +3398,17 @@ static void ibx_irq_pre_postinstall(struct drm_device *dev) static void gen5_gt_irq_reset(struct drm_i915_private *dev_priv) { - GEN3_IRQ_RESET(GT); + struct intel_uncore *uncore = &dev_priv->uncore; + + GEN3_IRQ_RESET(uncore, GT); if (INTEL_GEN(dev_priv) >= 6) - GEN3_IRQ_RESET(GEN6_PM); + GEN3_IRQ_RESET(uncore, GEN6_PM); } static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_uncore *uncore = &dev_priv->uncore; + if (IS_CHERRYVIEW(dev_priv)) I915_WRITE(DPINVGTT, DPINVGTT_STATUS_MASK_CHV); else @@ -3413,12 +3419,14 @@ static void vlv_display_irq_reset(struct drm_i915_private *dev_priv) i9xx_pipestat_irq_reset(dev_priv); - GEN3_IRQ_RESET(VLV_); + GEN3_IRQ_RESET(uncore, VLV_); dev_priv->irq_mask = ~0u; } static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_uncore *uncore = &dev_priv->uncore; + u32 pipestat_mask; u32 enable_mask; enum pipe pipe; @@ -3443,7 +3451,7 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->irq_mask = ~enable_mask; - GEN3_IRQ_INIT(VLV_, dev_priv->irq_mask, enable_mask); + GEN3_IRQ_INIT(uncore, VLV_, dev_priv->irq_mask, enable_mask); } /* drm_dma.h hooks @@ -3451,8 +3459,9 @@ static void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) static void ironlake_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; - GEN3_IRQ_RESET(DE); + GEN3_IRQ_RESET(uncore, DE); if (IS_GEN(dev_priv, 7)) I915_WRITE(GEN7_ERR_INT, 0xffffffff); @@ -3483,15 +3492,18 @@ static void valleyview_irq_reset(struct drm_device *dev) static void gen8_gt_irq_reset(struct drm_i915_private *dev_priv) { - GEN8_IRQ_RESET_NDX(GT, 0); - GEN8_IRQ_RESET_NDX(GT, 1); - GEN8_IRQ_RESET_NDX(GT, 2); - GEN8_IRQ_RESET_NDX(GT, 3); + struct intel_uncore *uncore = &dev_priv->uncore; + + GEN8_IRQ_RESET_NDX(uncore, GT, 0); + GEN8_IRQ_RESET_NDX(uncore, GT, 1); + GEN8_IRQ_RESET_NDX(uncore, GT, 2); + GEN8_IRQ_RESET_NDX(uncore, GT, 3); } static void gen8_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; int pipe; gen8_master_intr_disable(dev_priv->uncore.regs); @@ -3504,11 +3516,11 @@ static void gen8_irq_reset(struct drm_device *dev) for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); + GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); - GEN3_IRQ_RESET(GEN8_DE_PORT_); - GEN3_IRQ_RESET(GEN8_DE_MISC_); - GEN3_IRQ_RESET(GEN8_PCU_); + GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_); + GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_); + GEN3_IRQ_RESET(uncore, GEN8_PCU_); if (HAS_PCH_SPLIT(dev_priv)) ibx_irq_reset(dev_priv); @@ -3534,6 +3546,7 @@ static void gen11_gt_irq_reset(struct drm_i915_private *dev_priv) static void gen11_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_uncore *uncore = &dev_priv->uncore; int pipe; gen11_master_intr_disable(dev_priv->uncore.regs); @@ -3548,21 +3561,23 @@ static void gen11_irq_reset(struct drm_device *dev) for_each_pipe(dev_priv, pipe) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); + GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); - GEN3_IRQ_RESET(GEN8_DE_PORT_); - GEN3_IRQ_RESET(GEN8_DE_MISC_); - GEN3_IRQ_RESET(GEN11_DE_HPD_); - GEN3_IRQ_RESET(GEN11_GU_MISC_); - GEN3_IRQ_RESET(GEN8_PCU_); + GEN3_IRQ_RESET(uncore, GEN8_DE_PORT_); + GEN3_IRQ_RESET(uncore, GEN8_DE_MISC_); + GEN3_IRQ_RESET(uncore, GEN11_DE_HPD_); + GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_); + GEN3_IRQ_RESET(uncore, GEN8_PCU_); if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - GEN3_IRQ_RESET(SDE); + GEN3_IRQ_RESET(uncore, SDE); } void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, u8 pipe_mask) { + struct intel_uncore *uncore = &dev_priv->uncore; + u32 extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; enum pipe pipe; @@ -3574,7 +3589,7 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, } for_each_pipe_masked(dev_priv, pipe, pipe_mask) - GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, + GEN8_IRQ_INIT_NDX(uncore, DE_PIPE, pipe, dev_priv->de_irq_mask[pipe], ~dev_priv->de_irq_mask[pipe] | extra_ier); @@ -3584,6 +3599,7 @@ void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, u8 pipe_mask) { + struct intel_uncore *uncore = &dev_priv->uncore; enum pipe pipe; spin_lock_irq(&dev_priv->irq_lock); @@ -3594,7 +3610,7 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, } for_each_pipe_masked(dev_priv, pipe, pipe_mask) - GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); + GEN8_IRQ_RESET_NDX(uncore, DE_PIPE, pipe); spin_unlock_irq(&dev_priv->irq_lock); @@ -3605,13 +3621,14 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, static void cherryview_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; I915_WRITE(GEN8_MASTER_IRQ, 0); POSTING_READ(GEN8_MASTER_IRQ); gen8_gt_irq_reset(dev_priv); - GEN3_IRQ_RESET(GEN8_PCU_); + GEN3_IRQ_RESET(uncore, GEN8_PCU_); spin_lock_irq(&dev_priv->irq_lock); if (dev_priv->display_irqs_enabled) @@ -3896,6 +3913,7 @@ static void ibx_irq_postinstall(struct drm_device *dev) static void gen5_gt_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; u32 pm_irqs, gt_irqs; pm_irqs = gt_irqs = 0; @@ -3914,7 +3932,7 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) gt_irqs |= GT_BLT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; } - GEN3_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); + GEN3_IRQ_INIT(uncore, GT, dev_priv->gt_irq_mask, gt_irqs); if (INTEL_GEN(dev_priv) >= 6) { /* @@ -3927,13 +3945,14 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) } dev_priv->pm_imr = 0xffffffff; - GEN3_IRQ_INIT(GEN6_PM, dev_priv->pm_imr, pm_irqs); + GEN3_IRQ_INIT(uncore, GEN6_PM, dev_priv->pm_imr, pm_irqs); } } static int ironlake_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; u32 display_mask, extra_mask; if (INTEL_GEN(dev_priv) >= 7) { @@ -3952,7 +3971,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) } if (IS_HASWELL(dev_priv)) { - gen3_assert_iir_is_zero(&dev_priv->uncore, EDP_PSR_IIR); + gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR); intel_psr_irq_control(dev_priv, dev_priv->psr.debug); display_mask |= DE_EDP_PSR_INT_HSW; } @@ -3961,7 +3980,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev) ibx_irq_pre_postinstall(dev); - GEN3_IRQ_INIT(DE, dev_priv->irq_mask, display_mask | extra_mask); + GEN3_IRQ_INIT(uncore, DE, dev_priv->irq_mask, + display_mask | extra_mask); gen5_gt_irq_postinstall(dev); @@ -4031,6 +4051,8 @@ static int valleyview_irq_postinstall(struct drm_device *dev) static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_uncore *uncore = &dev_priv->uncore; + /* These are interrupts we'll toggle with the ring mask register */ u32 gt_interrupts[] = { (GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | @@ -4051,18 +4073,20 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) dev_priv->pm_ier = 0x0; dev_priv->pm_imr = ~dev_priv->pm_ier; - GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]); - GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]); + GEN8_IRQ_INIT_NDX(uncore, GT, 0, ~gt_interrupts[0], gt_interrupts[0]); + GEN8_IRQ_INIT_NDX(uncore, GT, 1, ~gt_interrupts[1], gt_interrupts[1]); /* * RPS interrupts will get enabled/disabled on demand when RPS itself * is enabled/disabled. Same wil be the case for GuC interrupts. */ - GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_imr, dev_priv->pm_ier); - GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]); + GEN8_IRQ_INIT_NDX(uncore, GT, 2, dev_priv->pm_imr, dev_priv->pm_ier); + GEN8_IRQ_INIT_NDX(uncore, GT, 3, ~gt_interrupts[3], gt_interrupts[3]); } static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_uncore *uncore = &dev_priv->uncore; + u32 de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; u32 de_pipe_enables; u32 de_port_masked = GEN8_AUX_CHANNEL_A; @@ -4098,7 +4122,7 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) else if (IS_BROADWELL(dev_priv)) de_port_enables |= GEN8_PORT_DP_A_HOTPLUG; - gen3_assert_iir_is_zero(&dev_priv->uncore, EDP_PSR_IIR); + gen3_assert_iir_is_zero(uncore, EDP_PSR_IIR); intel_psr_irq_control(dev_priv, dev_priv->psr.debug); for_each_pipe(dev_priv, pipe) { @@ -4106,20 +4130,21 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PIPE(pipe))) - GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, + GEN8_IRQ_INIT_NDX(uncore, DE_PIPE, pipe, dev_priv->de_irq_mask[pipe], de_pipe_enables); } - GEN3_IRQ_INIT(GEN8_DE_PORT_, ~de_port_masked, de_port_enables); - GEN3_IRQ_INIT(GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); + GEN3_IRQ_INIT(uncore, GEN8_DE_PORT_, ~de_port_masked, de_port_enables); + GEN3_IRQ_INIT(uncore, GEN8_DE_MISC_, ~de_misc_masked, de_misc_masked); if (INTEL_GEN(dev_priv) >= 11) { u32 de_hpd_masked = 0; u32 de_hpd_enables = GEN11_DE_TC_HOTPLUG_MASK | GEN11_DE_TBT_HOTPLUG_MASK; - GEN3_IRQ_INIT(GEN11_DE_HPD_, ~de_hpd_masked, de_hpd_enables); + GEN3_IRQ_INIT(uncore, GEN11_DE_HPD_, ~de_hpd_masked, + de_hpd_enables); gen11_hpd_detection_setup(dev_priv); } else if (IS_GEN9_LP(dev_priv)) { bxt_hpd_detection_setup(dev_priv); @@ -4191,6 +4216,7 @@ static void icp_irq_postinstall(struct drm_device *dev) static int gen11_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_uncore *uncore = &dev_priv->uncore; u32 gu_misc_masked = GEN11_GU_MISC_GSE; if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) @@ -4199,7 +4225,7 @@ static int gen11_irq_postinstall(struct drm_device *dev) gen11_gt_irq_postinstall(dev_priv); gen8_de_irq_postinstall(dev_priv); - GEN3_IRQ_INIT(GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked); + GEN3_IRQ_INIT(uncore, GEN11_GU_MISC_, ~gu_misc_masked, gu_misc_masked); I915_WRITE(GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); @@ -4229,15 +4255,17 @@ static int cherryview_irq_postinstall(struct drm_device *dev) static void i8xx_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; i9xx_pipestat_irq_reset(dev_priv); - GEN2_IRQ_RESET(); + GEN2_IRQ_RESET(uncore); } static int i8xx_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; u16 enable_mask; I915_WRITE16(EMR, ~(I915_ERROR_PAGE_TABLE | @@ -4255,7 +4283,7 @@ static int i8xx_irq_postinstall(struct drm_device *dev) I915_MASTER_ERROR_INTERRUPT | I915_USER_INTERRUPT; - GEN2_IRQ_INIT(dev_priv->irq_mask, enable_mask); + GEN2_IRQ_INIT(uncore, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -4391,6 +4419,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg) static void i915_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; if (I915_HAS_HOTPLUG(dev_priv)) { i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); @@ -4399,12 +4428,13 @@ static void i915_irq_reset(struct drm_device *dev) i9xx_pipestat_irq_reset(dev_priv); - GEN3_IRQ_RESET(GEN2_); + GEN3_IRQ_RESET(uncore, GEN2_); } static int i915_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; I915_WRITE(EMR, ~(I915_ERROR_PAGE_TABLE | @@ -4431,7 +4461,7 @@ static int i915_irq_postinstall(struct drm_device *dev) dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; } - GEN3_IRQ_INIT(GEN2_, dev_priv->irq_mask, enable_mask); + GEN3_IRQ_INIT(uncore, GEN2_, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ @@ -4502,18 +4532,20 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) static void i965_irq_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0); I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT)); i9xx_pipestat_irq_reset(dev_priv); - GEN3_IRQ_RESET(GEN2_); + GEN3_IRQ_RESET(uncore, GEN2_); } static int i965_irq_postinstall(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; u32 error_mask; @@ -4551,7 +4583,7 @@ static int i965_irq_postinstall(struct drm_device *dev) if (IS_G4X(dev_priv)) enable_mask |= I915_BSD_USER_INTERRUPT; - GEN3_IRQ_INIT(GEN2_, dev_priv->irq_mask, enable_mask); + GEN3_IRQ_INIT(uncore, GEN2_, dev_priv->irq_mask, enable_mask); /* Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked check happy. */ -- cgit v1.2.3 From d1172ab3d443e84ade75285f8c107bfac7e386d8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Apr 2019 08:14:16 +0100 Subject: drm/i915: Introduce struct class_instance for engines across the uAPI SSEU reprogramming of the context introduced the notion of engine class and instance for a forwards compatible method of describing any engine beyond the old execbuf interface. We wish to adopt this class:instance description for more interfaces, so pull it out into a separate type for userspace convenience. Fixes: e46c2e99f600 ("drm/i915: Expose RPCS (SSEU) configuration to userspace (Gen11 only)") Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Cc: Lionel Landwerlin Cc: Dmitry Rogozhkin Cc: Tony Ye Cc: Andi Shyti Reviewed-by: Tvrtko Ursulin Acked-by: Tony Ye Reviewed-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20190412071416.30097-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_context.c | 8 ++++---- include/uapi/drm/i915_drm.h | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 7fc34ab6df87..dd728b26b5aa 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -1386,8 +1386,8 @@ static int set_sseu(struct i915_gem_context *ctx, return -EINVAL; engine = intel_engine_lookup_user(i915, - user_sseu.engine_class, - user_sseu.engine_instance); + user_sseu.engine.engine_class, + user_sseu.engine.engine_instance); if (!engine) return -EINVAL; @@ -1626,8 +1626,8 @@ static int get_sseu(struct i915_gem_context *ctx, return -EINVAL; engine = intel_engine_lookup_user(ctx->i915, - user_sseu.engine_class, - user_sseu.engine_instance); + user_sseu.engine.engine_class, + user_sseu.engine.engine_instance); if (!engine) return -EINVAL; diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 52051d24d89d..3a73f5316766 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -126,6 +126,18 @@ enum drm_i915_gem_engine_class { I915_ENGINE_CLASS_INVALID = -1 }; +/* + * There may be more than one engine fulfilling any role within the system. + * Each engine of a class is given a unique instance number and therefore + * any engine can be specified by its class:instance tuplet. APIs that allow + * access to any engine in the system will use struct i915_engine_class_instance + * for this identification. + */ +struct i915_engine_class_instance { + __u16 engine_class; /* see enum drm_i915_gem_engine_class */ + __u16 engine_instance; +}; + /** * DOC: perf_events exposed by i915 through /sys/bus/event_sources/drivers/i915 * @@ -1525,8 +1537,7 @@ struct drm_i915_gem_context_param_sseu { /* * Engine class & instance to be configured or queried. */ - __u16 engine_class; - __u16 engine_instance; + struct i915_engine_class_instance engine; /* * Unused for now. Must be cleared to zero. -- cgit v1.2.3 From 5b354966d0d470488d8dd244f0b5d82e9ecc4e18 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 16 Apr 2019 11:28:52 +0300 Subject: drm/i915/ehl: inherit icl cdclk init/uninit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cdclk init/uninit code was changed by commit 93a643f29bcb ("drm/i915/cdclk: have only one init/uninit function") between the versions of commit 39564ae86d51 ("drm/i915/ehl: Inherit Ice Lake conditional code"). What got merged fails to do cdclk init/uninit on ehl. Fixes: 39564ae86d51 ("drm/i915/ehl: Inherit Ice Lake conditional code") Cc: José Roberto de Souza Cc: Lucas De Marchi Cc: Bob Paauwe Cc: Rodrigo Vivi Reviewed-by: Bob Paauwe Reviewed-by: José Roberto de Souza Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20190416082852.18141-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_cdclk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c index 7f060eaf1b17..ae40a8679314 100644 --- a/drivers/gpu/drm/i915/intel_cdclk.c +++ b/drivers/gpu/drm/i915/intel_cdclk.c @@ -2034,7 +2034,7 @@ static void cnl_uninit_cdclk(struct drm_i915_private *dev_priv) */ void intel_cdclk_init(struct drm_i915_private *i915) { - if (IS_ICELAKE(i915)) + if (INTEL_GEN(i915) >= 11) icl_init_cdclk(i915); else if (IS_CANNONLAKE(i915)) cnl_init_cdclk(i915); @@ -2053,7 +2053,7 @@ void intel_cdclk_init(struct drm_i915_private *i915) */ void intel_cdclk_uninit(struct drm_i915_private *i915) { - if (IS_ICELAKE(i915)) + if (INTEL_GEN(i915) >= 11) icl_uninit_cdclk(i915); else if (IS_CANNONLAKE(i915)) cnl_uninit_cdclk(i915); -- cgit v1.2.3 From ad2c467aa92e283e9e8009bb9eb29a5c6a2d1217 Mon Sep 17 00:00:00 2001 From: Joonas Lahtinen Date: Wed, 17 Apr 2019 12:07:47 +0300 Subject: drm/i915: Update DRIVER_DATE to 20190417 Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 35d0782c077e..066fd2a12851 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -93,8 +93,8 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20190404" -#define DRIVER_TIMESTAMP 1554389037 +#define DRIVER_DATE "20190417" +#define DRIVER_TIMESTAMP 1555492067 /* Use I915_STATE_WARN(x) and I915_STATE_WARN_ON() (rather than WARN() and * WARN_ON()) for hw state sanity checks to check for unexpected conditions -- cgit v1.2.3 From 1262cc8893ecb0eb2c21e042d0d268cc180edb61 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 25 Feb 2019 10:51:30 +0000 Subject: drm: etnaviv: avoid DMA API warning when importing buffers During boot, I get this kernel warning: WARNING: CPU: 0 PID: 19001 at kernel/dma/debug.c:1301 debug_dma_map_sg+0x284/0x3dc etnaviv etnaviv: DMA-API: mapping sg segment longer than device claims to support [len=3145728] [max=65536] Modules linked in: ip6t_REJECT nf_reject_ipv6 ip6t_rpfilter xt_tcpudp ipt_REJECT nf_reject_ipv4 xt_conntrack ip_set nfnetlink ebtable_broute ebtable_nat ip6table_raw ip6table_nat nf_nat_ipv6 ip6table_mangle iptable_raw iptable_nat nf_nat_ipv4 nf_nat nf_conntrack nf_defrag_ipv4 nf_defrag_ipv6 libcrc32c iptable_mangle ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter caam_jr error snd_soc_imx_spdif imx_thermal snd_soc_imx_audmux nvmem_imx_ocotp snd_soc_sgtl5000 caam imx_sdma virt_dma coda rc_cec v4l2_mem2mem snd_soc_fsl_ssi snd_soc_fsl_spdif imx_vdoa imx_pcm_dma videobuf2_dma_contig etnaviv dw_hdmi_cec gpu_sched dw_hdmi_ahb_audio imx6q_cpufreq nfsd sch_fq_codel ip_tables x_tables CPU: 0 PID: 19001 Comm: Xorg Not tainted 4.20.0+ #307 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x9c/0xd4) [] (dump_stack) from [] (__warn+0xf8/0x124) [] (__warn) from [] (warn_slowpath_fmt+0x38/0x48) [] (warn_slowpath_fmt) from [] (debug_dma_map_sg+0x284/0x3dc) [] (debug_dma_map_sg) from [] (drm_gem_map_dma_buf+0xc4/0x13c) [] (drm_gem_map_dma_buf) from [] (dma_buf_map_attachment+0x38/0x5c) [] (dma_buf_map_attachment) from [] (drm_gem_prime_import_dev+0x74/0x104) [] (drm_gem_prime_import_dev) from [] (drm_gem_prime_fd_to_handle+0x84/0x17c) [] (drm_gem_prime_fd_to_handle) from [] (drm_prime_fd_to_handle_ioctl+0x38/0x4c) [] (drm_prime_fd_to_handle_ioctl) from [] (drm_ioctl_kernel+0x90/0xc8) [] (drm_ioctl_kernel) from [] (drm_ioctl+0x1e0/0x3b0) [] (drm_ioctl) from [] (do_vfs_ioctl+0x90/0xa48) [] (do_vfs_ioctl) from [] (ksys_ioctl+0x34/0x60) [] (ksys_ioctl) from [] (ret_fast_syscall+0x0/0x28) Exception stack(0xd81a9fa8 to 0xd81a9ff0) 9fa0: b6c69c88 bec613f8 00000009 c00c642e bec613f8 b86c4600 9fc0: b6c69c88 bec613f8 c00c642e 00000036 012762e0 01276348 00000300 012d91f8 9fe0: b6989f18 bec613dc b697185c b667be5c irq event stamp: 47905 hardirqs last enabled at (47913): [] console_unlock+0x46c/0x680 hardirqs last disabled at (47922): [] console_unlock+0xb8/0x680 softirqs last enabled at (47754): [] __do_softirq+0x344/0x540 softirqs last disabled at (47701): [] irq_exit+0x124/0x144 ---[ end trace af477747acbcc642 ]--- The reason is the contiguous buffer exceeds the default maximum segment size of 64K as specified by dma_get_max_seg_size() in linux/dma-mapping.h. Fix this by providing our own segment size, which is set to 2GiB to cover the window found in MMUv1 GPUs. Signed-off-by: Russell King Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 5 +++++ drivers/gpu/drm/etnaviv/etnaviv_drv.h | 1 + 2 files changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 18c27f795cf6..3156450723ba 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -515,6 +515,9 @@ static int etnaviv_bind(struct device *dev) } drm->dev_private = priv; + dev->dma_parms = &priv->dma_parms; + dma_set_max_seg_size(dev, SZ_2G); + mutex_init(&priv->gem_lock); INIT_LIST_HEAD(&priv->gem_list); priv->num_gpus = 0; @@ -552,6 +555,8 @@ static void etnaviv_unbind(struct device *dev) component_unbind_all(dev, drm); + dev->dma_parms = NULL; + drm->dev_private = NULL; kfree(priv); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index a6a7ded37ef1..6a4ea127c4f1 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -42,6 +42,7 @@ struct etnaviv_file_private { struct etnaviv_drm_private { int num_gpus; + struct device_dma_parameters dma_parms; struct etnaviv_gpu *gpu[ETNA_MAX_PIPES]; /* list of GEM objects: */ -- cgit v1.2.3 From fd2450a77d3360ac3d54c84e0aa0672f4d8ad4b2 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Tue, 19 Feb 2019 14:10:51 +0100 Subject: drm/etnaviv: clean up etnaviv_gem_new_handle Setting the GFP flags does not need a new code block if moved to the right location, which makes this function a bit easier to read. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel Reviewed-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 5c48915f492d..033ca4600e1a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -628,24 +628,18 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, lockdep_set_class(&to_etnaviv_bo(obj)->lock, &etnaviv_shm_lock_class); ret = drm_gem_object_init(dev, obj, size); - if (ret == 0) { - struct address_space *mapping; - - /* - * Our buffers are kept pinned, so allocating them - * from the MOVABLE zone is a really bad idea, and - * conflicts with CMA. See comments above new_inode() - * why this is required _and_ expected if you're - * going to pin these pages. - */ - mapping = obj->filp->f_mapping; - mapping_set_gfp_mask(mapping, GFP_HIGHUSER | - __GFP_RETRY_MAYFAIL | __GFP_NOWARN); - } - if (ret) goto fail; + /* + * Our buffers are kept pinned, so allocating them from the MOVABLE + * zone is a really bad idea, and conflicts with CMA. See comments + * above new_inode() why this is required _and_ expected if you're + * going to pin these pages. + */ + mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER | + __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + etnaviv_gem_obj_add(dev, obj); ret = drm_gem_handle_create(file, obj, handle); -- cgit v1.2.3 From bd53280ef042301ea9663824568ecba5a88b2f9d Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Wed, 17 Apr 2019 15:32:31 +0200 Subject: drm/drv: Fix incorrect resolution of merge conflict Commit f06ddb53096b ("BackMerge v5.1-rc5 into drm-next") incorrectly resolved a merge conflict related to a patch having been merged twice: - commit 3f04e0a6cfeb ("drm: Fix drm_release() and device unplug") introduced as a standalone fix via drm-fixes branch, - commit 1ee57d4d75fb ("drm: Fix drm_release() and device unplug") applied as patch 1/2 of a series on drm-next branch. That incorrect resolution of the conflict effectively reverted a change introduced to drivers/gpu/drm/drm_drv.c by patch 2/2 of that series - commit ba3bf37e150a ("drm/drv: drm_dev_unplug(): Move out drm_dev_put() call"). Fix it. Fixes: f06ddb53096b ("BackMerge v5.1-rc5 into drm-next") Signed-off-by: Janusz Krzysztofik Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190417133232.16232-1-janusz.krzysztofik@linux.intel.com --- drivers/gpu/drm/drm_drv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index e87799e3e7ff..50d849d1bc6e 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -508,7 +508,6 @@ void drm_dev_unplug(struct drm_device *dev) synchronize_srcu(&drm_unplug_srcu); drm_dev_unregister(dev); - drm_dev_put(dev); } EXPORT_SYMBOL(drm_dev_unplug); -- cgit v1.2.3 From dbb92471674a48892f5e50779425e03388073ab9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Apr 2019 06:46:33 +1000 Subject: Revert "drm: allow render capable master with DRM_AUTH ioctls" This reverts commit 8059add0478e29cb641936011a8fcc9ce9fd80be. This commit while seemingly a good idea, breaks a radv check, for a node being master because something succeeds where it failed before now. Apply the Linus rule, revert early and try again, we don't break userspace. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_ioctl.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index d337f161909c..ce8a70875bd5 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -508,13 +508,6 @@ int drm_version(struct drm_device *dev, void *data, return err; } -static inline bool -drm_render_driver_and_ioctl(const struct drm_device *dev, u32 flags) -{ - return drm_core_check_feature(dev, DRIVER_RENDER) && - (flags & DRM_RENDER_ALLOW); -} - /** * drm_ioctl_permit - Check ioctl permissions against caller * @@ -529,19 +522,14 @@ drm_render_driver_and_ioctl(const struct drm_device *dev, u32 flags) */ int drm_ioctl_permit(u32 flags, struct drm_file *file_priv) { - const struct drm_device *dev = file_priv->minor->dev; - /* ROOT_ONLY is only for CAP_SYS_ADMIN */ if (unlikely((flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN))) return -EACCES; - /* AUTH is only for master ... */ - if (unlikely((flags & DRM_AUTH) && drm_is_primary_client(file_priv))) { - /* authenticated ones, or render capable on DRM_RENDER_ALLOW. */ - if (!file_priv->authenticated && - !drm_render_driver_and_ioctl(dev, flags)) - return -EACCES; - } + /* AUTH is only for authenticated or render client */ + if (unlikely((flags & DRM_AUTH) && !drm_is_render_client(file_priv) && + !file_priv->authenticated)) + return -EACCES; /* MASTER is only for master or control clients */ if (unlikely((flags & DRM_MASTER) && -- cgit v1.2.3 From 61b51fb51c01a519a249d28ec55c6513a13be5a3 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 7 Mar 2019 01:55:19 +0300 Subject: drm/tegra: gem: Fix CPU-cache maintenance for BO's allocated using get_pages() The allocated pages need to be invalidated in CPU caches. On ARM32 the DMA_BIDIRECTIONAL flag only ensures that data is written-back to DRAM and the data stays in CPU cache lines. While the DMA_FROM_DEVICE flag ensures that the corresponding CPU cache lines are getting invalidated and nothing more, that's exactly what is needed for a newly allocated pages. This fixes randomly failing rendercheck tests on Tegra30 using the Opentegra driver for tests that use small-sized pixmaps (10x10 and less, i.e. 1-2 memory pages) because apparently CPU reads out stale data from caches and/or that data is getting evicted to DRAM at the time of HW job execution. Fixes: bd43c9f0fa1f ("drm/tegra: gem: Map pages via the DMA API") Cc: stable Signed-off-by: Dmitry Osipenko Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 4f80100ff5f3..4cce11fd8836 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -204,7 +204,7 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) { if (bo->pages) { dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents, - DMA_BIDIRECTIONAL); + DMA_FROM_DEVICE); drm_gem_put_pages(&bo->gem, bo->pages, true, true); sg_free_table(bo->sgt); kfree(bo->sgt); @@ -230,7 +230,7 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) } err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents, - DMA_BIDIRECTIONAL); + DMA_FROM_DEVICE); if (err == 0) { err = -EFAULT; goto free_sgt; -- cgit v1.2.3 From 0abdba47dc1df708c365421d481734d3f7fecb01 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 28 Feb 2019 07:23:29 +0100 Subject: drm/msm: don't allocate pages from the MOVABLE zone The pages backing the GEM objects are kept pinned in place as long as they are alive, so they must not be allocated from the MOVABLE zone. Blocking page migration for too long will cause the VM subsystem headaches and will outright break CMA, as a few pinned pages in CMA will lead to failure to find the required large contiguous regions. Signed-off-by: Lucas Stach Signed-off-by: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 18ca651ab942..76940a9da980 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1026,6 +1026,13 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, ret = drm_gem_object_init(dev, obj, size); if (ret) goto fail; + /* + * Our buffers are kept pinned, so allocating them from the + * MOVABLE zone is a really bad idea, and conflicts with CMA. + * See comments above new_inode() why this is required _and_ + * expected if you're going to pin these pages. + */ + mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER); } return obj; -- cgit v1.2.3 From a6bb79ab48796a6293b9c60597b631bca6011041 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Tue, 19 Feb 2019 11:48:20 -0700 Subject: drm/msm: Remove pm_runtime calls from msm_iommu.c Currently the IOMMU code calls pm_runtime_get/put on the GPU or display device before doing a IOMMU operation. This was because usually the IOMMU driver didn't do power control of its own and since the hardware used the same clocks and power as the respective multimedia device it was a easy way to make sure that the power was available. Now two things have changed. First, the SMMU devices can do their own power control and more important bringing up the a6xx GPU isn't as easy as turning on some clocks. To bring the GPU up we need the GMU which itself needs the IOMMU so we have a chicken and egg problem. Luckily this is easily fixed by removing the pm_runtime calls from the functions and letting the device link to the IOMMU device handle the magic. Signed-off-by: Jordan Crouse Tested-by: Bjorn Andersson Signed-off-by: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_iommu.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 4d62790cd425..12bb54cefd46 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -38,13 +38,8 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names, int cnt) { struct msm_iommu *iommu = to_msm_iommu(mmu); - int ret; - pm_runtime_get_sync(mmu->dev); - ret = iommu_attach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); - - return ret; + return iommu_attach_device(iommu->domain, mmu->dev); } static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, @@ -52,9 +47,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); iommu_detach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); } static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, @@ -63,9 +56,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, struct msm_iommu *iommu = to_msm_iommu(mmu); size_t ret; -// pm_runtime_get_sync(mmu->dev); ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); -// pm_runtime_put_sync(mmu->dev); WARN_ON(!ret); return (ret == len) ? 0 : -EINVAL; @@ -75,9 +66,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len) { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); iommu_unmap(iommu->domain, iova, len); - pm_runtime_put_sync(mmu->dev); return 0; } -- cgit v1.2.3 From 7603df38cc8c1e5d540b18ec9eb9d62d823197d0 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sat, 2 Mar 2019 13:35:29 +0100 Subject: drm/msm: Fix NULL pointer dereference [ 3.707412] Unable to handle kernel NULL pointer dereference at virtual address 0000009c [ 3.714511] pgd = (ptrval) [ 3.722742] [0000009c] *pgd=00000000 [ 3.725238] Internal error: Oops: 5 [#1] PREEMPT SMP ARM [ 3.728968] Modules linked in: [ 3.734265] CPU: 3 PID: 112 Comm: kworker/3:2 Tainted: G W 5.0.0-rc7-00183-g06a1c31df9eb #4 [ 3.737142] Hardware name: Generic DT based system [ 3.746778] Workqueue: events deferred_probe_work_func [ 3.751542] PC is at msm_gem_map_vma+0x3c/0xac [ 3.756669] LR is at msm_gem_get_and_pin_iova+0xd8/0x134 [ 3.761086] pc : [] lr : [] psr: 60000013 [ 3.766560] sp : ee297be8 ip : ed9ab1c0 fp : ed93b800 [ 3.772546] r10: ee35e180 r9 : 00000000 r8 : ee297c80 [ 3.777752] r7 : 00000000 r6 : 7c100000 r5 : 00000000 r4 : ee35e180 [ 3.782968] r3 : 00000001 r2 : 00000003 r1 : ee35e180 r0 : 00000000 [ 3.789562] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 3.796079] Control: 10c5787d Table: 2e3a806a DAC: 00000051 [ 3.803282] Process kworker/3:2 (pid: 112, stack limit = 0x(ptrval)) [ 3.809006] Stack: (0xee297be8 to 0xee298000) [ 3.815445] 7be0: 00000000 c1108c48 eda8c000 00000003 eda8c0fc c1108c48 [ 3.819715] 7c00: eda8c000 00000003 eda8c0fc c07d14f8 00000001 c07d1100 7c100000 00000000 [ 3.827873] 7c20: eda8c000 bb7ffb78 00000000 eda8c000 00000000 00000000 c0c8b1d4 ee3bfa00 [ 3.836037] 7c40: ee3b9800 c07d1684 00000000 c1108c48 ee0d7810 ee3b9800 c0c8b1d4 c07d222c [ 3.844193] 7c60: ee3bfd84 ee297c80 00000000 c0b1d5b0 ee3bfc40 c07dcfd8 ee3bfd84 ee297c80 [ 3.852357] 7c80: 0000006d ee3bfc40 ee0d7810 bb7ffb78 c0c8b1d4 00000000 ee3bfc40 c07ddb48 [ 3.860516] 7ca0: 00002004 c0eba384 ee3bfc40 c079eba0 ee3bd040 ee3b9800 00000001 ed93b800 [ 3.868673] 7cc0: ed9aa100 c07db7e8 ee3bf240 ed9a6500 00000001 ee3b9800 ee3bf2d4 c07a0a30 [ 3.876834] 7ce0: ed93b800 7d100000 c1108c48 ee0d7610 ee3b9800 ed93b800 c1108c48 00000000 [ 3.884991] 7d00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 3.893151] 7d20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bb7ffb78 [ 3.901310] 7d40: c12113c4 ed93b800 ee3b9800 c1108c48 ee9eec10 00000000 ed93b800 7d100000 [ 3.909472] 7d60: eff7b000 c07cf748 7d100000 00000000 c0e9a350 c0b1d5b0 c12113c4 c0961e40 [ 3.917633] 7d80: c12113c4 40000113 eeff4bec c0ebe004 00000019 c0b1d230 ee9eeda8 60000113 [ 3.925791] 7da0: ee35d300 ee9eeda8 c07ce260 bb7ffb78 c07ce260 ee35d2c0 00000028 00000002 [ 3.933950] 7dc0: eeb76280 c118f884 ee0be640 c11c6128 c07ce260 c07ea4ac 00000000 c0962b48 [ 3.942108] 7de0: c118f868 00000001 c0ebbc98 ee35d2c0 00000000 eeb76280 00000000 c118f87c [ 3.950270] 7e00: ee35d2c0 00000000 c11c63e0 c118f694 00000019 c07ea5d0 ee0d7810 00000000 [ 3.958430] 7e20: c118f694 00000000 00000000 c07f2b0c c120f55c ee0d7810 c120f560 00000000 [ 3.966590] 7e40: 00000000 c07f08c4 c07f0e8c ee0d7810 c11ba3d0 ee0d7810 c118f694 c07f0e8c [ 3.974748] 7e60: c1108c48 00000001 c0ebc3cc c11c63f8 c11ba3d0 c07f0c08 00000001 c07f2f8c [ 3.982908] 7e80: c118f694 00000000 ee297ed4 c07f0e8c c1108c48 00000001 c0ebc3cc c11c63f8 [ 3.991068] 7ea0: c11ba3d0 c07ee8a0 c11ba3d0 ee82686c ee0baf38 bb7ffb78 ee0d7810 ee0d7810 [ 3.999227] 7ec0: c1108c48 ee0d7844 c118faac c07f05b0 ee0d7810 ee0d7810 00000001 bb7ffb78 [ 4.007389] 7ee0: ee0d7810 ee0d7810 c118fd18 c118faac c11c63e0 c07ef7d0 ee0d7810 c118fa90 [ 4.015548] 7f00: c118fa90 c07efd68 c118fac8 ee27fe00 eefd9c80 eefdcd00 00000000 c118facc [ 4.023708] 7f20: 00000000 c033c038 eefd9c80 eefd9c80 00000008 ee27fe00 ee27fe14 eefd9c80 [ 4.031866] 7f40: 00000008 c1103d00 eefd9c98 ee296000 eefd9c80 c033ce54 ee907eac c0b1d230 [ 4.040026] 7f60: ee907eac eea24440 ee285000 00000000 ee296000 ee27fe00 c033ce24 eea2445c [ 4.048188] 7f80: ee907eac c0341db0 00000000 ee285000 c0341c8c 00000000 00000000 00000000 [ 4.056346] 7fa0: 00000000 00000000 00000000 c03010e8 00000000 00000000 00000000 00000000 [ 4.064505] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 4.072665] 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 4.080828] [] (msm_gem_map_vma) from [] (msm_gem_get_and_pin_iova+0xd8/0x134) [ 4.088983] [] (msm_gem_get_and_pin_iova) from [] (_msm_gem_kernel_new+0x38/0xac) [ 4.097839] [] (_msm_gem_kernel_new) from [] (msm_gem_kernel_new+0x24/0x2c) [ 4.107130] [] (msm_gem_kernel_new) from [] (dsi_tx_buf_alloc_6g+0x44/0x90) [ 4.115631] [] (dsi_tx_buf_alloc_6g) from [] (msm_dsi_host_modeset_init+0x80/0x104) [ 4.124313] [] (msm_dsi_host_modeset_init) from [] (msm_dsi_modeset_init+0x34/0x1c0) [ 4.133691] [] (msm_dsi_modeset_init) from [] (mdp5_kms_init+0x764/0x7e0) [ 4.143409] [] (mdp5_kms_init) from [] (msm_drm_bind+0x56c/0x740) [ 4.151824] [] (msm_drm_bind) from [] (try_to_bring_up_master+0x238/0x2b4) [ 4.159636] [] (try_to_bring_up_master) from [] (component_add+0xa8/0x170) [ 4.168146] [] (component_add) from [] (platform_drv_probe+0x48/0x9c) [ 4.176737] [] (platform_drv_probe) from [] (really_probe+0x278/0x404) [ 4.184981] [] (really_probe) from [] (driver_probe_device+0x78/0x1c0) [ 4.193147] [] (driver_probe_device) from [] (bus_for_each_drv+0x74/0xb8) [ 4.201389] [] (bus_for_each_drv) from [] (__device_attach+0xd0/0x164) [ 4.209984] [] (__device_attach) from [] (bus_probe_device+0x84/0x8c) [ 4.218143] [] (bus_probe_device) from [] (deferred_probe_work_func+0x48/0xc4) [ 4.226398] [] (deferred_probe_work_func) from [] (process_one_work+0x204/0x574) [ 4.235254] [] (process_one_work) from [] (worker_thread+0x30/0x560) [ 4.244534] [] (worker_thread) from [] (kthread+0x124/0x154) [ 4.252606] [] (kthread) from [] (ret_from_fork+0x14/0x2c) [ 4.259966] Exception stack(0xee297fb0 to 0xee297ff8) [ 4.266998] 7fa0: 00000000 00000000 00000000 00000000 [ 4.272143] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 4.280297] 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 [ 4.288451] Code: e5813080 1a000013 e3a03001 e5c4307c (e590009c) [ 4.294933] ---[ end trace 18729cc2bca2b4b3 ]--- Signed-off-by: Luca Weiss Signed-off-by: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem_vma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 49c04829cf34..fcf7a83f0e6f 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -85,7 +85,7 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, vma->mapped = true; - if (aspace->mmu) + if (aspace && aspace->mmu) ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, size, prot); -- cgit v1.2.3 From 6117f86202720cae2397dfcba7acf374cde3c6c9 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Mon, 28 Jan 2019 15:42:48 -0500 Subject: drm/msm: Use drm_mode_vrefresh instead of mode->vrefresh Use the drm_mode_vrefresh helper where we need refresh rate in case vrefresh is empty. Reviewed-by: Abhinav Kumar Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20190128204306.95076-1-sean@poorly.run Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 +++--- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 5 +++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 5aa3307f3f0c..3a714695d536 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -520,8 +520,8 @@ static void _dpu_encoder_adjust_mode(struct drm_connector *connector, list_for_each_entry(cur_mode, &connector->modes, head) { if (cur_mode->vdisplay == adj_mode->vdisplay && - cur_mode->hdisplay == adj_mode->hdisplay && - cur_mode->vrefresh == adj_mode->vrefresh) { + cur_mode->hdisplay == adj_mode->hdisplay && + drm_mode_vrefresh(cur_mode) == drm_mode_vrefresh(adj_mode)) { adj_mode->private = cur_mode->private; adj_mode->private_flags |= cur_mode->private_flags; } @@ -1802,7 +1802,7 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) atomic_set(&dpu_enc->frame_done_timeout, DPU_FRAME_DONE_TIMEOUT * 1000 / - drm_enc->crtc->state->adjusted_mode.vrefresh); + drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode)); mod_timer(&dpu_enc->frame_done_timer, jiffies + ((atomic_read(&dpu_enc->frame_done_timeout) * HZ) / 1000)); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index a399e1edd313..973737fb5c9f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -404,7 +404,8 @@ static void dpu_encoder_phys_cmd_tearcheck_config( return; } - tc_cfg.vsync_count = vsync_hz / (mode->vtotal * mode->vrefresh); + tc_cfg.vsync_count = vsync_hz / + (mode->vtotal * drm_mode_vrefresh(mode)); /* enable external TE after kickoff to avoid premature autorefresh */ tc_cfg.hw_vsync_mode = 0; @@ -424,7 +425,7 @@ static void dpu_encoder_phys_cmd_tearcheck_config( DPU_DEBUG_CMDENC(cmd_enc, "tc %d vsync_clk_speed_hz %u vtotal %u vrefresh %u\n", phys_enc->hw_pp->idx - PINGPONG_0, vsync_hz, - mode->vtotal, mode->vrefresh); + mode->vtotal, drm_mode_vrefresh(mode)); DPU_DEBUG_CMDENC(cmd_enc, "tc %d enable %u start_pos %u rd_ptr_irq %u\n", phys_enc->hw_pp->idx - PINGPONG_0, tc_enable, tc_cfg.start_pos, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index b01183b309b9..da1f727d7495 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -387,7 +387,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane, ot_params.width = drm_rect_width(&pdpu->pipe_cfg.src_rect); ot_params.height = drm_rect_height(&pdpu->pipe_cfg.src_rect); ot_params.is_wfd = !pdpu->is_rt_pipe; - ot_params.frame_rate = crtc->mode.vrefresh; + ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode); ot_params.vbif_idx = VBIF_RT; ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl; ot_params.rd = true; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c index 9bf9d6065c55..7b9edc21bc2c 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c @@ -59,10 +59,10 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, return -EINVAL; } - total_lines_x100 = mode->vtotal * mode->vrefresh; + total_lines_x100 = mode->vtotal * drm_mode_vrefresh(mode); if (!total_lines_x100) { DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n", - __func__, mode->vtotal, mode->vrefresh); + __func__, mode->vtotal, drm_mode_vrefresh(mode)); return -EINVAL; } -- cgit v1.2.3 From 2e0391865bd71e076139ca8059bf68469012c27a Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Mon, 28 Jan 2019 15:42:49 -0500 Subject: drm/msm: dpu: Simplify frame_done watchdog timeout calculation Instead of setting the timeout and then immediately reading it back (along with the hand-rolled msecs_to_jiffies calculation), just calculate it once and set it in both places at the same time. Reviewed-by: Abhinav Kumar Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20190128204306.95076-2-sean@poorly.run Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a714695d536..107abd4b99d2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1788,6 +1788,7 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) { struct dpu_encoder_virt *dpu_enc; struct dpu_encoder_phys *phys; + unsigned long timeout_ms; ktime_t wakeup_time; unsigned int i; @@ -1800,11 +1801,12 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) trace_dpu_enc_kickoff(DRMID(drm_enc)); - atomic_set(&dpu_enc->frame_done_timeout, - DPU_FRAME_DONE_TIMEOUT * 1000 / - drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode)); - mod_timer(&dpu_enc->frame_done_timer, jiffies + - ((atomic_read(&dpu_enc->frame_done_timeout) * HZ) / 1000)); + timeout_ms = DPU_FRAME_DONE_TIMEOUT * 1000 / + drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode); + + atomic_set(&dpu_enc->frame_done_timeout, timeout_ms); + mod_timer(&dpu_enc->frame_done_timer, + jiffies + msecs_to_jiffies(timeout_ms)); /* All phys encs are ready to go, trigger the kickoff */ _dpu_encoder_kickoff_phys(dpu_enc, async); -- cgit v1.2.3 From 70df9610de0fd3bbcb746f501ab7426a3052250f Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Mon, 28 Jan 2019 15:42:50 -0500 Subject: drm/msm: dpu: Untangle frame_done timeout units There exists a bunch of confusion as to what the actual units of frame_done is: - The definition states it's in # of frames - CRTC treats it like it's ms - frame_done_timeout comment thinks it's Hz, but it stores ms - frame_done timer is setup such that it _should_ be in frames, but the timeout is super long So this patch tries to interpret what the driver really wants. I've de-centralized the #define since the consumers are expecting different units. For crtc, we just use 60ms since that's what it was doing before. Perhaps we could get fancy and scale with vrefresh, but that's for another time. For encoder, fix the comments and rename frame_done_timeout so it's obvious what the units are. In practice, frame_done_timeout is really just checked against 0 || !0, which I guess is why the units being wrong didn't matter. I've also dropped the timeout from the previous 60 frames to 5. That seems like more than enough time to give up on a frame, and my guess is that no one intended for the timeout to _actually_ be 60 frames. Reviewed-by: Fritz Koenig Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20190128204306.95076-3-sean@poorly.run Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 ++++- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 19 +++++++++++-------- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 3 --- 3 files changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b776fca571f3..366e88f6c5d1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -46,6 +46,9 @@ #define LEFT_MIXER 0 #define RIGHT_MIXER 1 +/* timeout in ms waiting for frame done */ +#define DPU_CRTC_FRAME_DONE_TIMEOUT_MS 60 + static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) { struct msm_drm_private *priv = crtc->dev->dev_private; @@ -683,7 +686,7 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) DPU_ATRACE_BEGIN("frame done completion wait"); ret = wait_for_completion_timeout(&dpu_crtc->frame_done_comp, - msecs_to_jiffies(DPU_FRAME_DONE_TIMEOUT)); + msecs_to_jiffies(DPU_CRTC_FRAME_DONE_TIMEOUT_MS)); if (!ret) { DRM_ERROR("frame done wait timed out, ret:%d\n", ret); rc = -ETIMEDOUT; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 107abd4b99d2..e8dfdb48016e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -69,6 +69,9 @@ #define MAX_VDISPLAY_SPLIT 1080 +/* timeout in frames waiting for frame done */ +#define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5 + /** * enum dpu_enc_rc_events - events for resource control state machine * @DPU_ENC_RC_EVENT_KICKOFF: @@ -158,7 +161,7 @@ enum dpu_enc_rc_states { * Bit0 = phys_encs[0] etc. * @crtc_frame_event_cb: callback handler for frame event * @crtc_frame_event_cb_data: callback handler private data - * @frame_done_timeout: frame done timeout in Hz + * @frame_done_timeout_ms: frame done timeout in ms * @frame_done_timer: watchdog timer for frame done event * @vsync_event_timer: vsync timer * @disp_info: local copy of msm_display_info struct @@ -196,7 +199,7 @@ struct dpu_encoder_virt { void (*crtc_frame_event_cb)(void *, u32 event); void *crtc_frame_event_cb_data; - atomic_t frame_done_timeout; + atomic_t frame_done_timeout_ms; struct timer_list frame_done_timer; struct timer_list vsync_event_timer; @@ -1182,7 +1185,7 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) } /* after phys waits for frame-done, should be no more frames pending */ - if (atomic_xchg(&dpu_enc->frame_done_timeout, 0)) { + if (atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) { DPU_ERROR("enc%d timeout pending\n", drm_enc->base.id); del_timer_sync(&dpu_enc->frame_done_timer); } @@ -1339,7 +1342,7 @@ static void dpu_encoder_frame_done_callback( } if (!dpu_enc->frame_busy_mask[0]) { - atomic_set(&dpu_enc->frame_done_timeout, 0); + atomic_set(&dpu_enc->frame_done_timeout_ms, 0); del_timer(&dpu_enc->frame_done_timer); dpu_encoder_resource_control(drm_enc, @@ -1801,10 +1804,10 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) trace_dpu_enc_kickoff(DRMID(drm_enc)); - timeout_ms = DPU_FRAME_DONE_TIMEOUT * 1000 / + timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 / drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode); - atomic_set(&dpu_enc->frame_done_timeout, timeout_ms); + atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms); mod_timer(&dpu_enc->frame_done_timer, jiffies + msecs_to_jiffies(timeout_ms)); @@ -2126,7 +2129,7 @@ static void dpu_encoder_frame_done_timeout(struct timer_list *t) DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n", DRMID(drm_enc), dpu_enc->frame_busy_mask[0]); return; - } else if (!atomic_xchg(&dpu_enc->frame_done_timeout, 0)) { + } else if (!atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) { DRM_DEBUG_KMS("id:%u invalid timeout\n", DRMID(drm_enc)); return; } @@ -2172,7 +2175,7 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, spin_lock_init(&dpu_enc->enc_spinlock); - atomic_set(&dpu_enc->frame_done_timeout, 0); + atomic_set(&dpu_enc->frame_done_timeout_ms, 0); timer_setup(&dpu_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index ac75cfc267f4..31e9ef96ca5d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -73,9 +73,6 @@ #define DPU_NAME_SIZE 12 -/* timeout in frames waiting for frame done */ -#define DPU_FRAME_DONE_TIMEOUT 60 - /* * struct dpu_irq_callback - IRQ callback handlers * @list: list to callback -- cgit v1.2.3 From be77ef760cd351b27916a3b4e74e7fefb4809c4a Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Mon, 28 Jan 2019 15:42:51 -0500 Subject: drm/msm: dpu: Don't queue the frame_done watchdog for cursor In the case of an async/cursor update, we don't wait for the frame_done event, which means handle_frame_done is never called, and the frame_done watchdog isn't canceled. Currently, this results in a frame_done timeout every time the cursor moves without a synchronous frame following it up before the timeout expires. Since we don't wait for frame_done, and don't handle it, we shouldn't modify the watchdog. Reviewed-by: Fritz Koenig Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20190128204306.95076-4-sean@poorly.run Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index e8dfdb48016e..472cdb464458 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1791,7 +1791,6 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) { struct dpu_encoder_virt *dpu_enc; struct dpu_encoder_phys *phys; - unsigned long timeout_ms; ktime_t wakeup_time; unsigned int i; @@ -1804,12 +1803,20 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) trace_dpu_enc_kickoff(DRMID(drm_enc)); - timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 / - drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode); + /* + * Asynchronous frames don't handle FRAME_DONE events. As such, they + * shouldn't enable the frame_done watchdog since it will always time + * out. + */ + if (!async) { + unsigned long timeout_ms; + timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 / + drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode); - atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms); - mod_timer(&dpu_enc->frame_done_timer, - jiffies + msecs_to_jiffies(timeout_ms)); + atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms); + mod_timer(&dpu_enc->frame_done_timer, + jiffies + msecs_to_jiffies(timeout_ms)); + } /* All phys encs are ready to go, trigger the kickoff */ _dpu_encoder_kickoff_phys(dpu_enc, async); -- cgit v1.2.3 From f98baa3109cea46083d2361ab14a0207d1b1bd16 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 30 Jan 2019 11:32:12 -0500 Subject: drm/msm: dpu: Don't set frame_busy_mask for async updates The frame_busy mask is used in frame_done event handling, which is not invoked for async commits. So an async commit will leave the frame_busy mask populated after it completes and future commits will start with the busy mask incorrect. This showed up on disable after cursor move. I was hitting the "this should not happen" comment in the frame event worker since frame_busy was set, we queued the event, but there were no frames pending (since async also doesn't set that). Reviewed-by: Fritz Koenig Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20190130163220.138637-1-sean@poorly.run Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 472cdb464458..c51bc0fdd9c3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1550,8 +1550,14 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc, if (!ctl) continue; - if (phys->split_role != ENC_ROLE_SLAVE) + /* + * This is cleared in frame_done worker, which isn't invoked + * for async commits. So don't set this for async, since it'll + * roll over to the next commit. + */ + if (!async && phys->split_role != ENC_ROLE_SLAVE) set_bit(i, dpu_enc->frame_busy_mask); + if (!phys->ops.needs_single_flush || !phys->ops.needs_single_flush(phys)) _dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0, -- cgit v1.2.3 From b6057cda8f6cac5f50dbac7ff5ca825fdafdeb39 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 13 Feb 2019 17:19:10 -0800 Subject: drm/msm/dpu: move hw_inf encoder baseclass Both video and command physical encoders will have a hw interface assigned to it. So there is really no need to track the hw block in specific encoder subclass. Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/1550107156-17625-2-git-send-email-jsanka@codeaurora.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 4 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 125 +++++++++------------ 2 files changed, 52 insertions(+), 77 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index db94f3d3bea3..66a1fd4b014c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -200,6 +200,7 @@ struct dpu_encoder_irq { * @hw_mdptop: Hardware interface to the top registers * @hw_ctl: Hardware interface to the ctl registers * @hw_pp: Hardware interface to the ping pong registers + * @hw_intf: Hardware interface to the intf registers * @dpu_kms: Pointer to the dpu_kms top level * @cached_mode: DRM mode cached at mode_set time, acted on in enable * @enabled: Whether the encoder has enabled and running a mode @@ -228,6 +229,7 @@ struct dpu_encoder_phys { struct dpu_hw_mdp *hw_mdptop; struct dpu_hw_ctl *hw_ctl; struct dpu_hw_pingpong *hw_pp; + struct dpu_hw_intf *hw_intf; struct dpu_kms *dpu_kms; struct drm_display_mode cached_mode; enum dpu_enc_split_role split_role; @@ -254,12 +256,10 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) * struct dpu_encoder_phys_vid - sub-class of dpu_encoder_phys to handle video * mode specific operations * @base: Baseclass physical encoder structure - * @hw_intf: Hardware interface to the intf registers * @timing_params: Current timing parameter */ struct dpu_encoder_phys_vid { struct dpu_encoder_phys base; - struct dpu_hw_intf *hw_intf; struct intf_timing_params timing_params; }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 3c4eb470a82c..1b706eada90f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -18,14 +18,14 @@ #include "dpu_trace.h" #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \ - (e) && (e)->base.parent ? \ - (e)->base.parent->base.id : -1, \ + (e) && (e)->parent ? \ + (e)->parent->base.id : -1, \ (e) && (e)->hw_intf ? \ (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) #define DPU_ERROR_VIDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \ - (e) && (e)->base.parent ? \ - (e)->base.parent->base.id : -1, \ + (e) && (e)->parent ? \ + (e)->parent->base.id : -1, \ (e) && (e)->hw_intf ? \ (e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__) @@ -44,7 +44,7 @@ static bool dpu_encoder_phys_vid_is_master( } static void drm_mode_to_intf_timing_params( - const struct dpu_encoder_phys_vid *vid_enc, + const struct dpu_encoder_phys *phys_enc, const struct drm_display_mode *mode, struct intf_timing_params *timing) { @@ -92,7 +92,7 @@ static void drm_mode_to_intf_timing_params( timing->hsync_skew = mode->hskew; /* DSI controller cannot handle active-low sync signals. */ - if (vid_enc->hw_intf->cap->type == INTF_DSI) { + if (phys_enc->hw_intf->cap->type == INTF_DSI) { timing->hsync_polarity = 0; timing->vsync_polarity = 0; } @@ -143,11 +143,11 @@ static u32 get_vertical_total(const struct intf_timing_params *timing) * lines based on the chip worst case latencies. */ static u32 programmable_fetch_get_num_lines( - struct dpu_encoder_phys_vid *vid_enc, + struct dpu_encoder_phys *phys_enc, const struct intf_timing_params *timing) { u32 worst_case_needed_lines = - vid_enc->hw_intf->cap->prog_fetch_lines_worst_case; + phys_enc->hw_intf->cap->prog_fetch_lines_worst_case; u32 start_of_frame_lines = timing->v_back_porch + timing->vsync_pulse_width; u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines; @@ -155,26 +155,26 @@ static u32 programmable_fetch_get_num_lines( /* Fetch must be outside active lines, otherwise undefined. */ if (start_of_frame_lines >= worst_case_needed_lines) { - DPU_DEBUG_VIDENC(vid_enc, + DPU_DEBUG_VIDENC(phys_enc, "prog fetch is not needed, large vbp+vsw\n"); actual_vfp_lines = 0; } else if (timing->v_front_porch < needed_vfp_lines) { /* Warn fetch needed, but not enough porch in panel config */ pr_warn_once ("low vbp+vfp may lead to perf issues in some cases\n"); - DPU_DEBUG_VIDENC(vid_enc, + DPU_DEBUG_VIDENC(phys_enc, "less vfp than fetch req, using entire vfp\n"); actual_vfp_lines = timing->v_front_porch; } else { - DPU_DEBUG_VIDENC(vid_enc, "room in vfp for needed prefetch\n"); + DPU_DEBUG_VIDENC(phys_enc, "room in vfp for needed prefetch\n"); actual_vfp_lines = needed_vfp_lines; } - DPU_DEBUG_VIDENC(vid_enc, + DPU_DEBUG_VIDENC(phys_enc, "v_front_porch %u v_back_porch %u vsync_pulse_width %u\n", timing->v_front_porch, timing->v_back_porch, timing->vsync_pulse_width); - DPU_DEBUG_VIDENC(vid_enc, + DPU_DEBUG_VIDENC(phys_enc, "wc_lines %u needed_vfp_lines %u actual_vfp_lines %u\n", worst_case_needed_lines, needed_vfp_lines, actual_vfp_lines); @@ -194,8 +194,6 @@ static u32 programmable_fetch_get_num_lines( static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc, const struct intf_timing_params *timing) { - struct dpu_encoder_phys_vid *vid_enc = - to_dpu_encoder_phys_vid(phys_enc); struct intf_prog_fetch f = { 0 }; u32 vfp_fetch_lines = 0; u32 horiz_total = 0; @@ -203,10 +201,10 @@ static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc, u32 vfp_fetch_start_vsync_counter = 0; unsigned long lock_flags; - if (WARN_ON_ONCE(!vid_enc->hw_intf->ops.setup_prg_fetch)) + if (WARN_ON_ONCE(!phys_enc->hw_intf->ops.setup_prg_fetch)) return; - vfp_fetch_lines = programmable_fetch_get_num_lines(vid_enc, timing); + vfp_fetch_lines = programmable_fetch_get_num_lines(phys_enc, timing); if (vfp_fetch_lines) { vert_total = get_vertical_total(timing); horiz_total = get_horizontal_total(timing); @@ -216,12 +214,12 @@ static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc, f.fetch_start = vfp_fetch_start_vsync_counter; } - DPU_DEBUG_VIDENC(vid_enc, + DPU_DEBUG_VIDENC(phys_enc, "vfp_fetch_lines %u vfp_fetch_start_vsync_counter %u\n", vfp_fetch_lines, vfp_fetch_start_vsync_counter); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); - vid_enc->hw_intf->ops.setup_prg_fetch(vid_enc->hw_intf, &f); + phys_enc->hw_intf->ops.setup_prg_fetch(phys_enc->hw_intf, &f); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); } @@ -231,7 +229,7 @@ static bool dpu_encoder_phys_vid_mode_fixup( struct drm_display_mode *adj_mode) { if (phys_enc) - DPU_DEBUG_VIDENC(to_dpu_encoder_phys_vid(phys_enc), "\n"); + DPU_DEBUG_VIDENC(phys_enc, "\n"); /* * Modifying mode has consequences when the mode comes back to us @@ -257,12 +255,12 @@ static void dpu_encoder_phys_vid_setup_timing_engine( mode = phys_enc->cached_mode; vid_enc = to_dpu_encoder_phys_vid(phys_enc); - if (!vid_enc->hw_intf->ops.setup_timing_gen) { + if (!phys_enc->hw_intf->ops.setup_timing_gen) { DPU_ERROR("timing engine setup is not supported\n"); return; } - DPU_DEBUG_VIDENC(vid_enc, "enabling mode:\n"); + DPU_DEBUG_VIDENC(phys_enc, "enabling mode:\n"); drm_mode_debug_printmodeline(&mode); if (phys_enc->split_role != ENC_ROLE_SOLO) { @@ -271,25 +269,25 @@ static void dpu_encoder_phys_vid_setup_timing_engine( mode.hsync_start >>= 1; mode.hsync_end >>= 1; - DPU_DEBUG_VIDENC(vid_enc, + DPU_DEBUG_VIDENC(phys_enc, "split_role %d, halve horizontal %d %d %d %d\n", phys_enc->split_role, mode.hdisplay, mode.htotal, mode.hsync_start, mode.hsync_end); } - drm_mode_to_intf_timing_params(vid_enc, &mode, &timing_params); + drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params); fmt = dpu_get_dpu_format(fmt_fourcc); - DPU_DEBUG_VIDENC(vid_enc, "fmt_fourcc 0x%X\n", fmt_fourcc); + DPU_DEBUG_VIDENC(phys_enc, "fmt_fourcc 0x%X\n", fmt_fourcc); - intf_cfg.intf = vid_enc->hw_intf->idx; + intf_cfg.intf = phys_enc->hw_intf->idx; intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID; intf_cfg.stream_sel = 0; /* Don't care value for video mode */ intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); - vid_enc->hw_intf->ops.setup_timing_gen(vid_enc->hw_intf, + phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf, &timing_params, fmt); phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); @@ -396,19 +394,15 @@ static void dpu_encoder_phys_vid_mode_set( struct drm_display_mode *mode, struct drm_display_mode *adj_mode) { - struct dpu_encoder_phys_vid *vid_enc; - if (!phys_enc || !phys_enc->dpu_kms) { DPU_ERROR("invalid encoder/kms\n"); return; } - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - if (adj_mode) { phys_enc->cached_mode = *adj_mode; drm_mode_debug_printmodeline(adj_mode); - DPU_DEBUG_VIDENC(vid_enc, "caching mode:\n"); + DPU_DEBUG_VIDENC(phys_enc, "caching mode:\n"); } _dpu_encoder_phys_vid_setup_irq_hw_idx(phys_enc); @@ -419,7 +413,6 @@ static int dpu_encoder_phys_vid_control_vblank_irq( bool enable) { int ret = 0; - struct dpu_encoder_phys_vid *vid_enc; int refcount; if (!phys_enc) { @@ -428,7 +421,6 @@ static int dpu_encoder_phys_vid_control_vblank_irq( } refcount = atomic_read(&phys_enc->vblank_refcount); - vid_enc = to_dpu_encoder_phys_vid(phys_enc); /* Slave encoders don't report vblank */ if (!dpu_encoder_phys_vid_is_master(phys_enc)) @@ -453,7 +445,7 @@ end: if (ret) { DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n", DRMID(phys_enc->parent), - vid_enc->hw_intf->idx - INTF_0, ret, enable, + phys_enc->hw_intf->idx - INTF_0, ret, enable, refcount); } return ret; @@ -462,7 +454,6 @@ end: static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) { struct msm_drm_private *priv; - struct dpu_encoder_phys_vid *vid_enc; struct dpu_rm_hw_iter iter; struct dpu_hw_ctl *ctl; u32 flush_mask = 0; @@ -474,7 +465,6 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) } priv = phys_enc->parent->dev->dev_private; - vid_enc = to_dpu_encoder_phys_vid(phys_enc); ctl = phys_enc->hw_ctl; dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_INTF); @@ -482,22 +472,22 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) struct dpu_hw_intf *hw_intf = (struct dpu_hw_intf *)iter.hw; if (hw_intf->idx == phys_enc->intf_idx) { - vid_enc->hw_intf = hw_intf; + phys_enc->hw_intf = hw_intf; break; } } - if (!vid_enc->hw_intf) { + if (!phys_enc->hw_intf) { DPU_ERROR("hw_intf not assigned\n"); return; } - DPU_DEBUG_VIDENC(vid_enc, "\n"); + DPU_DEBUG_VIDENC(phys_enc, "\n"); - if (WARN_ON(!vid_enc->hw_intf->ops.enable_timing)) + if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing)) return; - dpu_encoder_helper_split_config(phys_enc, vid_enc->hw_intf->idx); + dpu_encoder_helper_split_config(phys_enc, phys_enc->hw_intf->idx); dpu_encoder_phys_vid_setup_timing_engine(phys_enc); @@ -510,12 +500,13 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) !dpu_encoder_phys_vid_is_master(phys_enc)) goto skip_flush; - ctl->ops.get_bitmask_intf(ctl, &flush_mask, vid_enc->hw_intf->idx); + ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->hw_intf->idx); ctl->ops.update_pending_flush(ctl, flush_mask); skip_flush: - DPU_DEBUG_VIDENC(vid_enc, "update pending flush ctl %d flush_mask %x\n", - ctl->idx - CTL_0, flush_mask); + DPU_DEBUG_VIDENC(phys_enc, + "update pending flush ctl %d flush_mask %x\n", + ctl->idx - CTL_0, flush_mask); /* ctl_flush & timing engine enable will be triggered by framework */ if (phys_enc->enable_state == DPU_ENC_DISABLED) @@ -532,7 +523,7 @@ static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc) } vid_enc = to_dpu_encoder_phys_vid(phys_enc); - DPU_DEBUG_VIDENC(vid_enc, "\n"); + DPU_DEBUG_VIDENC(phys_enc, "\n"); kfree(vid_enc); } @@ -589,7 +580,6 @@ static int dpu_encoder_phys_vid_wait_for_vblank( static void dpu_encoder_phys_vid_prepare_for_kickoff( struct dpu_encoder_phys *phys_enc) { - struct dpu_encoder_phys_vid *vid_enc; struct dpu_hw_ctl *ctl; int rc; @@ -597,7 +587,6 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff( DPU_ERROR("invalid encoder/parameters\n"); return; } - vid_enc = to_dpu_encoder_phys_vid(phys_enc); ctl = phys_enc->hw_ctl; if (!ctl || !ctl->ops.wait_reset_status) @@ -609,7 +598,7 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff( */ rc = ctl->ops.wait_reset_status(ctl); if (rc) { - DPU_ERROR_VIDENC(vid_enc, "ctl %d reset failure: %d\n", + DPU_ERROR_VIDENC(phys_enc, "ctl %d reset failure: %d\n", ctl->idx, rc); dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC); } @@ -618,7 +607,6 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff( static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) { struct msm_drm_private *priv; - struct dpu_encoder_phys_vid *vid_enc; unsigned long lock_flags; int ret; @@ -629,16 +617,13 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) } priv = phys_enc->parent->dev->dev_private; - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { + if (!phys_enc->hw_intf || !phys_enc->hw_ctl) { DPU_ERROR("invalid hw_intf %d hw_ctl %d\n", - vid_enc->hw_intf != 0, phys_enc->hw_ctl != 0); + phys_enc->hw_intf != 0, phys_enc->hw_ctl != 0); return; } - DPU_DEBUG_VIDENC(vid_enc, "\n"); - - if (WARN_ON(!vid_enc->hw_intf->ops.enable_timing)) + if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing)) return; if (phys_enc->enable_state == DPU_ENC_DISABLED) { @@ -647,7 +632,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) } spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); - vid_enc->hw_intf->ops.enable_timing(vid_enc->hw_intf, 0); + phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0); if (dpu_encoder_phys_vid_is_master(phys_enc)) dpu_encoder_phys_inc_pending(phys_enc); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); @@ -666,7 +651,7 @@ static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc) atomic_set(&phys_enc->pending_kickoff_cnt, 0); DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n", DRMID(phys_enc->parent), - vid_enc->hw_intf->idx - INTF_0, ret); + phys_enc->hw_intf->idx - INTF_0, ret); } } @@ -677,25 +662,21 @@ static void dpu_encoder_phys_vid_handle_post_kickoff( struct dpu_encoder_phys *phys_enc) { unsigned long lock_flags; - struct dpu_encoder_phys_vid *vid_enc; if (!phys_enc) { DPU_ERROR("invalid encoder\n"); return; } - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - DPU_DEBUG_VIDENC(vid_enc, "enable_state %d\n", phys_enc->enable_state); - /* * Video mode must flush CTL before enabling timing engine * Video encoders need to turn on their interfaces now */ if (phys_enc->enable_state == DPU_ENC_ENABLING) { trace_dpu_enc_phys_vid_post_kickoff(DRMID(phys_enc->parent), - vid_enc->hw_intf->idx - INTF_0); + phys_enc->hw_intf->idx - INTF_0); spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); - vid_enc->hw_intf->ops.enable_timing(vid_enc->hw_intf, 1); + phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); phys_enc->enable_state = DPU_ENC_ENABLED; } @@ -704,16 +685,13 @@ static void dpu_encoder_phys_vid_handle_post_kickoff( static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc, bool enable) { - struct dpu_encoder_phys_vid *vid_enc; int ret; if (!phys_enc) return; - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent), - vid_enc->hw_intf->idx - INTF_0, + phys_enc->hw_intf->idx - INTF_0, enable, atomic_read(&phys_enc->vblank_refcount)); @@ -732,19 +710,16 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc, static int dpu_encoder_phys_vid_get_line_count( struct dpu_encoder_phys *phys_enc) { - struct dpu_encoder_phys_vid *vid_enc; - if (!phys_enc) return -EINVAL; if (!dpu_encoder_phys_vid_is_master(phys_enc)) return -EINVAL; - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - if (!vid_enc->hw_intf || !vid_enc->hw_intf->ops.get_line_count) + if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_line_count) return -EINVAL; - return vid_enc->hw_intf->ops.get_line_count(vid_enc->hw_intf); + return phys_enc->hw_intf->ops.get_line_count(phys_enc->hw_intf); } static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) @@ -791,7 +766,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; phys_enc->intf_idx = p->intf_idx; - DPU_DEBUG_VIDENC(vid_enc, "\n"); + DPU_DEBUG_VIDENC(phys_enc, "\n"); dpu_encoder_phys_vid_init_ops(&phys_enc->ops); phys_enc->parent = p->parent; @@ -825,7 +800,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( init_waitqueue_head(&phys_enc->pending_kickoff_wq); phys_enc->enable_state = DPU_ENC_DISABLED; - DPU_DEBUG_VIDENC(vid_enc, "created intf idx:%d\n", p->intf_idx); + DPU_DEBUG_VIDENC(phys_enc, "created intf idx:%d\n", p->intf_idx); return phys_enc; -- cgit v1.2.3 From 366334a3127eb654410660987919e1de231f15f2 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 13 Feb 2019 17:19:11 -0800 Subject: drm/msm/dpu: remove phys_vid subclass Not holding any video encoder specific data. Get rid of it. Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/1550107156-17625-3-git-send-email-jsanka@codeaurora.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 11 ----------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 18 ++++-------------- 2 files changed, 4 insertions(+), 25 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 66a1fd4b014c..97fb868a4ef6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -252,17 +252,6 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) return atomic_inc_return(&phys->pending_kickoff_cnt); } -/** - * struct dpu_encoder_phys_vid - sub-class of dpu_encoder_phys to handle video - * mode specific operations - * @base: Baseclass physical encoder structure - * @timing_params: Current timing parameter - */ -struct dpu_encoder_phys_vid { - struct dpu_encoder_phys base; - struct intf_timing_params timing_params; -}; - /** * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command * mode specific operations diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 1b706eada90f..ae5449c73c5e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -240,7 +240,6 @@ static bool dpu_encoder_phys_vid_mode_fixup( static void dpu_encoder_phys_vid_setup_timing_engine( struct dpu_encoder_phys *phys_enc) { - struct dpu_encoder_phys_vid *vid_enc; struct drm_display_mode mode; struct intf_timing_params timing_params = { 0 }; const struct dpu_format *fmt = NULL; @@ -254,7 +253,6 @@ static void dpu_encoder_phys_vid_setup_timing_engine( } mode = phys_enc->cached_mode; - vid_enc = to_dpu_encoder_phys_vid(phys_enc); if (!phys_enc->hw_intf->ops.setup_timing_gen) { DPU_ERROR("timing engine setup is not supported\n"); return; @@ -293,8 +291,6 @@ static void dpu_encoder_phys_vid_setup_timing_engine( spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); programmable_fetch_config(phys_enc, &timing_params); - - vid_enc->timing_params = timing_params; } static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) @@ -515,16 +511,13 @@ skip_flush: static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc) { - struct dpu_encoder_phys_vid *vid_enc; - if (!phys_enc) { DPU_ERROR("invalid encoder\n"); return; } - vid_enc = to_dpu_encoder_phys_vid(phys_enc); DPU_DEBUG_VIDENC(phys_enc, "\n"); - kfree(vid_enc); + kfree(phys_enc); } static void dpu_encoder_phys_vid_get_hw_resources( @@ -746,7 +739,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( struct dpu_enc_phys_init_params *p) { struct dpu_encoder_phys *phys_enc = NULL; - struct dpu_encoder_phys_vid *vid_enc = NULL; struct dpu_encoder_irq *irq; int i, ret = 0; @@ -755,14 +747,12 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( goto fail; } - vid_enc = kzalloc(sizeof(*vid_enc), GFP_KERNEL); - if (!vid_enc) { + phys_enc = kzalloc(sizeof(*phys_enc), GFP_KERNEL); + if (!phys_enc) { ret = -ENOMEM; goto fail; } - phys_enc = &vid_enc->base; - phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; phys_enc->intf_idx = p->intf_idx; @@ -806,7 +796,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( fail: DPU_ERROR("failed to create encoder\n"); - if (vid_enc) + if (phys_enc) dpu_encoder_phys_vid_destroy(phys_enc); return ERR_PTR(ret); -- cgit v1.2.3 From a7fcc3237f31a4e206953bb73cf41bd429442f09 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 13 Feb 2019 17:19:12 -0800 Subject: drm/msm/dpu: release resources on modeset failure release resources allocated in mode_set if any of the hw check fails. Most of these checks are not necessary and they will be removed in the follow up patches with state based resource allocations. Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/1550107156-17625-4-git-send-email-jsanka@codeaurora.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index c51bc0fdd9c3..7d7779d70145 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1026,13 +1026,13 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, if (!dpu_enc->hw_pp[i]) { DPU_ERROR_ENC(dpu_enc, "no pp block assigned" "at idx: %d\n", i); - return; + goto error; } if (!hw_ctl[i]) { DPU_ERROR_ENC(dpu_enc, "no ctl block assigned" "at idx: %d\n", i); - return; + goto error; } phys->hw_pp = dpu_enc->hw_pp[i]; @@ -1045,6 +1045,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, } dpu_enc->mode_set_complete = true; + +error: + dpu_rm_release(&dpu_kms->rm, drm_enc); } static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) -- cgit v1.2.3 From c2ab55a68a33746591971f3e1d4ef3374f1d7e18 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 13 Feb 2019 17:19:13 -0800 Subject: drm/msm/dpu: dont use encoder->crtc in atomic path encoder->crtc is not really meaningful for atomic path. Use crtc->encoder_mask to identify the crtc attached with an encoder. Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/1550107156-17625-5-git-send-email-jsanka@codeaurora.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 7d7779d70145..99cbf3524348 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -962,6 +962,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct dpu_kms *dpu_kms; struct list_head *connector_list; struct drm_connector *conn = NULL, *conn_iter; + struct drm_crtc *drm_crtc; struct dpu_rm_hw_iter pp_iter, ctl_iter; struct msm_display_topology topology; struct dpu_hw_ctl *hw_ctl[MAX_CHANNELS_PER_ENC] = { NULL }; @@ -993,10 +994,14 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, return; } + drm_for_each_crtc(drm_crtc, drm_enc->dev) + if (drm_crtc->state->encoder_mask & drm_encoder_mask(drm_enc)) + break; + topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode); /* Reserve dynamic resources now. Indicating non-AtomicTest phase */ - ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_enc->crtc->state, + ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_crtc->state, topology, false); if (ret) { DPU_ERROR_ENC(dpu_enc, -- cgit v1.2.3 From b107603b4ad0f2624425bb2402701480bb59cafe Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 13 Feb 2019 17:19:14 -0800 Subject: drm/msm/dpu: map mixer/ctl hw blocks in encoder modeset After resource allocation, iterate and populate mixer/ctl hw blocks in encoder modeset thereby centralizing all the resource mapping to the CRTC. This change is made for easy switching to state based allocation using private objects later in this series. Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/1550107156-17625-6-git-send-email-jsanka@codeaurora.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 64 +---------------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 37 +++++++++++++---- 2 files changed, 31 insertions(+), 70 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 366e88f6c5d1..dfdfa766da8f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -428,65 +428,6 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc, trace_dpu_crtc_complete_commit(DRMID(crtc)); } -static void _dpu_crtc_setup_mixer_for_encoder( - struct drm_crtc *crtc, - struct drm_encoder *enc) -{ - struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); - struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); - struct dpu_rm *rm = &dpu_kms->rm; - struct dpu_crtc_mixer *mixer; - struct dpu_hw_ctl *last_valid_ctl = NULL; - int i; - struct dpu_rm_hw_iter lm_iter, ctl_iter; - - dpu_rm_init_hw_iter(&lm_iter, enc->base.id, DPU_HW_BLK_LM); - dpu_rm_init_hw_iter(&ctl_iter, enc->base.id, DPU_HW_BLK_CTL); - - /* Set up all the mixers and ctls reserved by this encoder */ - for (i = cstate->num_mixers; i < ARRAY_SIZE(cstate->mixers); i++) { - mixer = &cstate->mixers[i]; - - if (!dpu_rm_get_hw(rm, &lm_iter)) - break; - mixer->hw_lm = (struct dpu_hw_mixer *)lm_iter.hw; - - /* CTL may be <= LMs, if <, multiple LMs controlled by 1 CTL */ - if (!dpu_rm_get_hw(rm, &ctl_iter)) { - DPU_DEBUG("no ctl assigned to lm %d, using previous\n", - mixer->hw_lm->idx - LM_0); - mixer->lm_ctl = last_valid_ctl; - } else { - mixer->lm_ctl = (struct dpu_hw_ctl *)ctl_iter.hw; - last_valid_ctl = mixer->lm_ctl; - } - - /* Shouldn't happen, mixers are always >= ctls */ - if (!mixer->lm_ctl) { - DPU_ERROR("no valid ctls found for lm %d\n", - mixer->hw_lm->idx - LM_0); - return; - } - - cstate->num_mixers++; - DPU_DEBUG("setup mixer %d: lm %d\n", - i, mixer->hw_lm->idx - LM_0); - DPU_DEBUG("setup mixer %d: ctl %d\n", - i, mixer->lm_ctl->idx - CTL_0); - } -} - -static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc) -{ - struct drm_encoder *enc; - - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); - - /* Check for mixers on all encoders attached to this crtc */ - drm_for_each_encoder_mask(enc, crtc->dev, crtc->state->encoder_mask) - _dpu_crtc_setup_mixer_for_encoder(crtc, enc); -} - static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -536,10 +477,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, dev = crtc->dev; smmu_state = &dpu_crtc->smmu_state; - if (!cstate->num_mixers) { - _dpu_crtc_setup_mixers(crtc); - _dpu_crtc_setup_lm_bounds(crtc, crtc->state); - } + _dpu_crtc_setup_lm_bounds(crtc, crtc->state); if (dpu_crtc->event) { WARN_ON(dpu_crtc->event); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 99cbf3524348..c4e4e19b5ea1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -963,9 +963,12 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct list_head *connector_list; struct drm_connector *conn = NULL, *conn_iter; struct drm_crtc *drm_crtc; - struct dpu_rm_hw_iter pp_iter, ctl_iter; + struct dpu_crtc_state *cstate; + struct dpu_rm_hw_iter hw_iter; struct msm_display_topology topology; struct dpu_hw_ctl *hw_ctl[MAX_CHANNELS_PER_ENC] = { NULL }; + struct dpu_hw_mixer *hw_lm[MAX_CHANNELS_PER_ENC] = { NULL }; + int num_lm = 0, num_ctl = 0; int i = 0, ret; if (!drm_enc) { @@ -1009,21 +1012,41 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, return; } - dpu_rm_init_hw_iter(&pp_iter, drm_enc->base.id, DPU_HW_BLK_PINGPONG); + dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_PINGPONG); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { dpu_enc->hw_pp[i] = NULL; - if (!dpu_rm_get_hw(&dpu_kms->rm, &pp_iter)) + if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) break; - dpu_enc->hw_pp[i] = (struct dpu_hw_pingpong *) pp_iter.hw; + dpu_enc->hw_pp[i] = (struct dpu_hw_pingpong *) hw_iter.hw; } - dpu_rm_init_hw_iter(&ctl_iter, drm_enc->base.id, DPU_HW_BLK_CTL); + dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_CTL); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { - if (!dpu_rm_get_hw(&dpu_kms->rm, &ctl_iter)) + if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) break; - hw_ctl[i] = (struct dpu_hw_ctl *)ctl_iter.hw; + hw_ctl[i] = (struct dpu_hw_ctl *)hw_iter.hw; + num_ctl++; } + dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, DPU_HW_BLK_LM); + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) + break; + hw_lm[i] = (struct dpu_hw_mixer *)hw_iter.hw; + num_lm++; + } + + cstate = to_dpu_crtc_state(drm_crtc->state); + + for (i = 0; i < num_lm; i++) { + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); + + cstate->mixers[i].hw_lm = hw_lm[i]; + cstate->mixers[i].lm_ctl = hw_ctl[ctl_idx]; + } + + cstate->num_mixers = num_lm; + for (i = 0; i < dpu_enc->num_phys_encs; i++) { struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; -- cgit v1.2.3 From 9d4c8fd1af4687eb477ae26b7ecc386b336cea72 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 13 Feb 2019 17:19:15 -0800 Subject: drm/msm/dpu: assign intf to encoder in mode_set Iterate and assign HW intf block to physical encoders in encoder modeset. Moving all the HW block assignments to encoder modeset to allow easy switching to state based resource management. Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/1550107156-17625-7-git-send-email-jsanka@codeaurora.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 22 +++++++++++++++++++- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 24 ---------------------- 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index c4e4e19b5ea1..82bf16d61a45 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -969,7 +969,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct dpu_hw_ctl *hw_ctl[MAX_CHANNELS_PER_ENC] = { NULL }; struct dpu_hw_mixer *hw_lm[MAX_CHANNELS_PER_ENC] = { NULL }; int num_lm = 0, num_ctl = 0; - int i = 0, ret; + int i, j, ret; if (!drm_enc) { DPU_ERROR("invalid encoder\n"); @@ -1066,6 +1066,26 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = hw_ctl[i]; + dpu_rm_init_hw_iter(&hw_iter, drm_enc->base.id, + DPU_HW_BLK_INTF); + for (j = 0; j < MAX_CHANNELS_PER_ENC; j++) { + struct dpu_hw_intf *hw_intf; + + if (!dpu_rm_get_hw(&dpu_kms->rm, &hw_iter)) + break; + + hw_intf = (struct dpu_hw_intf *)hw_iter.hw; + if (hw_intf->idx == phys->intf_idx) + phys->hw_intf = hw_intf; + } + + if (!phys->hw_intf) { + DPU_ERROR_ENC(dpu_enc, + "no intf block assigned at idx: %d\n", + i); + goto error; + } + phys->connector = conn->state->connector; if (phys->ops.mode_set) phys->ops.mode_set(phys, mode, adj_mode); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index ae5449c73c5e..0adfdfc8775f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -449,35 +449,11 @@ end: static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) { - struct msm_drm_private *priv; - struct dpu_rm_hw_iter iter; struct dpu_hw_ctl *ctl; u32 flush_mask = 0; - if (!phys_enc || !phys_enc->parent || !phys_enc->parent->dev || - !phys_enc->parent->dev->dev_private) { - DPU_ERROR("invalid encoder/device\n"); - return; - } - priv = phys_enc->parent->dev->dev_private; - ctl = phys_enc->hw_ctl; - dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_INTF); - while (dpu_rm_get_hw(&phys_enc->dpu_kms->rm, &iter)) { - struct dpu_hw_intf *hw_intf = (struct dpu_hw_intf *)iter.hw; - - if (hw_intf->idx == phys_enc->intf_idx) { - phys_enc->hw_intf = hw_intf; - break; - } - } - - if (!phys_enc->hw_intf) { - DPU_ERROR("hw_intf not assigned\n"); - return; - } - DPU_DEBUG_VIDENC(phys_enc, "\n"); if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing)) -- cgit v1.2.3 From 4e99851742470a64326d5484a44e7940c0e6d056 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Wed, 13 Feb 2019 17:19:16 -0800 Subject: drm/msm/dpu: check split role for single flush Removing unwanted access of crtc_state for finding this information. Use split role information to know whether we have slave ctl. Signed-off-by: Jeykumar Sankaran Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/1550107156-17625-8-git-send-email-jsanka@codeaurora.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 0adfdfc8775f..1b7a335a6140 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -347,22 +347,10 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx) phys_enc); } -static bool _dpu_encoder_phys_is_dual_ctl(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_crtc_state *dpu_cstate; - - if (!phys_enc) - return false; - - dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state); - - return dpu_cstate->num_ctls > 1; -} - static bool dpu_encoder_phys_vid_needs_single_flush( struct dpu_encoder_phys *phys_enc) { - return (phys_enc && _dpu_encoder_phys_is_dual_ctl(phys_enc)); + return phys_enc->split_role != ENC_ROLE_SOLO; } static void _dpu_encoder_phys_vid_setup_irq_hw_idx( -- cgit v1.2.3 From e1505f627e2edaf9ba6cad4a352d897db1f99ef3 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 16 Jan 2019 10:46:22 -0800 Subject: drm/msm: Cleanup A6XX opp-level reading The patch ("OPP: Add support for parsing the 'opp-level' property") adds an API enabling a cleaner way to read the opp-level. Let's use the new API. Signed-off-by: Douglas Anderson Reviewed-by: Jordan Crouse Signed-off-by: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index d1662a75c7ec..a12aa4664c8b 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -948,25 +948,20 @@ static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu) } /* Return the 'arc-level' for the given frequency */ -static u32 a6xx_gmu_get_arc_level(struct device *dev, unsigned long freq) +static unsigned int a6xx_gmu_get_arc_level(struct device *dev, + unsigned long freq) { struct dev_pm_opp *opp; - struct device_node *np; - u32 val = 0; + unsigned int val; if (!freq) return 0; - opp = dev_pm_opp_find_freq_exact(dev, freq, true); + opp = dev_pm_opp_find_freq_exact(dev, freq, true); if (IS_ERR(opp)) return 0; - np = dev_pm_opp_get_of_node(opp); - - if (np) { - of_property_read_u32(np, "opp-level", &val); - of_node_put(np); - } + val = dev_pm_opp_get_level(opp); dev_pm_opp_put(opp); @@ -1002,7 +997,7 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, /* Construct a vote for each frequency */ for (i = 0; i < freqs_count; i++) { u8 pindex = 0, sindex = 0; - u32 level = a6xx_gmu_get_arc_level(dev, freqs[i]); + unsigned int level = a6xx_gmu_get_arc_level(dev, freqs[i]); /* Get the primary index that matches the arc level */ for (j = 0; j < pri_count; j++) { -- cgit v1.2.3 From 6cd5235c3135ea84b32469ea51b2aae384eda8af Mon Sep 17 00:00:00 2001 From: Wen Yang Date: Thu, 4 Apr 2019 00:04:11 +0800 Subject: drm/msm: a5xx: fix possible object reference leak The call to of_get_child_by_name returns a node pointer with refcount incremented thus it must be explicitly decremented after the last usage. Detected by coccinelle with the following warnings: drivers/gpu/drm/msm/adreno/a5xx_gpu.c:57:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 47, but without a corresponding object release within this function. drivers/gpu/drm/msm/adreno/a5xx_gpu.c:66:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 47, but without a corresponding object release within this function. drivers/gpu/drm/msm/adreno/a5xx_gpu.c:118:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 47, but without a corresponding object release within this function. drivers/gpu/drm/msm/adreno/a5xx_gpu.c:57:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 51, but without a corresponding object release within this function. drivers/gpu/drm/msm/adreno/a5xx_gpu.c:66:2-8: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 51, but without a corresponding object release within this function. drivers/gpu/drm/msm/adreno/a5xx_gpu.c:118:1-7: ERROR: missing of_node_put; acquired a node pointer with refcount incremented on line 51, but without a corresponding object release within this function. Signed-off-by: Wen Yang Cc: Rob Clark Cc: Sean Paul Cc: David Airlie Cc: Daniel Vetter Cc: Jordan Crouse Cc: Mamta Shukla Cc: Thomas Zimmermann Cc: Sharat Masetty Cc: linux-arm-msm@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: freedreno@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org (open list) Reviewed-by: Jordan Crouse Signed-off-by: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index d5f5e56422f5..270da14cba67 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -34,7 +34,7 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname) { struct device *dev = &gpu->pdev->dev; const struct firmware *fw; - struct device_node *np; + struct device_node *np, *mem_np; struct resource r; phys_addr_t mem_phys; ssize_t mem_size; @@ -48,11 +48,13 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname) if (!np) return -ENODEV; - np = of_parse_phandle(np, "memory-region", 0); - if (!np) + mem_np = of_parse_phandle(np, "memory-region", 0); + of_node_put(np); + if (!mem_np) return -EINVAL; - ret = of_address_to_resource(np, 0, &r); + ret = of_address_to_resource(mem_np, 0, &r); + of_node_put(mem_np); if (ret) return ret; -- cgit v1.2.3 From 017d75f1f96f5d969a04fafb1dcd617f9c27f21a Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Mon, 15 Apr 2019 12:07:28 +0800 Subject: drm/amdgpu: enable Vega20 BACO reset support PSP SOS firmware needs to be 0x80067 or later. Signed-off-by: Evan Quan Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index bdb5ad93990d..a136632bf91c 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -470,6 +470,12 @@ static int soc15_asic_reset(struct amdgpu_device *adev) case CHIP_VEGA12: soc15_asic_get_baco_capability(adev, &baco_reset); break; + case CHIP_VEGA20: + if (adev->psp.sos_fw_version >= 0x80067) + soc15_asic_get_baco_capability(adev, &baco_reset); + else + baco_reset = false; + break; default: baco_reset = false; break; -- cgit v1.2.3 From 46dd9ff7246fd21cc4228a4e7e1d40c30f210dec Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 15 Apr 2019 10:27:50 -0400 Subject: drm/amd/display: Expose support for DRM_FORMAT_RGB565 DC and DM already support DRM_FORMAT_RGB565, it's just missing from the list of valid formats. Cc: Harry Wentland Cc: Leo Li Signed-off-by: Nicholas Kazlauskas Acked-by: Alex Deucher Reviewed-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 054681113d71..fb248984b7ba 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4188,6 +4188,7 @@ static const uint32_t rgb_formats[] = { DRM_FORMAT_ABGR2101010, DRM_FORMAT_XBGR8888, DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB565, }; static const uint32_t overlay_formats[] = { -- cgit v1.2.3 From a1b11201af9a934f0c4b2218c25a7b75ca2ff42a Mon Sep 17 00:00:00 2001 From: shaoyunl Date: Mon, 15 Apr 2019 11:22:38 -0400 Subject: drm/powerplay : send SMC message to set XGMI pstate Send message with parameter to SMC to set xgmi pstate Signed-off-by: shaoyunl Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c index c478b38662d0..92903a4cc4d8 100644 --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -1896,8 +1896,13 @@ set_fan_speed_rpm_failed: static int smu_v11_0_set_xgmi_pstate(struct smu_context *smu, uint32_t pstate) { - /* send msg to SMU to set pstate */ - return 0; + int ret = 0; + mutex_lock(&(smu->mutex)); + ret = smu_send_smc_msg_with_param(smu, + SMU_MSG_SetXgmiMode, + pstate ? XGMI_STATE_D0 : XGMI_STATE_D3); + mutex_unlock(&(smu->mutex)); + return ret; } static const struct smu_funcs smu_v11_0_funcs = { -- cgit v1.2.3 From 0da8b10e36e91b1c68b88cdcc6efb285a3b386ed Mon Sep 17 00:00:00 2001 From: Amber Lin Date: Fri, 12 Apr 2019 11:07:16 -0400 Subject: drm/amdgpu: get_fw_version isn't ASIC specific Method of getting firmware version is the same across ASICs, so remove them from ASIC-specific files and create one in amdgpu_amdkfd.c. This new created get_fw_version simply reads fw_version from adev->gfx than parsing the ucode header. Signed-off-by: Amber Lin Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 37 ++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 14 ++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 61 ----------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 61 ----------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 54 -------------------- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 4 +- drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 16 ------ 7 files changed, 53 insertions(+), 194 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index acf8ae0cee9a..aeead072fa79 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -335,6 +335,43 @@ void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj) amdgpu_bo_unref(&(bo)); } +uint32_t amdgpu_amdkfd_get_fw_version(struct kgd_dev *kgd, + enum kgd_engine_type type) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)kgd; + + switch (type) { + case KGD_ENGINE_PFP: + return adev->gfx.pfp_fw_version; + + case KGD_ENGINE_ME: + return adev->gfx.me_fw_version; + + case KGD_ENGINE_CE: + return adev->gfx.ce_fw_version; + + case KGD_ENGINE_MEC1: + return adev->gfx.mec_fw_version; + + case KGD_ENGINE_MEC2: + return adev->gfx.mec2_fw_version; + + case KGD_ENGINE_RLC: + return adev->gfx.rlc_fw_version; + + case KGD_ENGINE_SDMA1: + return adev->sdma.instance[0].fw_version; + + case KGD_ENGINE_SDMA2: + return adev->sdma.instance[1].fw_version; + + default: + return 0; + } + + return 0; +} + void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd, struct kfd_local_mem_info *mem_info) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 775f815f9521..4e37fa7e85b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -81,6 +81,18 @@ struct amdgpu_kfd_dev { uint64_t vram_used; }; +enum kgd_engine_type { + KGD_ENGINE_PFP = 1, + KGD_ENGINE_ME, + KGD_ENGINE_CE, + KGD_ENGINE_MEC1, + KGD_ENGINE_MEC2, + KGD_ENGINE_RLC, + KGD_ENGINE_SDMA1, + KGD_ENGINE_SDMA2, + KGD_ENGINE_MAX +}; + struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context, struct mm_struct *mm); bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm); @@ -142,6 +154,8 @@ int amdgpu_amdkfd_alloc_gtt_mem(struct kgd_dev *kgd, size_t size, void **mem_obj, uint64_t *gpu_addr, void **cpu_ptr, bool mqd_gfx9); void amdgpu_amdkfd_free_gtt_mem(struct kgd_dev *kgd, void *mem_obj); +uint32_t amdgpu_amdkfd_get_fw_version(struct kgd_dev *kgd, + enum kgd_engine_type type); void amdgpu_amdkfd_get_local_mem_info(struct kgd_dev *kgd, struct kfd_local_mem_info *mem_info); uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct kgd_dev *kgd); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index ff7fac7df34b..fa09e11a600c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c @@ -22,14 +22,12 @@ #include #include -#include #include #include #include "amdgpu.h" #include "amdgpu_amdkfd.h" #include "cikd.h" #include "cik_sdma.h" -#include "amdgpu_ucode.h" #include "gfx_v7_0.h" #include "gca/gfx_7_2_d.h" #include "gca/gfx_7_2_enum.h" @@ -139,7 +137,6 @@ static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid); static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, uint8_t vmid); -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); static void set_scratch_backing_va(struct kgd_dev *kgd, uint64_t va, uint32_t vmid); static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, @@ -191,7 +188,6 @@ static const struct kfd2kgd_calls kfd2kgd = { .address_watch_get_offset = kgd_address_watch_get_offset, .get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid, .get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid, - .get_fw_version = get_fw_version, .set_scratch_backing_va = set_scratch_backing_va, .get_tile_config = get_tile_config, .set_vm_context_page_table_base = set_vm_context_page_table_base, @@ -792,63 +788,6 @@ static void set_scratch_backing_va(struct kgd_dev *kgd, unlock_srbm(kgd); } -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) -{ - struct amdgpu_device *adev = (struct amdgpu_device *) kgd; - const union amdgpu_firmware_header *hdr; - - switch (type) { - case KGD_ENGINE_PFP: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.pfp_fw->data; - break; - - case KGD_ENGINE_ME: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.me_fw->data; - break; - - case KGD_ENGINE_CE: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.ce_fw->data; - break; - - case KGD_ENGINE_MEC1: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.mec_fw->data; - break; - - case KGD_ENGINE_MEC2: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.mec2_fw->data; - break; - - case KGD_ENGINE_RLC: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.rlc_fw->data; - break; - - case KGD_ENGINE_SDMA1: - hdr = (const union amdgpu_firmware_header *) - adev->sdma.instance[0].fw->data; - break; - - case KGD_ENGINE_SDMA2: - hdr = (const union amdgpu_firmware_header *) - adev->sdma.instance[1].fw->data; - break; - - default: - return 0; - } - - if (hdr == NULL) - return 0; - - /* Only 12 bit in use*/ - return hdr->common.ucode_version; -} - static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index 56ea929f524b..fec3a6aa1de6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c @@ -23,12 +23,10 @@ #include #include #include -#include #include #include #include "amdgpu.h" #include "amdgpu_amdkfd.h" -#include "amdgpu_ucode.h" #include "gfx_v8_0.h" #include "gca/gfx_8_0_sh_mask.h" #include "gca/gfx_8_0_d.h" @@ -95,7 +93,6 @@ static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid); static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, uint8_t vmid); -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); static void set_scratch_backing_va(struct kgd_dev *kgd, uint64_t va, uint32_t vmid); static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, @@ -148,7 +145,6 @@ static const struct kfd2kgd_calls kfd2kgd = { get_atc_vmid_pasid_mapping_pasid, .get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid, - .get_fw_version = get_fw_version, .set_scratch_backing_va = set_scratch_backing_va, .get_tile_config = get_tile_config, .set_vm_context_page_table_base = set_vm_context_page_table_base, @@ -751,63 +747,6 @@ static void set_scratch_backing_va(struct kgd_dev *kgd, unlock_srbm(kgd); } -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) -{ - struct amdgpu_device *adev = (struct amdgpu_device *) kgd; - const union amdgpu_firmware_header *hdr; - - switch (type) { - case KGD_ENGINE_PFP: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.pfp_fw->data; - break; - - case KGD_ENGINE_ME: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.me_fw->data; - break; - - case KGD_ENGINE_CE: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.ce_fw->data; - break; - - case KGD_ENGINE_MEC1: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.mec_fw->data; - break; - - case KGD_ENGINE_MEC2: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.mec2_fw->data; - break; - - case KGD_ENGINE_RLC: - hdr = (const union amdgpu_firmware_header *) - adev->gfx.rlc_fw->data; - break; - - case KGD_ENGINE_SDMA1: - hdr = (const union amdgpu_firmware_header *) - adev->sdma.instance[0].fw->data; - break; - - case KGD_ENGINE_SDMA2: - hdr = (const union amdgpu_firmware_header *) - adev->sdma.instance[1].fw->data; - break; - - default: - return 0; - } - - if (hdr == NULL) - return 0; - - /* Only 12 bit in use*/ - return hdr->common.ucode_version; -} - static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index 5c51d4910650..ef3d93b995b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -25,12 +25,10 @@ #include #include #include -#include #include #include #include "amdgpu.h" #include "amdgpu_amdkfd.h" -#include "amdgpu_ucode.h" #include "soc15_hw_ip.h" #include "gc/gc_9_0_offset.h" #include "gc/gc_9_0_sh_mask.h" @@ -111,7 +109,6 @@ static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, uint8_t vmid); static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base); -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); static void set_scratch_backing_va(struct kgd_dev *kgd, uint64_t va, uint32_t vmid); static int invalidate_tlbs(struct kgd_dev *kgd, uint16_t pasid); @@ -158,7 +155,6 @@ static const struct kfd2kgd_calls kfd2kgd = { get_atc_vmid_pasid_mapping_pasid, .get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid, - .get_fw_version = get_fw_version, .set_scratch_backing_va = set_scratch_backing_va, .get_tile_config = amdgpu_amdkfd_get_tile_config, .set_vm_context_page_table_base = set_vm_context_page_table_base, @@ -874,56 +870,6 @@ static void set_scratch_backing_va(struct kgd_dev *kgd, */ } -/* FIXME: Does this need to be ASIC-specific code? */ -static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) -{ - struct amdgpu_device *adev = (struct amdgpu_device *) kgd; - const union amdgpu_firmware_header *hdr; - - switch (type) { - case KGD_ENGINE_PFP: - hdr = (const union amdgpu_firmware_header *)adev->gfx.pfp_fw->data; - break; - - case KGD_ENGINE_ME: - hdr = (const union amdgpu_firmware_header *)adev->gfx.me_fw->data; - break; - - case KGD_ENGINE_CE: - hdr = (const union amdgpu_firmware_header *)adev->gfx.ce_fw->data; - break; - - case KGD_ENGINE_MEC1: - hdr = (const union amdgpu_firmware_header *)adev->gfx.mec_fw->data; - break; - - case KGD_ENGINE_MEC2: - hdr = (const union amdgpu_firmware_header *)adev->gfx.mec2_fw->data; - break; - - case KGD_ENGINE_RLC: - hdr = (const union amdgpu_firmware_header *)adev->gfx.rlc_fw->data; - break; - - case KGD_ENGINE_SDMA1: - hdr = (const union amdgpu_firmware_header *)adev->sdma.instance[0].fw->data; - break; - - case KGD_ENGINE_SDMA2: - hdr = (const union amdgpu_firmware_header *)adev->sdma.instance[1].fw->data; - break; - - default: - return 0; - } - - if (hdr == NULL) - return 0; - - /* Only 12 bit in use*/ - return hdr->common.ucode_version; -} - static void set_vm_context_page_table_base(struct kgd_dev *kgd, uint32_t vmid, uint64_t page_table_base) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index b3cdbf79f47b..aaa5989e9831 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -493,9 +493,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, { unsigned int size; - kfd->mec_fw_version = kfd->kfd2kgd->get_fw_version(kfd->kgd, + kfd->mec_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd, KGD_ENGINE_MEC1); - kfd->sdma_fw_version = kfd->kfd2kgd->get_fw_version(kfd->kgd, + kfd->sdma_fw_version = amdgpu_amdkfd_get_fw_version(kfd->kgd, KGD_ENGINE_SDMA1); kfd->shared_resources = *gpu_resources; diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 5f3c10ebff08..b897aca9b4c9 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -85,18 +85,6 @@ enum kgd_memory_pool { KGD_POOL_FRAMEBUFFER = 3, }; -enum kgd_engine_type { - KGD_ENGINE_PFP = 1, - KGD_ENGINE_ME, - KGD_ENGINE_CE, - KGD_ENGINE_MEC1, - KGD_ENGINE_MEC2, - KGD_ENGINE_RLC, - KGD_ENGINE_SDMA1, - KGD_ENGINE_SDMA2, - KGD_ENGINE_MAX -}; - /** * enum kfd_sched_policy * @@ -230,8 +218,6 @@ struct tile_config { * @hqd_sdma_destroy: Destructs and preempts the SDMA queue assigned to that * SDMA hqd slot. * - * @get_fw_version: Returns FW versions from the header - * * @set_scratch_backing_va: Sets VA for scratch backing memory of a VMID. * Only used for no cp scheduling mode * @@ -311,8 +297,6 @@ struct kfd2kgd_calls { struct kgd_dev *kgd, uint8_t vmid); - uint16_t (*get_fw_version)(struct kgd_dev *kgd, - enum kgd_engine_type type); void (*set_scratch_backing_va)(struct kgd_dev *kgd, uint64_t va, uint32_t vmid); int (*get_tile_config)(struct kgd_dev *kgd, struct tile_config *config); -- cgit v1.2.3 From 20299a8812dccdd24acfaa5f935fa8d81222bf9c Mon Sep 17 00:00:00 2001 From: Leo Li Date: Tue, 16 Apr 2019 11:32:34 -0400 Subject: drm/amd/include: Add USB_C_TYPE to atom_encoder_cap_defs This is needed by DC to support EDID emulation on USB-C ports. CC: Samson Tam CC: Harry Wentland CC: Alex Deucher Signed-off-by: Leo Li Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/atomfirmware.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h index 08769b4b7a74..d3075adb3297 100644 --- a/drivers/gpu/drm/amd/include/atomfirmware.h +++ b/drivers/gpu/drm/amd/include/atomfirmware.h @@ -718,6 +718,7 @@ enum atom_encoder_caps_def ATOM_ENCODER_CAP_RECORD_HBR2_EN =0x02, // DP1.2 HBR2 setting is qualified and HBR2 can be enabled ATOM_ENCODER_CAP_RECORD_HDMI6Gbps_EN =0x04, // HDMI2.0 6Gbps enable or not. ATOM_ENCODER_CAP_RECORD_HBR3_EN =0x08, // DP1.3 HBR3 is supported by board. + ATOM_ENCODER_CAP_RECORD_USB_C_TYPE =0x100, // the DP connector is a USB-C type. }; struct atom_encoder_caps_record -- cgit v1.2.3 From 36e499b2490a470a9a1e8d40096b4e397efac056 Mon Sep 17 00:00:00 2001 From: wentalou Date: Tue, 16 Apr 2019 15:09:16 +0800 Subject: drm/amdgpu: amdgpu_device_recover_vram got NULL of shadow->parent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amdgpu_bo_destroy had a bug by calling amdgpu_bo_unref outside mutex_lock. If amdgpu_device_recover_vram executed between amdgpu_bo_unref and list_del_init, it would get NULL of shadow->parent, then caused Call Trace and GPU reset failed. Signed-off-by: Wentao Lou Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index ec9e45004bff..93b2c5a48a71 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -88,12 +88,14 @@ static void amdgpu_bo_destroy(struct ttm_buffer_object *tbo) if (bo->gem_base.import_attach) drm_prime_gem_destroy(&bo->gem_base, bo->tbo.sg); drm_gem_object_release(&bo->gem_base); - amdgpu_bo_unref(&bo->parent); + /* in case amdgpu_device_recover_vram got NULL of bo->parent */ if (!list_empty(&bo->shadow_list)) { mutex_lock(&adev->shadow_list_lock); list_del_init(&bo->shadow_list); mutex_unlock(&adev->shadow_list_lock); } + amdgpu_bo_unref(&bo->parent); + kfree(bo->metadata); kfree(bo); } -- cgit v1.2.3 From 4cb62b50de6fccf957e8926e37a2840c204c2a76 Mon Sep 17 00:00:00 2001 From: Yintian Tao Date: Tue, 16 Apr 2019 14:04:38 +0800 Subject: drm/amdgpu: disable DRIVER_ATOMIC under SRIOV Under SRIOV, we need disable DRIVER_ATOMIC. Otherwise, it will trigger WARN_ON at drm_universal_plane_init. Signed-off-by: Yintian Tao Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 7e7f9ed89ee1..7d484fad3909 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -36,6 +36,7 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev) /* enable virtual display */ adev->mode_info.num_crtc = 1; adev->enable_virtual_display = true; + adev->ddev->driver->driver_features &= ~DRIVER_ATOMIC; adev->cg_flags = 0; adev->pg_flags = 0; } -- cgit v1.2.3 From fced5c70da82c94130948b6a3effcf292acc63fb Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Fri, 19 Apr 2019 15:12:34 +0800 Subject: drm/amdgpu: enable MGCG for PCO Enable MGCG for picasso. Signed-off-by: Likun Gao Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index a136632bf91c..4900e4958dec 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -901,7 +901,8 @@ static int soc15_common_early_init(void *handle) adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; } else if (adev->pdev->device == 0x15d8) { - adev->cg_flags = AMD_CG_SUPPORT_GFX_MGLS | + adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | + AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | -- cgit v1.2.3 From f4895610f2ee3f817eeb0dab1c11fb1432594bcf Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 16 Apr 2019 12:59:26 +0100 Subject: drm/amdgpu: fix spelling mistake "gateing" -> "gating" There is a spelling mistake in a DRM_INFO message. Fix it. Reviewed-by: Mukesh Ojha Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index bed78a778e3f..40363ca6c5f1 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c @@ -283,7 +283,7 @@ static int vce_v2_0_stop(struct amdgpu_device *adev) } if (vce_v2_0_wait_for_idle(adev)) { - DRM_INFO("VCE is busy, Can't set clock gateing"); + DRM_INFO("VCE is busy, Can't set clock gating"); return 0; } -- cgit v1.2.3 From c9d66b361ed1693666dc4816d76ba17b51423014 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 18 Apr 2019 11:25:10 +0100 Subject: drm/amd/amdgpu: fix spelling mistake "recieve" -> "receive" There is a spelling mistake in a pr_err message. Fix it. Reviewed-by: Mukesh Ojha Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c index 6a0fcd67662a..aef9d059ae52 100644 --- a/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c +++ b/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c @@ -515,7 +515,7 @@ static void xgpu_vi_mailbox_flr_work(struct work_struct *work) /* wait until RCV_MSG become 3 */ if (xgpu_vi_poll_msg(adev, IDH_FLR_NOTIFICATION_CMPL)) { - pr_err("failed to recieve FLR_CMPL\n"); + pr_err("failed to receive FLR_CMPL\n"); return; } -- cgit v1.2.3 From d674c963af7470b6394b4b7f98cf2716b3a757d7 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 15 Apr 2019 16:55:45 -0700 Subject: drm/msm/gpu: add per-process pagetables param For now it always returns '0' (false), but once the iommu work is in place to enable per-process pagetables we can update the value returned. Userspace needs to know this to make an informed decision about exposing KHR_robustness. Signed-off-by: Rob Clark Reviewed-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ include/uapi/drm/msm_drm.h | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 27898475cdf4..7727917806ce 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -63,6 +63,9 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) case MSM_PARAM_NR_RINGS: *value = gpu->nr_rings; return 0; + case MSM_PARAM_PP_PGTABLE: + *value = 0; + return 0; default: DBG("%s: invalid param: %u", gpu->name, param); return -EINVAL; diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 91a16b333c69..a9fdcf1689ce 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -74,6 +74,7 @@ struct drm_msm_timespec { #define MSM_PARAM_TIMESTAMP 0x05 #define MSM_PARAM_GMEM_BASE 0x06 #define MSM_PARAM_NR_RINGS 0x07 +#define MSM_PARAM_PP_PGTABLE 0x08 /* => 1 for per-process pagetables, else 0 */ struct drm_msm_param { __u32 pipe; /* in, MSM_PIPE_x */ -- cgit v1.2.3 From 48dc4241c9cd62bfbe33625e669e21d7081d35fa Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 16 Apr 2019 16:13:28 -0700 Subject: drm/msm: add param to retrieve # of GPU faults (global) For KHR_robustness, userspace wants to know two things, the count of GPU faults globally, and the count of faults attributed to a given context. This patch providees the former, and the next patch provides the latter. Signed-off-by: Rob Clark Reviewed-by: Jordan Crouse --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ drivers/gpu/drm/msm/msm_gpu.c | 3 +++ drivers/gpu/drm/msm/msm_gpu.h | 3 +++ include/uapi/drm/msm_drm.h | 1 + 4 files changed, 10 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 7727917806ce..6de08cfc38aa 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -66,6 +66,9 @@ int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) case MSM_PARAM_PP_PGTABLE: *value = 0; return 0; + case MSM_PARAM_FAULTS: + *value = gpu->global_faults; + return 0; default: DBG("%s: invalid param: %u", gpu->name, param); return -EINVAL; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 10babd18e286..194847a220b6 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -443,6 +443,9 @@ static void recover_worker(struct work_struct *work) if (submit) { struct task_struct *task; + /* Increment the fault count */ + gpu->global_faults++; + task = get_pid_task(submit->pid, PIDTYPE_PID); if (task) { comm = kstrdup(task->comm, GFP_KERNEL); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 6241986bab51..f2739cd97cea 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -104,6 +104,9 @@ struct msm_gpu { /* does gpu need hw_init? */ bool needs_hw_init; + /* number of GPU hangs (for all contexts) */ + int global_faults; + /* worker for handling active-list retiring: */ struct work_struct retire_work; diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index a9fdcf1689ce..178d7b407f3a 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -75,6 +75,7 @@ struct drm_msm_timespec { #define MSM_PARAM_GMEM_BASE 0x06 #define MSM_PARAM_NR_RINGS 0x07 #define MSM_PARAM_PP_PGTABLE 0x08 /* => 1 for per-process pagetables, else 0 */ +#define MSM_PARAM_FAULTS 0x09 struct drm_msm_param { __u32 pipe; /* in, MSM_PIPE_x */ -- cgit v1.2.3 From b0fb66043a0d471a5acfe743adf90a0c447aca6b Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 22 Mar 2019 14:21:22 -0600 Subject: drm/msm/gpu: Add submit queue queries Add the capability to query information from a submit queue. The first available parameter is for querying the number of GPU faults (hangs) that can be attributed to the queue. This is useful for implementing context robustness. A user context can regularly query the number of faults to see if it is responsible for any and if so it can invalidate itself. This is also helpful for testing by confirming to the user driver if a particular command stream caused a fault (or not as the case may be). Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 9 +++++++- drivers/gpu/drm/msm/msm_drv.h | 2 ++ drivers/gpu/drm/msm/msm_gpu.c | 3 ++- drivers/gpu/drm/msm/msm_submitqueue.c | 41 +++++++++++++++++++++++++++++++++++ include/uapi/drm/msm_drm.h | 12 ++++++++++ 5 files changed, 65 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 0bdd93648761..37f18b55d11f 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -39,9 +39,10 @@ * MSM_GEM_INFO ioctl. * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get * GEM object's debug name + * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl */ #define MSM_VERSION_MAJOR 1 -#define MSM_VERSION_MINOR 4 +#define MSM_VERSION_MINOR 5 #define MSM_VERSION_PATCHLEVEL 0 static const struct drm_mode_config_funcs mode_config_funcs = { @@ -964,6 +965,11 @@ static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data, args->flags, &args->id); } +static int msm_ioctl_submitqueue_query(struct drm_device *dev, void *data, + struct drm_file *file) +{ + return msm_submitqueue_query(dev, file->driver_priv, data); +} static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data, struct drm_file *file) @@ -984,6 +990,7 @@ static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_GEM_MADVISE, msm_ioctl_gem_madvise, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW, msm_ioctl_submitqueue_new, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_AUTH|DRM_RENDER_ALLOW), }; static const struct vm_operations_struct vm_ops = { diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index c56dade2c1dc..f09d12ddb3ac 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -420,6 +420,8 @@ struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx, u32 id); int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx, u32 prio, u32 flags, u32 *id); +int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx, + struct drm_msm_submitqueue_query *args); int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id); void msm_submitqueue_close(struct msm_file_private *ctx); diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 194847a220b6..2b76657badd5 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -443,8 +443,9 @@ static void recover_worker(struct work_struct *work) if (submit) { struct task_struct *task; - /* Increment the fault count */ + /* Increment the fault counts */ gpu->global_faults++; + submit->queue->faults++; task = get_pid_task(submit->pid, PIDTYPE_PID); if (task) { diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c index 5115f75b5b7f..f160ec40a39b 100644 --- a/drivers/gpu/drm/msm/msm_submitqueue.c +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -120,6 +120,47 @@ int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx) return msm_submitqueue_create(drm, ctx, default_prio, 0, NULL); } +static int msm_submitqueue_query_faults(struct msm_gpu_submitqueue *queue, + struct drm_msm_submitqueue_query *args) +{ + size_t size = min_t(size_t, args->len, sizeof(queue->faults)); + int ret; + + /* If a zero length was passed in, return the data size we expect */ + if (!args->len) { + args->len = sizeof(queue->faults); + return 0; + } + + /* Set the length to the actual size of the data */ + args->len = size; + + ret = copy_to_user(u64_to_user_ptr(args->data), &queue->faults, size); + + return ret ? -EFAULT : 0; +} + +int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx, + struct drm_msm_submitqueue_query *args) +{ + struct msm_gpu_submitqueue *queue; + int ret = -EINVAL; + + if (args->pad) + return -EINVAL; + + queue = msm_submitqueue_get(ctx, args->id); + if (!queue) + return -ENOENT; + + if (args->param == MSM_SUBMITQUEUE_PARAM_FAULTS) + ret = msm_submitqueue_query_faults(queue, args); + + msm_submitqueue_put(queue); + + return ret; +} + int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id) { struct msm_gpu_submitqueue *entry; diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 178d7b407f3a..0b85ed6a3710 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -288,6 +288,16 @@ struct drm_msm_submitqueue { __u32 id; /* out, identifier */ }; +#define MSM_SUBMITQUEUE_PARAM_FAULTS 0 + +struct drm_msm_submitqueue_query { + __u64 data; + __u32 id; + __u32 param; + __u32 len; + __u32 pad; +}; + #define DRM_MSM_GET_PARAM 0x00 /* placeholder: #define DRM_MSM_SET_PARAM 0x01 @@ -304,6 +314,7 @@ struct drm_msm_submitqueue { */ #define DRM_MSM_SUBMITQUEUE_NEW 0x0A #define DRM_MSM_SUBMITQUEUE_CLOSE 0x0B +#define DRM_MSM_SUBMITQUEUE_QUERY 0x0C #define DRM_IOCTL_MSM_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param) #define DRM_IOCTL_MSM_GEM_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new) @@ -315,6 +326,7 @@ struct drm_msm_submitqueue { #define DRM_IOCTL_MSM_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_MADVISE, struct drm_msm_gem_madvise) #define DRM_IOCTL_MSM_SUBMITQUEUE_NEW DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_NEW, struct drm_msm_submitqueue) #define DRM_IOCTL_MSM_SUBMITQUEUE_CLOSE DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_CLOSE, __u32) +#define DRM_IOCTL_MSM_SUBMITQUEUE_QUERY DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_SUBMITQUEUE_QUERY, struct drm_msm_submitqueue_query) #if defined(__cplusplus) } -- cgit v1.2.3 From b94a6e3737ac7b5c67570cbbd02858b9aec8fbf1 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 4 Feb 2019 09:15:39 -0700 Subject: drm/msm/a6xx: Remove unwanted regulator code The GMU code currently has some misguided code to try to work around a hardware quirk that requires the power domains on the GPU be collapsed in a certain order. Upcoming patches will do this the right way so get rid of the unused and unwanted regulator code. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 4 ---- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 2 -- 2 files changed, 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index a12aa4664c8b..4618438886df 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -681,9 +681,6 @@ int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu) gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val, (val & 1), 100, 1000); - /* Force off the GX GSDC */ - regulator_force_disable(gmu->gx); - /* Disable the resources */ clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); pm_runtime_put_sync(gmu->dev); @@ -1218,7 +1215,6 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) gmu->idle_level = GMU_IDLE_STATE_ACTIVE; pm_runtime_enable(gmu->dev); - gmu->gx = devm_regulator_get(gmu->dev, "vdd"); /* Get the list of clocks */ ret = a6xx_gmu_clocks_probe(gmu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index c721d9165d8e..8081083cd062 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -52,8 +52,6 @@ struct a6xx_gmu { int hfi_irq; int gmu_irq; - struct regulator *gx; - struct iommu_domain *domain; u64 uncached_iova_base; -- cgit v1.2.3 From 9325d4266afd4e54ff4aae0018d420d596964126 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 4 Feb 2019 09:15:41 -0700 Subject: drm/msm/gpu: Attach to the GPU GX power domain 99.999% of the time during normal operation the GMU is responsible for power and clock control on the GX domain and the CPU remains blissfully unaware. However, there is one situation where the CPU needs to get involved: The power sequencing rules dictate that the GX needs to be turned off before the CX so that the CX can be turned on before the GX during power up. During normal operation when the CPU is taking down the CX domain a stop command is sent to the GMU which turns off the GX domain and then the CPU handles the CX domain. But if the GMU happened to be unresponsive while the GX domain was left then the CPU will need to step in and turn off the GX domain before resetting the CX and rebooting the GMU. This unfortunately means that the CPU needs to be marginally aware of the GX domain even though it is expected to usually keep its hands off. To support this we create a semi-disabled GX power domain that does nothing to the hardware on power up but tries to shut it down normally on power down. In this method the reference counting is correct and we can step in with the pm_runtime_put() at the right time during the failure path. This patch sets up the connection to the GX power domain and does the magic to "enable" and disable it at the right points. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 41 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 2 ++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 4618438886df..f804cfe7407c 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -681,6 +682,16 @@ int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu) gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val, (val & 1), 100, 1000); + /* + * Depending on the state of the GMU at this point the GX domain might + * have been left on. Hardware sequencing rules state that the GX has to + * be turned off before the CX domain so this is that one time that + * that calling pm_runtime_put_sync() is expected to do something useful + * (turn off the headswitch) + */ + if (!IS_ERR(gmu->gxpd)) + pm_runtime_put_sync(gmu->gxpd); + /* Disable the resources */ clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); pm_runtime_put_sync(gmu->dev); @@ -747,6 +758,14 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Set the GPU to the highest power frequency */ __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1); + /* + * "enable" the GX power domain which won't actually do anything but it + * will make sure that the refcounting is correct in case we need to + * bring down the GX after a GMU failure + */ + if (!IS_ERR(gmu->gxpd)) + pm_runtime_get(gmu->gxpd); + out: /* Make sure to turn off the boot OOB request on error */ if (ret) @@ -823,6 +842,14 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) /* Remove the bus vote */ icc_set_bw(gpu->icc_path, 0, 0); + /* + * Mark the GPU power domain as off. During the shutdown process the GMU + * should actually turn off the power so this is really just a + * houskeeping step + */ + if (!IS_ERR(gmu->gxpd)) + pm_runtime_put_sync(gmu->gxpd); + clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); pm_runtime_put_sync(gmu->dev); @@ -1187,9 +1214,15 @@ void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu) if (IS_ERR_OR_NULL(gmu->mmio)) return; - pm_runtime_disable(gmu->dev); a6xx_gmu_stop(a6xx_gpu); + pm_runtime_disable(gmu->dev); + + if (!IS_ERR(gmu->gxpd)) { + pm_runtime_disable(gmu->gxpd); + dev_pm_domain_detach(gmu->gxpd, false); + } + a6xx_gmu_irq_disable(gmu); a6xx_gmu_memory_free(gmu, gmu->hfi); @@ -1248,6 +1281,12 @@ int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node) if (gmu->hfi_irq < 0 || gmu->gmu_irq < 0) goto err; + /* + * Get a link to the GX power domain to reset the GPU in case of GMU + * crash + */ + gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx"); + /* Get the power levels for the GMU and GPU */ a6xx_gmu_pwrlevels_probe(gmu); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 8081083cd062..078d418c8179 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -55,6 +55,8 @@ struct a6xx_gmu { struct iommu_domain *domain; u64 uncached_iova_base; + struct device *gxpd; + int idle_level; struct a6xx_gmu_bo *hfi; -- cgit v1.2.3 From e31fdb74c183a8cfe32dc31974f3d626b3af4393 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 4 Feb 2019 09:15:42 -0700 Subject: drm/msm/a6xx: Make GMU reset useful Now that the GX domain is sorted we can wire up a working GMU reset. IF a GMU hang was detected then try to forcefully shut down the GMU in the power down sequence which should ensure that it can recover normally on the next power up. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 112 ++++++++++++++++------------------ drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 4 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 3 +- 4 files changed, 56 insertions(+), 65 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index f804cfe7407c..b3bc2a5c28e6 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -10,6 +10,24 @@ #include "a6xx_gpu.h" #include "a6xx_gmu.xml.h" +static void a6xx_gmu_fault(struct a6xx_gmu *gmu) +{ + struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + struct msm_gpu *gpu = &adreno_gpu->base; + struct drm_device *dev = gpu->dev; + struct msm_drm_private *priv = dev->dev_private; + + /* FIXME: add a banner here */ + gmu->hung = true; + + /* Turn off the hangcheck timer while we are resetting */ + del_timer(&gpu->hangcheck_timer); + + /* Queue the GPU handler because we need to treat this as a recovery */ + queue_work(priv->wq, &gpu->recover_work); +} + static irqreturn_t a6xx_gmu_irq(int irq, void *data) { struct a6xx_gmu *gmu = data; @@ -21,8 +39,7 @@ static irqreturn_t a6xx_gmu_irq(int irq, void *data) if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE) { dev_err_ratelimited(gmu->dev, "GMU watchdog expired\n"); - /* Temporary until we can recover safely */ - BUG(); + a6xx_gmu_fault(gmu); } if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR) @@ -46,8 +63,7 @@ static irqreturn_t a6xx_hfi_irq(int irq, void *data) if (status & A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT) { dev_err_ratelimited(gmu->dev, "GMU firmware fault\n"); - /* Temporary until we can recover safely */ - BUG(); + a6xx_gmu_fault(gmu); } return IRQ_HANDLED; @@ -166,10 +182,8 @@ static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu) } /* Wait for the GMU to get to its most idle state */ -int a6xx_gmu_wait_for_idle(struct a6xx_gpu *a6xx_gpu) +int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu) { - struct a6xx_gmu *gmu = &a6xx_gpu->gmu; - return spin_until(a6xx_gmu_check_idle_level(gmu)); } @@ -568,7 +582,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) if (!rpmh_init) { a6xx_gmu_rpmh_init(gmu); rpmh_init = true; - } else if (state != GMU_RESET) { + } else { ret = a6xx_rpmh_start(gmu); if (ret) return ret; @@ -657,10 +671,9 @@ static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu) gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~0); } -int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu) +/* Force the GMU off in case it isn't responsive */ +static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) { - struct a6xx_gmu *gmu = &a6xx_gpu->gmu; - int ret; u32 val; /* Flush all the queues */ @@ -681,44 +694,6 @@ int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu) (val & 1), 100, 10000); gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val, (val & 1), 100, 1000); - - /* - * Depending on the state of the GMU at this point the GX domain might - * have been left on. Hardware sequencing rules state that the GX has to - * be turned off before the CX domain so this is that one time that - * that calling pm_runtime_put_sync() is expected to do something useful - * (turn off the headswitch) - */ - if (!IS_ERR(gmu->gxpd)) - pm_runtime_put_sync(gmu->gxpd); - - /* Disable the resources */ - clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks); - pm_runtime_put_sync(gmu->dev); - - /* Re-enable the resources */ - pm_runtime_get_sync(gmu->dev); - - /* Use a known rate to bring up the GMU */ - clk_set_rate(gmu->core_clk, 200000000); - ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); - if (ret) - goto out; - - a6xx_gmu_irq_enable(gmu); - - ret = a6xx_gmu_fw_start(gmu, GMU_RESET); - if (!ret) - ret = a6xx_hfi_start(gmu, GMU_COLD_BOOT); - - /* Set the GPU back to the highest power frequency */ - __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1); - -out: - if (ret) - a6xx_gmu_clear_oob(gmu, GMU_OOB_BOOT_SLUMBER); - - return ret; } int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) @@ -731,6 +706,8 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) if (WARN(!gmu->mmio, "The GMU is not set up yet\n")) return 0; + gmu->hung = false; + /* Turn on the resources */ pm_runtime_get_sync(gmu->dev); @@ -789,11 +766,9 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu) return true; } -int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) +/* Gracefully try to shut down the GMU and by extension the GPU */ +static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu) { - struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; - struct msm_gpu *gpu = &adreno_gpu->base; - struct a6xx_gmu *gmu = &a6xx_gpu->gmu; u32 val; /* @@ -803,10 +778,13 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) val = gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE); if (val != 0xf) { - int ret = a6xx_gmu_wait_for_idle(a6xx_gpu); + int ret = a6xx_gmu_wait_for_idle(gmu); - /* Temporary until we can recover safely */ - BUG_ON(ret); + /* If the GMU isn't responding assume it is hung */ + if (ret) { + a6xx_gmu_force_off(gmu); + return; + } /* tell the GMU we want to slumber */ a6xx_gmu_notify_slumber(gmu); @@ -838,14 +816,30 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) /* Tell RPMh to power off the GPU */ a6xx_rpmh_stop(gmu); +} + + +int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) +{ + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; + struct msm_gpu *gpu = &a6xx_gpu->base.base; + + /* + * Force the GMU off if we detected a hang, otherwise try to shut it + * down gracefully + */ + if (gmu->hung) + a6xx_gmu_force_off(gmu); + else + a6xx_gmu_shutdown(gmu); /* Remove the bus vote */ icc_set_bw(gpu->icc_path, 0, 0); /* - * Mark the GPU power domain as off. During the shutdown process the GMU - * should actually turn off the power so this is really just a - * houskeeping step + * Make sure the GX domain is off before turning off the GMU (CX) + * domain. Usually the GMU does this but only if the shutdown sequence + * was successful */ if (!IS_ERR(gmu->gxpd)) pm_runtime_put_sync(gmu->gxpd); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 078d418c8179..c5b1887f259f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -27,9 +27,6 @@ struct a6xx_gmu_bo { /* the GMU is coming up for the first time or back from a power collapse */ #define GMU_COLD_BOOT 1 -/* The GMU is being soft reset after a fault */ -#define GMU_RESET 2 - /* * These define the level of control that the GMU has - the higher the number * the more things that the GMU hardware controls on its own. @@ -79,6 +76,7 @@ struct a6xx_gmu { struct a6xx_hfi_queue queues[2]; struct tasklet_struct hfi_tasklet; + bool hung; }; static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index fefe773c989e..f76d8cd06f93 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -698,7 +698,7 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) * Make sure the GMU is idle before continuing (because some transitions * may use VBIF */ - a6xx_gmu_wait_for_idle(a6xx_gpu); + a6xx_gmu_wait_for_idle(&a6xx_gpu->gmu); /* Clear the VBIF pipe before shutting down */ /* FIXME: This accesses the GPU - do we need to make sure it is on? */ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index 528a4cfe07cd..b46279eb18c5 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -46,9 +46,8 @@ struct a6xx_gpu { int a6xx_gmu_resume(struct a6xx_gpu *gpu); int a6xx_gmu_stop(struct a6xx_gpu *gpu); -int a6xx_gmu_wait_for_idle(struct a6xx_gpu *gpu); +int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu); -int a6xx_gmu_reset(struct a6xx_gpu *a6xx_gpu); bool a6xx_gmu_isidle(struct a6xx_gmu *gmu); int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); -- cgit v1.2.3 From 41570b747cf3ae8fcd1cb0ac954cb1b3240af9bd Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 4 Feb 2019 09:15:43 -0700 Subject: msm/drm/a6xx: Turn off the GMU if resume fails Currently if the GMU resume function fails all we try to do is clear the BOOT_SLUMBER oob which usually times out and ends up in a cycle of death. If the resume function fails at any point remove any RPMh votes that might have been added and try to shut down the GMU hardware cleanly. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 82 +++++++++++++++++++----------- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 20 ++------ drivers/gpu/drm/msm/adreno/adreno_device.c | 1 + 3 files changed, 58 insertions(+), 45 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index b3bc2a5c28e6..9155dafae2a9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -648,20 +648,6 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR | \ A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR) -static void a6xx_gmu_irq_enable(struct a6xx_gmu *gmu) -{ - gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0); - gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, ~0); - - gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK, - ~A6XX_GMU_IRQ_MASK); - gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, - ~A6XX_HFI_IRQ_MASK); - - enable_irq(gmu->gmu_irq); - enable_irq(gmu->hfi_irq); -} - static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu) { disable_irq(gmu->gmu_irq); @@ -671,11 +657,24 @@ static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu) gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~0); } -/* Force the GMU off in case it isn't responsive */ -static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) +static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu) { u32 val; + /* Make sure there are no outstanding RPMh votes */ + gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val, + (val & 1), 100, 10000); + gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS, val, + (val & 1), 100, 10000); + gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS, val, + (val & 1), 100, 10000); + gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val, + (val & 1), 100, 1000); +} + +/* Force the GMU off in case it isn't responsive */ +static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) +{ /* Flush all the queues */ a6xx_hfi_stop(gmu); @@ -686,14 +685,7 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu) a6xx_sptprac_disable(gmu); /* Make sure there are no outstanding RPMh votes */ - gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS, val, - (val & 1), 100, 10000); - gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS, val, - (val & 1), 100, 10000); - gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS, val, - (val & 1), 100, 10000); - gmu_poll_timeout(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS, val, - (val & 1), 100, 1000); + a6xx_gmu_rpmh_off(gmu); } int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) @@ -714,13 +706,18 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 200000000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); - if (ret) - goto out; + if (ret) { + pm_runtime_put(gmu->dev); + return ret; + } /* Set the bus quota to a reasonable value for boot */ icc_set_bw(gpu->icc_path, 0, MBps_to_icc(3072)); - a6xx_gmu_irq_enable(gmu); + /* Enable the GMU interrupt */ + gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0); + gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK, ~A6XX_GMU_IRQ_MASK); + enable_irq(gmu->gmu_irq); /* Check to see if we are doing a cold or warm boot */ status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ? @@ -731,6 +728,16 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) goto out; ret = a6xx_hfi_start(gmu, status); + if (ret) + goto out; + + /* + * Turn on the GMU firmware fault interrupt after we know the boot + * sequence is successful + */ + gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, ~0); + gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~A6XX_HFI_IRQ_MASK); + enable_irq(gmu->hfi_irq); /* Set the GPU to the highest power frequency */ __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1); @@ -744,9 +751,12 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu) pm_runtime_get(gmu->gxpd); out: - /* Make sure to turn off the boot OOB request on error */ - if (ret) - a6xx_gmu_clear_oob(gmu, GMU_OOB_BOOT_SLUMBER); + /* On failure, shut down the GMU to leave it in a good state */ + if (ret) { + disable_irq(gmu->gmu_irq); + a6xx_rpmh_stop(gmu); + pm_runtime_put(gmu->dev); + } return ret; } @@ -769,6 +779,9 @@ bool a6xx_gmu_isidle(struct a6xx_gmu *gmu) /* Gracefully try to shut down the GMU and by extension the GPU */ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu) { + struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + struct msm_gpu *gpu = &adreno_gpu->base; u32 val; /* @@ -786,6 +799,12 @@ static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu) return; } + /* Clear the VBIF pipe before shutting down */ + gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0xf); + spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & 0xf) + == 0xf); + gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0); + /* tell the GMU we want to slumber */ a6xx_gmu_notify_slumber(gmu); @@ -824,6 +843,9 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) struct a6xx_gmu *gmu = &a6xx_gpu->gmu; struct msm_gpu *gpu = &a6xx_gpu->base.base; + if (!pm_runtime_active(gmu->dev)) + return 0; + /* * Force the GMU off if we detected a hang, otherwise try to shut it * down gracefully diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index f76d8cd06f93..576559a3a523 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -678,13 +678,15 @@ static int a6xx_pm_resume(struct msm_gpu *gpu) struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); int ret; - ret = a6xx_gmu_resume(a6xx_gpu); - gpu->needs_hw_init = true; + ret = a6xx_gmu_resume(a6xx_gpu); + if (ret) + return ret; + msm_gpu_resume_devfreq(gpu); - return ret; + return 0; } static int a6xx_pm_suspend(struct msm_gpu *gpu) @@ -694,18 +696,6 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) devfreq_suspend_device(gpu->devfreq.devfreq); - /* - * Make sure the GMU is idle before continuing (because some transitions - * may use VBIF - */ - a6xx_gmu_wait_for_idle(&a6xx_gpu->gmu); - - /* Clear the VBIF pipe before shutting down */ - /* FIXME: This accesses the GPU - do we need to make sure it is on? */ - gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0xf); - spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) & 0xf) == 0xf); - gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0); - return a6xx_gmu_stop(a6xx_gpu); } diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 714ed6505e47..0d87db75b710 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -229,6 +229,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) { + pm_runtime_put_sync(&pdev->dev); DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret); return NULL; } -- cgit v1.2.3 From fb076b15d50dee36c75eb6c447c1b1026ad12e2e Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 4 Feb 2019 09:15:44 -0700 Subject: drm/msm/a6xx: Remove an unused struct member The HFI tasklet was removed in df0dff1 ("drm/msm/a6xx: Poll for HFI responses") but the tasklet_struct was accidentally left behind. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index c5b1887f259f..bedd8e6a63aa 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -75,7 +75,6 @@ struct a6xx_gmu { struct a6xx_hfi_queue queues[2]; - struct tasklet_struct hfi_tasklet; bool hung; }; -- cgit v1.2.3 From 48e7f18392c66f9b69ebac11c54f1a2e033ced54 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 20 Mar 2019 10:09:08 -0700 Subject: drm/msm: Implement .gem_free_object_unlocked We use a llist and a worker to delay the object cleanup. This avoids taking mmap_sem and struct_mutex in the wrong order when calling drm_gem_object_put_unlocked() from drm_gem_mmap(). Fixes lockdep problem with copy_from_user() in msm_ioctl_gem_submit(). Signed-off-by: Kristian H. Kristensen Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 5 ++++- drivers/gpu/drm/msm/msm_drv.h | 5 +++++ drivers/gpu/drm/msm/msm_gem.c | 35 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/msm/msm_gem.h | 3 +++ 4 files changed, 46 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 37f18b55d11f..154dab0775f3 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -458,6 +458,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) priv->wq = alloc_ordered_workqueue("msm", 0); + INIT_WORK(&priv->free_work, msm_gem_free_work); + init_llist_head(&priv->free_list); + INIT_LIST_HEAD(&priv->inactive_list); drm_mode_config_init(ddev); @@ -1026,7 +1029,7 @@ static struct drm_driver msm_driver = { .irq_uninstall = msm_irq_uninstall, .enable_vblank = msm_enable_vblank, .disable_vblank = msm_disable_vblank, - .gem_free_object = msm_gem_free_object, + .gem_free_object_unlocked = msm_gem_free_object, .gem_vm_ops = &vm_ops, .dumb_create = msm_gem_dumb_create, .dumb_map_offset = msm_gem_dumb_map_offset, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index f09d12ddb3ac..bbf739d85381 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -185,6 +185,10 @@ struct msm_drm_private { /* list of GEM objects: */ struct list_head inactive_list; + /* worker for delayed free of objects: */ + struct work_struct free_work; + struct llist_head free_list; + struct workqueue_struct *wq; unsigned int num_planes; @@ -325,6 +329,7 @@ void msm_gem_kernel_put(struct drm_gem_object *bo, struct msm_gem_address_space *aspace, bool locked); struct drm_gem_object *msm_gem_import(struct drm_device *dev, struct dma_buf *dmabuf, struct sg_table *sgt); +void msm_gem_free_work(struct work_struct *work); __printf(2, 3) void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 76940a9da980..d4dae0f0238e 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -853,8 +853,18 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m) /* don't call directly! Use drm_gem_object_put() and friends */ void msm_gem_free_object(struct drm_gem_object *obj) { - struct drm_device *dev = obj->dev; struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct drm_device *dev = obj->dev; + struct msm_drm_private *priv = dev->dev_private; + + if (llist_add(&msm_obj->freed, &priv->free_list)) + queue_work(priv->wq, &priv->free_work); +} + +static void free_object(struct msm_gem_object *msm_obj) +{ + struct drm_gem_object *obj = &msm_obj->base; + struct drm_device *dev = obj->dev; WARN_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -892,6 +902,29 @@ void msm_gem_free_object(struct drm_gem_object *obj) kfree(msm_obj); } +void msm_gem_free_work(struct work_struct *work) +{ + struct msm_drm_private *priv = + container_of(work, struct msm_drm_private, free_work); + struct drm_device *dev = priv->dev; + struct llist_node *freed; + struct msm_gem_object *msm_obj, *next; + + while ((freed = llist_del_all(&priv->free_list))) { + + mutex_lock(&dev->struct_mutex); + + llist_for_each_entry_safe(msm_obj, next, + freed, freed) + free_object(msm_obj); + + mutex_unlock(&dev->struct_mutex); + + if (need_resched()) + break; + } +} + /* convenience method to construct a GEM buffer object, and userspace handle */ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, uint32_t size, uint32_t flags, uint32_t *handle, diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 2064fac871b8..0617c44d99b0 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -84,6 +84,8 @@ struct msm_gem_object { struct list_head vmas; /* list of msm_gem_vma */ + struct llist_node freed; + /* normally (resv == &_resv) except for imported bo's */ struct reservation_object *resv; struct reservation_object _resv; @@ -133,6 +135,7 @@ enum msm_gem_lock { void msm_gem_purge(struct drm_gem_object *obj, enum msm_gem_lock subclass); void msm_gem_vunmap(struct drm_gem_object *obj, enum msm_gem_lock subclass); +void msm_gem_free_work(struct work_struct *work); /* Created per submit-ioctl, to track bo's and cmdstream bufs, etc, * associated with the cmdstream submission for synchronization (and -- cgit v1.2.3 From 8ea274accda92d36bd510a3272adf745c6376d3f Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 20 Mar 2019 10:09:09 -0700 Subject: drm/msm: Stop dropping struct_mutex in recover_worker() Now that we don't have the mmap_sem lock inversion, we don't need to jump through this particular hoop anymore. Signed-off-by: Kristian H. Kristensen Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 2b76657badd5..bf4ee2766431 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -450,21 +450,8 @@ static void recover_worker(struct work_struct *work) task = get_pid_task(submit->pid, PIDTYPE_PID); if (task) { comm = kstrdup(task->comm, GFP_KERNEL); - - /* - * So slightly annoying, in other paths like - * mmap'ing gem buffers, mmap_sem is acquired - * before struct_mutex, which means we can't - * hold struct_mutex across the call to - * get_cmdline(). But submits are retired - * from the same in-order workqueue, so we can - * safely drop the lock here without worrying - * about the submit going away. - */ - mutex_unlock(&dev->struct_mutex); cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); put_task_struct(task); - mutex_lock(&dev->struct_mutex); } if (comm && cmd) { -- cgit v1.2.3 From b673499ae738e7790b1b9f65e784999e5804abd3 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Wed, 20 Mar 2019 10:09:10 -0700 Subject: drm/msm: Split submit_lookup_objects() into two loops First loop does copy_from_user() without the table lock held and just stores the handle. Second loop looks up buffer objects with the table_lock held without potentially blocking or faulting. This lets us clean up a bunch of custom, non-faulting copy_from_user() code. Signed-off-by: Kristian H. Kristensen Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.h | 5 +++- drivers/gpu/drm/msm/msm_gem_submit.c | 44 ++++++++++++++---------------------- 2 files changed, 21 insertions(+), 28 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index 0617c44d99b0..c5ac781dffee 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -166,7 +166,10 @@ struct msm_gem_submit { } *cmd; /* array of size nr_cmds */ struct { uint32_t flags; - struct msm_gem_object *obj; + union { + struct msm_gem_object *obj; + uint32_t handle; + }; uint64_t iova; } bos[0]; }; diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 12b983fc0b56..648e0c1b92e6 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -74,27 +74,14 @@ void msm_gem_submit_free(struct msm_gem_submit *submit) kfree(submit); } -static inline unsigned long __must_check -copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) -{ - if (access_ok(from, n)) - return __copy_from_user_inatomic(to, from, n); - return -EFAULT; -} - static int submit_lookup_objects(struct msm_gem_submit *submit, struct drm_msm_gem_submit *args, struct drm_file *file) { unsigned i; int ret = 0; - spin_lock(&file->table_lock); - pagefault_disable(); - for (i = 0; i < args->nr_bos; i++) { struct drm_msm_gem_submit_bo submit_bo; - struct drm_gem_object *obj; - struct msm_gem_object *msm_obj; void __user *userptr = u64_to_user_ptr(args->bos + (i * sizeof(submit_bo))); @@ -103,15 +90,10 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, */ submit->bos[i].flags = 0; - if (copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo))) { - pagefault_enable(); - spin_unlock(&file->table_lock); - if (copy_from_user(&submit_bo, userptr, sizeof(submit_bo))) { - ret = -EFAULT; - goto out; - } - spin_lock(&file->table_lock); - pagefault_disable(); + if (copy_from_user(&submit_bo, userptr, sizeof(submit_bo))) { + ret = -EFAULT; + i = 0; + goto out; } /* at least one of READ and/or WRITE flags should be set: */ @@ -121,19 +103,28 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, !(submit_bo.flags & MANDATORY_FLAGS)) { DRM_ERROR("invalid flags: %x\n", submit_bo.flags); ret = -EINVAL; - goto out_unlock; + i = 0; + goto out; } + submit->bos[i].handle = submit_bo.handle; submit->bos[i].flags = submit_bo.flags; /* in validate_objects() we figure out if this is true: */ submit->bos[i].iova = submit_bo.presumed; + } + + spin_lock(&file->table_lock); + + for (i = 0; i < args->nr_bos; i++) { + struct drm_gem_object *obj; + struct msm_gem_object *msm_obj; /* normally use drm_gem_object_lookup(), but for bulk lookup * all under single table_lock just hit object_idr directly: */ - obj = idr_find(&file->object_idr, submit_bo.handle); + obj = idr_find(&file->object_idr, submit->bos[i].handle); if (!obj) { - DRM_ERROR("invalid handle %u at index %u\n", submit_bo.handle, i); + DRM_ERROR("invalid handle %u at index %u\n", submit->bos[i].handle, i); ret = -EINVAL; goto out_unlock; } @@ -142,7 +133,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, if (!list_empty(&msm_obj->submit_entry)) { DRM_ERROR("handle %u at index %u already on submit list\n", - submit_bo.handle, i); + submit->bos[i].handle, i); ret = -EINVAL; goto out_unlock; } @@ -155,7 +146,6 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, } out_unlock: - pagefault_enable(); spin_unlock(&file->table_lock); out: -- cgit v1.2.3 From a9e2559c931d7c44ae7d677b12093956ffa864b9 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 19 Apr 2019 13:46:14 -0600 Subject: drm/msm/gpu: Move zap shader loading to adreno a5xx and a6xx both share (mostly) the same code to load the zap shader and bring the GPU out of secure mode. Move the formerly 5xx specific code to adreno to make it available for a6xx too. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 111 +------------------------- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 135 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/adreno/adreno_gpu.h | 6 ++ 3 files changed, 142 insertions(+), 110 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 270da14cba67..e5fcefa49f19 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -15,9 +15,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -30,96 +27,6 @@ static void a5xx_dump(struct msm_gpu *gpu); #define GPU_PAS_ID 13 -static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname) -{ - struct device *dev = &gpu->pdev->dev; - const struct firmware *fw; - struct device_node *np, *mem_np; - struct resource r; - phys_addr_t mem_phys; - ssize_t mem_size; - void *mem_region = NULL; - int ret; - - if (!IS_ENABLED(CONFIG_ARCH_QCOM)) - return -EINVAL; - - np = of_get_child_by_name(dev->of_node, "zap-shader"); - if (!np) - return -ENODEV; - - mem_np = of_parse_phandle(np, "memory-region", 0); - of_node_put(np); - if (!mem_np) - return -EINVAL; - - ret = of_address_to_resource(mem_np, 0, &r); - of_node_put(mem_np); - if (ret) - return ret; - - mem_phys = r.start; - mem_size = resource_size(&r); - - /* Request the MDT file for the firmware */ - fw = adreno_request_fw(to_adreno_gpu(gpu), fwname); - if (IS_ERR(fw)) { - DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname); - return PTR_ERR(fw); - } - - /* Figure out how much memory we need */ - mem_size = qcom_mdt_get_size(fw); - if (mem_size < 0) { - ret = mem_size; - goto out; - } - - /* Allocate memory for the firmware image */ - mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC); - if (!mem_region) { - ret = -ENOMEM; - goto out; - } - - /* - * Load the rest of the MDT - * - * Note that we could be dealing with two different paths, since - * with upstream linux-firmware it would be in a qcom/ subdir.. - * adreno_request_fw() handles this, but qcom_mdt_load() does - * not. But since we've already gotten thru adreno_request_fw() - * we know which of the two cases it is: - */ - if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) { - ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID, - mem_region, mem_phys, mem_size, NULL); - } else { - char *newname; - - newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname); - - ret = qcom_mdt_load(dev, fw, newname, GPU_PAS_ID, - mem_region, mem_phys, mem_size, NULL); - kfree(newname); - } - if (ret) - goto out; - - /* Send the image to the secure world */ - ret = qcom_scm_pas_auth_and_reset(GPU_PAS_ID); - if (ret) - DRM_DEV_ERROR(dev, "Unable to authorize the image\n"); - -out: - if (mem_region) - memunmap(mem_region); - - release_firmware(fw); - - return ret; -} - static void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -565,8 +472,6 @@ static int a5xx_zap_shader_resume(struct msm_gpu *gpu) static int a5xx_zap_shader_init(struct msm_gpu *gpu) { static bool loaded; - struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - struct platform_device *pdev = gpu->pdev; int ret; /* @@ -576,23 +481,9 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu) if (loaded) return a5xx_zap_shader_resume(gpu); - /* We need SCM to be able to load the firmware */ - if (!qcom_scm_is_available()) { - DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n"); - return -EPROBE_DEFER; - } - - /* Each GPU has a target specific zap shader firmware name to use */ - if (!adreno_gpu->info->zapfw) { - DRM_DEV_ERROR(&pdev->dev, - "Zap shader firmware file not specified for this target\n"); - return -ENODEV; - } - - ret = zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw); + ret = adreno_zap_shader_load(gpu, GPU_PAS_ID); loaded = !ret; - return ret; } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 6de08cfc38aa..6f7f4114afcf 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -19,13 +19,148 @@ #include #include +#include #include +#include #include #include +#include #include "adreno_gpu.h" #include "msm_gem.h" #include "msm_mmu.h" +static bool zap_available = true; + +static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname, + u32 pasid) +{ + struct device *dev = &gpu->pdev->dev; + const struct firmware *fw; + struct device_node *np, *mem_np; + struct resource r; + phys_addr_t mem_phys; + ssize_t mem_size; + void *mem_region = NULL; + int ret; + + if (!IS_ENABLED(CONFIG_ARCH_QCOM)) { + zap_available = false; + return -EINVAL; + } + + np = of_get_child_by_name(dev->of_node, "zap-shader"); + if (!np) { + zap_available = false; + return -ENODEV; + } + + mem_np = of_parse_phandle(np, "memory-region", 0); + of_node_put(np); + if (!mem_np) { + zap_available = false; + return -EINVAL; + } + + ret = of_address_to_resource(mem_np, 0, &r); + of_node_put(mem_np); + if (ret) + return ret; + + mem_phys = r.start; + mem_size = resource_size(&r); + + /* Request the MDT file for the firmware */ + fw = adreno_request_fw(to_adreno_gpu(gpu), fwname); + if (IS_ERR(fw)) { + DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname); + return PTR_ERR(fw); + } + + /* Figure out how much memory we need */ + mem_size = qcom_mdt_get_size(fw); + if (mem_size < 0) { + ret = mem_size; + goto out; + } + + /* Allocate memory for the firmware image */ + mem_region = memremap(mem_phys, mem_size, MEMREMAP_WC); + if (!mem_region) { + ret = -ENOMEM; + goto out; + } + + /* + * Load the rest of the MDT + * + * Note that we could be dealing with two different paths, since + * with upstream linux-firmware it would be in a qcom/ subdir.. + * adreno_request_fw() handles this, but qcom_mdt_load() does + * not. But since we've already gotten through adreno_request_fw() + * we know which of the two cases it is: + */ + if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) { + ret = qcom_mdt_load(dev, fw, fwname, pasid, + mem_region, mem_phys, mem_size, NULL); + } else { + char *newname; + + newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname); + + ret = qcom_mdt_load(dev, fw, newname, pasid, + mem_region, mem_phys, mem_size, NULL); + kfree(newname); + } + if (ret) + goto out; + + /* Send the image to the secure world */ + ret = qcom_scm_pas_auth_and_reset(pasid); + + /* + * If the scm call returns -EOPNOTSUPP we assume that this target + * doesn't need/support the zap shader so quietly fail + */ + if (ret == -EOPNOTSUPP) + zap_available = false; + else if (ret) + DRM_DEV_ERROR(dev, "Unable to authorize the image\n"); + +out: + if (mem_region) + memunmap(mem_region); + + release_firmware(fw); + + return ret; +} + +int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct platform_device *pdev = gpu->pdev; + + /* Short cut if we determine the zap shader isn't available/needed */ + if (!zap_available) + return -ENODEV; + + /* We need SCM to be able to load the firmware */ + if (!qcom_scm_is_available()) { + DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n"); + return -EPROBE_DEFER; + } + + /* Each GPU has a target specific zap shader firmware name to use */ + if (!adreno_gpu->info->zapfw) { + zap_available = false; + DRM_DEV_ERROR(&pdev->dev, + "Zap shader firmware file not specified for this target\n"); + return -ENODEV; + } + + return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid); +} + int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 5db459bc28a7..0925606ec9b5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -252,6 +252,12 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state); int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state); int adreno_gpu_state_put(struct msm_gpu_state *state); +/* + * For a5xx and a6xx targets load the zap shader that is used to pull the GPU + * out of secure mode + */ +int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid); + /* ringbuffer helpers (the parts that are adreno specific) */ static inline void -- cgit v1.2.3 From abccb9fe326743b72c8099d5cc039e9038bc50da Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 19 Apr 2019 13:46:15 -0600 Subject: drm/msm/a6xx: Add zap shader load The a6xx GPU powers on in secure mode which restricts what memory it can write to. To get out of secure mode the GPU driver can write to REG_A6XX_RBBM_SECVID_TRUST_CNTL but on targets that are "secure" that register region is blocked and writes will cause the system to go down. For those targets we need to execute a special sequence that involves loadinga special shader that clears the GPU registers and use a PM4 sequence to pull the GPU out of secure. Add support for loading the zap shader and executing the secure sequence. For targets that do not support SCM or the specific SCM sequence this should fail and we would fall back to writing the register. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 38 +++++++++++++++++++++++++++++- drivers/gpu/drm/msm/adreno/adreno_device.c | 1 + 2 files changed, 38 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 576559a3a523..7028bb784427 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -10,6 +10,8 @@ #include +#define GPU_PAS_ID 13 + static inline bool _a6xx_check_idle(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -343,6 +345,20 @@ static int a6xx_ucode_init(struct msm_gpu *gpu) return 0; } +static int a6xx_zap_shader_init(struct msm_gpu *gpu) +{ + static bool loaded; + int ret; + + if (loaded) + return 0; + + ret = adreno_zap_shader_load(gpu, GPU_PAS_ID); + + loaded = !ret; + return ret; +} + #define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \ A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \ A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \ @@ -491,7 +507,27 @@ static int a6xx_hw_init(struct msm_gpu *gpu) if (ret) goto out; - gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0); + /* + * Try to load a zap shader into the secure world. If successful + * we can use the CP to switch out of secure mode. If not then we + * have no resource but to try to switch ourselves out manually. If we + * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will + * be blocked and a permissions violation will soon follow. + */ + ret = a6xx_zap_shader_init(gpu); + if (!ret) { + OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1); + OUT_RING(gpu->rb[0], 0x00000000); + + a6xx_flush(gpu, gpu->rb[0]); + if (!a6xx_idle(gpu, gpu->rb[0])) + return -EINVAL; + } else { + /* Print a warning so if we die, we know why */ + dev_warn_once(gpu->dev->dev, + "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n"); + gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0); + } out: /* diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 0d87db75b710..b907245d3d96 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -155,6 +155,7 @@ static const struct adreno_info gpulist[] = { .gmem = SZ_1M, .inactive_period = DRM_MSM_INACTIVE_PERIOD, .init = a6xx_gpu_init, + .zapfw = "a630_zap.mdt", }, }; -- cgit v1.2.3 From b02872df58aca66d0e7af3ec5065dbc6f0630dd1 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 10 Apr 2019 10:58:16 -0600 Subject: drm/msm/a6xx: Don't enable GPU state code if dependencies are missing Add CONFIG_DRM_MSM_GPU_STATE to conditionally compile Adreno GPU state code depending on the availability of the dependencies. Reported-by: Hulk Robot Reported-by: YueHaibing Fixes: 1707add81551 ("drm/msm/a6xx: Add a6xx gpu state") Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Kconfig | 5 +++++ drivers/gpu/drm/msm/Makefile | 3 ++- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 +++- drivers/gpu/drm/msm/msm_debugfs.c | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 78c9e5a5e793..9f2029eca39f 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -21,6 +21,11 @@ config DRM_MSM help DRM/KMS driver for MSM/snapdragon. +config DRM_MSM_GPU_STATE + bool + depends on DRM_MSM && (DEBUG_FS || DEV_COREDUMP) + default y + config DRM_MSM_REGISTER_LOGGING bool "MSM DRM register logging" depends on DRM_MSM diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 56a70c74af4e..72d1bfcaab7a 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -15,7 +15,6 @@ msm-y := \ adreno/a6xx_gpu.o \ adreno/a6xx_gmu.o \ adreno/a6xx_hfi.o \ - adreno/a6xx_gpu_state.o \ hdmi/hdmi.o \ hdmi/hdmi_audio.o \ hdmi/hdmi_bridge.o \ @@ -96,6 +95,8 @@ msm-y := \ msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o +msm-$(CONFIG_DRM_MSM_GPU_STATE) += adreno/a6xx_gpu_state.o + msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o msm-$(CONFIG_COMMON_CLK) += hdmi/hdmi_pll_8960.o diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 7028bb784427..ec24508b9d68 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -807,14 +807,16 @@ static const struct adreno_gpu_funcs funcs = { .active_ring = a6xx_active_ring, .irq = a6xx_irq, .destroy = a6xx_destroy, -#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) +#if defined(CONFIG_DRM_MSM_GPU_STATE) .show = a6xx_show, #endif .gpu_busy = a6xx_gpu_busy, .gpu_get_freq = a6xx_gmu_get_freq, .gpu_set_freq = a6xx_gmu_set_freq, +#if defined(CONFIG_DRM_MSM_GPU_STATE) .gpu_state_get = a6xx_gpu_state_get, .gpu_state_put = a6xx_gpu_state_put, +#endif }, .get_timestamp = a6xx_get_timestamp, }; diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index fb423d309e91..67ef300559cf 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -75,7 +75,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file) struct msm_gpu_show_priv *show_priv; int ret; - if (!gpu) + if (!gpu || !gpu->funcs->gpu_state_get) return -ENODEV; show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL); -- cgit v1.2.3 From 45516e91c2707f38bd78da4fca5558eaf3d2cddd Mon Sep 17 00:00:00 2001 From: Chengming Gui Date: Wed, 27 Mar 2019 11:30:00 +0800 Subject: drm/amd/powerplay: add set/get_power_profile_mode for Raven (v2) The power profile allows the user to adjust the power state heuristics for clock level transitions. v2: squash in warning fix (Alex) Reviewed-by: Evan Quan Reviewed-by: Huang Rui Signed-off-by: Chengming Gui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 91 +++++++++++++++++++++++ drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h | 1 - drivers/gpu/drm/amd/powerplay/inc/smu10.h | 14 ++-- 3 files changed, 99 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index f32e3d0aaea6..bbb9b1ecf9e1 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -35,6 +35,7 @@ #include "smu10_hwmgr.h" #include "power_state.h" #include "soc15_common.h" +#include "smu10.h" #define SMU10_MAX_DEEPSLEEP_DIVIDER_ID 5 #define SMU10_MINIMUM_ENGINE_CLOCK 800 /* 8Mhz, the low boundary of engine clock allowed on this chip */ @@ -1200,6 +1201,94 @@ static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, bool bgate) } } +static int conv_power_profile_to_pplib_workload(int power_profile) +{ + int pplib_workload = 0; + + switch (power_profile) { + case PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT: + pplib_workload = WORKLOAD_DEFAULT_BIT; + break; + case PP_SMC_POWER_PROFILE_FULLSCREEN3D: + pplib_workload = WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT; + break; + case PP_SMC_POWER_PROFILE_POWERSAVING: + pplib_workload = WORKLOAD_PPLIB_POWER_SAVING_BIT; + break; + case PP_SMC_POWER_PROFILE_VIDEO: + pplib_workload = WORKLOAD_PPLIB_VIDEO_BIT; + break; + case PP_SMC_POWER_PROFILE_VR: + pplib_workload = WORKLOAD_PPLIB_VR_BIT; + break; + case PP_SMC_POWER_PROFILE_COMPUTE: + pplib_workload = WORKLOAD_PPLIB_COMPUTE_BIT; + break; + } + + return pplib_workload; +} + +static int smu10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) +{ + uint32_t i, size = 0; + static const uint8_t + profile_mode_setting[6][4] = {{70, 60, 0, 0,}, + {70, 60, 1, 3,}, + {90, 60, 0, 0,}, + {70, 60, 0, 0,}, + {70, 90, 0, 0,}, + {30, 60, 0, 6,}, + }; + static const char *profile_name[6] = { + "BOOTUP_DEFAULT", + "3D_FULL_SCREEN", + "POWER_SAVING", + "VIDEO", + "VR", + "COMPUTE"}; + static const char *title[6] = {"NUM", + "MODE_NAME", + "BUSY_SET_POINT", + "FPS", + "USE_RLC_BUSY", + "MIN_ACTIVE_LEVEL"}; + + if (!buf) + return -EINVAL; + + size += sprintf(buf + size, "%s %16s %s %s %s %s\n",title[0], + title[1], title[2], title[3], title[4], title[5]); + + for (i = 0; i <= PP_SMC_POWER_PROFILE_COMPUTE; i++) + size += sprintf(buf + size, "%3d %14s%s: %14d %3d %10d %14d\n", + i, profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ", + profile_mode_setting[i][0], profile_mode_setting[i][1], + profile_mode_setting[i][2], profile_mode_setting[i][3]); + + return size; +} + +static int smu10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size) +{ + int workload_type = 0; + + if (input[size] > PP_SMC_POWER_PROFILE_COMPUTE) { + pr_err("Invalid power profile mode %ld\n", input[size]); + return -EINVAL; + } + hwmgr->power_profile_mode = input[size]; + + /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ + workload_type = + conv_power_profile_to_pplib_workload(hwmgr->power_profile_mode); + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_ActiveProcessNotify, + 1 << workload_type); + + return 0; +} + + static const struct pp_hwmgr_func smu10_hwmgr_funcs = { .backend_init = smu10_hwmgr_backend_init, .backend_fini = smu10_hwmgr_backend_fini, @@ -1241,6 +1330,8 @@ static const struct pp_hwmgr_func smu10_hwmgr_funcs = { .powergate_sdma = smu10_powergate_sdma, .set_hard_min_dcefclk_by_freq = smu10_set_hard_min_dcefclk_by_freq, .set_hard_min_fclk_by_freq = smu10_set_hard_min_fclk_by_freq, + .get_power_profile_mode = smu10_get_power_profile_mode, + .set_power_profile_mode = smu10_set_power_profile_mode, }; int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h index a2991fa2e6f8..90879e4092a3 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h +++ b/drivers/gpu/drm/amd/powerplay/inc/rv_ppsmc.h @@ -85,7 +85,6 @@ #define PPSMC_MSG_SetRccPfcPmeRestoreRegister 0x36 #define PPSMC_Message_Count 0x37 - typedef uint16_t PPSMC_Result; typedef int PPSMC_Msg; diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu10.h b/drivers/gpu/drm/amd/powerplay/inc/smu10.h index 9e837a5014c5..b96520528240 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smu10.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smu10.h @@ -136,12 +136,14 @@ #define FEATURE_CORE_CSTATES_MASK (1 << FEATURE_CORE_CSTATES_BIT) /* Workload bits */ -#define WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT 0 -#define WORKLOAD_PPLIB_VIDEO_BIT 2 -#define WORKLOAD_PPLIB_VR_BIT 3 -#define WORKLOAD_PPLIB_COMPUTE_BIT 4 -#define WORKLOAD_PPLIB_CUSTOM_BIT 5 -#define WORKLOAD_PPLIB_COUNT 6 +#define WORKLOAD_DEFAULT_BIT 0 +#define WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT 1 +#define WORKLOAD_PPLIB_POWER_SAVING_BIT 2 +#define WORKLOAD_PPLIB_VIDEO_BIT 3 +#define WORKLOAD_PPLIB_VR_BIT 4 +#define WORKLOAD_PPLIB_COMPUTE_BIT 5 +#define WORKLOAD_PPLIB_CUSTOM_BIT 6 +#define WORKLOAD_PPLIB_COUNT 7 typedef struct { /* MP1_EXT_SCRATCH0 */ -- cgit v1.2.3 From 8d01071d26634d6c577f92911177a882935597a3 Mon Sep 17 00:00:00 2001 From: Chengming Gui Date: Mon, 22 Apr 2019 16:35:39 +0800 Subject: drm/amd/powerplay: enable UMDPSTATE support on raven2 (v2) enable UMDPSTATE support to force performance level for raven2. v2: squash in warning fix (Alex) Signed-off-by: Chengming Gui Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index bbb9b1ecf9e1..5f5dec9b97e2 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -573,7 +573,6 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level) { struct smu10_hwmgr *data = hwmgr->backend; - struct amdgpu_device *adev = hwmgr->adev; uint32_t min_sclk = hwmgr->display_config->min_core_set_clock; uint32_t min_mclk = hwmgr->display_config->min_mem_set_clock/100; @@ -582,11 +581,6 @@ static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, return 0; } - /* Disable UMDPSTATE support on rv2 temporarily */ - if ((adev->asic_type == CHIP_RAVEN) && - (adev->rev_id >= 8)) - return 0; - if (min_sclk < data->gfx_min_freq_limit) min_sclk = data->gfx_min_freq_limit; -- cgit v1.2.3 From 77e7f82985fd205c66b49fdbf4271e389d8506cc Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Thu, 18 Apr 2019 18:45:31 -0400 Subject: drm/amdgpu: Change VRAM lost print from ERR to INF It's normal for VRAM to lost during GPU reset and so change the log level to INFO to avoid confusing users. Signed-off-by: Andrey Grodzovsky Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 3f08be7a913e..b726e1ea4a77 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3432,7 +3432,7 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, vram_lost = amdgpu_device_check_vram_lost(tmp_adev); if (vram_lost) { - DRM_ERROR("VRAM is lost!\n"); + DRM_INFO("VRAM is lost due to GPU reset!\n"); atomic_inc(&tmp_adev->vram_lost_counter); } -- cgit v1.2.3 From 2fac0f53fe5921264c525a0439ee9baf0fe9ada1 Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 2 Apr 2019 16:28:13 +0200 Subject: drm/amd/display: wait for fence without holding reservation lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't block others while waiting for the fences to finish, concurrent submission is perfectly valid in this case and holding the lock can prevent killed applications from terminating. Signed-off-by: Christian König Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fb248984b7ba..36331e70fa83 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5205,23 +5205,26 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, continue; } + abo = gem_to_amdgpu_bo(fb->obj[0]); + + /* Wait for all fences on this FB */ + r = reservation_object_wait_timeout_rcu(abo->tbo.resv, true, + false, + MAX_SCHEDULE_TIMEOUT); + WARN_ON(r < 0); + /* * TODO This might fail and hence better not used, wait * explicitly on fences instead * and in general should be called for * blocking commit to as per framework helpers */ - abo = gem_to_amdgpu_bo(fb->obj[0]); r = amdgpu_bo_reserve(abo, true); if (unlikely(r != 0)) { DRM_ERROR("failed to reserve buffer before flip\n"); WARN_ON(1); } - /* Wait for all fences on this FB */ - WARN_ON(reservation_object_wait_timeout_rcu(abo->tbo.resv, true, false, - MAX_SCHEDULE_TIMEOUT) < 0); - amdgpu_bo_get_tiling_flags(abo, &tiling_flags); amdgpu_bo_unreserve(abo); -- cgit v1.2.3 From f83088981a431f8ee13ebc442cfccbecb0ed95bf Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Mon, 15 Apr 2019 10:57:14 -0400 Subject: drm/amd/display: Use a reasonable timeout for framebuffer fence waits Patch '5edb0c9b Fix deadlock with display during hanged ring recovery' was accidentaly removed during one of DALs code merges. Signed-off-by: Andrey Grodzovsky Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 36331e70fa83..a3dc7ab523de 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5207,11 +5207,16 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, abo = gem_to_amdgpu_bo(fb->obj[0]); - /* Wait for all fences on this FB */ + /* + * Wait for all fences on this FB. Do limited wait to avoid + * deadlock during GPU reset when this fence will not signal + * but we hold reservation lock for the BO. + */ r = reservation_object_wait_timeout_rcu(abo->tbo.resv, true, false, - MAX_SCHEDULE_TIMEOUT); - WARN_ON(r < 0); + msecs_to_jiffies(5000)); + if (unlikely(r <= 0)) + DRM_ERROR("Waiting for fences timed out or interrupted!"); /* * TODO This might fail and hence better not used, wait @@ -5220,10 +5225,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, * blocking commit to as per framework helpers */ r = amdgpu_bo_reserve(abo, true); - if (unlikely(r != 0)) { + if (unlikely(r != 0)) DRM_ERROR("failed to reserve buffer before flip\n"); - WARN_ON(1); - } amdgpu_bo_get_tiling_flags(abo, &tiling_flags); -- cgit v1.2.3 From 3b8cea6f645c909783455265f2cb0fb64fd68f51 Mon Sep 17 00:00:00 2001 From: Leo Li Date: Mon, 15 Apr 2019 20:57:36 -0400 Subject: drm/amd/include: Add HUBPREQ_DEBUG register offsets They will be used by DC when runing ASIC-specific HUBP initialization. Signed-off-by: Leo Li Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h index 721c61171045..5a44e614ab7e 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dcn/dcn_1_0_offset.h @@ -2347,6 +2347,8 @@ #define mmHUBP0_DCHUBP_VMPG_CONFIG_BASE_IDX 2 #define mmHUBP0_HUBPREQ_DEBUG_DB 0x0569 #define mmHUBP0_HUBPREQ_DEBUG_DB_BASE_IDX 2 +#define mmHUBP0_HUBPREQ_DEBUG 0x056a +#define mmHUBP0_HUBPREQ_DEBUG_BASE_IDX 2 #define mmHUBP0_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x056e #define mmHUBP0_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2 #define mmHUBP0_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x056f @@ -2631,6 +2633,8 @@ #define mmHUBP1_DCHUBP_VMPG_CONFIG_BASE_IDX 2 #define mmHUBP1_HUBPREQ_DEBUG_DB 0x062d #define mmHUBP1_HUBPREQ_DEBUG_DB_BASE_IDX 2 +#define mmHUBP1_HUBPREQ_DEBUG 0x062e +#define mmHUBP1_HUBPREQ_DEBUG_BASE_IDX 2 #define mmHUBP1_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x0632 #define mmHUBP1_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2 #define mmHUBP1_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x0633 @@ -2915,6 +2919,8 @@ #define mmHUBP2_DCHUBP_VMPG_CONFIG_BASE_IDX 2 #define mmHUBP2_HUBPREQ_DEBUG_DB 0x06f1 #define mmHUBP2_HUBPREQ_DEBUG_DB_BASE_IDX 2 +#define mmHUBP2_HUBPREQ_DEBUG 0x06f2 +#define mmHUBP2_HUBPREQ_DEBUG_BASE_IDX 2 #define mmHUBP2_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x06f6 #define mmHUBP2_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2 #define mmHUBP2_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x06f7 @@ -3199,6 +3205,8 @@ #define mmHUBP3_DCHUBP_VMPG_CONFIG_BASE_IDX 2 #define mmHUBP3_HUBPREQ_DEBUG_DB 0x07b5 #define mmHUBP3_HUBPREQ_DEBUG_DB_BASE_IDX 2 +#define mmHUBP3_HUBPREQ_DEBUG 0x07b6 +#define mmHUBP3_HUBPREQ_DEBUG_BASE_IDX 2 #define mmHUBP3_HUBP_MEASURE_WIN_CTRL_DCFCLK 0x07ba #define mmHUBP3_HUBP_MEASURE_WIN_CTRL_DCFCLK_BASE_IDX 2 #define mmHUBP3_HUBP_MEASURE_WIN_CTRL_DPPCLK 0x07bb -- cgit v1.2.3 From bb20be7510203db17c6c09f888cf328e307f1701 Mon Sep 17 00:00:00 2001 From: Leo Li Date: Thu, 18 Apr 2019 11:53:58 -0400 Subject: drm/amdgpu: Check if SW SMU is supported before accessing funcs smu.ppt_funcs is only initialized for ASICs supporting SW SMU. On a Hawaii ASIC, attempting to access the udev attribute ATTRS{power_dpm_state} will cause a null pointer deref in amdgpu_get_dpm_state() because of this. Fix by checking if SW SMU is supported first. Signed-off-by: Leo Li Reviewed-by: Alex Deucher Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 4b7a076eea9c..95144e49c7f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -144,7 +144,7 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev, struct amdgpu_device *adev = ddev->dev_private; enum amd_pm_state_type pm; - if (adev->smu.ppt_funcs->get_current_power_state) + if (is_support_sw_smu(adev) && adev->smu.ppt_funcs->get_current_power_state) pm = amdgpu_smu_get_current_power_state(adev); else if (adev->powerplay.pp_funcs->get_current_power_state) pm = amdgpu_dpm_get_current_power_state(adev); -- cgit v1.2.3 From 41629f02c604546e24a911413b99cd9d80e842db Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Wed, 3 Apr 2019 16:59:56 -0400 Subject: drm/amd/display: Allow system to enter stutter on init [Why] Workaround was missing in one HW disable path, meaning when all pipes are power gated, stutter was not working [How] Add workaround for init_hw path for stutter workaround Signed-off-by: Anthony Koo Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index dab370676bfa..f0cc7c9c9de3 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1126,6 +1126,8 @@ static void dcn10_init_hw(struct dc *dc) dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst; plane_atomic_power_down(dc, dpp, hubp); } + + apply_DEGVIDCN10_253_wa(dc); } for (i = 0; i < dc->res_pool->audio_count; i++) { -- cgit v1.2.3 From 43e3ac8389ef68ab2347eb1ae4a6e5b49793614e Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Fri, 29 Mar 2019 18:22:16 -0400 Subject: drm/amd/display: Add function to copy DC streams We'll need the ability to copy a dc_stream_state for some features. Implement it here. Signed-off-by: Wenjing Liu Reviewed-by: Jun Lei Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 21 +++++++++++++++++++++ drivers/gpu/drm/amd/display/dc/dc_stream.h | 2 ++ 2 files changed, 23 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index e10479d58c11..09d765f359b0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -163,6 +163,27 @@ struct dc_stream_state *dc_create_stream_for_sink( return stream; } +struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream) +{ + struct dc_stream_state *new_stream; + + new_stream = kzalloc(sizeof(struct dc_stream_state), GFP_KERNEL); + if (stream == NULL) + return NULL; + + memcpy(new_stream, stream, sizeof(struct dc_stream_state)); + + if (new_stream->sink) + dc_sink_retain(new_stream->sink); + + if (new_stream->out_transfer_func) + dc_transfer_func_retain(new_stream->out_transfer_func); + + kref_init(&new_stream->refcount); + + return new_stream; +} + /** * dc_stream_get_status_from_state - Get stream status from given dc state * @state: DC state to find the stream status in diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 17fa3bf6cf7b..189bdab929a5 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -307,6 +307,8 @@ enum surface_update_type dc_check_update_surfaces_for_stream( */ struct dc_stream_state *dc_create_stream_for_sink(struct dc_sink *dc_sink); +struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream); + void update_stream_signal(struct dc_stream_state *stream, struct dc_sink *sink); void dc_stream_retain(struct dc_stream_state *dc_stream); -- cgit v1.2.3 From abdef7558358ea34c7ad03edc8c82557d0c1df51 Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Thu, 4 Apr 2019 09:44:55 -0400 Subject: drm/amd/display: Send DMCU messages only if FW loaded [Why] Some DMCU messages were being sent in cases where there was no DMCU FW at all, which resulted in some wait timeouts [How] Delay sending some of the DMCU messages after FW init is called and DMCU is running. Signed-off-by: Anthony Koo Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce/dce_abm.c | 18 ---------------- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 31 ++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 19 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index 855360b1414f..da96229db53a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -50,7 +50,6 @@ #define MCP_ABM_LEVEL_SET 0x65 #define MCP_ABM_PIPE_SET 0x66 #define MCP_BL_SET 0x67 -#define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ #define MCP_DISABLE_ABM_IMMEDIATELY 255 @@ -391,23 +390,6 @@ static bool dce_abm_init_backlight(struct abm *abm) REG_UPDATE(BL_PWM_GRP1_REG_LOCK, BL_PWM_GRP1_REG_LOCK, 0); - /* Wait until microcontroller is ready to process interrupt */ - REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800); - - /* Set PWM fractional enable/disable */ - value = (abm->ctx->dc->config.disable_fractional_pwm == false) ? 1 : 0; - REG_WRITE(MASTER_COMM_DATA_REG1, value); - - /* Set command to enable or disable fractional PWM microcontroller */ - REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, - MCP_BL_SET_PWM_FRAC); - - /* Notify microcontroller of new command */ - REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); - - /* Ensure command has been executed before continuing */ - REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800); - return true; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index aa586672e8cd..9ad7c543cc4c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -51,6 +51,7 @@ #define PSR_SET_WAITLOOP 0x31 #define MCP_INIT_DMCU 0x88 #define MCP_INIT_IRAM 0x89 +#define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L static bool dce_dmcu_init(struct dmcu *dmcu) @@ -339,9 +340,32 @@ static void dcn10_get_dmcu_version(struct dmcu *dmcu) IRAM_RD_ADDR_AUTO_INC, 0); } +static void dcn10_dmcu_enable_fractional_pwm(struct dmcu *dmcu, + uint32_t fractional_pwm) +{ + struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + + /* Wait until microcontroller is ready to process interrupt */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800); + + /* Set PWM fractional enable/disable */ + REG_WRITE(MASTER_COMM_DATA_REG1, fractional_pwm); + + /* Set command to enable or disable fractional PWM microcontroller */ + REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0, + MCP_BL_SET_PWM_FRAC); + + /* Notify microcontroller of new command */ + REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); + + /* Ensure command has been executed before continuing */ + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800); +} + static bool dcn10_dmcu_init(struct dmcu *dmcu) { struct dce_dmcu *dmcu_dce = TO_DCE_DMCU(dmcu); + const struct dc_config *config = &dmcu->ctx->dc->config; bool status = false; /* Definition of DC_DMCU_SCRATCH @@ -379,9 +403,14 @@ static bool dcn10_dmcu_init(struct dmcu *dmcu) if (dmcu->dmcu_state == DMCU_RUNNING) { /* Retrieve and cache the DMCU firmware version. */ dcn10_get_dmcu_version(dmcu); + + /* Initialize DMCU to use fractional PWM or not */ + dcn10_dmcu_enable_fractional_pwm(dmcu, + (config->disable_fractional_pwm == false) ? 1 : 0); status = true; - } else + } else { status = false; + } break; case DMCU_RUNNING: -- cgit v1.2.3 From 5b7c0d8d2bade0f743009e5c2deb541792e0e963 Mon Sep 17 00:00:00 2001 From: Anthony Koo Date: Thu, 4 Apr 2019 14:42:44 -0400 Subject: drm/amd/display: Fix eDP Black screen after S4 resume [Why] Power down of PHY on eDP requires us to call eDP power control to power on again [How] 1. In the case link rates don't match, disable PHY requires calling of eDP power control ON after 2. Link disable case limit to eDP path since this is not really applicable to DP since we do power down PHY as part of verify link cap 3. Move detection of eDP link settings to be done even for S4 resume cases where other dpcd cap read and edid read can be skipped Signed-off-by: Anthony Koo Reviewed-by: Jun Lei Acked-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 71 ++++++++++++++++++------ drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 30 ---------- 2 files changed, 55 insertions(+), 46 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index 3b1e38e110ee..e449839c2c34 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -514,6 +514,40 @@ static void link_disconnect_remap(struct dc_sink *prev_sink, struct dc_link *lin } +static void read_edp_current_link_settings_on_detect(struct dc_link *link) +{ + union lane_count_set lane_count_set = { {0} }; + uint8_t link_bw_set; + uint8_t link_rate_set; + + // Read DPCD 00101h to find out the number of lanes currently set + core_link_read_dpcd(link, DP_LANE_COUNT_SET, + &lane_count_set.raw, sizeof(lane_count_set)); + link->cur_link_settings.lane_count = lane_count_set.bits.LANE_COUNT_SET; + + // Read DPCD 00100h to find if standard link rates are set + core_link_read_dpcd(link, DP_LINK_BW_SET, + &link_bw_set, sizeof(link_bw_set)); + + if (link_bw_set == 0) { + /* If standard link rates are not being used, + * Read DPCD 00115h to find the link rate set used + */ + core_link_read_dpcd(link, DP_LINK_RATE_SET, + &link_rate_set, sizeof(link_rate_set)); + + if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { + link->cur_link_settings.link_rate = + link->dpcd_caps.edp_supported_link_rates[link_rate_set]; + link->cur_link_settings.link_rate_set = link_rate_set; + link->cur_link_settings.use_link_rate_set = true; + } + } else { + link->cur_link_settings.link_rate = link_bw_set; + link->cur_link_settings.use_link_rate_set = false; + } +} + static bool detect_dp( struct dc_link *link, struct display_sink_capability *sink_caps, @@ -648,9 +682,14 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason) return false; } - if (link->connector_signal == SIGNAL_TYPE_EDP && - link->local_sink) - return true; + if (link->connector_signal == SIGNAL_TYPE_EDP) { + /* On detect, we want to make sure current link settings are + * up to date, especially if link was powered on by GOP. + */ + read_edp_current_link_settings_on_detect(link); + if (link->local_sink) + return true; + } if (link->connector_signal == SIGNAL_TYPE_LVDS && link->local_sink) @@ -1396,13 +1435,19 @@ static enum dc_status enable_link_dp( /* get link settings for video mode timing */ decide_link_settings(stream, &link_settings); - /* If link settings are different than current and link already enabled - * then need to disable before programming to new rate. - */ - if (link->link_status.link_active && - (link->cur_link_settings.lane_count != link_settings.lane_count || - link->cur_link_settings.link_rate != link_settings.link_rate)) { - dp_disable_link_phy(link, pipe_ctx->stream->signal); + if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP) { + /* If link settings are different than current and link already enabled + * then need to disable before programming to new rate. + */ + if (link->link_status.link_active && + (link->cur_link_settings.lane_count != link_settings.lane_count || + link->cur_link_settings.link_rate != link_settings.link_rate)) { + dp_disable_link_phy(link, pipe_ctx->stream->signal); + } + + /*in case it is not on*/ + link->dc->hwss.edp_power_control(link, true); + link->dc->hwss.edp_wait_for_hpd_ready(link, true); } pipe_ctx->stream_res.pix_clk_params.requested_sym_clk = @@ -1448,15 +1493,9 @@ static enum dc_status enable_link_edp( struct pipe_ctx *pipe_ctx) { enum dc_status status; - struct dc_stream_state *stream = pipe_ctx->stream; - struct dc_link *link = stream->link; - /*in case it is not on*/ - link->dc->hwss.edp_power_control(link, true); - link->dc->hwss.edp_wait_for_hpd_ready(link, true); status = enable_link_dp(state, pipe_ctx); - return status; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index a6424c70f4c5..64a309a5e1c9 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2586,9 +2586,6 @@ void detect_edp_sink_caps(struct dc_link *link) uint32_t entry; uint32_t link_rate_in_khz; enum dc_link_rate link_rate = LINK_RATE_UNKNOWN; - union lane_count_set lane_count_set = { {0} }; - uint8_t link_bw_set; - uint8_t link_rate_set; retrieve_link_cap(link); link->dpcd_caps.edp_supported_link_rates_count = 0; @@ -2614,33 +2611,6 @@ void detect_edp_sink_caps(struct dc_link *link) } } link->verified_link_cap = link->reported_link_cap; - - // Read DPCD 00101h to find out the number of lanes currently set - core_link_read_dpcd(link, DP_LANE_COUNT_SET, - &lane_count_set.raw, sizeof(lane_count_set)); - link->cur_link_settings.lane_count = lane_count_set.bits.LANE_COUNT_SET; - - // Read DPCD 00100h to find if standard link rates are set - core_link_read_dpcd(link, DP_LINK_BW_SET, - &link_bw_set, sizeof(link_bw_set)); - - if (link_bw_set == 0) { - /* If standard link rates are not being used, - * Read DPCD 00115h to find the link rate set used - */ - core_link_read_dpcd(link, DP_LINK_RATE_SET, - &link_rate_set, sizeof(link_rate_set)); - - if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { - link->cur_link_settings.link_rate = - link->dpcd_caps.edp_supported_link_rates[link_rate_set]; - link->cur_link_settings.link_rate_set = link_rate_set; - link->cur_link_settings.use_link_rate_set = true; - } - } else { - link->cur_link_settings.link_rate = link_bw_set; - link->cur_link_settings.use_link_rate_set = false; - } } void dc_link_dp_enable_hpd(const struct dc_link *link) -- cgit v1.2.3 From 00ae0af700ccef23d8c2ec76a11bd95c46ebdfd2 Mon Sep 17 00:00:00 2001 From: Aric Cyr Date: Mon, 8 Apr 2019 08:27:18 -0400 Subject: drm/amd/display: 3.2.27 Signed-off-by: Aric Cyr Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 3459e39714bc..aa2954dda129 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -39,7 +39,7 @@ #include "inc/hw/dmcu.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.2.26" +#define DC_VER "3.2.27" #define MAX_SURFACES 3 #define MAX_PLANES 6 -- cgit v1.2.3 From cc602e2b0d78254e41bb81f32e2825f00c7cc69c Mon Sep 17 00:00:00 2001 From: Eric Bernstein Date: Mon, 8 Apr 2019 13:47:10 -0400 Subject: drm/amd/display: Allow cursor position when plane_res.ipp is NULL [Why] Starting with DCN1, the input_pixel_processor (ipp) struct has been replaced by dpp struct (part of DAL3.1 SW architecture change). Need to update logic to handle cases where ipp is never allocated. [How] Only skip cursor position programming if both ipp and dpp resources are NULL. Signed-off-by: Eric Bernstein Reviewed-by: Dmytro Laktyushkin Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 09d765f359b0..6200df3edcd0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -333,7 +333,7 @@ bool dc_stream_set_cursor_position( (!pipe_ctx->plane_res.mi && !pipe_ctx->plane_res.hubp) || !pipe_ctx->plane_state || (!pipe_ctx->plane_res.xfm && !pipe_ctx->plane_res.dpp) || - !pipe_ctx->plane_res.ipp) + (!pipe_ctx->plane_res.ipp && !pipe_ctx->plane_res.dpp)) continue; if (!pipe_to_program) { -- cgit v1.2.3 From a9a3c0da1427153e74a4ad97b1a897384a6b0404 Mon Sep 17 00:00:00 2001 From: Jun Lei Date: Mon, 8 Apr 2019 15:27:53 -0400 Subject: drm/amd/display: add explicit handshake between x86 and DMCU [why] When DMCU interrupts x86, it leads to undefined phy programming [how] expand dmcu interface to support new PHY lock and unlock commands if DMCU FW doesn't support these commands, they fail silently so its okay Signed-off-by: Jun Lei Reviewed-by: Anthony Koo Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 21 ++++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c | 4 +++- drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index f7f7515f65f4..b0dea759cd86 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -58,6 +58,8 @@ void dp_enable_link_phy( const struct dc_link_settings *link_settings) { struct link_encoder *link_enc = link->link_enc; + struct dc *core_dc = link->ctx->dc; + struct dmcu *dmcu = core_dc->res_pool->dmcu; struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx; @@ -84,6 +86,9 @@ void dp_enable_link_phy( } } + if (dmcu != NULL && dmcu->funcs->lock_phy) + dmcu->funcs->lock_phy(dmcu); + if (dc_is_dp_sst_signal(signal)) { link_enc->funcs->enable_dp_output( link_enc, @@ -95,6 +100,10 @@ void dp_enable_link_phy( link_settings, clock_source); } + + if (dmcu != NULL && dmcu->funcs->unlock_phy) + dmcu->funcs->unlock_phy(dmcu); + link->cur_link_settings = *link_settings; dp_receiver_power_ctrl(link, true); @@ -150,15 +159,25 @@ bool edp_receiver_ready_T7(struct dc_link *link) void dp_disable_link_phy(struct dc_link *link, enum signal_type signal) { + struct dc *core_dc = link->ctx->dc; + struct dmcu *dmcu = core_dc->res_pool->dmcu; + if (!link->wa_flags.dp_keep_receiver_powered) dp_receiver_power_ctrl(link, false); if (signal == SIGNAL_TYPE_EDP) { link->link_enc->funcs->disable_output(link->link_enc, signal); link->dc->hwss.edp_power_control(link, false); - } else + } else { + if (dmcu != NULL && dmcu->funcs->lock_phy) + dmcu->funcs->lock_phy(dmcu); + link->link_enc->funcs->disable_output(link->link_enc, signal); + if (dmcu != NULL && dmcu->funcs->unlock_phy) + dmcu->funcs->unlock_phy(dmcu); + } + /* Clear current link setting.*/ memset(&link->cur_link_settings, 0, sizeof(link->cur_link_settings)); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index 9ad7c543cc4c..818536eea00a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -51,6 +51,8 @@ #define PSR_SET_WAITLOOP 0x31 #define MCP_INIT_DMCU 0x88 #define MCP_INIT_IRAM 0x89 +#define MCP_SYNC_PHY_LOCK 0x90 +#define MCP_SYNC_PHY_UNLOCK 0x91 #define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */ #define MASTER_COMM_CNTL_REG__MASTER_COMM_INTERRUPT_MASK 0x00000001L @@ -719,7 +721,7 @@ static bool dcn10_is_dmcu_initialized(struct dmcu *dmcu) return true; } -#endif +#endif //(CONFIG_DRM_AMD_DC_DCN1_0) static const struct dmcu_funcs dce_funcs = { .dmcu_init = dce_dmcu_init, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h index cbaa43853611..c68f0ce346c7 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h @@ -70,6 +70,8 @@ struct dmcu_funcs { void (*get_psr_wait_loop)(struct dmcu *dmcu, unsigned int *psr_wait_loop_number); bool (*is_dmcu_initialized)(struct dmcu *dmcu); + bool (*lock_phy)(struct dmcu *dmcu); + bool (*unlock_phy)(struct dmcu *dmcu); }; #endif -- cgit v1.2.3 From f9af3f846c31b4295bc276c57433215414e84392 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 27 Mar 2019 14:07:09 +0900 Subject: drm/exynos: g2d: remove style error Remove checkpatch error, "foo* bar" should be "foo *bar". Signed-off-by: Seung-Woo Kim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 24c536d6d9cf..a9c26b32e814 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -845,7 +845,7 @@ static void g2d_free_runqueue_node(struct g2d_data *g2d, * * Has to be called under runqueue lock. */ -static void g2d_remove_runqueue_nodes(struct g2d_data *g2d, struct drm_file* file) +static void g2d_remove_runqueue_nodes(struct g2d_data *g2d, struct drm_file *file) { struct g2d_runqueue_node *node, *n; -- cgit v1.2.3 From e59305305c6bf5c1e60e988006e0a9d8da6b3aa1 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 15 Apr 2019 09:32:53 +0900 Subject: drm/fimd: use DRM_ERROR instead of DRM_INFO in error case This patch makes error messages to be printed out using DRM_ERROR instead of DRM_INFO. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 786a8ee6f10f..78427ecd0478 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -400,7 +400,7 @@ static int fimd_atomic_check(struct exynos_drm_crtc *crtc, u32 clkdiv; if (mode->clock == 0) { - DRM_INFO("Mode has zero clock value.\n"); + DRM_ERROR("Mode has zero clock value.\n"); return -EINVAL; } @@ -416,7 +416,7 @@ static int fimd_atomic_check(struct exynos_drm_crtc *crtc, lcd_rate = clk_get_rate(ctx->lcd_clk); if (2 * lcd_rate < ideal_clk) { - DRM_INFO("sclk_fimd clock too low(%lu) for requested pixel clock(%lu)\n", + DRM_ERROR("sclk_fimd clock too low(%lu) for requested pixel clock(%lu)\n", lcd_rate, ideal_clk); return -EINVAL; } @@ -424,7 +424,7 @@ static int fimd_atomic_check(struct exynos_drm_crtc *crtc, /* Find the clock divider value that gets us closest to ideal_clk */ clkdiv = DIV_ROUND_CLOSEST(lcd_rate, ideal_clk); if (clkdiv >= 0x200) { - DRM_INFO("requested pixel clock(%lu) too low\n", ideal_clk); + DRM_ERROR("requested pixel clock(%lu) too low\n", ideal_clk); return -EINVAL; } -- cgit v1.2.3 From 62f28738f1f87c5355fc09ba127665a3c353f7be Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 15 Apr 2019 09:41:15 +0900 Subject: drm/exynos: remove unnecessary messages This patch removes unnecessary messages from fimd_clear_channels and decon_clear_channels functions which print out just function name. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 2 -- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 2 -- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 2 -- 3 files changed, 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 5b4e0e8b23bc..ba5218022402 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -561,8 +561,6 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; int win, i, ret; - DRM_DEBUG_KMS("%s\n", __FILE__); - for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { ret = clk_prepare_enable(ctx->clks[i]); if (ret < 0) diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 381aa3d60e37..a6bb411e4bd3 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -107,8 +107,6 @@ static void decon_clear_channels(struct exynos_drm_crtc *crtc) struct decon_context *ctx = crtc->ctx; unsigned int win, ch_enabled = 0; - DRM_DEBUG_KMS("%s\n", __FILE__); - /* Check if any channel is enabled. */ for (win = 0; win < WINDOWS_NR; win++) { u32 val = readl(ctx->regs + WINCON(win)); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 78427ecd0478..ffb686af287e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -350,8 +350,6 @@ static void fimd_clear_channels(struct exynos_drm_crtc *crtc) struct fimd_context *ctx = crtc->ctx; unsigned int win, ch_enabled = 0; - DRM_DEBUG_KMS("%s\n", __FILE__); - /* Hardware is in unknown state, so ensure it gets enabled properly */ pm_runtime_get_sync(ctx->dev); -- cgit v1.2.3 From 6f83d20838c09936b2884d5b35fed8d208679947 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 15 Apr 2019 14:24:36 +0900 Subject: drm/exynos: use DRM_DEV_ERROR to print out error message This patch just cleans up the use of error log macro, which changes the log macro to DRM_DEV_ERROR. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 2 +- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 14 +++++--- drivers/gpu/drm/exynos/exynos_dp.c | 9 +++-- drivers/gpu/drm/exynos/exynos_drm_dma.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_dpi.c | 9 +++-- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 7 ++-- drivers/gpu/drm/exynos/exynos_drm_fb.c | 9 +++-- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 19 +++++++---- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 7 ++-- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 27 ++++++++++----- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 49 +++++++++++++++------------ drivers/gpu/drm/exynos/exynos_drm_gem.c | 17 +++++----- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 19 ++++++----- drivers/gpu/drm/exynos/exynos_drm_mic.c | 25 ++++++++------ drivers/gpu/drm/exynos/exynos_drm_plane.c | 5 +-- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 11 +++--- drivers/gpu/drm/exynos/exynos_hdmi.c | 42 +++++++++++++---------- drivers/gpu/drm/exynos/exynos_mixer.c | 26 +++++++++----- 18 files changed, 179 insertions(+), 120 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index ba5218022402..c2715e54db90 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -188,7 +188,7 @@ static void decon_setup_trigger(struct decon_context *ctx) if (regmap_update_bits(ctx->sysreg, DSD_CFG_MUX, DSD_CFG_MUX_TE_UNMASK_GLOBAL, ~0)) - DRM_ERROR("Cannot update sysreg.\n"); + DRM_DEV_ERROR(ctx->dev, "Cannot update sysreg.\n"); } static void decon_commit(struct exynos_drm_crtc *crtc) diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index a6bb411e4bd3..bc76f2772e44 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -620,7 +620,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) ret = decon_ctx_initialize(ctx, drm_dev); if (ret) { - DRM_ERROR("decon_ctx_initialize failed.\n"); + DRM_DEV_ERROR(dev, "decon_ctx_initialize failed.\n"); return ret; } @@ -800,25 +800,29 @@ static int exynos7_decon_resume(struct device *dev) ret = clk_prepare_enable(ctx->pclk); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret); + DRM_DEV_ERROR(dev, "Failed to prepare_enable the pclk [%d]\n", + ret); return ret; } ret = clk_prepare_enable(ctx->aclk); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret); + DRM_DEV_ERROR(dev, "Failed to prepare_enable the aclk [%d]\n", + ret); return ret; } ret = clk_prepare_enable(ctx->eclk); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret); + DRM_DEV_ERROR(dev, "Failed to prepare_enable the eclk [%d]\n", + ret); return ret; } ret = clk_prepare_enable(ctx->vclk); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret); + DRM_DEV_ERROR(dev, "Failed to prepare_enable the vclk [%d]\n", + ret); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 471242a5e580..b0288cf85701 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c @@ -83,7 +83,8 @@ static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data, mode = drm_mode_create(connector->dev); if (!mode) { - DRM_ERROR("failed to create a new display mode.\n"); + DRM_DEV_ERROR(dp->dev, + "failed to create a new display mode.\n"); return num_modes; } @@ -111,7 +112,8 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, if (dp->ptn_bridge) { ret = drm_bridge_attach(&dp->encoder, dp->ptn_bridge, bridge); if (ret) { - DRM_ERROR("Failed to attach bridge to drm\n"); + DRM_DEV_ERROR(dp->dev, + "Failed to attach bridge to drm\n"); bridge->next = NULL; return ret; } @@ -147,7 +149,8 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE); if (ret) { - DRM_ERROR("failed: of_get_videomode() : %d\n", ret); + DRM_DEV_ERROR(dp->dev, + "failed: of_get_videomode() : %d\n", ret); return ret; } return 0; diff --git a/drivers/gpu/drm/exynos/exynos_drm_dma.c b/drivers/gpu/drm/exynos/exynos_drm_dma.c index 3432c5ee9f0c..bef8bc3c8e00 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dma.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dma.c @@ -62,7 +62,7 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev, int ret; if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) { - DRM_ERROR("Device %s lacks support for IOMMU\n", + DRM_DEV_ERROR(subdrv_dev, "Device %s lacks support for IOMMU\n", dev_name(subdrv_dev)); return -EINVAL; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index ae425c9a3f7b..6ea92173db9f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -77,7 +77,8 @@ static int exynos_dpi_get_modes(struct drm_connector *connector) mode = drm_mode_create(connector->dev); if (!mode) { - DRM_ERROR("failed to create a new display mode\n"); + DRM_DEV_ERROR(ctx->dev, + "failed to create a new display mode\n"); return 0; } drm_display_mode_from_videomode(ctx->vm, mode); @@ -108,7 +109,8 @@ static int exynos_dpi_create_connector(struct drm_encoder *encoder) &exynos_dpi_connector_funcs, DRM_MODE_CONNECTOR_VGA); if (ret) { - DRM_ERROR("failed to initialize connector with drm\n"); + DRM_DEV_ERROR(ctx->dev, + "failed to initialize connector with drm\n"); return ret; } @@ -213,7 +215,8 @@ int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder) ret = exynos_dpi_create_connector(encoder); if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); + DRM_DEV_ERROR(encoder_to_dpi(encoder)->dev, + "failed to create connector ret = %d\n", ret); drm_encoder_cleanup(encoder); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index a4253dd55f86..63a4b5074a99 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1483,7 +1483,8 @@ static int exynos_dsi_create_connector(struct drm_encoder *encoder) ret = drm_connector_init(drm, connector, &exynos_dsi_connector_funcs, DRM_MODE_CONNECTOR_DSI); if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); + DRM_DEV_ERROR(dsi->dev, + "Failed to initialize connector with drm\n"); return ret; } @@ -1527,7 +1528,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, int ret = exynos_dsi_create_connector(encoder); if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); + DRM_DEV_ERROR(dsi->dev, + "failed to create connector ret = %d\n", + ret); drm_encoder_cleanup(encoder); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 1f11ab0f8e9d..832d22f57b4b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -45,7 +45,8 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev, * supported without IOMMU. */ if (IS_NONCONTIG_BUFFER(flags)) { - DRM_ERROR("Non-contiguous GEM memory is not supported.\n"); + DRM_DEV_ERROR(drm_dev->dev, + "Non-contiguous GEM memory is not supported.\n"); return -EINVAL; } @@ -83,7 +84,8 @@ exynos_drm_framebuffer_init(struct drm_device *dev, ret = drm_framebuffer_init(dev, fb, &exynos_drm_fb_funcs); if (ret < 0) { - DRM_ERROR("failed to initialize framebuffer\n"); + DRM_DEV_ERROR(dev->dev, + "failed to initialize framebuffer\n"); goto err; } @@ -113,7 +115,8 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, exynos_gem[i] = exynos_drm_gem_get(file_priv, mode_cmd->handles[i]); if (!exynos_gem[i]) { - DRM_ERROR("failed to lookup gem object\n"); + DRM_DEV_ERROR(dev->dev, + "failed to lookup gem object\n"); ret = -ENOENT; goto err; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 581a6a207995..ca3f6cda1fda 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -55,7 +55,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info, exynos_gem->dma_addr, exynos_gem->size, exynos_gem->dma_attrs); if (ret < 0) { - DRM_ERROR("failed to mmap.\n"); + DRM_DEV_ERROR(to_dma_dev(helper->dev), "failed to mmap.\n"); return ret; } @@ -83,7 +83,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, fbi = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(fbi)) { - DRM_ERROR("failed to allocate fb info.\n"); + DRM_DEV_ERROR(to_dma_dev(helper->dev), + "failed to allocate fb info.\n"); return PTR_ERR(fbi); } @@ -96,7 +97,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, exynos_gem->kvaddr = (void __iomem *) vmap(exynos_gem->pages, nr_pages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); if (!exynos_gem->kvaddr) { - DRM_ERROR("failed to map pages to kernel space.\n"); + DRM_DEV_ERROR(to_dma_dev(helper->dev), + "failed to map pages to kernel space.\n"); return -EIO; } @@ -152,7 +154,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd, &exynos_gem, 1); if (IS_ERR(helper->fb)) { - DRM_ERROR("failed to create drm framebuffer.\n"); + DRM_DEV_ERROR(dev->dev, "failed to create drm framebuffer.\n"); ret = PTR_ERR(helper->fb); goto err_destroy_gem; } @@ -201,20 +203,23 @@ int exynos_drm_fbdev_init(struct drm_device *dev) ret = drm_fb_helper_init(dev, helper, MAX_CONNECTOR); if (ret < 0) { - DRM_ERROR("failed to initialize drm fb helper.\n"); + DRM_DEV_ERROR(dev->dev, + "failed to initialize drm fb helper.\n"); goto err_init; } ret = drm_fb_helper_single_add_all_connectors(helper); if (ret < 0) { - DRM_ERROR("failed to register drm_fb_helper_connector.\n"); + DRM_DEV_ERROR(dev->dev, + "failed to register drm_fb_helper_connector.\n"); goto err_setup; } ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); if (ret < 0) { - DRM_ERROR("failed to set up hw configuration.\n"); + DRM_DEV_ERROR(dev->dev, + "failed to set up hw configuration.\n"); goto err_setup; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 90dfea0aec4d..5a5641b43c6a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -232,8 +232,9 @@ static bool fimc_check_ovf(struct fimc_context *ctx) EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB | EXYNOS_CIWDOFST_CLROVFICR); - dev_err(ctx->dev, "occurred overflow at %d, status 0x%x.\n", - ctx->id, status); + DRM_DEV_ERROR(ctx->dev, + "occurred overflow at %d, status 0x%x.\n", + ctx->id, status); return true; } @@ -273,7 +274,7 @@ static int fimc_get_buf_id(struct fimc_context *ctx) EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg)); if (frame_cnt == 0) { - DRM_ERROR("failed to get frame count.\n"); + DRM_DEV_ERROR(ctx->dev, "failed to get frame count.\n"); return -EIO; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index ffb686af287e..5b109ae1b390 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -398,7 +398,7 @@ static int fimd_atomic_check(struct exynos_drm_crtc *crtc, u32 clkdiv; if (mode->clock == 0) { - DRM_ERROR("Mode has zero clock value.\n"); + DRM_DEV_ERROR(ctx->dev, "Mode has zero clock value.\n"); return -EINVAL; } @@ -414,15 +414,17 @@ static int fimd_atomic_check(struct exynos_drm_crtc *crtc, lcd_rate = clk_get_rate(ctx->lcd_clk); if (2 * lcd_rate < ideal_clk) { - DRM_ERROR("sclk_fimd clock too low(%lu) for requested pixel clock(%lu)\n", - lcd_rate, ideal_clk); + DRM_DEV_ERROR(ctx->dev, + "sclk_fimd clock too low(%lu) for requested pixel clock(%lu)\n", + lcd_rate, ideal_clk); return -EINVAL; } /* Find the clock divider value that gets us closest to ideal_clk */ clkdiv = DIV_ROUND_CLOSEST(lcd_rate, ideal_clk); if (clkdiv >= 0x200) { - DRM_ERROR("requested pixel clock(%lu) too low\n", ideal_clk); + DRM_DEV_ERROR(ctx->dev, "requested pixel clock(%lu) too low\n", + ideal_clk); return -EINVAL; } @@ -479,7 +481,8 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) driver_data->lcdblk_offset, 0x3 << driver_data->lcdblk_vt_shift, 0x1 << driver_data->lcdblk_vt_shift)) { - DRM_ERROR("Failed to update sysreg for I80 i/f.\n"); + DRM_DEV_ERROR(ctx->dev, + "Failed to update sysreg for I80 i/f.\n"); return; } } else { @@ -523,7 +526,8 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) driver_data->lcdblk_offset, 0x1 << driver_data->lcdblk_bypass_shift, 0x1 << driver_data->lcdblk_bypass_shift)) { - DRM_ERROR("Failed to update sysreg for bypass setting.\n"); + DRM_DEV_ERROR(ctx->dev, + "Failed to update sysreg for bypass setting.\n"); return; } @@ -535,7 +539,8 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) driver_data->lcdblk_offset, 0x1 << driver_data->lcdblk_mic_bypass_shift, 0x1 << driver_data->lcdblk_mic_bypass_shift)) { - DRM_ERROR("Failed to update sysreg for bypass mic.\n"); + DRM_DEV_ERROR(ctx->dev, + "Failed to update sysreg for bypass mic.\n"); return; } @@ -1250,13 +1255,17 @@ static int exynos_fimd_resume(struct device *dev) ret = clk_prepare_enable(ctx->bus_clk); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the bus clk [%d]\n", ret); + DRM_DEV_ERROR(dev, + "Failed to prepare_enable the bus clk [%d]\n", + ret); return ret; } ret = clk_prepare_enable(ctx->lcd_clk); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the lcd clk [%d]\n", ret); + DRM_DEV_ERROR(dev, + "Failed to prepare_enable the lcd clk [%d]\n", + ret); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index a9c26b32e814..c20b3a759370 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -429,7 +429,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, int ret; if (!size) { - DRM_ERROR("invalid userptr size.\n"); + DRM_DEV_ERROR(g2d->dev, "invalid userptr size.\n"); return ERR_PTR(-EINVAL); } @@ -482,7 +482,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE, g2d_userptr->vec); if (ret != npages) { - DRM_ERROR("failed to get user pages from userptr.\n"); + DRM_DEV_ERROR(g2d->dev, + "failed to get user pages from userptr.\n"); if (ret < 0) goto err_destroy_framevec; ret = -EFAULT; @@ -503,7 +504,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, frame_vector_pages(g2d_userptr->vec), npages, offset, size, GFP_KERNEL); if (ret < 0) { - DRM_ERROR("failed to get sgt from pages.\n"); + DRM_DEV_ERROR(g2d->dev, "failed to get sgt from pages.\n"); goto err_free_sgt; } @@ -511,7 +512,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) { - DRM_ERROR("failed to map sgt with dma region.\n"); + DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n"); ret = -ENOMEM; goto err_sg_free_table; } @@ -560,7 +561,7 @@ static void g2d_userptr_free_all(struct g2d_data *g2d, struct drm_file *filp) g2d->current_pool = 0; } -static enum g2d_reg_type g2d_get_reg_type(int reg_offset) +static enum g2d_reg_type g2d_get_reg_type(struct g2d_data *g2d, int reg_offset) { enum g2d_reg_type reg_type; @@ -593,7 +594,8 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset) break; default: reg_type = REG_TYPE_NONE; - DRM_ERROR("Unknown register offset![%d]\n", reg_offset); + DRM_DEV_ERROR(g2d->dev, "Unknown register offset![%d]\n", + reg_offset); break; } @@ -627,9 +629,10 @@ static unsigned long g2d_get_buf_bpp(unsigned int format) return bpp; } -static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc, - enum g2d_reg_type reg_type, - unsigned long size) +static bool g2d_check_buf_desc_is_valid(struct g2d_data *g2d, + struct g2d_buf_desc *buf_desc, + enum g2d_reg_type reg_type, + unsigned long size) { int width, height; unsigned long bpp, last_pos; @@ -644,14 +647,15 @@ static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc, /* This check also makes sure that right_x > left_x. */ width = (int)buf_desc->right_x - (int)buf_desc->left_x; if (width < G2D_LEN_MIN || width > G2D_LEN_MAX) { - DRM_ERROR("width[%d] is out of range!\n", width); + DRM_DEV_ERROR(g2d->dev, "width[%d] is out of range!\n", width); return false; } /* This check also makes sure that bottom_y > top_y. */ height = (int)buf_desc->bottom_y - (int)buf_desc->top_y; if (height < G2D_LEN_MIN || height > G2D_LEN_MAX) { - DRM_ERROR("height[%d] is out of range!\n", height); + DRM_DEV_ERROR(g2d->dev, + "height[%d] is out of range!\n", height); return false; } @@ -670,8 +674,8 @@ static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc, */ if (last_pos >= size) { - DRM_ERROR("last engine access position [%lu] " - "is out of range [%lu]!\n", last_pos, size); + DRM_DEV_ERROR(g2d->dev, "last engine access position [%lu] " + "is out of range [%lu]!\n", last_pos, size); return false; } @@ -701,7 +705,7 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, offset = cmdlist->data[reg_pos]; handle = cmdlist->data[reg_pos + 1]; - reg_type = g2d_get_reg_type(offset); + reg_type = g2d_get_reg_type(g2d, offset); if (reg_type == REG_TYPE_NONE) { ret = -EFAULT; goto err; @@ -718,7 +722,7 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, goto err; } - if (!g2d_check_buf_desc_is_valid(buf_desc, + if (!g2d_check_buf_desc_is_valid(g2d, buf_desc, reg_type, exynos_gem->size)) { exynos_drm_gem_put(exynos_gem); ret = -EFAULT; @@ -736,8 +740,9 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, goto err; } - if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type, - g2d_userptr.size)) { + if (!g2d_check_buf_desc_is_valid(g2d, buf_desc, + reg_type, + g2d_userptr.size)) { ret = -EFAULT; goto err; } @@ -1044,7 +1049,7 @@ static int g2d_check_reg_offset(struct g2d_data *g2d, if (!for_addr) goto err; - reg_type = g2d_get_reg_type(reg_offset); + reg_type = g2d_get_reg_type(g2d, reg_offset); /* check userptr buffer type. */ if ((cmdlist->data[index] & ~0x7fffffff) >> 31) { @@ -1058,7 +1063,7 @@ static int g2d_check_reg_offset(struct g2d_data *g2d, if (for_addr) goto err; - reg_type = g2d_get_reg_type(reg_offset); + reg_type = g2d_get_reg_type(g2d, reg_offset); buf_desc = &buf_info->descs[reg_type]; buf_desc->stride = cmdlist->data[index + 1]; @@ -1068,7 +1073,7 @@ static int g2d_check_reg_offset(struct g2d_data *g2d, if (for_addr) goto err; - reg_type = g2d_get_reg_type(reg_offset); + reg_type = g2d_get_reg_type(g2d, reg_offset); buf_desc = &buf_info->descs[reg_type]; value = cmdlist->data[index + 1]; @@ -1080,7 +1085,7 @@ static int g2d_check_reg_offset(struct g2d_data *g2d, if (for_addr) goto err; - reg_type = g2d_get_reg_type(reg_offset); + reg_type = g2d_get_reg_type(g2d, reg_offset); buf_desc = &buf_info->descs[reg_type]; value = cmdlist->data[index + 1]; @@ -1093,7 +1098,7 @@ static int g2d_check_reg_offset(struct g2d_data *g2d, if (for_addr) goto err; - reg_type = g2d_get_reg_type(reg_offset); + reg_type = g2d_get_reg_type(g2d, reg_offset); buf_desc = &buf_info->descs[reg_type]; value = cmdlist->data[index + 1]; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index df66c383a877..7b4883b1e29c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -61,7 +61,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) exynos_gem->pages = kvmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL | __GFP_ZERO); if (!exynos_gem->pages) { - DRM_ERROR("failed to allocate pages.\n"); + DRM_DEV_ERROR(to_dma_dev(dev), "failed to allocate pages.\n"); return -ENOMEM; } @@ -69,7 +69,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) &exynos_gem->dma_addr, GFP_KERNEL, exynos_gem->dma_attrs); if (!exynos_gem->cookie) { - DRM_ERROR("failed to allocate buffer.\n"); + DRM_DEV_ERROR(to_dma_dev(dev), "failed to allocate buffer.\n"); goto err_free; } @@ -77,13 +77,13 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) exynos_gem->dma_addr, exynos_gem->size, exynos_gem->dma_attrs); if (ret < 0) { - DRM_ERROR("failed to get sgtable.\n"); + DRM_DEV_ERROR(to_dma_dev(dev), "failed to get sgtable.\n"); goto err_dma_free; } if (drm_prime_sg_to_page_addr_arrays(&sgt, exynos_gem->pages, NULL, nr_pages)) { - DRM_ERROR("invalid sgtable.\n"); + DRM_DEV_ERROR(to_dma_dev(dev), "invalid sgtable.\n"); ret = -EINVAL; goto err_sgt_free; } @@ -186,7 +186,7 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev, ret = drm_gem_object_init(dev, obj, size); if (ret < 0) { - DRM_ERROR("failed to initialize gem object\n"); + DRM_DEV_ERROR(dev->dev, "failed to initialize gem object\n"); kfree(exynos_gem); return ERR_PTR(ret); } @@ -211,12 +211,13 @@ struct exynos_drm_gem *exynos_drm_gem_create(struct drm_device *dev, int ret; if (flags & ~(EXYNOS_BO_MASK)) { - DRM_ERROR("invalid GEM buffer flags: %u\n", flags); + DRM_DEV_ERROR(dev->dev, + "invalid GEM buffer flags: %u\n", flags); return ERR_PTR(-EINVAL); } if (!size) { - DRM_ERROR("invalid GEM buffer size: %lu\n", size); + DRM_DEV_ERROR(dev->dev, "invalid GEM buffer size: %lu\n", size); return ERR_PTR(-EINVAL); } @@ -325,7 +326,7 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(file_priv, args->handle); if (!obj) { - DRM_ERROR("failed to lookup gem object.\n"); + DRM_DEV_ERROR(dev->dev, "failed to lookup gem object.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index f048d97fe9e2..ef10e45f9e7d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -395,7 +395,7 @@ static int gsc_sw_reset(struct gsc_context *ctx) } if (cfg) { - DRM_ERROR("failed to reset gsc h/w.\n"); + DRM_DEV_ERROR(ctx->dev, "failed to reset gsc h/w.\n"); return -EBUSY; } @@ -706,12 +706,13 @@ static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) gsc_write(cfg, GSC_OUT_CON); } -static int gsc_get_ratio_shift(u32 src, u32 dst, u32 *ratio) +static int gsc_get_ratio_shift(struct gsc_context *ctx, u32 src, u32 dst, + u32 *ratio) { DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst); if (src >= dst * 8) { - DRM_ERROR("failed to make ratio and shift.\n"); + DRM_DEV_ERROR(ctx->dev, "failed to make ratio and shift.\n"); return -EINVAL; } else if (src >= dst * 4) *ratio = 4; @@ -759,15 +760,15 @@ static int gsc_set_prescaler(struct gsc_context *ctx, struct gsc_scaler *sc, dst_h = dst->h; } - ret = gsc_get_ratio_shift(src_w, dst_w, &sc->pre_hratio); + ret = gsc_get_ratio_shift(ctx, src_w, dst_w, &sc->pre_hratio); if (ret) { - dev_err(ctx->dev, "failed to get ratio horizontal.\n"); + DRM_DEV_ERROR(ctx->dev, "failed to get ratio horizontal.\n"); return ret; } - ret = gsc_get_ratio_shift(src_h, dst_h, &sc->pre_vratio); + ret = gsc_get_ratio_shift(ctx, src_h, dst_h, &sc->pre_vratio); if (ret) { - dev_err(ctx->dev, "failed to get ratio vertical.\n"); + DRM_DEV_ERROR(ctx->dev, "failed to get ratio vertical.\n"); return ret; } @@ -979,7 +980,7 @@ static int gsc_get_src_buf_index(struct gsc_context *ctx) curr_index, buf_id); if (buf_id == GSC_MAX_SRC) { - DRM_ERROR("failed to get in buffer index.\n"); + DRM_DEV_ERROR(ctx->dev, "failed to get in buffer index.\n"); return -EINVAL; } @@ -1006,7 +1007,7 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx) } if (buf_id == GSC_MAX_DST) { - DRM_ERROR("failed to get out buffer index.\n"); + DRM_DEV_ERROR(ctx->dev, "failed to get out buffer index.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index dd02e8a323ef..ddf5b4dfd6c3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -113,7 +113,8 @@ static void mic_set_path(struct exynos_mic *mic, bool enable) ret = regmap_read(mic->sysreg, DSD_CFG_MUX, &val); if (ret) { - DRM_ERROR("mic: Failed to read system register\n"); + DRM_DEV_ERROR(mic->dev, + "mic: Failed to read system register\n"); return; } @@ -129,7 +130,8 @@ static void mic_set_path(struct exynos_mic *mic, bool enable) ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val); if (ret) - DRM_ERROR("mic: Failed to read system register\n"); + DRM_DEV_ERROR(mic->dev, + "mic: Failed to read system register\n"); } static int mic_sw_reset(struct exynos_mic *mic) @@ -274,7 +276,7 @@ static void mic_pre_enable(struct drm_bridge *bridge) ret = mic_sw_reset(mic); if (ret) { - DRM_ERROR("Failed to reset\n"); + DRM_DEV_ERROR(mic->dev, "Failed to reset\n"); goto turn_off; } @@ -354,8 +356,8 @@ static int exynos_mic_resume(struct device *dev) for (i = 0; i < NUM_CLKS; i++) { ret = clk_prepare_enable(mic->clks[i]); if (ret < 0) { - DRM_ERROR("Failed to enable clock (%s)\n", - clk_names[i]); + DRM_DEV_ERROR(dev, "Failed to enable clock (%s)\n", + clk_names[i]); while (--i > -1) clk_disable_unprepare(mic->clks[i]); return ret; @@ -380,7 +382,8 @@ static int exynos_mic_probe(struct platform_device *pdev) mic = devm_kzalloc(dev, sizeof(*mic), GFP_KERNEL); if (!mic) { - DRM_ERROR("mic: Failed to allocate memory for MIC object\n"); + DRM_DEV_ERROR(dev, + "mic: Failed to allocate memory for MIC object\n"); ret = -ENOMEM; goto err; } @@ -389,12 +392,12 @@ static int exynos_mic_probe(struct platform_device *pdev) ret = of_address_to_resource(dev->of_node, 0, &res); if (ret) { - DRM_ERROR("mic: Failed to get mem region for MIC\n"); + DRM_DEV_ERROR(dev, "mic: Failed to get mem region for MIC\n"); goto err; } mic->reg = devm_ioremap(dev, res.start, resource_size(&res)); if (!mic->reg) { - DRM_ERROR("mic: Failed to remap for MIC\n"); + DRM_DEV_ERROR(dev, "mic: Failed to remap for MIC\n"); ret = -ENOMEM; goto err; } @@ -402,7 +405,7 @@ static int exynos_mic_probe(struct platform_device *pdev) mic->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,disp-syscon"); if (IS_ERR(mic->sysreg)) { - DRM_ERROR("mic: Failed to get system register.\n"); + DRM_DEV_ERROR(dev, "mic: Failed to get system register.\n"); ret = PTR_ERR(mic->sysreg); goto err; } @@ -410,8 +413,8 @@ static int exynos_mic_probe(struct platform_device *pdev) for (i = 0; i < NUM_CLKS; i++) { mic->clks[i] = devm_clk_get(dev, clk_names[i]); if (IS_ERR(mic->clks[i])) { - DRM_ERROR("mic: Failed to get clock (%s)\n", - clk_names[i]); + DRM_DEV_ERROR(dev, "mic: Failed to get clock (%s)\n", + clk_names[i]); ret = PTR_ERR(mic->clks[i]); goto err; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index df0508e0e49e..6328565f889e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -181,6 +181,7 @@ exynos_drm_plane_check_format(const struct exynos_drm_plane_config *config, struct exynos_drm_plane_state *state) { struct drm_framebuffer *fb = state->base.fb; + struct drm_device *dev = fb->dev; switch (fb->modifier) { case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE: @@ -192,7 +193,7 @@ exynos_drm_plane_check_format(const struct exynos_drm_plane_config *config, break; default: - DRM_ERROR("unsupported pixel format modifier"); + DRM_DEV_ERROR(dev->dev, "unsupported pixel format modifier"); return -ENOTSUPP; } @@ -310,7 +311,7 @@ int exynos_plane_init(struct drm_device *dev, config->num_pixel_formats, NULL, config->type, NULL); if (err) { - DRM_ERROR("failed to initialize plane\n"); + DRM_DEV_ERROR(dev->dev, "failed to initialize plane\n"); return err; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 29f4c1932aed..302275604b87 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -339,7 +339,8 @@ static int vidi_create_connector(struct drm_encoder *encoder) ret = drm_connector_init(ctx->drm_dev, connector, &vidi_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); + DRM_DEV_ERROR(ctx->drm_dev->dev, + "Failed to initialize connector with drm\n"); return ret; } @@ -402,7 +403,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, EXYNOS_DISPLAY_TYPE_VIDI, &vidi_crtc_ops, ctx); if (IS_ERR(ctx->crtc)) { - DRM_ERROR("failed to create crtc.\n"); + DRM_DEV_ERROR(dev, "failed to create crtc.\n"); return PTR_ERR(ctx->crtc); } @@ -417,7 +418,8 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) ret = vidi_create_connector(encoder); if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); + DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n", + ret); drm_encoder_cleanup(encoder); return ret; } @@ -457,7 +459,8 @@ static int vidi_probe(struct platform_device *pdev) ret = device_create_file(&pdev->dev, &dev_attr_connection); if (ret < 0) { - DRM_ERROR("failed to create connection sysfs.\n"); + DRM_DEV_ERROR(&pdev->dev, + "failed to create connection sysfs.\n"); return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 8e2c02fc66e8..d391e2f6d271 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -947,7 +947,8 @@ static int hdmi_create_connector(struct drm_encoder *encoder) ret = drm_connector_init(hdata->drm_dev, connector, &hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); + DRM_DEV_ERROR(hdata->dev, + "Failed to initialize connector with drm\n"); return ret; } @@ -957,7 +958,7 @@ static int hdmi_create_connector(struct drm_encoder *encoder) if (hdata->bridge) { ret = drm_bridge_attach(encoder, hdata->bridge, NULL); if (ret) - DRM_ERROR("Failed to attach bridge\n"); + DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n"); } return ret; @@ -1175,7 +1176,7 @@ static void hdmiphy_wait_for_pll(struct hdmi_context *hdata) usleep_range(10, 20); } - DRM_ERROR("PLL could not reach steady state\n"); + DRM_DEV_ERROR(hdata->dev, "PLL could not reach steady state\n"); } static void hdmi_v13_mode_apply(struct hdmi_context *hdata) @@ -1411,7 +1412,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) ret = hdmi_find_phy_conf(hdata, m->clock * 1000); if (ret < 0) { - DRM_ERROR("failed to find hdmiphy conf\n"); + DRM_DEV_ERROR(hdata->dev, "failed to find hdmiphy conf\n"); return; } phy_conf = hdata->drv_data->phy_confs.data[ret].conf; @@ -1423,7 +1424,7 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata) hdmiphy_enable_mode_set(hdata, true); ret = hdmiphy_reg_write_buf(hdata, 0, phy_conf, 32); if (ret) { - DRM_ERROR("failed to configure hdmiphy\n"); + DRM_DEV_ERROR(hdata->dev, "failed to configure hdmiphy\n"); return; } hdmiphy_enable_mode_set(hdata, false); @@ -1734,7 +1735,7 @@ static int hdmi_bridge_init(struct hdmi_context *hdata) np = of_graph_get_remote_port_parent(ep); of_node_put(ep); if (!np) { - DRM_ERROR("failed to get remote port parent"); + DRM_DEV_ERROR(dev, "failed to get remote port parent"); return -EINVAL; } @@ -1756,13 +1757,13 @@ static int hdmi_resources_init(struct hdmi_context *hdata) hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN); if (IS_ERR(hdata->hpd_gpio)) { - DRM_ERROR("cannot get hpd gpio property\n"); + DRM_DEV_ERROR(dev, "cannot get hpd gpio property\n"); return PTR_ERR(hdata->hpd_gpio); } hdata->irq = gpiod_to_irq(hdata->hpd_gpio); if (hdata->irq < 0) { - DRM_ERROR("failed to get GPIO irq\n"); + DRM_DEV_ERROR(dev, "failed to get GPIO irq\n"); return hdata->irq; } @@ -1780,7 +1781,7 @@ static int hdmi_resources_init(struct hdmi_context *hdata) ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(supply), hdata->regul_bulk); if (ret) { if (ret != -EPROBE_DEFER) - DRM_ERROR("failed to get regulators\n"); + DRM_DEV_ERROR(dev, "failed to get regulators\n"); return ret; } @@ -1792,7 +1793,8 @@ static int hdmi_resources_init(struct hdmi_context *hdata) ret = regulator_enable(hdata->reg_hdmi_en); if (ret) { - DRM_ERROR("failed to enable hdmi-en regulator\n"); + DRM_DEV_ERROR(dev, + "failed to enable hdmi-en regulator\n"); return ret; } } @@ -1845,7 +1847,8 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) ret = hdmi_create_connector(encoder); if (ret) { - DRM_ERROR("failed to create connector ret = %d\n", ret); + DRM_DEV_ERROR(dev, "failed to create connector ret = %d\n", + ret); drm_encoder_cleanup(encoder); return ret; } @@ -1875,7 +1878,8 @@ static int hdmi_get_ddc_adapter(struct hdmi_context *hdata) np = of_parse_phandle(hdata->dev->of_node, "ddc", 0); if (!np) { - DRM_ERROR("Failed to find ddc node in device tree\n"); + DRM_DEV_ERROR(hdata->dev, + "Failed to find ddc node in device tree\n"); return -ENODEV; } @@ -1902,7 +1906,8 @@ static int hdmi_get_phy_io(struct hdmi_context *hdata) if (!np) { np = of_parse_phandle(hdata->dev->of_node, "phy", 0); if (!np) { - DRM_ERROR("Failed to find hdmiphy node in device tree\n"); + DRM_DEV_ERROR(hdata->dev, + "Failed to find hdmiphy node in device tree\n"); return -ENODEV; } } @@ -1910,7 +1915,8 @@ static int hdmi_get_phy_io(struct hdmi_context *hdata) if (hdata->drv_data->is_apb_phy) { hdata->regs_hdmiphy = of_iomap(np, 0); if (!hdata->regs_hdmiphy) { - DRM_ERROR("failed to ioremap hdmi phy\n"); + DRM_DEV_ERROR(hdata->dev, + "failed to ioremap hdmi phy\n"); ret = -ENOMEM; goto out; } @@ -1951,7 +1957,7 @@ static int hdmi_probe(struct platform_device *pdev) ret = hdmi_resources_init(hdata); if (ret) { if (ret != -EPROBE_DEFER) - DRM_ERROR("hdmi_resources_init failed\n"); + DRM_DEV_ERROR(dev, "hdmi_resources_init failed\n"); return ret; } @@ -1977,14 +1983,14 @@ static int hdmi_probe(struct platform_device *pdev) IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "hdmi", hdata); if (ret) { - DRM_ERROR("failed to register hdmi interrupt\n"); + DRM_DEV_ERROR(dev, "failed to register hdmi interrupt\n"); goto err_hdmiphy; } hdata->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,syscon-phandle"); if (IS_ERR(hdata->pmureg)) { - DRM_ERROR("syscon regmap lookup failed.\n"); + DRM_DEV_ERROR(dev, "syscon regmap lookup failed.\n"); ret = -EPROBE_DEFER; goto err_hdmiphy; } @@ -1993,7 +1999,7 @@ static int hdmi_probe(struct platform_device *pdev) hdata->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,sysreg-phandle"); if (IS_ERR(hdata->sysreg)) { - DRM_ERROR("sysreg regmap lookup failed.\n"); + DRM_DEV_ERROR(dev, "sysreg regmap lookup failed.\n"); ret = -EPROBE_DEFER; goto err_hdmiphy; } diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index f35e4ab55b27..9bda3d4bd17a 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -885,7 +885,8 @@ static int mixer_initialize(struct mixer_context *mixer_ctx, /* acquire resources: regs, irqs, clocks */ ret = mixer_resources_init(mixer_ctx); if (ret) { - DRM_ERROR("mixer_resources_init failed ret=%d\n", ret); + DRM_DEV_ERROR(mixer_ctx->dev, + "mixer_resources_init failed ret=%d\n", ret); return ret; } @@ -893,7 +894,8 @@ static int mixer_initialize(struct mixer_context *mixer_ctx, /* acquire vp resources: regs, irqs, clocks */ ret = vp_resources_init(mixer_ctx); if (ret) { - DRM_ERROR("vp_resources_init failed ret=%d\n", ret); + DRM_DEV_ERROR(mixer_ctx->dev, + "vp_resources_init failed ret=%d\n", ret); return ret; } } @@ -1227,7 +1229,7 @@ static int mixer_probe(struct platform_device *pdev) ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) { - DRM_ERROR("failed to alloc mixer context.\n"); + DRM_DEV_ERROR(dev, "failed to alloc mixer context.\n"); return -ENOMEM; } @@ -1282,27 +1284,33 @@ static int __maybe_unused exynos_mixer_resume(struct device *dev) ret = clk_prepare_enable(ctx->mixer); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret); + DRM_DEV_ERROR(ctx->dev, + "Failed to prepare_enable the mixer clk [%d]\n", + ret); return ret; } ret = clk_prepare_enable(ctx->hdmi); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); + DRM_DEV_ERROR(dev, + "Failed to prepare_enable the hdmi clk [%d]\n", + ret); return ret; } if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) { ret = clk_prepare_enable(ctx->vp); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n", - ret); + DRM_DEV_ERROR(dev, + "Failed to prepare_enable the vp clk [%d]\n", + ret); return ret; } if (test_bit(MXR_BIT_HAS_SCLK, &ctx->flags)) { ret = clk_prepare_enable(ctx->sclk_mixer); if (ret < 0) { - DRM_ERROR("Failed to prepare_enable the " \ + DRM_DEV_ERROR(dev, + "Failed to prepare_enable the " \ "sclk_mixer clk [%d]\n", - ret); + ret); return ret; } } -- cgit v1.2.3 From 6be900563a9e7420ead7de5737a004e1878ef145 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 15 Apr 2019 16:25:12 +0900 Subject: drm/exynos: use DRM_DEV_DEBUG* instead of DRM_DEBUG macro Use DRM_DEV_DEBUG* instead of DRM_DEBUG macro to print out debug messages. This patch just cleans up the use of debug log macro, which changes the log macro to DRM_DEV_DEBUG*. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 2 +- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 10 ++-- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 7 ++- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 85 ++++++++++++++------------- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 19 +++--- drivers/gpu/drm/exynos/exynos_drm_gem.c | 18 +++--- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 48 +++++++-------- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 61 ++++++++++++------- drivers/gpu/drm/exynos/exynos_drm_mic.c | 4 +- drivers/gpu/drm/exynos/exynos_drm_plane.c | 10 ++-- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 25 ++++---- drivers/gpu/drm/exynos/exynos_hdmi.c | 33 +++++++---- drivers/gpu/drm/exynos/exynos_mixer.c | 17 +++--- 13 files changed, 191 insertions(+), 148 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index c2715e54db90..73b318a7ef49 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -356,7 +356,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, break; } - DRM_DEBUG_KMS("cpp = %u\n", fb->format->cpp[0]); + DRM_DEV_DEBUG_KMS(ctx->dev, "cpp = %u\n", fb->format->cpp[0]); /* * In case of exynos, setting dma-burst to 16Word causes permanent diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index bc76f2772e44..0217ee9a118d 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -99,7 +99,7 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) if (!wait_event_timeout(ctx->wait_vsync_queue, !atomic_read(&ctx->wait_vsync_event), HZ/20)) - DRM_DEBUG_KMS("vblank wait timed out.\n"); + DRM_DEV_DEBUG_KMS(ctx->dev, "vblank wait timed out.\n"); } static void decon_clear_channels(struct exynos_drm_crtc *crtc) @@ -313,7 +313,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, break; } - DRM_DEBUG_KMS("cpp = %d\n", fb->format->cpp[0]); + DRM_DEV_DEBUG_KMS(ctx->dev, "cpp = %d\n", fb->format->cpp[0]); /* * In case of exynos, setting dma-burst to 16Word causes permanent @@ -420,9 +420,9 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, writel(state->src.x, ctx->regs + VIDW_OFFSET_X(win)); writel(state->src.y, ctx->regs + VIDW_OFFSET_Y(win)); - DRM_DEBUG_KMS("start addr = 0x%lx\n", + DRM_DEV_DEBUG_KMS(ctx->dev, "start addr = 0x%lx\n", (unsigned long)val); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", + DRM_DEV_DEBUG_KMS(ctx->dev, "ovl_width = %d, ovl_height = %d\n", state->crtc.w, state->crtc.h); val = VIDOSDxA_TOPLEFT_X(state->crtc.x) | @@ -440,7 +440,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, writel(val, ctx->regs + VIDOSD_B(win)); - DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", + DRM_DEV_DEBUG_KMS(ctx->dev, "osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", state->crtc.x, state->crtc.y, last_x, last_y); /* OSD alpha */ diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index ca3f6cda1fda..724cb52a374a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -122,9 +122,10 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, unsigned long size; int ret; - DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", - sizes->surface_width, sizes->surface_height, - sizes->surface_bpp); + DRM_DEV_DEBUG_KMS(dev->dev, + "surface width(%d), height(%d) and bpp(%d\n", + sizes->surface_width, sizes->surface_height, + sizes->surface_bpp); mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 5a5641b43c6a..71b0cb123a56 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -186,7 +186,7 @@ static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable) { u32 cfg; - DRM_DEBUG_KMS("enable[%d]\n", enable); + DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable); cfg = fimc_read(ctx, EXYNOS_CIGCTRL); if (enable) @@ -201,7 +201,7 @@ static void fimc_mask_irq(struct fimc_context *ctx, bool enable) { u32 cfg; - DRM_DEBUG_KMS("enable[%d]\n", enable); + DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable); cfg = fimc_read(ctx, EXYNOS_CIGCTRL); if (enable) { @@ -225,7 +225,7 @@ static bool fimc_check_ovf(struct fimc_context *ctx) flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB | EXYNOS_CISTATUS_OVFICR; - DRM_DEBUG_KMS("flag[0x%x]\n", flag); + DRM_DEV_DEBUG_KMS(ctx->dev, "flag[0x%x]\n", flag); if (status & flag) { fimc_set_bits(ctx, EXYNOS_CIWDOFST, @@ -247,7 +247,7 @@ static bool fimc_check_frame_end(struct fimc_context *ctx) cfg = fimc_read(ctx, EXYNOS_CISTATUS); - DRM_DEBUG_KMS("cfg[0x%x]\n", cfg); + DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]\n", cfg); if (!(cfg & EXYNOS_CISTATUS_FRAMEEND)) return false; @@ -269,9 +269,9 @@ static int fimc_get_buf_id(struct fimc_context *ctx) if (frame_cnt == 0) frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg); - DRM_DEBUG_KMS("present[%d]before[%d]\n", - EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg), - EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg)); + DRM_DEV_DEBUG_KMS(ctx->dev, "present[%d]before[%d]\n", + EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg), + EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg)); if (frame_cnt == 0) { DRM_DEV_ERROR(ctx->dev, "failed to get frame count.\n"); @@ -279,7 +279,7 @@ static int fimc_get_buf_id(struct fimc_context *ctx) } buf_id = frame_cnt - 1; - DRM_DEBUG_KMS("buf_id[%d]\n", buf_id); + DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]\n", buf_id); return buf_id; } @@ -288,7 +288,7 @@ static void fimc_handle_lastend(struct fimc_context *ctx, bool enable) { u32 cfg; - DRM_DEBUG_KMS("enable[%d]\n", enable); + DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable); cfg = fimc_read(ctx, EXYNOS_CIOCTRL); if (enable) @@ -303,7 +303,7 @@ static void fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt) { u32 cfg; - DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); + DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); /* RGB */ cfg = fimc_read(ctx, EXYNOS_CISCCTRL); @@ -368,7 +368,7 @@ static void fimc_src_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled) { u32 cfg; - DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); + DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); cfg = fimc_read(ctx, EXYNOS_MSCTRL); cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB; @@ -421,7 +421,7 @@ static void fimc_src_set_transf(struct fimc_context *ctx, unsigned int rotation) unsigned int degree = rotation & DRM_MODE_ROTATE_MASK; u32 cfg1, cfg2; - DRM_DEBUG_KMS("rotation[%x]\n", rotation); + DRM_DEV_DEBUG_KMS(ctx->dev, "rotation[%x]\n", rotation); cfg1 = fimc_read(ctx, EXYNOS_MSCTRL); cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR | @@ -479,10 +479,11 @@ static void fimc_set_window(struct fimc_context *ctx, v1 = buf->rect.y; v2 = buf->buf.height - buf->rect.h - buf->rect.y; - DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n", - buf->rect.x, buf->rect.y, buf->rect.w, buf->rect.h, - real_width, buf->buf.height); - DRM_DEBUG_KMS("h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, v2); + DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n", + buf->rect.x, buf->rect.y, buf->rect.w, buf->rect.h, + real_width, buf->buf.height); + DRM_DEV_DEBUG_KMS(ctx->dev, "h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1, + v2); /* * set window offset 1, 2 size @@ -507,7 +508,8 @@ static void fimc_src_set_size(struct fimc_context *ctx, unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; u32 cfg; - DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", real_width, buf->buf.height); + DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width, + buf->buf.height); /* original size */ cfg = (EXYNOS_ORGISIZE_HORIZONTAL(real_width) | @@ -515,8 +517,8 @@ static void fimc_src_set_size(struct fimc_context *ctx, fimc_write(ctx, cfg, EXYNOS_ORGISIZE); - DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, buf->rect.y, - buf->rect.w, buf->rect.h); + DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, + buf->rect.y, buf->rect.w, buf->rect.h); /* set input DMA image size */ cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE); @@ -561,7 +563,7 @@ static void fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt) { u32 cfg; - DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); + DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); /* RGB */ cfg = fimc_read(ctx, EXYNOS_CISCCTRL); @@ -632,7 +634,7 @@ static void fimc_dst_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled) { u32 cfg; - DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); + DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); cfg = fimc_read(ctx, EXYNOS_CIEXTEN); @@ -692,7 +694,7 @@ static void fimc_dst_set_transf(struct fimc_context *ctx, unsigned int rotation) unsigned int degree = rotation & DRM_MODE_ROTATE_MASK; u32 cfg; - DRM_DEBUG_KMS("rotation[0x%x]\n", rotation); + DRM_DEV_DEBUG_KMS(ctx->dev, "rotation[0x%x]\n", rotation); cfg = fimc_read(ctx, EXYNOS_CITRGFMT); cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK; @@ -776,19 +778,20 @@ static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc, pre_dst_width = src_w >> hfactor; pre_dst_height = src_h >> vfactor; - DRM_DEBUG_KMS("pre_dst_width[%d]pre_dst_height[%d]\n", - pre_dst_width, pre_dst_height); - DRM_DEBUG_KMS("hfactor[%d]vfactor[%d]\n", hfactor, vfactor); + DRM_DEV_DEBUG_KMS(ctx->dev, "pre_dst_width[%d]pre_dst_height[%d]\n", + pre_dst_width, pre_dst_height); + DRM_DEV_DEBUG_KMS(ctx->dev, "hfactor[%d]vfactor[%d]\n", hfactor, + vfactor); sc->hratio = (src_w << 14) / (dst_w << hfactor); sc->vratio = (src_h << 14) / (dst_h << vfactor); sc->up_h = (dst_w >= src_w) ? true : false; sc->up_v = (dst_h >= src_h) ? true : false; - DRM_DEBUG_KMS("hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n", - sc->hratio, sc->vratio, sc->up_h, sc->up_v); + DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n", + sc->hratio, sc->vratio, sc->up_h, sc->up_v); shfactor = FIMC_SHFACTOR - (hfactor + vfactor); - DRM_DEBUG_KMS("shfactor[%d]\n", shfactor); + DRM_DEV_DEBUG_KMS(ctx->dev, "shfactor[%d]\n", shfactor); cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) | EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) | @@ -806,10 +809,10 @@ static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc) { u32 cfg, cfg_ext; - DRM_DEBUG_KMS("range[%d]bypass[%d]up_h[%d]up_v[%d]\n", - sc->range, sc->bypass, sc->up_h, sc->up_v); - DRM_DEBUG_KMS("hratio[%d]vratio[%d]\n", - sc->hratio, sc->vratio); + DRM_DEV_DEBUG_KMS(ctx->dev, "range[%d]bypass[%d]up_h[%d]up_v[%d]\n", + sc->range, sc->bypass, sc->up_h, sc->up_v); + DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]\n", + sc->hratio, sc->vratio); cfg = fimc_read(ctx, EXYNOS_CISCCTRL); cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS | @@ -847,7 +850,8 @@ static void fimc_dst_set_size(struct fimc_context *ctx, unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0]; u32 cfg, cfg_ext; - DRM_DEBUG_KMS("hsize[%d]vsize[%d]\n", real_width, buf->buf.height); + DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width, + buf->buf.height); /* original size */ cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(real_width) | @@ -855,8 +859,9 @@ static void fimc_dst_set_size(struct fimc_context *ctx, fimc_write(ctx, cfg, EXYNOS_ORGOSIZE); - DRM_DEBUG_KMS("x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, buf->rect.y, - buf->rect.w, buf->rect.h); + DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x, + buf->rect.y, + buf->rect.w, buf->rect.h); /* CSC ITU */ cfg = fimc_read(ctx, EXYNOS_CIGCTRL); @@ -906,7 +911,7 @@ static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id, u32 buf_num; u32 cfg; - DRM_DEBUG_KMS("buf_id[%d]enqueu[%d]\n", buf_id, enqueue); + DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]enqueu[%d]\n", buf_id, enqueue); spin_lock_irqsave(&ctx->lock, flags); @@ -946,7 +951,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id) struct fimc_context *ctx = dev_id; int buf_id; - DRM_DEBUG_KMS("fimc id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(ctx->dev, "fimc id[%d]\n", ctx->id); fimc_clear_irq(ctx); if (fimc_check_ovf(ctx)) @@ -959,7 +964,7 @@ static irqreturn_t fimc_irq_handler(int irq, void *dev_id) if (buf_id < 0) return IRQ_HANDLED; - DRM_DEBUG_KMS("buf_id[%d]\n", buf_id); + DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]\n", buf_id); if (ctx->task) { struct exynos_drm_ipp_task *task = ctx->task; @@ -1381,7 +1386,7 @@ static int fimc_runtime_suspend(struct device *dev) { struct fimc_context *ctx = get_fimc_context(dev); - DRM_DEBUG_KMS("id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]); return 0; } @@ -1390,7 +1395,7 @@ static int fimc_runtime_resume(struct device *dev) { struct fimc_context *ctx = get_fimc_context(dev); - DRM_DEBUG_KMS("id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); return clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]); } #endif diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 5b109ae1b390..8039e1a3671d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -315,7 +315,7 @@ static void fimd_wait_for_vblank(struct exynos_drm_crtc *crtc) if (!wait_event_timeout(ctx->wait_vsync_queue, !atomic_read(&ctx->wait_vsync_event), HZ/20)) - DRM_DEBUG_KMS("vblank wait timed out.\n"); + DRM_DEV_DEBUG_KMS(ctx->dev, "vblank wait timed out.\n"); } static void fimd_enable_video_output(struct fimd_context *ctx, unsigned int win, @@ -817,10 +817,11 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, val = (unsigned long)(dma_addr + size); writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); - DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", - (unsigned long)dma_addr, val, size); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - state->crtc.w, state->crtc.h); + DRM_DEV_DEBUG_KMS(ctx->dev, + "start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", + (unsigned long)dma_addr, val, size); + DRM_DEV_DEBUG_KMS(ctx->dev, "ovl_width = %d, ovl_height = %d\n", + state->crtc.w, state->crtc.h); /* buffer size */ buf_offsize = pitch - (state->crtc.w * cpp); @@ -850,8 +851,9 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, writel(val, ctx->regs + VIDOSD_B(win)); - DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", - state->crtc.x, state->crtc.y, last_x, last_y); + DRM_DEV_DEBUG_KMS(ctx->dev, + "osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", + state->crtc.x, state->crtc.y, last_x, last_y); /* OSD size */ if (win != 3 && win != 4) { @@ -861,7 +863,8 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, val = state->crtc.w * state->crtc.h; writel(val, ctx->regs + offset); - DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); + DRM_DEV_DEBUG_KMS(ctx->dev, "osd size = 0x%x\n", + (unsigned int)val); } fimd_win_set_pixfmt(ctx, win, fb, state->src.w); diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 7b4883b1e29c..a55f5ac41bf3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -29,7 +29,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) int ret = -ENOMEM; if (exynos_gem->dma_addr) { - DRM_DEBUG_KMS("already allocated.\n"); + DRM_DEV_DEBUG_KMS(to_dma_dev(dev), "already allocated.\n"); return 0; } @@ -90,7 +90,7 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem) sg_free_table(&sgt); - DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", + DRM_DEV_DEBUG_KMS(to_dma_dev(dev), "dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)exynos_gem->dma_addr, exynos_gem->size); return 0; @@ -111,11 +111,11 @@ static void exynos_drm_free_buf(struct exynos_drm_gem *exynos_gem) struct drm_device *dev = exynos_gem->base.dev; if (!exynos_gem->dma_addr) { - DRM_DEBUG_KMS("dma_addr is invalid.\n"); + DRM_DEV_DEBUG_KMS(dev->dev, "dma_addr is invalid.\n"); return; } - DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", + DRM_DEV_DEBUG_KMS(dev->dev, "dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)exynos_gem->dma_addr, exynos_gem->size); dma_free_attrs(to_dma_dev(dev), exynos_gem->size, exynos_gem->cookie, @@ -139,7 +139,7 @@ static int exynos_drm_gem_handle_create(struct drm_gem_object *obj, if (ret) return ret; - DRM_DEBUG_KMS("gem handle = 0x%x\n", *handle); + DRM_DEV_DEBUG_KMS(to_dma_dev(obj->dev), "gem handle = 0x%x\n", *handle); /* drop reference from allocate - handle holds it now. */ drm_gem_object_put_unlocked(obj); @@ -151,7 +151,8 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem) { struct drm_gem_object *obj = &exynos_gem->base; - DRM_DEBUG_KMS("handle count = %d\n", obj->handle_count); + DRM_DEV_DEBUG_KMS(to_dma_dev(obj->dev), "handle count = %d\n", + obj->handle_count); /* * do not release memory region from exporter. @@ -198,7 +199,7 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev, return ERR_PTR(ret); } - DRM_DEBUG_KMS("created file object = %pK\n", obj->filp); + DRM_DEV_DEBUG_KMS(dev->dev, "created file object = %pK\n", obj->filp); return exynos_gem; } @@ -409,7 +410,8 @@ static int exynos_drm_gem_mmap_obj(struct drm_gem_object *obj, struct exynos_drm_gem *exynos_gem = to_exynos_gem(obj); int ret; - DRM_DEBUG_KMS("flags = 0x%x\n", exynos_gem->flags); + DRM_DEV_DEBUG_KMS(to_dma_dev(obj->dev), "flags = 0x%x\n", + exynos_gem->flags); /* non-cachable as default. */ if (exynos_gem->flags & EXYNOS_BO_CACHABLE) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index ef10e45f9e7d..433df3ef731b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -422,8 +422,8 @@ static void gsc_handle_irq(struct gsc_context *ctx, bool enable, { u32 cfg; - DRM_DEBUG_KMS("enable[%d]overflow[%d]level[%d]\n", - enable, overflow, done); + DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]overflow[%d]level[%d]\n", + enable, overflow, done); cfg = gsc_read(GSC_IRQ); cfg |= (GSC_IRQ_OR_MASK | GSC_IRQ_FRMDONE_MASK); @@ -451,7 +451,7 @@ static void gsc_src_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) { u32 cfg; - DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); + DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); cfg = gsc_read(GSC_IN_CON); cfg &= ~(GSC_IN_RGB_TYPE_MASK | GSC_IN_YUV422_1P_ORDER_MASK | @@ -638,7 +638,7 @@ static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) { u32 cfg; - DRM_DEBUG_KMS("fmt[0x%x]\n", fmt); + DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt); cfg = gsc_read(GSC_OUT_CON); cfg &= ~(GSC_OUT_RGB_TYPE_MASK | GSC_OUT_YUV422_1P_ORDER_MASK | @@ -709,7 +709,7 @@ static void gsc_dst_set_fmt(struct gsc_context *ctx, u32 fmt, bool tiled) static int gsc_get_ratio_shift(struct gsc_context *ctx, u32 src, u32 dst, u32 *ratio) { - DRM_DEBUG_KMS("src[%d]dst[%d]\n", src, dst); + DRM_DEV_DEBUG_KMS(ctx->dev, "src[%d]dst[%d]\n", src, dst); if (src >= dst * 8) { DRM_DEV_ERROR(ctx->dev, "failed to make ratio and shift.\n"); @@ -772,19 +772,19 @@ static int gsc_set_prescaler(struct gsc_context *ctx, struct gsc_scaler *sc, return ret; } - DRM_DEBUG_KMS("pre_hratio[%d]pre_vratio[%d]\n", - sc->pre_hratio, sc->pre_vratio); + DRM_DEV_DEBUG_KMS(ctx->dev, "pre_hratio[%d]pre_vratio[%d]\n", + sc->pre_hratio, sc->pre_vratio); sc->main_hratio = (src_w << 16) / dst_w; sc->main_vratio = (src_h << 16) / dst_h; - DRM_DEBUG_KMS("main_hratio[%ld]main_vratio[%ld]\n", - sc->main_hratio, sc->main_vratio); + DRM_DEV_DEBUG_KMS(ctx->dev, "main_hratio[%ld]main_vratio[%ld]\n", + sc->main_hratio, sc->main_vratio); gsc_get_prescaler_shfactor(sc->pre_hratio, sc->pre_vratio, &sc->pre_shfactor); - DRM_DEBUG_KMS("pre_shfactor[%d]\n", sc->pre_shfactor); + DRM_DEV_DEBUG_KMS(ctx->dev, "pre_shfactor[%d]\n", sc->pre_shfactor); cfg = (GSC_PRESC_SHFACTOR(sc->pre_shfactor) | GSC_PRESC_H_RATIO(sc->pre_hratio) | @@ -850,8 +850,8 @@ static void gsc_set_scaler(struct gsc_context *ctx, struct gsc_scaler *sc) { u32 cfg; - DRM_DEBUG_KMS("main_hratio[%ld]main_vratio[%ld]\n", - sc->main_hratio, sc->main_vratio); + DRM_DEV_DEBUG_KMS(ctx->dev, "main_hratio[%ld]main_vratio[%ld]\n", + sc->main_hratio, sc->main_vratio); gsc_set_h_coef(ctx, sc->main_hratio); cfg = GSC_MAIN_H_RATIO_VALUE(sc->main_hratio); @@ -917,7 +917,7 @@ static int gsc_dst_get_buf_seq(struct gsc_context *ctx) if (cfg & (mask << i)) buf_num--; - DRM_DEBUG_KMS("buf_num[%d]\n", buf_num); + DRM_DEV_DEBUG_KMS(ctx->dev, "buf_num[%d]\n", buf_num); return buf_num; } @@ -964,7 +964,7 @@ static int gsc_get_src_buf_index(struct gsc_context *ctx) u32 cfg, curr_index, i; u32 buf_id = GSC_MAX_SRC; - DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id); cfg = gsc_read(GSC_IN_BASE_ADDR_Y_MASK); curr_index = GSC_IN_CURR_GET_INDEX(cfg); @@ -976,8 +976,8 @@ static int gsc_get_src_buf_index(struct gsc_context *ctx) } } - DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg, - curr_index, buf_id); + DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg, + curr_index, buf_id); if (buf_id == GSC_MAX_SRC) { DRM_DEV_ERROR(ctx->dev, "failed to get in buffer index.\n"); @@ -994,7 +994,7 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx) u32 cfg, curr_index, i; u32 buf_id = GSC_MAX_DST; - DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id); cfg = gsc_read(GSC_OUT_BASE_ADDR_Y_MASK); curr_index = GSC_OUT_CURR_GET_INDEX(cfg); @@ -1013,8 +1013,8 @@ static int gsc_get_dst_buf_index(struct gsc_context *ctx) gsc_dst_set_buf_seq(ctx, buf_id, false); - DRM_DEBUG_KMS("cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg, - curr_index, buf_id); + DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]curr_index[%d]buf_id[%d]\n", cfg, + curr_index, buf_id); return buf_id; } @@ -1025,7 +1025,7 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id) u32 status; int err = 0; - DRM_DEBUG_KMS("gsc id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(ctx->dev, "gsc id[%d]\n", ctx->id); status = gsc_read(GSC_IRQ); if (status & GSC_IRQ_STATUS_OR_IRQ) { @@ -1043,8 +1043,8 @@ static irqreturn_t gsc_irq_handler(int irq, void *dev_id) src_buf_id = gsc_get_src_buf_index(ctx); dst_buf_id = gsc_get_dst_buf_index(ctx); - DRM_DEBUG_KMS("buf_id_src[%d]buf_id_dst[%d]\n", src_buf_id, - dst_buf_id); + DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id_src[%d]buf_id_dst[%d]\n", + src_buf_id, dst_buf_id); if (src_buf_id < 0 || dst_buf_id < 0) err = -EINVAL; @@ -1325,7 +1325,7 @@ static int __maybe_unused gsc_runtime_suspend(struct device *dev) struct gsc_context *ctx = get_gsc_context(dev); int i; - DRM_DEBUG_KMS("id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); for (i = ctx->num_clocks - 1; i >= 0; i--) clk_disable_unprepare(ctx->clocks[i]); @@ -1338,7 +1338,7 @@ static int __maybe_unused gsc_runtime_resume(struct device *dev) struct gsc_context *ctx = get_gsc_context(dev); int i, ret; - DRM_DEBUG_KMS("id[%d]\n", ctx->id); + DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id); for (i = 0; i < ctx->num_clocks; i++) { ret = clk_prepare_enable(ctx->clocks[i]); diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 23226a0212e8..a1ee5416927d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -67,7 +67,7 @@ int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp, list_add_tail(&ipp->head, &ipp_list); ipp->id = num_ipp++; - DRM_DEBUG_DRIVER("Registered ipp %d\n", ipp->id); + DRM_DEV_DEBUG_DRIVER(dev->dev, "Registered ipp %d\n", ipp->id); return 0; } @@ -268,7 +268,7 @@ static inline struct exynos_drm_ipp_task * task->src.rect.h = task->dst.rect.h = UINT_MAX; task->transform.rotation = DRM_MODE_ROTATE_0; - DRM_DEBUG_DRIVER("Allocated task %pK\n", task); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Allocated task %pK\n", task); return task; } @@ -335,7 +335,9 @@ static int exynos_drm_ipp_task_set(struct exynos_drm_ipp_task *task, size -= map[i].size; } - DRM_DEBUG_DRIVER("Got task %pK configuration from userspace\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev->dev, + "Got task %pK configuration from userspace\n", + task); return 0; } @@ -389,7 +391,7 @@ static void exynos_drm_ipp_task_release_buf(struct exynos_drm_ipp_buffer *buf) static void exynos_drm_ipp_task_free(struct exynos_drm_ipp *ipp, struct exynos_drm_ipp_task *task) { - DRM_DEBUG_DRIVER("Freeing task %pK\n", task); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Freeing task %pK\n", task); exynos_drm_ipp_task_release_buf(&task->src); exynos_drm_ipp_task_release_buf(&task->dst); @@ -553,8 +555,9 @@ static int exynos_drm_ipp_check_format(struct exynos_drm_ipp_task *task, buf == src ? DRM_EXYNOS_IPP_FORMAT_SOURCE : DRM_EXYNOS_IPP_FORMAT_DESTINATION); if (!fmt) { - DRM_DEBUG_DRIVER("Task %pK: %s format not supported\n", task, - buf == src ? "src" : "dst"); + DRM_DEV_DEBUG_DRIVER(task->dev->dev, + "Task %pK: %s format not supported\n", + task, buf == src ? "src" : "dst"); return -EINVAL; } @@ -603,7 +606,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) bool rotate = (rotation != DRM_MODE_ROTATE_0); bool scale = false; - DRM_DEBUG_DRIVER("Checking task %pK\n", task); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Checking task %pK\n", task); if (src->rect.w == UINT_MAX) src->rect.w = src->buf.width; @@ -618,8 +621,9 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) src->rect.y + src->rect.h > (src->buf.height) || dst->rect.x + dst->rect.w > (dst->buf.width) || dst->rect.y + dst->rect.h > (dst->buf.height)) { - DRM_DEBUG_DRIVER("Task %pK: defined area is outside provided buffers\n", - task); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, + "Task %pK: defined area is outside provided buffers\n", + task); return -EINVAL; } @@ -635,7 +639,8 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) (!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_SCALE) && scale) || (!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_CONVERT) && src->buf.fourcc != dst->buf.fourcc)) { - DRM_DEBUG_DRIVER("Task %pK: hw capabilities exceeded\n", task); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Task %pK: hw capabilities exceeded\n", + task); return -EINVAL; } @@ -647,7 +652,8 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) if (ret) return ret; - DRM_DEBUG_DRIVER("Task %pK: all checks done.\n", task); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Task %pK: all checks done.\n", + task); return ret; } @@ -658,20 +664,26 @@ static int exynos_drm_ipp_task_setup_buffers(struct exynos_drm_ipp_task *task, struct exynos_drm_ipp_buffer *src = &task->src, *dst = &task->dst; int ret = 0; - DRM_DEBUG_DRIVER("Setting buffer for task %pK\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev->dev, "Setting buffer for task %pK\n", + task); ret = exynos_drm_ipp_task_setup_buffer(src, filp); if (ret) { - DRM_DEBUG_DRIVER("Task %pK: src buffer setup failed\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev->dev, + "Task %pK: src buffer setup failed\n", + task); return ret; } ret = exynos_drm_ipp_task_setup_buffer(dst, filp); if (ret) { - DRM_DEBUG_DRIVER("Task %pK: dst buffer setup failed\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev->dev, + "Task %pK: dst buffer setup failed\n", + task); return ret; } - DRM_DEBUG_DRIVER("Task %pK: buffers prepared.\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev->dev, "Task %pK: buffers prepared.\n", + task); return ret; } @@ -749,7 +761,8 @@ void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret) struct exynos_drm_ipp *ipp = task->ipp; unsigned long flags; - DRM_DEBUG_DRIVER("ipp: %d, task %pK done: %d\n", ipp->id, task, ret); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "ipp: %d, task %pK done: %d\n", + ipp->id, task, ret); spin_lock_irqsave(&ipp->lock, flags); if (ipp->task == task) @@ -773,7 +786,8 @@ static void exynos_drm_ipp_next_task(struct exynos_drm_ipp *ipp) unsigned long flags; int ret; - DRM_DEBUG_DRIVER("ipp: %d, try to run new task\n", ipp->id); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "ipp: %d, try to run new task\n", + ipp->id); spin_lock_irqsave(&ipp->lock, flags); @@ -789,7 +803,9 @@ static void exynos_drm_ipp_next_task(struct exynos_drm_ipp *ipp) spin_unlock_irqrestore(&ipp->lock, flags); - DRM_DEBUG_DRIVER("ipp: %d, selected task %pK to run\n", ipp->id, task); + DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, + "ipp: %d, selected task %pK to run\n", ipp->id, + task); ret = ipp->funcs->commit(ipp, task); if (ret) @@ -897,15 +913,16 @@ int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, void *data, * then freed after exynos_drm_ipp_task_done() */ if (arg->flags & DRM_EXYNOS_IPP_FLAG_NONBLOCK) { - DRM_DEBUG_DRIVER("ipp: %d, nonblocking processing task %pK\n", - ipp->id, task); + DRM_DEV_DEBUG_DRIVER(dev->dev, + "ipp: %d, nonblocking processing task %pK\n", + ipp->id, task); task->flags |= DRM_EXYNOS_IPP_TASK_ASYNC; exynos_drm_ipp_schedule_task(task->ipp, task); ret = 0; } else { - DRM_DEBUG_DRIVER("ipp: %d, processing task %pK\n", ipp->id, - task); + DRM_DEV_DEBUG_DRIVER(dev->dev, "ipp: %d, processing task %pK\n", + ipp->id, task); exynos_drm_ipp_schedule_task(ipp, task); ret = wait_event_interruptible(ipp->done_wq, task->flags & DRM_EXYNOS_IPP_TASK_DONE); diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index ddf5b4dfd6c3..d1c8411ae7d4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -192,7 +192,7 @@ static void mic_set_output_timing(struct exynos_mic *mic) struct videomode vm = mic->vm; u32 reg, bs_size_2d; - DRM_DEBUG("w: %u, h: %u\n", vm.hactive, vm.vactive); + DRM_DEV_DEBUG(mic->dev, "w: %u, h: %u\n", vm.hactive, vm.vactive); bs_size_2d = ((vm.hactive >> 2) << 1) + (vm.vactive % 4); reg = MIC_BS_SIZE_2D(bs_size_2d); writel(reg, mic->reg + MIC_2D_OUTPUT_TIMING_2); @@ -433,7 +433,7 @@ static int exynos_mic_probe(struct platform_device *pdev) if (ret) goto err_pm; - DRM_DEBUG_KMS("MIC has been probed\n"); + DRM_DEV_DEBUG_KMS(dev, "MIC has been probed\n"); return 0; diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 6328565f889e..e18babb25170 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -119,9 +119,10 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) exynos_state->crtc.w = actual_w; exynos_state->crtc.h = actual_h; - DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)", - exynos_state->crtc.x, exynos_state->crtc.y, - exynos_state->crtc.w, exynos_state->crtc.h); + DRM_DEV_DEBUG_KMS(crtc->dev->dev, + "plane : offset_x/y(%d,%d), width/height(%d,%d)", + exynos_state->crtc.x, exynos_state->crtc.y, + exynos_state->crtc.w, exynos_state->crtc.h); } static void exynos_drm_plane_reset(struct drm_plane *plane) @@ -204,6 +205,7 @@ static int exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config, struct exynos_drm_plane_state *state) { + struct drm_crtc *crtc = state->base.crtc; bool width_ok = false, height_ok = false; if (config->capabilities & EXYNOS_DRM_PLANE_CAP_SCALE) @@ -226,7 +228,7 @@ exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config, if (width_ok && height_ok) return 0; - DRM_DEBUG_KMS("scaling mode is not supported"); + DRM_DEV_DEBUG_KMS(crtc->dev->dev, "scaling mode is not supported"); return -ENOTSUPP; } diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 302275604b87..08e610cb9a48 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -123,7 +123,7 @@ static void vidi_update_plane(struct exynos_drm_crtc *crtc, return; addr = exynos_drm_fb_dma_addr(state->fb, 0); - DRM_DEBUG_KMS("dma_addr = %pad\n", &addr); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, "dma_addr = %pad\n", &addr); } static void vidi_enable(struct exynos_drm_crtc *crtc) @@ -205,11 +205,11 @@ static ssize_t vidi_store_connection(struct device *dev, /* if raw_edid isn't same as fake data then it can't be tested. */ if (ctx->raw_edid != (struct edid *)fake_edid_info) { - DRM_DEBUG_KMS("edid data is not fake data.\n"); + DRM_DEV_DEBUG_KMS(dev, "edid data is not fake data.\n"); return -EINVAL; } - DRM_DEBUG_KMS("requested connection.\n"); + DRM_DEV_DEBUG_KMS(dev, "requested connection.\n"); drm_helper_hpd_irq_event(ctx->drm_dev); @@ -226,17 +226,20 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, struct drm_exynos_vidi_connection *vidi = data; if (!vidi) { - DRM_DEBUG_KMS("user data for vidi is null.\n"); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + "user data for vidi is null.\n"); return -EINVAL; } if (vidi->connection > 1) { - DRM_DEBUG_KMS("connection should be 0 or 1.\n"); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + "connection should be 0 or 1.\n"); return -EINVAL; } if (ctx->connected == vidi->connection) { - DRM_DEBUG_KMS("same connection request.\n"); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + "same connection request.\n"); return -EINVAL; } @@ -245,12 +248,14 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, raw_edid = (struct edid *)(unsigned long)vidi->edid; if (!drm_edid_is_valid(raw_edid)) { - DRM_DEBUG_KMS("edid data is invalid.\n"); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + "edid data is invalid.\n"); return -EINVAL; } ctx->raw_edid = drm_edid_duplicate(raw_edid); if (!ctx->raw_edid) { - DRM_DEBUG_KMS("failed to allocate raw_edid.\n"); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + "failed to allocate raw_edid.\n"); return -ENOMEM; } } else { @@ -308,14 +313,14 @@ static int vidi_get_modes(struct drm_connector *connector) * to ctx->raw_edid through specific ioctl. */ if (!ctx->raw_edid) { - DRM_DEBUG_KMS("raw_edid is null.\n"); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, "raw_edid is null.\n"); return -EFAULT; } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); if (!edid) { - DRM_DEBUG_KMS("failed to allocate edid\n"); + DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, "failed to allocate edid\n"); return -ENOMEM; } diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index d391e2f6d271..19c252f659dd 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -885,9 +885,9 @@ static int hdmi_get_modes(struct drm_connector *connector) return -ENODEV; hdata->dvi_mode = !drm_detect_hdmi_monitor(edid); - DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", - (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), - edid->width_cm, edid->height_cm); + DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n", + (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), + edid->width_cm, edid->height_cm); drm_connector_update_edid_property(connector, edid); cec_notifier_set_phys_addr_from_edid(hdata->notifier, edid); @@ -908,7 +908,8 @@ static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) if (confs->data[i].pixel_clock == pixel_clock) return i; - DRM_DEBUG_KMS("Could not find phy config for %d\n", pixel_clock); + DRM_DEV_DEBUG_KMS(hdata->dev, "Could not find phy config for %d\n", + pixel_clock); return -EINVAL; } @@ -918,10 +919,11 @@ static int hdmi_mode_valid(struct drm_connector *connector, struct hdmi_context *hdata = connector_to_hdmi(connector); int ret; - DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", - mode->hdisplay, mode->vdisplay, mode->vrefresh, - (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true : - false, mode->clock * 1000); + DRM_DEV_DEBUG_KMS(hdata->dev, + "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", + mode->hdisplay, mode->vdisplay, mode->vrefresh, + (mode->flags & DRM_MODE_FLAG_INTERLACE) ? true : + false, mode->clock * 1000); ret = hdmi_find_phy_conf(hdata, mode->clock * 1000); if (ret < 0) @@ -1003,8 +1005,10 @@ static bool hdmi_mode_fixup(struct drm_encoder *encoder, DRM_INFO("desired mode doesn't exist so\n"); DRM_INFO("use the most suitable mode among modes.\n"); - DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n", - m->hdisplay, m->vdisplay, m->vrefresh); + DRM_DEV_DEBUG_KMS(dev->dev, + "Adjusted Mode: [%d]x[%d] [%d]Hz\n", + m->hdisplay, m->vdisplay, + m->vrefresh); drm_mode_copy(adjusted_mode, m); break; @@ -1170,7 +1174,9 @@ static void hdmiphy_wait_for_pll(struct hdmi_context *hdata) u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS); if (val & HDMI_PHY_STATUS_READY) { - DRM_DEBUG_KMS("PLL stabilized after %d tries\n", tries); + DRM_DEV_DEBUG_KMS(hdata->dev, + "PLL stabilized after %d tries\n", + tries); return; } usleep_range(10, 20); @@ -1461,7 +1467,8 @@ static void hdmiphy_enable(struct hdmi_context *hdata) pm_runtime_get_sync(hdata->dev); if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk)) - DRM_DEBUG_KMS("failed to enable regulator bulk\n"); + DRM_DEV_DEBUG_KMS(hdata->dev, + "failed to enable regulator bulk\n"); regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, PMU_HDMI_PHY_ENABLE_BIT, 1); @@ -1753,7 +1760,7 @@ static int hdmi_resources_init(struct hdmi_context *hdata) struct device *dev = hdata->dev; int i, ret; - DRM_DEBUG_KMS("HDMI resource init\n"); + DRM_DEV_DEBUG_KMS(dev, "HDMI resource init\n"); hdata->hpd_gpio = devm_gpiod_get(dev, "hpd", GPIOD_IN); if (IS_ERR(hdata->hpd_gpio)) { diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 9bda3d4bd17a..b8415e53964d 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -228,8 +228,8 @@ static void mixer_regs_dump(struct mixer_context *ctx) { #define DUMPREG(reg_id) \ do { \ - DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32)readl(ctx->mixer_regs + reg_id)); \ + DRM_DEV_DEBUG_KMS(ctx->dev, #reg_id " = %08x\n", \ + (u32)readl(ctx->mixer_regs + reg_id)); \ } while (0) DUMPREG(MXR_STATUS); @@ -260,8 +260,8 @@ static void vp_regs_dump(struct mixer_context *ctx) { #define DUMPREG(reg_id) \ do { \ - DRM_DEBUG_KMS(#reg_id " = %08x\n", \ - (u32) readl(ctx->vp_regs + reg_id)); \ + DRM_DEV_DEBUG_KMS(ctx->dev, #reg_id " = %08x\n", \ + (u32) readl(ctx->vp_regs + reg_id)); \ } while (0) DUMPREG(VP_ENABLE); @@ -954,7 +954,7 @@ static void mixer_update_plane(struct exynos_drm_crtc *crtc, { struct mixer_context *mixer_ctx = crtc->ctx; - DRM_DEBUG_KMS("win: %d\n", plane->index); + DRM_DEV_DEBUG_KMS(mixer_ctx->dev, "win: %d\n", plane->index); if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) return; @@ -971,7 +971,7 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc, struct mixer_context *mixer_ctx = crtc->ctx; unsigned long flags; - DRM_DEBUG_KMS("win: %d\n", plane->index); + DRM_DEV_DEBUG_KMS(mixer_ctx->dev, "win: %d\n", plane->index); if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) return; @@ -1048,8 +1048,9 @@ static int mixer_mode_valid(struct exynos_drm_crtc *crtc, struct mixer_context *ctx = crtc->ctx; u32 w = mode->hdisplay, h = mode->vdisplay; - DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n", w, h, - mode->vrefresh, !!(mode->flags & DRM_MODE_FLAG_INTERLACE)); + DRM_DEV_DEBUG_KMS(ctx->dev, "xres=%d, yres=%d, refresh=%d, intl=%d\n", + w, h, mode->vrefresh, + !!(mode->flags & DRM_MODE_FLAG_INTERLACE)); if (ctx->mxr_ver == MXR_VER_128_0_0_184) return MODE_OK; -- cgit v1.2.3 From df90a64eaf57b89ebc910ad0e4e2b4c3dc1567b9 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 15 Apr 2019 16:35:08 +0900 Subject: drm/vidi: replace platform_device pointer with device one Add device pointer to vidi_context and remove platform_device pointer. It doesn't need for vidi_context to contain platform_device object. Instead, this patch makes this driver more simply by replacing platform_device pointer with device one. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 33 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 08e610cb9a48..44bcb2d60bb2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -40,8 +40,8 @@ struct vidi_context { struct drm_encoder encoder; - struct platform_device *pdev; struct drm_device *drm_dev; + struct device *dev; struct exynos_drm_crtc *crtc; struct drm_connector connector; struct exynos_drm_plane planes[WINDOWS_NR]; @@ -123,7 +123,7 @@ static void vidi_update_plane(struct exynos_drm_crtc *crtc, return; addr = exynos_drm_fb_dma_addr(state->fb, 0); - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, "dma_addr = %pad\n", &addr); + DRM_DEV_DEBUG_KMS(ctx->dev, "dma_addr = %pad\n", &addr); } static void vidi_enable(struct exynos_drm_crtc *crtc) @@ -226,19 +226,19 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, struct drm_exynos_vidi_connection *vidi = data; if (!vidi) { - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + DRM_DEV_DEBUG_KMS(ctx->dev, "user data for vidi is null.\n"); return -EINVAL; } if (vidi->connection > 1) { - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + DRM_DEV_DEBUG_KMS(ctx->dev, "connection should be 0 or 1.\n"); return -EINVAL; } if (ctx->connected == vidi->connection) { - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + DRM_DEV_DEBUG_KMS(ctx->dev, "same connection request.\n"); return -EINVAL; } @@ -248,13 +248,13 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, raw_edid = (struct edid *)(unsigned long)vidi->edid; if (!drm_edid_is_valid(raw_edid)) { - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + DRM_DEV_DEBUG_KMS(ctx->dev, "edid data is invalid.\n"); return -EINVAL; } ctx->raw_edid = drm_edid_duplicate(raw_edid); if (!ctx->raw_edid) { - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, + DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate raw_edid.\n"); return -ENOMEM; } @@ -313,14 +313,14 @@ static int vidi_get_modes(struct drm_connector *connector) * to ctx->raw_edid through specific ioctl. */ if (!ctx->raw_edid) { - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, "raw_edid is null.\n"); + DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n"); return -EFAULT; } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); if (!edid) { - DRM_DEV_DEBUG_KMS(&ctx->pdev->dev, "failed to allocate edid\n"); + DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n"); return -ENOMEM; } @@ -344,7 +344,7 @@ static int vidi_create_connector(struct drm_encoder *encoder) ret = drm_connector_init(ctx->drm_dev, connector, &vidi_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); if (ret) { - DRM_DEV_ERROR(ctx->drm_dev->dev, + DRM_DEV_ERROR(ctx->dev, "Failed to initialize connector with drm\n"); return ret; } @@ -448,13 +448,14 @@ static const struct component_ops vidi_component_ops = { static int vidi_probe(struct platform_device *pdev) { struct vidi_context *ctx; + struct device *dev = &pdev->dev; int ret; - ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; - ctx->pdev = pdev; + ctx->dev = dev; timer_setup(&ctx->timer, vidi_fake_vblank_timer, 0); @@ -462,21 +463,21 @@ static int vidi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); - ret = device_create_file(&pdev->dev, &dev_attr_connection); + ret = device_create_file(dev, &dev_attr_connection); if (ret < 0) { - DRM_DEV_ERROR(&pdev->dev, + DRM_DEV_ERROR(dev, "failed to create connection sysfs.\n"); return ret; } - ret = component_add(&pdev->dev, &vidi_component_ops); + ret = component_add(dev, &vidi_component_ops); if (ret) goto err_remove_file; return ret; err_remove_file: - device_remove_file(&pdev->dev, &dev_attr_connection); + device_remove_file(dev, &dev_attr_connection); return ret; } -- cgit v1.2.3 From 8b9550344d3914cf606f365b6fa4279fb3cd4684 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 15 Apr 2019 17:13:38 +0900 Subject: drm/ipp: clean up debug messages Print out debug messages with correct device name. As for this, this patch adds device pointer to exynos_drm_ipp structure, and in case of exynos_drm_ipp_task structure, replace drm_device pointer with device one. This will make each ipp driver to print out debug messages with correct device name. Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimc.c | 5 ++-- drivers/gpu/drm/exynos/exynos_drm_gsc.c | 5 ++-- drivers/gpu/drm/exynos/exynos_drm_ipp.c | 46 ++++++++++++++--------------- drivers/gpu/drm/exynos/exynos_drm_ipp.h | 9 +++--- drivers/gpu/drm/exynos/exynos_drm_rotator.c | 6 ++-- drivers/gpu/drm/exynos/exynos_drm_scaler.c | 6 ++-- 6 files changed, 40 insertions(+), 37 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimc.c b/drivers/gpu/drm/exynos/exynos_drm_fimc.c index 71b0cb123a56..c50b0f9270a4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -1134,9 +1134,10 @@ static int fimc_bind(struct device *dev, struct device *master, void *data) struct exynos_drm_ipp *ipp = &ctx->ipp; ctx->drm_dev = drm_dev; + ipp->drm_dev = drm_dev; exynos_drm_register_dma(drm_dev, dev); - exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, + exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT, ctx->formats, ctx->num_formats, "fimc"); @@ -1153,7 +1154,7 @@ static void fimc_unbind(struct device *dev, struct device *master, struct drm_device *drm_dev = data; struct exynos_drm_ipp *ipp = &ctx->ipp; - exynos_drm_ipp_unregister(drm_dev, ipp); + exynos_drm_ipp_unregister(dev, ipp); exynos_drm_unregister_dma(drm_dev, dev); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 433df3ef731b..0bfb5e9f6e91 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -1169,10 +1169,11 @@ static int gsc_bind(struct device *dev, struct device *master, void *data) struct drm_device *drm_dev = data; struct exynos_drm_ipp *ipp = &ctx->ipp; + ctx->drm_dev = drm_dev; ctx->drm_dev = drm_dev; exynos_drm_register_dma(drm_dev, dev); - exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, + exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT, ctx->formats, ctx->num_formats, "gsc"); @@ -1189,7 +1190,7 @@ static void gsc_unbind(struct device *dev, struct device *master, struct drm_device *drm_dev = data; struct exynos_drm_ipp *ipp = &ctx->ipp; - exynos_drm_ipp_unregister(drm_dev, ipp); + exynos_drm_ipp_unregister(dev, ipp); exynos_drm_unregister_dma(drm_dev, dev); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index a1ee5416927d..c862099723a0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -43,7 +43,7 @@ static LIST_HEAD(ipp_list); * Returns: * Zero on success, error code on failure. */ -int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp, +int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp, const struct exynos_drm_ipp_funcs *funcs, unsigned int caps, const struct exynos_drm_ipp_formats *formats, unsigned int num_formats, const char *name) @@ -67,7 +67,7 @@ int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp, list_add_tail(&ipp->head, &ipp_list); ipp->id = num_ipp++; - DRM_DEV_DEBUG_DRIVER(dev->dev, "Registered ipp %d\n", ipp->id); + DRM_DEV_DEBUG_DRIVER(dev, "Registered ipp %d\n", ipp->id); return 0; } @@ -77,7 +77,7 @@ int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp, * @dev: DRM device * @ipp: ipp module */ -void exynos_drm_ipp_unregister(struct drm_device *dev, +void exynos_drm_ipp_unregister(struct device *dev, struct exynos_drm_ipp *ipp) { WARN_ON(ipp->task); @@ -268,7 +268,7 @@ static inline struct exynos_drm_ipp_task * task->src.rect.h = task->dst.rect.h = UINT_MAX; task->transform.rotation = DRM_MODE_ROTATE_0; - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Allocated task %pK\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev, "Allocated task %pK\n", task); return task; } @@ -335,7 +335,7 @@ static int exynos_drm_ipp_task_set(struct exynos_drm_ipp_task *task, size -= map[i].size; } - DRM_DEV_DEBUG_DRIVER(task->dev->dev, + DRM_DEV_DEBUG_DRIVER(task->dev, "Got task %pK configuration from userspace\n", task); return 0; @@ -391,12 +391,12 @@ static void exynos_drm_ipp_task_release_buf(struct exynos_drm_ipp_buffer *buf) static void exynos_drm_ipp_task_free(struct exynos_drm_ipp *ipp, struct exynos_drm_ipp_task *task) { - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Freeing task %pK\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev, "Freeing task %pK\n", task); exynos_drm_ipp_task_release_buf(&task->src); exynos_drm_ipp_task_release_buf(&task->dst); if (task->event) - drm_event_cancel_free(ipp->dev, &task->event->base); + drm_event_cancel_free(ipp->drm_dev, &task->event->base); kfree(task); } @@ -555,7 +555,7 @@ static int exynos_drm_ipp_check_format(struct exynos_drm_ipp_task *task, buf == src ? DRM_EXYNOS_IPP_FORMAT_SOURCE : DRM_EXYNOS_IPP_FORMAT_DESTINATION); if (!fmt) { - DRM_DEV_DEBUG_DRIVER(task->dev->dev, + DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: %s format not supported\n", task, buf == src ? "src" : "dst"); return -EINVAL; @@ -606,7 +606,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) bool rotate = (rotation != DRM_MODE_ROTATE_0); bool scale = false; - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Checking task %pK\n", task); + DRM_DEV_DEBUG_DRIVER(task->dev, "Checking task %pK\n", task); if (src->rect.w == UINT_MAX) src->rect.w = src->buf.width; @@ -621,7 +621,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) src->rect.y + src->rect.h > (src->buf.height) || dst->rect.x + dst->rect.w > (dst->buf.width) || dst->rect.y + dst->rect.h > (dst->buf.height)) { - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, + DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: defined area is outside provided buffers\n", task); return -EINVAL; @@ -639,7 +639,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) (!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_SCALE) && scale) || (!(ipp->capabilities & DRM_EXYNOS_IPP_CAP_CONVERT) && src->buf.fourcc != dst->buf.fourcc)) { - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Task %pK: hw capabilities exceeded\n", + DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: hw capabilities exceeded\n", task); return -EINVAL; } @@ -652,7 +652,7 @@ static int exynos_drm_ipp_task_check(struct exynos_drm_ipp_task *task) if (ret) return ret; - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "Task %pK: all checks done.\n", + DRM_DEV_DEBUG_DRIVER(ipp->dev, "Task %pK: all checks done.\n", task); return ret; @@ -664,25 +664,25 @@ static int exynos_drm_ipp_task_setup_buffers(struct exynos_drm_ipp_task *task, struct exynos_drm_ipp_buffer *src = &task->src, *dst = &task->dst; int ret = 0; - DRM_DEV_DEBUG_DRIVER(task->dev->dev, "Setting buffer for task %pK\n", + DRM_DEV_DEBUG_DRIVER(task->dev, "Setting buffer for task %pK\n", task); ret = exynos_drm_ipp_task_setup_buffer(src, filp); if (ret) { - DRM_DEV_DEBUG_DRIVER(task->dev->dev, + DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: src buffer setup failed\n", task); return ret; } ret = exynos_drm_ipp_task_setup_buffer(dst, filp); if (ret) { - DRM_DEV_DEBUG_DRIVER(task->dev->dev, + DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: dst buffer setup failed\n", task); return ret; } - DRM_DEV_DEBUG_DRIVER(task->dev->dev, "Task %pK: buffers prepared.\n", + DRM_DEV_DEBUG_DRIVER(task->dev, "Task %pK: buffers prepared.\n", task); return ret; @@ -703,7 +703,7 @@ static int exynos_drm_ipp_event_create(struct exynos_drm_ipp_task *task, e->event.base.length = sizeof(e->event); e->event.user_data = user_data; - ret = drm_event_reserve_init(task->dev, file_priv, &e->base, + ret = drm_event_reserve_init(task->ipp->drm_dev, file_priv, &e->base, &e->event.base); if (ret) goto free; @@ -724,7 +724,7 @@ static void exynos_drm_ipp_event_send(struct exynos_drm_ipp_task *task) task->event->event.tv_usec = now.tv_nsec / NSEC_PER_USEC; task->event->event.sequence = atomic_inc_return(&task->ipp->sequence); - drm_send_event(task->dev, &task->event->base); + drm_send_event(task->ipp->drm_dev, &task->event->base); } static int exynos_drm_ipp_task_cleanup(struct exynos_drm_ipp_task *task) @@ -761,7 +761,7 @@ void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret) struct exynos_drm_ipp *ipp = task->ipp; unsigned long flags; - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "ipp: %d, task %pK done: %d\n", + DRM_DEV_DEBUG_DRIVER(task->dev, "ipp: %d, task %pK done: %d\n", ipp->id, task, ret); spin_lock_irqsave(&ipp->lock, flags); @@ -786,7 +786,7 @@ static void exynos_drm_ipp_next_task(struct exynos_drm_ipp *ipp) unsigned long flags; int ret; - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, "ipp: %d, try to run new task\n", + DRM_DEV_DEBUG_DRIVER(ipp->dev, "ipp: %d, try to run new task\n", ipp->id); spin_lock_irqsave(&ipp->lock, flags); @@ -803,7 +803,7 @@ static void exynos_drm_ipp_next_task(struct exynos_drm_ipp *ipp) spin_unlock_irqrestore(&ipp->lock, flags); - DRM_DEV_DEBUG_DRIVER(ipp->dev->dev, + DRM_DEV_DEBUG_DRIVER(ipp->dev, "ipp: %d, selected task %pK to run\n", ipp->id, task); @@ -913,7 +913,7 @@ int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, void *data, * then freed after exynos_drm_ipp_task_done() */ if (arg->flags & DRM_EXYNOS_IPP_FLAG_NONBLOCK) { - DRM_DEV_DEBUG_DRIVER(dev->dev, + DRM_DEV_DEBUG_DRIVER(ipp->dev, "ipp: %d, nonblocking processing task %pK\n", ipp->id, task); @@ -921,7 +921,7 @@ int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, void *data, exynos_drm_ipp_schedule_task(task->ipp, task); ret = 0; } else { - DRM_DEV_DEBUG_DRIVER(dev->dev, "ipp: %d, processing task %pK\n", + DRM_DEV_DEBUG_DRIVER(ipp->dev, "ipp: %d, processing task %pK\n", ipp->id, task); exynos_drm_ipp_schedule_task(ipp, task); ret = wait_event_interruptible(ipp->done_wq, diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h index 0b27d4a9bf94..5524c457a947 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h @@ -54,7 +54,8 @@ struct exynos_drm_ipp_funcs { * struct exynos_drm_ipp - central picture processor module structure */ struct exynos_drm_ipp { - struct drm_device *dev; + struct drm_device *drm_dev; + struct device *dev; struct list_head head; unsigned int id; @@ -85,7 +86,7 @@ struct exynos_drm_ipp_buffer { * has to be performed by the picture processor hardware module */ struct exynos_drm_ipp_task { - struct drm_device *dev; + struct device *dev; struct exynos_drm_ipp *ipp; struct list_head head; @@ -129,11 +130,11 @@ struct exynos_drm_ipp_formats { #define IPP_SCALE_LIMIT(val...) \ .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val -int exynos_drm_ipp_register(struct drm_device *dev, struct exynos_drm_ipp *ipp, +int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp, const struct exynos_drm_ipp_funcs *funcs, unsigned int caps, const struct exynos_drm_ipp_formats *formats, unsigned int num_formats, const char *name); -void exynos_drm_ipp_unregister(struct drm_device *dev, +void exynos_drm_ipp_unregister(struct device *dev, struct exynos_drm_ipp *ipp); void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret); diff --git a/drivers/gpu/drm/exynos/exynos_drm_rotator.c b/drivers/gpu/drm/exynos/exynos_drm_rotator.c index 05abfed6f7f8..b6586fa95ad1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ b/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -243,9 +243,10 @@ static int rotator_bind(struct device *dev, struct device *master, void *data) struct exynos_drm_ipp *ipp = &rot->ipp; rot->drm_dev = drm_dev; + ipp->drm_dev = drm_dev; exynos_drm_register_dma(drm_dev, dev); - exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, + exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE, rot->formats, rot->num_formats, "rotator"); @@ -258,10 +259,9 @@ static void rotator_unbind(struct device *dev, struct device *master, void *data) { struct rot_context *rot = dev_get_drvdata(dev); - struct drm_device *drm_dev = data; struct exynos_drm_ipp *ipp = &rot->ipp; - exynos_drm_ipp_unregister(drm_dev, ipp); + exynos_drm_ipp_unregister(dev, ipp); exynos_drm_unregister_dma(rot->drm_dev, rot->dev); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_scaler.c b/drivers/gpu/drm/exynos/exynos_drm_scaler.c index ed1dd1aec902..f1cbdd1e6e3c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_scaler.c +++ b/drivers/gpu/drm/exynos/exynos_drm_scaler.c @@ -451,9 +451,10 @@ static int scaler_bind(struct device *dev, struct device *master, void *data) struct exynos_drm_ipp *ipp = &scaler->ipp; scaler->drm_dev = drm_dev; + ipp->drm_dev = drm_dev; exynos_drm_register_dma(drm_dev, dev); - exynos_drm_ipp_register(drm_dev, ipp, &ipp_funcs, + exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT, scaler->scaler_data->formats, @@ -468,10 +469,9 @@ static void scaler_unbind(struct device *dev, struct device *master, void *data) { struct scaler_context *scaler = dev_get_drvdata(dev); - struct drm_device *drm_dev = data; struct exynos_drm_ipp *ipp = &scaler->ipp; - exynos_drm_ipp_unregister(drm_dev, ipp); + exynos_drm_ipp_unregister(dev, ipp); exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev); } -- cgit v1.2.3 From b30a43ac7132cdda833ac4b13dd1ebd35ace14b7 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Apr 2019 16:45:15 +1000 Subject: drm/nouveau: add kconfig option to turn off nouveau legacy contexts. (v3) There was a nouveau DDX that relied on legacy context ioctls to work, but we fixed it years ago, give distros that have a modern DDX the option to break the uAPI and close the mess of holes that legacy context support is. Full context of the story: commit 0e975980d435d58df2d430d688b8c18778b42218 Author: Peter Antoine Date: Tue Jun 23 08:18:49 2015 +0100 drm: Turn off Legacy Context Functions The context functions are not used by the i915 driver and should not be used by modeset drivers. These driver functions contain several bugs and security holes. This change makes these functions optional can be turned on by a setting, they are turned off by default for modeset driver with the exception of the nouvea driver that may require them with an old version of libdrm. The previous attempt was commit 7c510133d93dd6f15ca040733ba7b2891ed61fd1 Author: Daniel Vetter Date: Thu Aug 8 15:41:21 2013 +0200 drm: mark context support as a legacy subsystem but this had to be reverted commit c21eb21cb50d58e7cbdcb8b9e7ff68b85cfa5095 Author: Dave Airlie Date: Fri Sep 20 08:32:59 2013 +1000 Revert "drm: mark context support as a legacy subsystem" v2: remove returns from void function, and formatting (Daniel Vetter) v3: - s/Nova/nouveau/ in the commit message, and add references to the previous attempts - drop the part touching the drm hw lock, that should be a separate patch. Signed-off-by: Peter Antoine (v2) Cc: Peter Antoine (v2) Reviewed-by: Peter Antoine Signed-off-by: Daniel Vetter v2: move DRM_VM dependency into legacy config. v3: fix missing dep (kbuild robot) Cc: stable@vger.kernel.org Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/Kconfig | 13 ++++++++++++- drivers/gpu/drm/nouveau/nouveau_drm.c | 7 +++++-- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 00cd9ab8948d..db28012dbf54 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -17,10 +17,21 @@ config DRM_NOUVEAU select INPUT if ACPI && X86 select THERMAL if ACPI && X86 select ACPI_VIDEO if ACPI && X86 - select DRM_VM help Choose this option for open-source NVIDIA support. +config NOUVEAU_LEGACY_CTX_SUPPORT + bool "Nouveau legacy context support" + depends on DRM_NOUVEAU + select DRM_VM + default y + help + There was a version of the nouveau DDX that relied on legacy + ctx ioctls not erroring out. But that was back in time a long + ways, so offer a way to disable it now. For uapi compat with + old nouveau ddx this should be on by default, but modern distros + should consider turning it off. + config NOUVEAU_PLATFORM_DRIVER bool "Nouveau (NVIDIA) SoC GPUs" depends on DRM_NOUVEAU && ARCH_TEGRA diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 5020265bfbd9..6ab9033f49da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1094,8 +1094,11 @@ nouveau_driver_fops = { static struct drm_driver driver_stub = { .driver_features = - DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER | - DRIVER_KMS_LEGACY_CONTEXT, + DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER +#if defined(CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT) + | DRIVER_KMS_LEGACY_CONTEXT +#endif + , .open = nouveau_drm_open, .postclose = nouveau_drm_postclose, -- cgit v1.2.3 From 15e60851e191c0e4ad19d755da7b92fefbf10c7e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 08:42:23 +1000 Subject: drm/legacy: move drm_legacy_master_rmmaps to non-driver legacy header. This isn't used by drivers, and won't be in the future. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_legacy.h | 3 +++ include/drm/drm_legacy.h | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index 280fbeb846ff..e6bf1a94374b 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -81,6 +81,9 @@ int __drm_legacy_mapbufs(struct drm_device *, void *, int *, int (*)(void *, int, unsigned long, struct drm_buf *), struct drm_file *); +void drm_legacy_master_rmmaps(struct drm_device *dev, + struct drm_master *master); + #ifdef CONFIG_DRM_VM void drm_legacy_vma_flush(struct drm_device *d); #else diff --git a/include/drm/drm_legacy.h b/include/drm/drm_legacy.h index 3e99ab69c122..2182a56ac421 100644 --- a/include/drm/drm_legacy.h +++ b/include/drm/drm_legacy.h @@ -162,8 +162,6 @@ int drm_legacy_addmap(struct drm_device *d, resource_size_t offset, struct drm_local_map *drm_legacy_findmap(struct drm_device *dev, unsigned int token); void drm_legacy_rmmap(struct drm_device *d, struct drm_local_map *map); int drm_legacy_rmmap_locked(struct drm_device *d, struct drm_local_map *map); -void drm_legacy_master_rmmaps(struct drm_device *dev, - struct drm_master *master); struct drm_local_map *drm_legacy_getsarea(struct drm_device *dev); int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma); -- cgit v1.2.3 From 35a280219b32a6960a094e195cf2930ff1702243 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 08:45:12 +1000 Subject: drm/legacy: move map cleanups into drm_bufs.c This makes it easier to clean this up later. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_bufs.c | 8 ++++++++ drivers/gpu/drm/drm_drv.c | 5 +---- drivers/gpu/drm/drm_legacy.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index e407adb033e7..bfc419ed9d6c 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -584,6 +584,14 @@ void drm_legacy_master_rmmaps(struct drm_device *dev, struct drm_master *master) mutex_unlock(&dev->struct_mutex); } +void drm_legacy_rmmaps(struct drm_device *dev) +{ + struct drm_map_list *r_list, *list_temp; + + list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) + drm_legacy_rmmap(dev, r_list->map); +} + /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on * the last close of the device, and this is necessary for cleanup when things * exit uncleanly. Therefore, having userland manually remove mappings seems diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 50d849d1bc6e..15b0fd5adaaf 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -1038,8 +1038,6 @@ EXPORT_SYMBOL(drm_dev_register); */ void drm_dev_unregister(struct drm_device *dev) { - struct drm_map_list *r_list, *list_temp; - if (drm_core_check_feature(dev, DRIVER_LEGACY)) drm_lastclose(dev); @@ -1056,8 +1054,7 @@ void drm_dev_unregister(struct drm_device *dev) if (dev->agp) drm_pci_agp_destroy(dev); - list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) - drm_legacy_rmmap(dev, r_list->map); + drm_legacy_rmmaps(dev); remove_compat_control_link(dev); drm_minor_unregister(dev, DRM_MINOR_PRIMARY); diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index e6bf1a94374b..3dc626090fcb 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -83,6 +83,7 @@ int __drm_legacy_mapbufs(struct drm_device *, void *, int *, void drm_legacy_master_rmmaps(struct drm_device *dev, struct drm_master *master); +void drm_legacy_rmmaps(struct drm_device *dev); #ifdef CONFIG_DRM_VM void drm_legacy_vma_flush(struct drm_device *d); -- cgit v1.2.3 From 9b7a77435c1d87d89101484c9a96e577742d8cc2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 09:33:56 +1000 Subject: drm/radeon: drop unused ati pcigart include. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Christian König Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_drv.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index afef2d9fccd8..173deb463414 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -35,7 +35,6 @@ #include #include -#include #include "radeon_family.h" /* General customization: -- cgit v1.2.3 From 058ca50ce3f1d40dac4d918a91684b0af4a0c468 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 09:36:54 +1000 Subject: drm/legacy: move lock cleanup for master into lock file (v2) This makes it easier to remove legacy code later. v2: move check into lock file as well. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_auth.c | 16 +--------------- drivers/gpu/drm/drm_legacy.h | 1 + drivers/gpu/drm/drm_lock.c | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 1669c42c40ed..ee969e9de472 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -274,21 +274,7 @@ void drm_master_release(struct drm_file *file_priv) if (!drm_is_current_master(file_priv)) goto out; - if (drm_core_check_feature(dev, DRIVER_LEGACY)) { - /* - * Since the master is disappearing, so is the - * possibility to lock. - */ - mutex_lock(&dev->struct_mutex); - if (master->lock.hw_lock) { - if (dev->sigdata.lock == master->lock.hw_lock) - dev->sigdata.lock = NULL; - master->lock.hw_lock = NULL; - master->lock.file_priv = NULL; - wake_up_interruptible_all(&master->lock.lock_queue); - } - mutex_unlock(&dev->struct_mutex); - } + drm_legacy_lock_master_cleanup(dev, master); if (dev->master == file_priv->master) drm_drop_master(dev, file_priv); diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index 3dc626090fcb..974c2be6bcd5 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -126,4 +126,5 @@ int drm_legacy_sg_alloc(struct drm_device *dev, void *data, int drm_legacy_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv); +void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *master); #endif /* __DRM_LEGACY_H__ */ diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 67a1a2ca7174..b70058e77a28 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c @@ -347,3 +347,22 @@ void drm_legacy_lock_release(struct drm_device *dev, struct file *filp) _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); } } + +void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *master) +{ + if (!drm_core_check_feature(dev, DRIVER_LEGACY)) + return; + + /* + * Since the master is disappearing, so is the + * possibility to lock. + */ mutex_lock(&dev->struct_mutex); + if (master->lock.hw_lock) { + if (dev->sigdata.lock == master->lock.hw_lock) + dev->sigdata.lock = NULL; + master->lock.hw_lock = NULL; + master->lock.file_priv = NULL; + wake_up_interruptible_all(&master->lock.lock_queue); + } + mutex_unlock(&dev->struct_mutex); +} -- cgit v1.2.3 From fabb0e2a256944c44e820ac411c91e9f6cfd7080 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 09:40:54 +1000 Subject: drm/legacy: move map_hash create/destroy into inlines This allows them to be removed later. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 6 +++--- drivers/gpu/drm/drm_legacy.h | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 15b0fd5adaaf..34109a0b3144 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -692,7 +692,7 @@ int drm_dev_init(struct drm_device *dev, if (ret) goto err_minors; - ret = drm_ht_create(&dev->map_hash, 12); + ret = drm_legacy_create_map_hash(dev); if (ret) goto err_minors; @@ -717,7 +717,7 @@ err_setunique: drm_gem_destroy(dev); err_ctxbitmap: drm_legacy_ctxbitmap_cleanup(dev); - drm_ht_remove(&dev->map_hash); + drm_legacy_remove_map_hash(dev); err_minors: drm_minor_free(dev, DRM_MINOR_PRIMARY); drm_minor_free(dev, DRM_MINOR_RENDER); @@ -792,7 +792,7 @@ void drm_dev_fini(struct drm_device *dev) drm_gem_destroy(dev); drm_legacy_ctxbitmap_cleanup(dev); - drm_ht_remove(&dev->map_hash); + drm_legacy_remove_map_hash(dev); drm_fs_inode_free(dev->anon_inode); drm_minor_free(dev, DRM_MINOR_PRIMARY); diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index 974c2be6bcd5..ef419d500e51 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -63,6 +63,16 @@ int drm_legacy_getsareactx(struct drm_device *d, void *v, struct drm_file *f); #define DRM_MAP_HASH_OFFSET 0x10000000 +static inline int drm_legacy_create_map_hash(struct drm_device *dev) +{ + return drm_ht_create(&dev->map_hash, 12); +} + +static inline void drm_legacy_remove_map_hash(struct drm_device *dev) +{ + drm_ht_remove(&dev->map_hash); +} + int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_legacy_addmap_ioctl(struct drm_device *d, void *v, struct drm_file *f); -- cgit v1.2.3 From 8437dd73b37f244863d1d8954a69d8b0eecd3470 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 09:47:27 +1000 Subject: drm/legacy: move init/destroy of struct members into legacy file This introduces drm_legacy_misc.c as a place for some misc legacy code, eventually I want to give the option to remove this from the build. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_drv.c | 10 +++----- drivers/gpu/drm/drm_legacy.h | 3 +++ drivers/gpu/drm/drm_legacy_misc.c | 52 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 drivers/gpu/drm/drm_legacy_misc.c (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 7ebae3d45505..0361ad93f6b9 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -19,7 +19,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ - drm_atomic_uapi.o + drm_atomic_uapi.o drm_legacy_misc.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 34109a0b3144..862621494a93 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -659,20 +659,16 @@ int drm_dev_init(struct drm_device *dev, /* no per-device feature limits by default */ dev->driver_features = ~0u; + drm_legacy_init_members(dev); INIT_LIST_HEAD(&dev->filelist); INIT_LIST_HEAD(&dev->filelist_internal); INIT_LIST_HEAD(&dev->clientlist); - INIT_LIST_HEAD(&dev->ctxlist); - INIT_LIST_HEAD(&dev->vmalist); - INIT_LIST_HEAD(&dev->maplist); INIT_LIST_HEAD(&dev->vblank_event_list); - spin_lock_init(&dev->buf_lock); spin_lock_init(&dev->event_lock); mutex_init(&dev->struct_mutex); mutex_init(&dev->filelist_mutex); mutex_init(&dev->clientlist_mutex); - mutex_init(&dev->ctxlist_mutex); mutex_init(&dev->master_mutex); dev->anon_inode = drm_fs_inode_new(); @@ -725,10 +721,10 @@ err_minors: err_free: put_device(dev->dev); mutex_destroy(&dev->master_mutex); - mutex_destroy(&dev->ctxlist_mutex); mutex_destroy(&dev->clientlist_mutex); mutex_destroy(&dev->filelist_mutex); mutex_destroy(&dev->struct_mutex); + drm_legacy_destroy_members(dev); return ret; } EXPORT_SYMBOL(drm_dev_init); @@ -801,10 +797,10 @@ void drm_dev_fini(struct drm_device *dev) put_device(dev->dev); mutex_destroy(&dev->master_mutex); - mutex_destroy(&dev->ctxlist_mutex); mutex_destroy(&dev->clientlist_mutex); mutex_destroy(&dev->filelist_mutex); mutex_destroy(&dev->struct_mutex); + drm_legacy_destroy_members(dev); kfree(dev->unique); } EXPORT_SYMBOL(drm_dev_fini); diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index ef419d500e51..4f6319d2bb03 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -136,5 +136,8 @@ int drm_legacy_sg_alloc(struct drm_device *dev, void *data, int drm_legacy_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv); +void drm_legacy_init_members(struct drm_device *dev); +void drm_legacy_destroy_members(struct drm_device *dev); + void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *master); #endif /* __DRM_LEGACY_H__ */ diff --git a/drivers/gpu/drm/drm_legacy_misc.c b/drivers/gpu/drm/drm_legacy_misc.c new file mode 100644 index 000000000000..94973885c913 --- /dev/null +++ b/drivers/gpu/drm/drm_legacy_misc.c @@ -0,0 +1,52 @@ +/** + * \file drm_legacy_misc.c + * Misc legacy support functions. + * + * \author Rickard E. (Rik) Faith + * \author Gareth Hughes + */ + +/* + * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * 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 (including the next + * paragraph) 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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 "drm_internal.h" +#include "drm_legacy.h" + +void drm_legacy_init_members(struct drm_device *dev) +{ + INIT_LIST_HEAD(&dev->ctxlist); + INIT_LIST_HEAD(&dev->vmalist); + INIT_LIST_HEAD(&dev->maplist); + spin_lock_init(&dev->buf_lock); + mutex_init(&dev->ctxlist_mutex); +} + +void drm_legacy_destroy_members(struct drm_device *dev) +{ + mutex_destroy(&dev->ctxlist_mutex); +} -- cgit v1.2.3 From 1fa32cb612a869e576cae489616b0cc286b93f6c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 09:48:13 +1000 Subject: drm/legacy: move legacy dev reinit into legacy misc This moves the legacy dev reinit into the legacy misc file. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_file.c | 24 ------------------------ drivers/gpu/drm/drm_legacy.h | 1 + drivers/gpu/drm/drm_legacy_misc.c | 24 ++++++++++++++++++++++++ 3 files changed, 25 insertions(+), 24 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 9701469a6e93..263fbef73fe5 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -425,30 +425,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) return 0; } -static void drm_legacy_dev_reinit(struct drm_device *dev) -{ - if (dev->irq_enabled) - drm_irq_uninstall(dev); - - mutex_lock(&dev->struct_mutex); - - drm_legacy_agp_clear(dev); - - drm_legacy_sg_cleanup(dev); - drm_legacy_vma_flush(dev); - drm_legacy_dma_takedown(dev); - - mutex_unlock(&dev->struct_mutex); - - dev->sigdata.lock = NULL; - - dev->context_flag = 0; - dev->last_context = 0; - dev->if_version = 0; - - DRM_DEBUG("lastclose completed\n"); -} - void drm_lastclose(struct drm_device * dev) { DRM_DEBUG("\n"); diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index 4f6319d2bb03..d7189aa22a48 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -138,6 +138,7 @@ int drm_legacy_sg_free(struct drm_device *dev, void *data, void drm_legacy_init_members(struct drm_device *dev); void drm_legacy_destroy_members(struct drm_device *dev); +void drm_legacy_dev_reinit(struct drm_device *dev); void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *master); #endif /* __DRM_LEGACY_H__ */ diff --git a/drivers/gpu/drm/drm_legacy_misc.c b/drivers/gpu/drm/drm_legacy_misc.c index 94973885c913..3616b1691007 100644 --- a/drivers/gpu/drm/drm_legacy_misc.c +++ b/drivers/gpu/drm/drm_legacy_misc.c @@ -50,3 +50,27 @@ void drm_legacy_destroy_members(struct drm_device *dev) { mutex_destroy(&dev->ctxlist_mutex); } + +void drm_legacy_dev_reinit(struct drm_device *dev) +{ + if (dev->irq_enabled) + drm_irq_uninstall(dev); + + mutex_lock(&dev->struct_mutex); + + drm_legacy_agp_clear(dev); + + drm_legacy_sg_cleanup(dev); + drm_legacy_vma_flush(dev); + drm_legacy_dma_takedown(dev); + + mutex_unlock(&dev->struct_mutex); + + dev->sigdata.lock = NULL; + + dev->context_flag = 0; + dev->last_context = 0; + dev->if_version = 0; + + DRM_DEBUG("lastclose completed\n"); +} -- cgit v1.2.3 From 848ee53894811e8bd3aade86415e6bc0afe5cbd3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 09:55:20 +1000 Subject: drm/legacy: don't include any of ati_pcigart in legacy. (v2) This could probably be done with Kconfig somehow, but I failed in my first 2 minute attempt. v2: use Kconfig better. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/Kconfig | 4 ++++ drivers/gpu/drm/Makefile | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index bcbc4234893a..39f87ed31347 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -255,6 +255,9 @@ config DRM_VKMS If M is selected the module will be called vkms. +config DRM_ATI_PCIGART + bool + source "drivers/gpu/drm/exynos/Kconfig" source "drivers/gpu/drm/rockchip/Kconfig" @@ -345,6 +348,7 @@ menuconfig DRM_LEGACY bool "Enable legacy drivers (DANGEROUS)" depends on DRM && MMU select DRM_VM + select DRM_ATI_PCIGART if PCI help Enable legacy DRI1 drivers. Those drivers expose unsafe and dangerous APIs to user-space, which can be used to circumvent access diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 0361ad93f6b9..c9caefe02f42 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -26,7 +26,7 @@ drm-$(CONFIG_DRM_VM) += drm_vm.o drm-$(CONFIG_COMPAT) += drm_ioc32.o drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o drm-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_gem_shmem_helper.o -drm-$(CONFIG_PCI) += ati_pcigart.o +drm-$(CONFIG_DRM_ATI_PCIGART) += ati_pcigart.o drm-$(CONFIG_DRM_PANEL) += drm_panel.o drm-$(CONFIG_OF) += drm_of.o drm-$(CONFIG_AGP) += drm_agpsupport.o -- cgit v1.2.3 From 61ae227032e7f9278cc7d7224045e77e0dedb33e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Apr 2019 17:10:40 +1000 Subject: drm: allow removal of legacy codepaths (v4.1) If you don't want the legacy drivers, then lets get rid of all the legacy codepaths from the core module. This drop the size of drm.ko for me by about 10%. 380515 7422 4192 392129 5fbc1 ../../drm-next-build/drivers/gpu/drm/drm.ko 351736 7298 4192 363226 58ada ../../drm-next-build/drivers/gpu/drm/drm.ko v2: drop drm_lock as well, fix some DMA->DRM typos v3: avoid ifdefs in mainline code v4: rework ioctl defs v4.1: fix nouveau Kconfig Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/Makefile | 9 +++---- drivers/gpu/drm/drm_internal.h | 2 ++ drivers/gpu/drm/drm_ioc32.c | 13 +++++++++- drivers/gpu/drm/drm_ioctl.c | 55 +++++++++++++++++++++++------------------ drivers/gpu/drm/drm_irq.c | 2 ++ drivers/gpu/drm/drm_legacy.h | 53 +++++++++++++++++++++++++++++++++++++-- drivers/gpu/drm/drm_vm.c | 2 ++ drivers/gpu/drm/nouveau/Kconfig | 2 +- 8 files changed, 105 insertions(+), 33 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index c9caefe02f42..f7ec57644df2 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -3,11 +3,9 @@ # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -drm-y := drm_auth.o drm_bufs.o drm_cache.o \ - drm_context.o drm_dma.o \ +drm-y := drm_auth.o drm_cache.o \ drm_file.o drm_gem.o drm_ioctl.o drm_irq.o \ - drm_lock.o drm_memory.o drm_drv.o \ - drm_scatter.o drm_pci.o \ + drm_memory.o drm_drv.o drm_pci.o \ drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_fourcc.o drm_modes.o drm_edid.o \ drm_encoder_slave.o \ @@ -19,8 +17,9 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_plane.o drm_color_mgmt.o drm_print.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \ - drm_atomic_uapi.o drm_legacy_misc.o + drm_atomic_uapi.o +drm-$(CONFIG_DRM_LEGACY) += drm_legacy_misc.o drm_bufs.o drm_context.o drm_dma.o drm_scatter.o drm_lock.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index d9a483a5fce0..e19ac7ca602d 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -71,8 +71,10 @@ int drm_legacy_modeset_ctl_ioctl(struct drm_device *dev, void *data, /* drm_irq.c */ /* IOCTLS */ +#if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_irq_control(struct drm_device *dev, void *data, struct drm_file *file_priv); +#endif int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index 0e3043e08c69..374b372da58a 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -156,6 +156,7 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd, return -EINVAL; } +#if IS_ENABLED(CONFIG_DRM_LEGACY) typedef struct drm_map32 { u32 offset; /* Requested physical address (0 for SAREA) */ u32 size; /* Requested physical size (bytes) */ @@ -239,6 +240,7 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd, map.handle = compat_ptr(handle); return drm_ioctl_kernel(file, drm_legacy_rmmap_ioctl, &map, DRM_AUTH); } +#endif typedef struct drm_client32 { int idx; /* Which client desired? */ @@ -301,6 +303,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, return 0; } +#if IS_ENABLED(CONFIG_DRM_LEGACY) typedef struct drm_buf_desc32 { int count; /* Number of buffers of this size */ int size; /* Size in bytes */ @@ -604,6 +607,7 @@ static int compat_drm_dma(struct file *file, unsigned int cmd, return 0; } +#endif #if IS_ENABLED(CONFIG_AGP) typedef struct drm_agp_mode32 { @@ -748,6 +752,7 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, } #endif /* CONFIG_AGP */ +#if IS_ENABLED(CONFIG_DRM_LEGACY) typedef struct drm_scatter_gather32 { u32 size; /**< In bytes -- will round to page boundary */ u32 handle; /**< Used for mapping / unmapping */ @@ -788,7 +793,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd, return drm_ioctl_kernel(file, drm_legacy_sg_free, &request, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); } - +#endif #if defined(CONFIG_X86) typedef struct drm_update_draw32 { drm_drawable_t handle; @@ -903,10 +908,13 @@ static struct { #define DRM_IOCTL32_DEF(n, f) [DRM_IOCTL_NR(n##32)] = {.fn = f, .name = #n} DRM_IOCTL32_DEF(DRM_IOCTL_VERSION, compat_drm_version), DRM_IOCTL32_DEF(DRM_IOCTL_GET_UNIQUE, compat_drm_getunique), +#if IS_ENABLED(CONFIG_DRM_LEGACY) DRM_IOCTL32_DEF(DRM_IOCTL_GET_MAP, compat_drm_getmap), +#endif DRM_IOCTL32_DEF(DRM_IOCTL_GET_CLIENT, compat_drm_getclient), DRM_IOCTL32_DEF(DRM_IOCTL_GET_STATS, compat_drm_getstats), DRM_IOCTL32_DEF(DRM_IOCTL_SET_UNIQUE, compat_drm_setunique), +#if IS_ENABLED(CONFIG_DRM_LEGACY) DRM_IOCTL32_DEF(DRM_IOCTL_ADD_MAP, compat_drm_addmap), DRM_IOCTL32_DEF(DRM_IOCTL_ADD_BUFS, compat_drm_addbufs), DRM_IOCTL32_DEF(DRM_IOCTL_MARK_BUFS, compat_drm_markbufs), @@ -918,6 +926,7 @@ static struct { DRM_IOCTL32_DEF(DRM_IOCTL_GET_SAREA_CTX, compat_drm_getsareactx), DRM_IOCTL32_DEF(DRM_IOCTL_RES_CTX, compat_drm_resctx), DRM_IOCTL32_DEF(DRM_IOCTL_DMA, compat_drm_dma), +#endif #if IS_ENABLED(CONFIG_AGP) DRM_IOCTL32_DEF(DRM_IOCTL_AGP_ENABLE, compat_drm_agp_enable), DRM_IOCTL32_DEF(DRM_IOCTL_AGP_INFO, compat_drm_agp_info), @@ -926,8 +935,10 @@ static struct { DRM_IOCTL32_DEF(DRM_IOCTL_AGP_BIND, compat_drm_agp_bind), DRM_IOCTL32_DEF(DRM_IOCTL_AGP_UNBIND, compat_drm_agp_unbind), #endif +#if IS_ENABLED(CONFIG_DRM_LEGACY) DRM_IOCTL32_DEF(DRM_IOCTL_SG_ALLOC, compat_drm_sg_alloc), DRM_IOCTL32_DEF(DRM_IOCTL_SG_FREE, compat_drm_sg_free), +#endif #if defined(CONFIG_X86) || defined(CONFIG_IA64) DRM_IOCTL32_DEF(DRM_IOCTL_UPDATE_DRAW, compat_drm_update_draw), #endif diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index ce8a70875bd5..5878145077d0 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -553,6 +553,12 @@ EXPORT_SYMBOL(drm_ioctl_permit); .name = #ioctl \ } +#if IS_ENABLED(CONFIG_DRM_LEGACY) +#define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, _func, _flags) +#else +#define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, drm_invalid_op, _flags) +#endif + /* Ioctl table */ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, @@ -560,7 +566,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, DRM_UNLOCKED), + + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW), @@ -572,39 +580,38 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_UNLOCKED|DRM_MASTER), - DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_legacy_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_legacy_rmmap_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_legacy_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_legacy_getsareactx, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_UNLOCKED|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_UNLOCKED|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_legacy_addctx, DRM_AUTH|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_legacy_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_legacy_getctx, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_legacy_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_legacy_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_legacy_resctx, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_legacy_lock, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_legacy_unlock, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_LOCK, drm_legacy_lock, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_legacy_unlock, DRM_AUTH), DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_legacy_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_legacy_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_legacy_infobufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_legacy_mapbufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_legacy_irq_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_legacy_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_legacy_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_legacy_infobufs, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_legacy_mapbufs, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_legacy_freebufs, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_DMA, drm_legacy_dma_ioctl, DRM_AUTH), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_legacy_irq_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), #if IS_ENABLED(CONFIG_AGP) DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), @@ -617,8 +624,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), #endif - DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_legacy_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_legacy_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank_ioctl, DRM_UNLOCKED), diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 9bd8908d5fd8..02f38cc9f468 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -213,6 +213,7 @@ int drm_irq_uninstall(struct drm_device *dev) } EXPORT_SYMBOL(drm_irq_uninstall); +#if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_irq_control(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -253,3 +254,4 @@ int drm_legacy_irq_control(struct drm_device *dev, void *data, return -EINVAL; } } +#endif diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index d7189aa22a48..0400ed19190e 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -42,11 +42,19 @@ struct drm_file; #define DRM_KERNEL_CONTEXT 0 #define DRM_RESERVED_CONTEXTS 1 +#if IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_ctxbitmap_init(struct drm_device *dev); void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev); -void drm_legacy_ctxbitmap_free(struct drm_device *dev, int ctx_handle); void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file); +#else +static inline void drm_legacy_ctxbitmap_init(struct drm_device *dev) {} +static inline void drm_legacy_ctxbitmap_cleanup(struct drm_device *dev) {} +static inline void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file) {} +#endif +void drm_legacy_ctxbitmap_free(struct drm_device *dev, int ctx_handle); + +#if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_resctx(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_addctx(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_getctx(struct drm_device *d, void *v, struct drm_file *f); @@ -56,6 +64,7 @@ int drm_legacy_rmctx(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_setsareactx(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_getsareactx(struct drm_device *d, void *v, struct drm_file *f); +#endif /* * Generic Buffer Management @@ -73,16 +82,20 @@ static inline void drm_legacy_remove_map_hash(struct drm_device *dev) drm_ht_remove(&dev->map_hash); } + +#if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_getmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_legacy_addmap_ioctl(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_rmmap_ioctl(struct drm_device *d, void *v, struct drm_file *f); + int drm_legacy_addbufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_infobufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_markbufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_freebufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_mapbufs(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_dma_ioctl(struct drm_device *d, void *v, struct drm_file *f); +#endif int __drm_legacy_infobufs(struct drm_device *, void *, int *, int (*)(void *, int, struct drm_buf_entry *)); @@ -91,11 +104,17 @@ int __drm_legacy_mapbufs(struct drm_device *, void *, int *, int (*)(void *, int, unsigned long, struct drm_buf *), struct drm_file *); +#if IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_master_rmmaps(struct drm_device *dev, struct drm_master *master); void drm_legacy_rmmaps(struct drm_device *dev); +#else +static inline void drm_legacy_master_rmmaps(struct drm_device *dev, + struct drm_master *master) {} +static inline void drm_legacy_rmmaps(struct drm_device *dev) {} +#endif -#ifdef CONFIG_DRM_VM +#if IS_ENABLED(CONFIG_DRM_VM) && IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_vma_flush(struct drm_device *d); #else static inline void drm_legacy_vma_flush(struct drm_device *d) @@ -117,28 +136,58 @@ struct drm_agp_mem { }; /* drm_lock.c */ +#if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_lock(struct drm_device *d, void *v, struct drm_file *f); int drm_legacy_unlock(struct drm_device *d, void *v, struct drm_file *f); void drm_legacy_lock_release(struct drm_device *dev, struct file *filp); +#else +static inline void drm_legacy_lock_release(struct drm_device *dev, struct file *filp) {} +#endif /* DMA support */ +#if IS_ENABLED(CONFIG_DRM_LEGACY) int drm_legacy_dma_setup(struct drm_device *dev); void drm_legacy_dma_takedown(struct drm_device *dev); +#else +static inline int drm_legacy_dma_setup(struct drm_device *dev) +{ + return 0; +} +#endif + void drm_legacy_free_buffer(struct drm_device *dev, struct drm_buf * buf); +#if IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_reclaim_buffers(struct drm_device *dev, struct drm_file *filp); +#else +static inline void drm_legacy_reclaim_buffers(struct drm_device *dev, + struct drm_file *filp) {} +#endif /* Scatter Gather Support */ +#if IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_sg_cleanup(struct drm_device *dev); int drm_legacy_sg_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); int drm_legacy_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv); +#endif +#if IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_init_members(struct drm_device *dev); void drm_legacy_destroy_members(struct drm_device *dev); void drm_legacy_dev_reinit(struct drm_device *dev); +#else +static inline void drm_legacy_init_members(struct drm_device *dev) {} +static inline void drm_legacy_destroy_members(struct drm_device *dev) {} +static inline void drm_legacy_dev_reinit(struct drm_device *dev) {} +#endif +#if IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *master); +#else +static inline void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *master) {} +#endif + #endif /* __DRM_LEGACY_H__ */ diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 8987501f53b2..10cf83d569e1 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -646,6 +646,7 @@ int drm_legacy_mmap(struct file *filp, struct vm_area_struct *vma) } EXPORT_SYMBOL(drm_legacy_mmap); +#if IS_ENABLED(CONFIG_DRM_LEGACY) void drm_legacy_vma_flush(struct drm_device *dev) { struct drm_vma_entry *vma, *vma_temp; @@ -656,3 +657,4 @@ void drm_legacy_vma_flush(struct drm_device *dev) kfree(vma); } } +#endif diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index db28012dbf54..553c7da5e8e0 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -23,7 +23,7 @@ config DRM_NOUVEAU config NOUVEAU_LEGACY_CTX_SUPPORT bool "Nouveau legacy context support" depends on DRM_NOUVEAU - select DRM_VM + select DRM_LEGACY default y help There was a version of the nouveau DDX that relied on legacy -- cgit v1.2.3 From 83c163f7eb5948051b6fcb084ab3b81880c147dd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 09:56:01 +1000 Subject: drm/legacy: place all drm legacy members under DRM_LEGACY. This places a bunch of the legacy members of drm_device into only being there when legacy is enabled. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_legacy.h | 9 +++++++++ include/drm/drm_device.h | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index 0400ed19190e..6f08066ce681 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -72,6 +72,7 @@ int drm_legacy_getsareactx(struct drm_device *d, void *v, struct drm_file *f); #define DRM_MAP_HASH_OFFSET 0x10000000 +#if IS_ENABLED(CONFIG_DRM_LEGACY) static inline int drm_legacy_create_map_hash(struct drm_device *dev) { return drm_ht_create(&dev->map_hash, 12); @@ -81,6 +82,14 @@ static inline void drm_legacy_remove_map_hash(struct drm_device *dev) { drm_ht_remove(&dev->map_hash); } +#else +static inline int drm_legacy_create_map_hash(struct drm_device *dev) +{ + return 0; +} + +static inline void drm_legacy_remove_map_hash(struct drm_device *dev) {} +#endif #if IS_ENABLED(CONFIG_DRM_LEGACY) diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index d5e092dccf3e..7f9ef709b2b6 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -306,7 +306,7 @@ struct drm_device { /* Everything below here is for legacy driver, never use! */ /* private: */ - +#if IS_ENABLED(CONFIG_DRM_LEGACY) /* Context handle management - linked list of context handles */ struct list_head ctxlist; @@ -353,6 +353,7 @@ struct drm_device { /* Scatter gather memory */ struct drm_sg_mem *sg; +#endif }; #endif -- cgit v1.2.3 From ee22f76306a68359c33809f8895eff603e71584b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Apr 2019 10:01:50 +1000 Subject: drm/legacy: remove some legacy lock struct members This removes these unless legacy is enabled. The lock count init is unneeded anyways since it's kzalloc. Reviewed-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_auth.c | 3 +-- drivers/gpu/drm/drm_file.c | 1 - drivers/gpu/drm/drm_legacy.h | 6 ++++++ drivers/gpu/drm/drm_legacy_misc.c | 6 ++++++ include/drm/drm_auth.h | 6 ++++-- include/drm/drm_file.h | 2 ++ 6 files changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index ee969e9de472..e88151b65c22 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -103,8 +103,7 @@ struct drm_master *drm_master_create(struct drm_device *dev) return NULL; kref_init(&master->refcount); - spin_lock_init(&master->lock.spinlock); - init_waitqueue_head(&master->lock.lock_queue); + drm_master_legacy_init(master); idr_init(&master->magic_map); master->dev = dev; diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index 263fbef73fe5..233f114d2186 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -128,7 +128,6 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) /* for compatibility root is always authenticated */ file->authenticated = capable(CAP_SYS_ADMIN); - file->lock_count = 0; INIT_LIST_HEAD(&file->lhead); INIT_LIST_HEAD(&file->fbs); diff --git a/drivers/gpu/drm/drm_legacy.h b/drivers/gpu/drm/drm_legacy.h index 6f08066ce681..51f1fabfa145 100644 --- a/drivers/gpu/drm/drm_legacy.h +++ b/drivers/gpu/drm/drm_legacy.h @@ -199,4 +199,10 @@ void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *m static inline void drm_legacy_lock_master_cleanup(struct drm_device *dev, struct drm_master *master) {} #endif +#if IS_ENABLED(CONFIG_DRM_LEGACY) +void drm_master_legacy_init(struct drm_master *master); +#else +static inline void drm_master_legacy_init(struct drm_master *master) {} +#endif + #endif /* __DRM_LEGACY_H__ */ diff --git a/drivers/gpu/drm/drm_legacy_misc.c b/drivers/gpu/drm/drm_legacy_misc.c index 3616b1691007..2fe786839ca8 100644 --- a/drivers/gpu/drm/drm_legacy_misc.c +++ b/drivers/gpu/drm/drm_legacy_misc.c @@ -74,3 +74,9 @@ void drm_legacy_dev_reinit(struct drm_device *dev) DRM_DEBUG("lastclose completed\n"); } + +void drm_master_legacy_init(struct drm_master *master) +{ + spin_lock_init(&master->lock.spinlock); + init_waitqueue_head(&master->lock.lock_queue); +} diff --git a/include/drm/drm_auth.h b/include/drm/drm_auth.h index 86bff9841b54..871008118bab 100644 --- a/include/drm/drm_auth.h +++ b/include/drm/drm_auth.h @@ -50,7 +50,6 @@ struct drm_lock_data { * * @refcount: Refcount for this master object. * @dev: Link back to the DRM device - * @lock: DRI1 lock information. * @driver_priv: Pointer to driver-private information. * @lessor: Lease holder * @lessee_id: id for lessees. Owners always have id 0 @@ -80,7 +79,6 @@ struct drm_master { * &drm_device.master_mutex. */ struct idr magic_map; - struct drm_lock_data lock; void *driver_priv; /* Tree of display resource leases, each of which is a drm_master struct @@ -95,6 +93,10 @@ struct drm_master { struct list_head lessees; struct idr leases; struct idr lessee_idr; + /* private: */ +#if IS_ENABLED(CONFIG_DRM_LEGACY) + struct drm_lock_data lock; +#endif }; struct drm_master *drm_master_get(struct drm_master *master); diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 6710b612e2f6..67af60bb527a 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -335,7 +335,9 @@ struct drm_file { struct drm_prime_file_private prime; /* private: */ +#if IS_ENABLED(CONFIG_DRM_LEGACY) unsigned long lock_count; /* DRI1 legacy lock count */ +#endif }; /** -- cgit v1.2.3 From fd96e0dba19c53c2d66f2a398716bb74df8ca85e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 5 Apr 2019 13:17:14 +1000 Subject: drm/udl: introduce a macro to convert dev to udl. This just makes it easier to later embed drm into udl. Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190405031715.5959-3-airlied@gmail.com --- drivers/gpu/drm/udl/udl_drv.h | 2 ++ drivers/gpu/drm/udl/udl_fb.c | 10 +++++----- drivers/gpu/drm/udl/udl_gem.c | 2 +- drivers/gpu/drm/udl/udl_main.c | 12 ++++++------ 4 files changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 4ae67d882eae..b3e08e876d62 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -71,6 +71,8 @@ struct udl_device { atomic_t cpu_kcycles_used; /* transpired during pixel processing */ }; +#define to_udl(x) ((x)->dev_private) + struct udl_gem_object { struct drm_gem_object base; struct page **pages; diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index f8ff5a6f559e..16593d4f02b4 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -82,7 +82,7 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, int width, int height) { struct drm_device *dev = fb->base.dev; - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); int i, ret; char *cmd; cycles_t start_cycles, end_cycles; @@ -210,7 +210,7 @@ static int udl_fb_open(struct fb_info *info, int user) { struct udl_fbdev *ufbdev = info->par; struct drm_device *dev = ufbdev->ufb.base.dev; - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); /* If the USB device is gone, we don't accept new opens */ if (drm_dev_is_unplugged(udl->ddev)) @@ -437,7 +437,7 @@ static void udl_fbdev_destroy(struct drm_device *dev, int udl_fbdev_init(struct drm_device *dev) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); int bpp_sel = fb_bpp; struct udl_fbdev *ufbdev; int ret; @@ -476,7 +476,7 @@ free: void udl_fbdev_cleanup(struct drm_device *dev) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); if (!udl->fbdev) return; @@ -487,7 +487,7 @@ void udl_fbdev_cleanup(struct drm_device *dev) void udl_fbdev_unplug(struct drm_device *dev) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct udl_fbdev *ufbdev; if (!udl->fbdev) return; diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index bb7b58407039..3b3e17652bb2 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -203,7 +203,7 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, { struct udl_gem_object *gobj; struct drm_gem_object *obj; - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); int ret = 0; mutex_lock(&udl->gem_lock); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 1f8ef34ade24..862c099d7c4c 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -30,7 +30,7 @@ static int udl_parse_vendor_descriptor(struct drm_device *dev, struct usb_device *usbdev) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); char *desc; char *buf; char *desc_end; @@ -166,7 +166,7 @@ void udl_urb_completion(struct urb *urb) static void udl_free_urb_list(struct drm_device *dev) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); int count = udl->urbs.count; struct list_head *node; struct urb_node *unode; @@ -199,7 +199,7 @@ static void udl_free_urb_list(struct drm_device *dev) static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); struct urb *urb; struct urb_node *unode; char *buf; @@ -263,7 +263,7 @@ retry: struct urb *udl_get_urb(struct drm_device *dev) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); int ret = 0; struct list_head *entry; struct urb_node *unode; @@ -296,7 +296,7 @@ error: int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); int ret; BUG_ON(len > udl->urbs.size); @@ -371,7 +371,7 @@ int udl_drop_usb(struct drm_device *dev) void udl_driver_unload(struct drm_device *dev) { - struct udl_device *udl = dev->dev_private; + struct udl_device *udl = to_udl(dev); drm_kms_helper_poll_fini(dev); -- cgit v1.2.3 From 6ecac85eadb9d4065b9038fa3d3c66d49038e14b Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 5 Apr 2019 13:17:15 +1000 Subject: drm/udl: move to embedding drm device inside udl device. This should help with some of the lifetime issues, and move us away from load/unload. Acked-by: Alex Deucher Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190405031715.5959-4-airlied@gmail.com --- drivers/gpu/drm/udl/udl_drv.c | 56 +++++++++++++++++++++++++++++++++--------- drivers/gpu/drm/udl/udl_drv.h | 9 +++---- drivers/gpu/drm/udl/udl_fb.c | 2 +- drivers/gpu/drm/udl/udl_main.c | 23 +++-------------- 4 files changed, 53 insertions(+), 37 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index b7d01b3664cb..312bf324841a 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -48,10 +48,16 @@ static const struct file_operations udl_driver_fops = { .llseek = noop_llseek, }; +static void udl_driver_release(struct drm_device *dev) +{ + udl_fini(dev); + udl_modeset_cleanup(dev); + drm_dev_fini(dev); + kfree(dev); +} + static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, - .load = udl_driver_load, - .unload = udl_driver_unload, .release = udl_driver_release, /* gem hooks */ @@ -75,28 +81,56 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, }; +static struct udl_device *udl_driver_create(struct usb_interface *interface) +{ + struct usb_device *udev = interface_to_usbdev(interface); + struct udl_device *udl; + int r; + + udl = kzalloc(sizeof(*udl), GFP_KERNEL); + if (!udl) + return ERR_PTR(-ENOMEM); + + r = drm_dev_init(&udl->drm, &driver, &interface->dev); + if (r) { + kfree(udl); + return ERR_PTR(r); + } + + udl->udev = udev; + udl->drm.dev_private = udl; + + r = udl_init(udl); + if (r) { + drm_dev_fini(&udl->drm); + kfree(udl); + return ERR_PTR(r); + } + + usb_set_intfdata(interface, udl); + return udl; +} + static int udl_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_device *udev = interface_to_usbdev(interface); - struct drm_device *dev; int r; + struct udl_device *udl; - dev = drm_dev_alloc(&driver, &interface->dev); - if (IS_ERR(dev)) - return PTR_ERR(dev); + udl = udl_driver_create(interface); + if (IS_ERR(udl)) + return PTR_ERR(udl); - r = drm_dev_register(dev, (unsigned long)udev); + r = drm_dev_register(&udl->drm, 0); if (r) goto err_free; - usb_set_intfdata(interface, dev); - DRM_INFO("Initialized udl on minor %d\n", dev->primary->index); + DRM_INFO("Initialized udl on minor %d\n", udl->drm.primary->index); return 0; err_free: - drm_dev_put(dev); + drm_dev_put(&udl->drm); return r; } diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index b3e08e876d62..35c1f33fbc1a 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -50,8 +50,8 @@ struct urb_list { struct udl_fbdev; struct udl_device { + struct drm_device drm; struct device *dev; - struct drm_device *ddev; struct usb_device *udev; struct drm_crtc *crtc; @@ -71,7 +71,7 @@ struct udl_device { atomic_t cpu_kcycles_used; /* transpired during pixel processing */ }; -#define to_udl(x) ((x)->dev_private) +#define to_udl(x) container_of(x, struct udl_device, drm) struct udl_gem_object { struct drm_gem_object base; @@ -104,9 +104,8 @@ struct urb *udl_get_urb(struct drm_device *dev); int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len); void udl_urb_completion(struct urb *urb); -int udl_driver_load(struct drm_device *dev, unsigned long flags); -void udl_driver_unload(struct drm_device *dev); -void udl_driver_release(struct drm_device *dev); +int udl_init(struct udl_device *udl); +void udl_fini(struct drm_device *dev); int udl_fbdev_init(struct drm_device *dev); void udl_fbdev_cleanup(struct drm_device *dev); diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 16593d4f02b4..b9b67a546d4c 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -213,7 +213,7 @@ static int udl_fb_open(struct fb_info *info, int user) struct udl_device *udl = to_udl(dev); /* If the USB device is gone, we don't accept new opens */ - if (drm_dev_is_unplugged(udl->ddev)) + if (drm_dev_is_unplugged(&udl->drm)) return -ENODEV; ufbdev->fb_count++; diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 862c099d7c4c..6743eaef4594 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -311,20 +311,12 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len) return ret; } -int udl_driver_load(struct drm_device *dev, unsigned long flags) +int udl_init(struct udl_device *udl) { - struct usb_device *udev = (void*)flags; - struct udl_device *udl; + struct drm_device *dev = &udl->drm; int ret = -ENOMEM; DRM_DEBUG("\n"); - udl = kzalloc(sizeof(struct udl_device), GFP_KERNEL); - if (!udl) - return -ENOMEM; - - udl->udev = udev; - udl->ddev = dev; - dev->dev_private = udl; mutex_init(&udl->gem_lock); @@ -358,7 +350,6 @@ int udl_driver_load(struct drm_device *dev, unsigned long flags) err: if (udl->urbs.count) udl_free_urb_list(dev); - kfree(udl); DRM_ERROR("%d\n", ret); return ret; } @@ -369,7 +360,7 @@ int udl_drop_usb(struct drm_device *dev) return 0; } -void udl_driver_unload(struct drm_device *dev) +void udl_fini(struct drm_device *dev) { struct udl_device *udl = to_udl(dev); @@ -379,12 +370,4 @@ void udl_driver_unload(struct drm_device *dev) udl_free_urb_list(dev); udl_fbdev_cleanup(dev); - kfree(udl); -} - -void udl_driver_release(struct drm_device *dev) -{ - udl_modeset_cleanup(dev); - drm_dev_fini(dev); - kfree(dev); } -- cgit v1.2.3 From 929eec99f5fd408fbc7e36f6c25fadbd3f45bfa3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 17 Apr 2019 14:25:07 +0100 Subject: drm/i915: Avoid use-after-free in reporting create.size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have to avoid chasing after a userspace race! <3>[ 473.114328] BUG: KASAN: use-after-free in i915_gem_create+0x1d2/0x1f0 [i915] <3>[ 473.114389] Read of size 8 at addr ffff88815bf1d840 by task gem_flink_race/1541 <4>[ 473.114464] CPU: 1 PID: 1541 Comm: gem_flink_race Tainted: G U 5.1.0-rc4-g7d07e025e786-kasan_88+ #1 <4>[ 473.114469] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./J4205-ITX, BIOS P1.10 09/29/2016 <4>[ 473.114474] Call Trace: <4>[ 473.114488] dump_stack+0x7c/0xbb <4>[ 473.114612] ? i915_gem_create+0x1d2/0x1f0 [i915] <4>[ 473.114621] print_address_description+0x65/0x270 <4>[ 473.114728] ? i915_gem_create+0x1d2/0x1f0 [i915] <4>[ 473.114839] ? i915_gem_create+0x1d2/0x1f0 [i915] <4>[ 473.114848] kasan_report+0x149/0x18d <4>[ 473.114962] ? i915_gem_create+0x1d2/0x1f0 [i915] <4>[ 473.115069] i915_gem_create+0x1d2/0x1f0 [i915] <4>[ 473.115176] ? i915_gem_object_create.part.28+0x4b0/0x4b0 [i915] <4>[ 473.115289] ? i915_gem_dumb_create+0x1a0/0x1a0 [i915] <4>[ 473.115297] drm_ioctl_kernel+0x192/0x260 <4>[ 473.115306] ? drm_ioctl_permit+0x280/0x280 <4>[ 473.115326] drm_ioctl+0x67c/0x960 <4>[ 473.115438] ? i915_gem_dumb_create+0x1a0/0x1a0 [i915] <4>[ 473.115448] ? drm_getstats+0x20/0x20 <4>[ 473.115459] ? __lock_acquire+0xa66/0x3fe0 <4>[ 473.115474] ? _raw_spin_unlock_irqrestore+0x39/0x60 <4>[ 473.115485] ? debug_object_active_state+0x2ea/0x4e0 <4>[ 473.115496] ? debug_show_all_locks+0x2d0/0x2d0 <4>[ 473.115513] do_vfs_ioctl+0x18d/0xfa0 <4>[ 473.115522] ? check_flags.part.27+0x440/0x440 <4>[ 473.115532] ? ioctl_preallocate+0x1a0/0x1a0 <4>[ 473.115547] ? __fget+0x2ac/0x410 <4>[ 473.115561] ? __ia32_sys_dup3+0xb0/0xb0 <4>[ 473.115569] ? rwlock_bug.part.0+0x90/0x90 <4>[ 473.115590] ksys_ioctl+0x35/0x70 <4>[ 473.115597] ? lockdep_hardirqs_off+0x1cb/0x2b0 <4>[ 473.115608] __x64_sys_ioctl+0x6a/0xb0 <4>[ 473.115614] ? lockdep_hardirqs_on+0x342/0x590 <4>[ 473.115623] do_syscall_64+0x97/0x400 <4>[ 473.115633] entry_SYSCALL_64_after_hwframe+0x49/0xbe <4>[ 473.115641] RIP: 0033:0x7fce590d55d7 <4>[ 473.115649] Code: b3 66 90 48 8b 05 b1 48 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 81 48 2d 00 f7 d8 64 89 01 48 <4>[ 473.115655] RSP: 002b:00007fce4d525ba8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 <4>[ 473.115662] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fce590d55d7 <4>[ 473.115667] RDX: 00007fce4d525c10 RSI: 00000000c010645b RDI: 0000000000000007 <4>[ 473.115672] RBP: 00007fce4d525c10 R08: 00007fce4d526700 R09: 00007fce4d526700 <4>[ 473.115677] R10: 0000000000000054 R11: 0000000000000246 R12: 00000000c010645b <4>[ 473.115682] R13: 0000000000000007 R14: 0000000000000000 R15: 00007ffe0e4a7450 <3>[ 473.115731] Allocated by task 1541: <4>[ 473.115766] kmem_cache_alloc+0xce/0x290 <4>[ 473.115895] i915_gem_object_create.part.28+0x1c/0x4b0 [i915] <4>[ 473.116000] i915_gem_create+0xe3/0x1f0 [i915] <4>[ 473.116008] drm_ioctl_kernel+0x192/0x260 <4>[ 473.116013] drm_ioctl+0x67c/0x960 <4>[ 473.116020] do_vfs_ioctl+0x18d/0xfa0 <4>[ 473.116026] ksys_ioctl+0x35/0x70 <4>[ 473.116032] __x64_sys_ioctl+0x6a/0xb0 <4>[ 473.116038] do_syscall_64+0x97/0x400 <4>[ 473.116044] entry_SYSCALL_64_after_hwframe+0x49/0xbe <3>[ 473.116071] Freed by task 1542: <4>[ 473.116101] kmem_cache_free+0xb7/0x2f0 <4>[ 473.116205] __i915_gem_free_objects+0x7d4/0xe10 [i915] <4>[ 473.116311] i915_gem_create_ioctl+0xaa/0xd0 [i915] <4>[ 473.116318] drm_ioctl_kernel+0x192/0x260 <4>[ 473.116323] drm_ioctl+0x67c/0x960 <4>[ 473.116330] do_vfs_ioctl+0x18d/0xfa0 <4>[ 473.116335] ksys_ioctl+0x35/0x70 <4>[ 473.116341] __x64_sys_ioctl+0x6a/0xb0 <4>[ 473.116347] do_syscall_64+0x97/0x400 <4>[ 473.116354] entry_SYSCALL_64_after_hwframe+0x49/0xbe Testcase: igt/gem_flink_race/flink_close Fixes: e163484afa8d ("drm/i915: Update size upon return from GEM_CREATE") Signed-off-by: Chris Wilson Cc: Michał Winiarski Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190417132507.27133-1-chris@chris-wilson.co.uk (cherry picked from commit 99534023490686ce4453c45e5cb813535b9bff95) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0a818a60ad31..db88ce4d5509 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -647,7 +647,7 @@ i915_gem_create(struct drm_file *file, return ret; *handle_p = handle; - *size_p = obj->base.size; + *size_p = size; return 0; } -- cgit v1.2.3 From 447811a686e8da7325516a78069ccfbd139ef1a7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 19 Apr 2019 10:10:26 +0300 Subject: drm/i915/icl: Fix MG_DP_MODE() register programming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the order of lane, port parameters passed to the register macro. Note that this was already partly fixed by commit 37fc7845df7b6 ("drm/i915: Call MG_DP_MODE() macro with the right parameters order") While at it simplify things by using the macro directly instead of an unnecessary redirection via an array. v2: - Add a note the commit message about simplifying things. (José) Fixes: 58106b7d816e1 ("drm/i915: Make MG PHY macros semantically consistent") Cc: José Roberto de Souza Cc: Lucas De Marchi Cc: Aditya Swarup Signed-off-by: Imre Deak Reviewed-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20190419071026.32370-1-imre.deak@intel.com (cherry picked from commit 9c11b12184bb01d8ba2c48e655509b184f02c769) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/intel_ddi.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 24f9106efcc6..f181c26f62fd 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2905,21 +2905,20 @@ static void icl_enable_phy_clock_gating(struct intel_digital_port *dig_port) struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); enum port port = dig_port->base.port; enum tc_port tc_port = intel_port_to_tc(dev_priv, port); - i915_reg_t mg_regs[2] = { MG_DP_MODE(0, port), MG_DP_MODE(1, port) }; u32 val; - int i; + int ln; if (tc_port == PORT_TC_NONE) return; - for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { - val = I915_READ(mg_regs[i]); + for (ln = 0; ln < 2; ln++) { + val = I915_READ(MG_DP_MODE(ln, port)); val |= MG_DP_MODE_CFG_TR2PWR_GATING | MG_DP_MODE_CFG_TRPWR_GATING | MG_DP_MODE_CFG_CLNPWR_GATING | MG_DP_MODE_CFG_DIGPWR_GATING | MG_DP_MODE_CFG_GAONPWR_GATING; - I915_WRITE(mg_regs[i], val); + I915_WRITE(MG_DP_MODE(ln, port), val); } val = I915_READ(MG_MISC_SUS0(tc_port)); @@ -2938,21 +2937,20 @@ static void icl_disable_phy_clock_gating(struct intel_digital_port *dig_port) struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); enum port port = dig_port->base.port; enum tc_port tc_port = intel_port_to_tc(dev_priv, port); - i915_reg_t mg_regs[2] = { MG_DP_MODE(port, 0), MG_DP_MODE(port, 1) }; u32 val; - int i; + int ln; if (tc_port == PORT_TC_NONE) return; - for (i = 0; i < ARRAY_SIZE(mg_regs); i++) { - val = I915_READ(mg_regs[i]); + for (ln = 0; ln < 2; ln++) { + val = I915_READ(MG_DP_MODE(ln, port)); val &= ~(MG_DP_MODE_CFG_TR2PWR_GATING | MG_DP_MODE_CFG_TRPWR_GATING | MG_DP_MODE_CFG_CLNPWR_GATING | MG_DP_MODE_CFG_DIGPWR_GATING | MG_DP_MODE_CFG_GAONPWR_GATING); - I915_WRITE(mg_regs[i], val); + I915_WRITE(MG_DP_MODE(ln, port), val); } val = I915_READ(MG_MISC_SUS0(tc_port)); -- cgit v1.2.3 From abbc0697d5fbf53f74ce0bcbe936670199764cfa Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 24 Apr 2019 16:33:29 +1000 Subject: drm/fb: revert the i915 Actually configure untiled displays from master This code moved in here in master, so revert it the same way. This is the same revert as 9fa246256e09 ("Revert "drm/i915/fbdev: Actually configure untiled displays"") in drm-fixes. Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 4de4b9d59d49..226c0910ba91 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2580,7 +2580,7 @@ static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper, { struct drm_device *dev = fb_helper->dev; unsigned int count = min(fb_helper->connector_count, BITS_PER_LONG); - unsigned long conn_configured, conn_seq; + unsigned long conn_configured, conn_seq, mask; int i, j; bool *save_enabled; bool fallback = true, ret = true; @@ -2598,9 +2598,10 @@ static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper, drm_modeset_backoff(&ctx); memcpy(save_enabled, enabled, count); - conn_seq = GENMASK(count - 1, 0); + mask = GENMASK(count - 1, 0); conn_configured = 0; retry: + conn_seq = conn_configured; for (i = 0; i < count; i++) { struct drm_fb_helper_connector *fb_conn; struct drm_connector *connector; @@ -2613,8 +2614,7 @@ retry: if (conn_configured & BIT(i)) continue; - /* First pass, only consider tiled connectors */ - if (conn_seq == GENMASK(count - 1, 0) && !connector->has_tile) + if (conn_seq == 0 && !connector->has_tile) continue; if (connector->status == connector_status_connected) @@ -2715,10 +2715,8 @@ retry: conn_configured |= BIT(i); } - if (conn_configured != conn_seq) { /* repeat until no more are found */ - conn_seq = conn_configured; + if ((conn_configured & mask) != mask && conn_configured != conn_seq) goto retry; - } /* * If the BIOS didn't enable everything it could, fall back to have the -- cgit v1.2.3 From e40b7642884239346265cd7adc06dfbb8988f93d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 15:49:04 +0100 Subject: drm/leases: Drop object_id validation for negative ids Not exactly sure what's the aim here, but the canonical nil object has id == 0, we don't use negative object ids for anything. Plus all object_id are valided by the object_idr, there's nothing we need to do on top of that ENOENT check a bit further down. Spotted while typing exhaustive igt coverage for all these corner-cases. Cc: Keith Packard Reviewed-by: Boris Brezillon Reviewed-by: Dave Airlie Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190228144910.26488-2-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_lease.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 603b0bd9c5ce..1176d814cf7f 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -403,11 +403,6 @@ static int fill_object_idr(struct drm_device *dev, /* step one - get references to all the mode objects and check for validity. */ for (o = 0; o < object_count; o++) { - if ((int) object_ids[o] < 0) { - ret = -EINVAL; - goto out_free_objects; - } - objects[o] = drm_mode_object_find(dev, lessor_priv, object_ids[o], DRM_MODE_OBJECT_ANY); -- cgit v1.2.3 From ae9d6c076c0d39e97c14cd531d278ea8471730f4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 15:49:05 +0100 Subject: drm/lease: Drop recursive leads checks We disallow subleasing, so no point checking whether the master holds all the leases - it will. Spotted while typing exhaustive igt coverage for all these corner cases. Cc: Keith Packard Reviewed-by: Boris Brezillon Reviewed-by: Dave Airlie Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190228144910.26488-3-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_lease.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 1176d814cf7f..cce5d9dd52ff 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -220,8 +220,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr error = 0; if (!idr_find(&dev->mode_config.object_idr, object)) error = -ENOENT; - else if (!_drm_lease_held_master(lessor, object)) - error = -EACCES; else if (_drm_has_leased(lessor, object)) error = -EBUSY; -- cgit v1.2.3 From 4285c7e1aaad6ffe5520b36047a28fc960e32482 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 15:49:06 +0100 Subject: drm/leases: Don't init to 0 in drm_master_create We kzalloc. Cc: Keith Packard Reviewed-by: Boris Brezillon Reviewed-by: Dave Airlie Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190228144910.26488-4-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_auth.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 1669c42c40ed..bcf0a5a1018f 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -109,8 +109,6 @@ struct drm_master *drm_master_create(struct drm_device *dev) master->dev = dev; /* initialize the tree of output resource lessees */ - master->lessor = NULL; - master->lessee_id = 0; INIT_LIST_HEAD(&master->lessees); INIT_LIST_HEAD(&master->lessee_list); idr_init(&master->leases); -- cgit v1.2.3 From 46b757780dfe60596124b85befa935554dba73a3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 15:49:07 +0100 Subject: drm/lease: Check for lessor outside of locks The lessor is invariant over a lifetime of a lease, we don't have to grab any locks for that. Speeds up the common case of not being a lease. Cc: Keith Packard Reviewed-by: Boris Brezillon Reviewed-by: Dave Airlie Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190228144910.26488-5-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_lease.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index cce5d9dd52ff..694ff363a90b 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -111,7 +111,7 @@ static bool _drm_has_leased(struct drm_master *master, int id) */ bool _drm_lease_held(struct drm_file *file_priv, int id) { - if (file_priv == NULL || file_priv->master == NULL) + if (!file_priv || !file_priv->master) return true; return _drm_lease_held_master(file_priv->master, id); @@ -133,7 +133,7 @@ bool drm_lease_held(struct drm_file *file_priv, int id) struct drm_master *master; bool ret; - if (file_priv == NULL || file_priv->master == NULL) + if (!file_priv || !file_priv->master || !file_priv->master->lessor) return true; master = file_priv->master; @@ -159,7 +159,7 @@ uint32_t drm_lease_filter_crtcs(struct drm_file *file_priv, uint32_t crtcs_in) int count_in, count_out; uint32_t crtcs_out = 0; - if (file_priv == NULL || file_priv->master == NULL) + if (!file_priv || !file_priv->master || !file_priv->master->lessor) return crtcs_in; master = file_priv->master; -- cgit v1.2.3 From 204f640da6914844b3270b41b29c84f6e3b74083 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 15:49:08 +0100 Subject: drm/lease: Make sure implicit planes are leased If userspace doesn't enable universal planes, then we automatically add the primary and cursor planes. But for universal userspace there's no such check (and maybe we only want to give the lessee one plane, maybe not even the primary one), hence we need to check for the implied plane. v2: don't forget setcrtc ioctl. v3: Still allow disabling of the crtc in SETCRTC. Cc: stable@vger.kernel.org Cc: Keith Packard Reviewed-by: Boris Brezillon Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190228144910.26488-6-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_crtc.c | 4 ++++ drivers/gpu/drm/drm_plane.c | 8 ++++++++ 2 files changed, 12 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 7dabbaf033a1..790ba5941954 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -559,6 +559,10 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, plane = crtc->primary; + /* allow disabling with the primary plane leased */ + if (crtc_req->mode_valid && !drm_lease_held(file_priv, plane->base.id)) + return -EACCES; + mutex_lock(&crtc->dev->mode_config.mutex); DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret); diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 4cfb56893b7f..d6ad60ab0d38 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -960,6 +960,11 @@ retry: if (ret) goto out; + if (!drm_lease_held(file_priv, crtc->cursor->base.id)) { + ret = -EACCES; + goto out; + } + ret = drm_mode_cursor_universal(crtc, req, file_priv, &ctx); goto out; } @@ -1062,6 +1067,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, plane = crtc->primary; + if (!drm_lease_held(file_priv, plane->base.id)) + return -EACCES; + if (crtc->funcs->page_flip_target) { u32 current_vblank; int r; -- cgit v1.2.3 From 36e4523aaf4a35de963e190064b53839fa131653 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 15:49:09 +0100 Subject: drm/atomic: Wire file_priv through for property changes We need this to make sure lessees can only connect their plane/connectors to crtc objects they own. And note that this is irrespective of whether the lessor is atomic or not, lessor cannot prevent lessees from enabling atomic. Cc: stable@vger.kernel.org Cc: Keith Packard Reviewed-by: Dave Airlie Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190228144910.26488-7-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic_uapi.c | 32 +++++++++++++++++++------------- drivers/gpu/drm/drm_crtc_internal.h | 1 + drivers/gpu/drm/drm_mode_object.c | 5 +++-- 3 files changed, 23 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index ea797d4c82ee..77d16f5d4a9a 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -512,8 +512,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, } static int drm_atomic_plane_set_property(struct drm_plane *plane, - struct drm_plane_state *state, struct drm_property *property, - uint64_t val) + struct drm_plane_state *state, struct drm_file *file_priv, + struct drm_property *property, uint64_t val) { struct drm_device *dev = plane->dev; struct drm_mode_config *config = &dev->mode_config; @@ -521,7 +521,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, int ret; if (property == config->prop_fb_id) { - struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); + struct drm_framebuffer *fb; + fb = drm_framebuffer_lookup(dev, file_priv, val); drm_atomic_set_fb_for_plane(state, fb); if (fb) drm_framebuffer_put(fb); @@ -537,7 +538,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, return -EINVAL; } else if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); + struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val); return drm_atomic_set_crtc_for_plane(state, crtc); } else if (property == config->prop_crtc_x) { state->crtc_x = U642I64(val); @@ -668,14 +669,14 @@ static int drm_atomic_set_writeback_fb_for_connector( } static int drm_atomic_connector_set_property(struct drm_connector *connector, - struct drm_connector_state *state, struct drm_property *property, - uint64_t val) + struct drm_connector_state *state, struct drm_file *file_priv, + struct drm_property *property, uint64_t val) { struct drm_device *dev = connector->dev; struct drm_mode_config *config = &dev->mode_config; if (property == config->prop_crtc_id) { - struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val); + struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val); return drm_atomic_set_crtc_for_connector(state, crtc); } else if (property == config->dpms_property) { /* setting DPMS property requires special handling, which @@ -736,8 +737,10 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, } else if (property == connector->colorspace_property) { state->colorspace = val; } else if (property == config->writeback_fb_id_property) { - struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val); - int ret = drm_atomic_set_writeback_fb_for_connector(state, fb); + struct drm_framebuffer *fb; + int ret; + fb = drm_framebuffer_lookup(dev, file_priv, val); + ret = drm_atomic_set_writeback_fb_for_connector(state, fb); if (fb) drm_framebuffer_put(fb); return ret; @@ -934,6 +937,7 @@ out: } int drm_atomic_set_property(struct drm_atomic_state *state, + struct drm_file *file_priv, struct drm_mode_object *obj, struct drm_property *prop, uint64_t prop_value) @@ -956,7 +960,8 @@ int drm_atomic_set_property(struct drm_atomic_state *state, } ret = drm_atomic_connector_set_property(connector, - connector_state, prop, prop_value); + connector_state, file_priv, + prop, prop_value); break; } case DRM_MODE_OBJECT_CRTC: { @@ -984,7 +989,8 @@ int drm_atomic_set_property(struct drm_atomic_state *state, } ret = drm_atomic_plane_set_property(plane, - plane_state, prop, prop_value); + plane_state, file_priv, + prop, prop_value); break; } default: @@ -1354,8 +1360,8 @@ retry: goto out; } - ret = drm_atomic_set_property(state, obj, prop, - prop_value); + ret = drm_atomic_set_property(state, file_priv, + obj, prop, prop_value); if (ret) { drm_mode_object_put(obj); goto out; diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 216f2a9ee3d4..0719a235d6cc 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -214,6 +214,7 @@ int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, struct drm_connector *connector, int mode); int drm_atomic_set_property(struct drm_atomic_state *state, + struct drm_file *file_priv, struct drm_mode_object *obj, struct drm_property *prop, uint64_t prop_value); diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index a9005c1c2384..f32507e65b79 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -451,6 +451,7 @@ static int set_property_legacy(struct drm_mode_object *obj, } static int set_property_atomic(struct drm_mode_object *obj, + struct drm_file *file_priv, struct drm_property *prop, uint64_t prop_value) { @@ -477,7 +478,7 @@ retry: obj_to_connector(obj), prop_value); } else { - ret = drm_atomic_set_property(state, obj, prop, prop_value); + ret = drm_atomic_set_property(state, file_priv, obj, prop, prop_value); if (ret) goto out; ret = drm_atomic_commit(state); @@ -520,7 +521,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, goto out_unref; if (drm_drv_uses_atomic_modeset(property->dev)) - ret = set_property_atomic(arg_obj, property, arg->value); + ret = set_property_atomic(arg_obj, file_priv, property, arg->value); else ret = set_property_legacy(arg_obj, property, arg->value); -- cgit v1.2.3 From b8c7d7bc8386924f57aac0a745ae3240f07b743b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 28 Feb 2019 15:49:10 +0100 Subject: drm/atomic: -EACCESS for lease-denied crtc lookup With the previous patch drm_crtc_find will return NULL when the crtc isn't in our lease, which will then disable the plane/connector. No longer an issue since the lessor can't escape their lease terms anymore, but not quite great semantics yet either. Catch this and return -EACCES, so that at least evil test cases have a better chance of making sure the kernel works correctly. Reviewed-by: Dave Airlie Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190228144910.26488-8-daniel.vetter@ffwll.ch --- drivers/gpu/drm/drm_atomic_uapi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 77d16f5d4a9a..428d82662dc4 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -539,6 +539,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, } else if (property == config->prop_crtc_id) { struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val); + if (val && !crtc) + return -EACCES; return drm_atomic_set_crtc_for_plane(state, crtc); } else if (property == config->prop_crtc_x) { state->crtc_x = U642I64(val); @@ -677,6 +679,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, if (property == config->prop_crtc_id) { struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val); + if (val && !crtc) + return -EACCES; return drm_atomic_set_crtc_for_connector(state, crtc); } else if (property == config->dpms_property) { /* setting DPMS property requires special handling, which -- cgit v1.2.3 From 1de7259275ca4ebc66459de6620558d3e38d4142 Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Tue, 23 Apr 2019 16:53:53 +0200 Subject: drm/fb-helper: Fix drm_fb_helper_firmware_config() NULL pointer deref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Non-atomic drivers like ast doesn't have connector->state set resulting in a NULL pointer deref: [ 29.609593] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 [ 29.609619] Call Trace: [ 29.609630] ? drm_helper_probe_single_connector_modes+0x27f/0x680 [ 29.609640] drm_setup_crtcs+0x431/0xd80 [drm_kms_helper] [ 29.753065] __drm_fb_helper_initial_config_and_unlock+0x6f/0x6a0 [ 29.753160] ? drm_modeset_unlock_all+0x31/0x50 [drm] [ 29.765758] ast_fbdev_init+0xa8/0xc0 [ast] [ 29.765762] ast_driver_load.cold.7+0x2b3/0xe11 [ast] [ 29.765775] drm_dev_register+0x111/0x150 [drm] Fix by bailing out if the driver does not support atomic modesetting. Fixes: 09ded8af57bc ("drm/i915/fbdev: Move intel_fb_initial_config() to fbdev helper") Reported-by: Thomas Zimmermann Cc: Daniel Vetter Cc: Jani Nikula Signed-off-by: Noralf Trønnes Reviewed-by: Daniel Vetter Tested-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20190423145353.30158-1-noralf@tronnes.org --- drivers/gpu/drm/drm_fb_helper.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 226c0910ba91..498f95c3e81d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2588,6 +2588,9 @@ static bool drm_fb_helper_firmware_config(struct drm_fb_helper *fb_helper, int num_connectors_detected = 0; struct drm_modeset_acquire_ctx ctx; + if (!drm_drv_uses_atomic_modeset(dev)) + return false; + save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL); if (!save_enabled) return false; -- cgit v1.2.3 From 761e473f6b23f206862d904a1a5fcbc012656b47 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 24 Apr 2019 16:49:09 -0400 Subject: drm/gem: Fix sphinx warnings Sphinx really wants colons after arguments :/ Fixes the following warnings: drm_gem.c:1384: warning: Function parameter or member 'fence_array' not described in 'drm_gem_fence_array_add' drm_gem.c:1384: warning: Function parameter or member 'fence' not described in 'drm_gem_fence_array_add' drm_gem.c:1435: warning: Function parameter or member 'fence_array' not described in 'drm_gem_fence_array_add_implicit' drm_gem.c:1435: warning: Function parameter or member 'obj' not described in 'drm_gem_fence_array_add_implicit' drm_gem.c:1435: warning: Function parameter or member 'write' not described in 'drm_gem_fence_array_add_implicit' Fixes: 5d5a179d3e90 ("drm: Add helpers for setting up an array of dma_fence dependencies.") Cc: Eric Anholt Cc: Qiang Yu (v1) Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Sean Paul Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Reviewed-by: Eric Anholt Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20190424204916.222155-1-sean@poorly.run --- drivers/gpu/drm/drm_gem.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index fae4676707b6..50de138c89e0 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -1372,8 +1372,8 @@ EXPORT_SYMBOL(drm_gem_unlock_reservations); * drm_gem_fence_array_add - Adds the fence to an array of fences to be * waited on, deduplicating fences from the same context. * - * @fence_array array of dma_fence * for the job to block on. - * @fence the dma_fence to add to the list of dependencies. + * @fence_array: array of dma_fence * for the job to block on. + * @fence: the dma_fence to add to the list of dependencies. * * Returns: * 0 on success, or an error on failing to expand the array. @@ -1423,9 +1423,9 @@ EXPORT_SYMBOL(drm_gem_fence_array_add); * GEM objects used in the job but before updating the reservations with your * own fences. * - * @fence_array array of dma_fence * for the job to block on. - * @obj the gem object to add new dependencies from. - * @write whether the job might write the object (so we need to depend on + * @fence_array: array of dma_fence * for the job to block on. + * @obj: the gem object to add new dependencies from. + * @write: whether the job might write the object (so we need to depend on * shared fences in the reservation object). */ int drm_gem_fence_array_add_implicit(struct xarray *fence_array, -- cgit v1.2.3 From 43068cb7ba1f6ceb1523e947c84002b2a61fd6d4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 29 Mar 2019 20:32:41 +0900 Subject: drm: prefix header search paths with $(srctree)/ Currently, the Kbuild core manipulates header search paths in a crazy way [1]. To fix this mess, I want all Makefiles to add explicit $(srctree)/ to the search paths in the srctree. Some Makefiles are already written in that way, but not all. The goal of this work is to make the notation consistent, and finally get rid of the gross hacks. Having whitespaces after -I does not matter since commit 48f6e3cf5bc6 ("kbuild: do not drop -I without parameter"). [1]: https://patchwork.kernel.org/patch/9632347/ Signed-off-by: Masahiro Yamada Reviewed-by: Sam Ravnborg Reviewed-by: James Qian Wang (Arm Technology China) Acked-by: Liviu Dudau Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1553859161-2628-1-git-send-email-yamada.masahiro@socionext.com --- drivers/gpu/drm/amd/amdgpu/Makefile | 2 +- drivers/gpu/drm/arm/display/komeda/Makefile | 4 ++-- drivers/gpu/drm/i915/gvt/Makefile | 2 +- drivers/gpu/drm/msm/Makefile | 6 +++--- drivers/gpu/drm/nouveau/Kbuild | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index f8c58c425eb9..fdd0ca4b0f0b 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -23,7 +23,7 @@ # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -FULL_AMD_PATH=$(src)/.. +FULL_AMD_PATH=$(srctree)/$(src)/.. DISPLAY_FOLDER_NAME=display FULL_AMD_DISPLAY_PATH = $(FULL_AMD_PATH)/$(DISPLAY_FOLDER_NAME) diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile b/drivers/gpu/drm/arm/display/komeda/Makefile index d593125236ae..7c0851a081d3 100644 --- a/drivers/gpu/drm/arm/display/komeda/Makefile +++ b/drivers/gpu/drm/arm/display/komeda/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 ccflags-y := \ - -I$(src)/../include \ - -I$(src) + -I $(srctree)/$(src)/../include \ + -I $(srctree)/$(src) komeda-y := \ komeda_drv.o \ diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile index 271fb46d4dd0..ea8324abc784 100644 --- a/drivers/gpu/drm/i915/gvt/Makefile +++ b/drivers/gpu/drm/i915/gvt/Makefile @@ -5,5 +5,5 @@ GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \ execlist.o scheduler.o sched_policy.o mmio_context.o cmd_parser.o debugfs.o \ fb_decoder.o dmabuf.o page_track.o -ccflags-y += -I$(src) -I$(src)/$(GVT_DIR) +ccflags-y += -I $(srctree)/$(src) -I $(srctree)/$(src)/$(GVT_DIR)/ i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE)) diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 72d1bfcaab7a..7a05cbf2f820 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 -ccflags-y := -Idrivers/gpu/drm/msm -ccflags-y += -Idrivers/gpu/drm/msm/disp/dpu1 -ccflags-$(CONFIG_DRM_MSM_DSI) += -Idrivers/gpu/drm/msm/dsi +ccflags-y := -I $(srctree)/$(src) +ccflags-y += -I $(srctree)/$(src)/disp/dpu1 +ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi msm-y := \ adreno/adreno_device.o \ diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 581404e6544d..378c5dd692b0 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -1,7 +1,7 @@ -ccflags-y += -I$(src)/include -ccflags-y += -I$(src)/include/nvkm -ccflags-y += -I$(src)/nvkm -ccflags-y += -I$(src) +ccflags-y += -I $(srctree)/$(src)/include +ccflags-y += -I $(srctree)/$(src)/include/nvkm +ccflags-y += -I $(srctree)/$(src)/nvkm +ccflags-y += -I $(srctree)/$(src) # NVKM - HW resource manager #- code also used by various userspace tools/tests -- cgit v1.2.3 From 879a4e70f96a26a9368a3caed2f552aa67105852 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 25 Apr 2019 22:24:19 +0300 Subject: drm/i915: Fix ICL output CSC programming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When I refactored the code into its own function I accidentally misplaced the <<16 shifts for some of the registers causing us to lose the blue channel entirely. We should really find a way to test this... Cc: Uma Shankar Fixes: d2c19b06d6ea ("drm/i915: Clean up ilk/icl pipe/output CSC programming") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20190425192419.24931-1-ville.syrjala@linux.intel.com Reviewed-by: Swati Sharma (cherry picked from commit d428ca17ea3d307c5a7f77cf24586584bf1c2d74) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/intel_color.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index ca341a9e47e6..9093daabc290 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -173,13 +173,13 @@ static void icl_update_output_csc(struct intel_crtc *crtc, I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]); I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]); - I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe), coeff[2]); + I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe), coeff[2] << 16); I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]); - I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe), coeff[5]); + I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe), coeff[5] << 16); I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]); - I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe), coeff[8]); + I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe), coeff[8] << 16); I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]); I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]); -- cgit v1.2.3 From 9801a7eadf4cc29cdc90583a49f12decbb832ced Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:05:41 +0000 Subject: drm: Add drm_atomic_get_old/new_private_obj_state This pair of functions return the old/new private object state for the given private_obj, or NULL if the private_obj is not part of the global atomic state. Reviewed-by: Alexandru Gheorghe Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/drm_atomic.c | 45 +++++++++++++++++++++++++++++++++++++++++++- include/drm/drm_atomic.h | 6 ++++++ 2 files changed, 50 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 5eb40130fafb..f4924cb7f495 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -797,6 +797,50 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, } EXPORT_SYMBOL(drm_atomic_get_private_obj_state); +/** + * drm_atomic_get_old_private_obj_state + * @state: global atomic state object + * @obj: private_obj to grab + * + * This function returns the old private object state for the given private_obj, + * or NULL if the private_obj is not part of the global atomic state. + */ +struct drm_private_state * +drm_atomic_get_old_private_obj_state(struct drm_atomic_state *state, + struct drm_private_obj *obj) +{ + int i; + + for (i = 0; i < state->num_private_objs; i++) + if (obj == state->private_objs[i].ptr) + return state->private_objs[i].old_state; + + return NULL; +} +EXPORT_SYMBOL(drm_atomic_get_old_private_obj_state); + +/** + * drm_atomic_get_new_private_obj_state + * @state: global atomic state object + * @obj: private_obj to grab + * + * This function returns the new private object state for the given private_obj, + * or NULL if the private_obj is not part of the global atomic state. + */ +struct drm_private_state * +drm_atomic_get_new_private_obj_state(struct drm_atomic_state *state, + struct drm_private_obj *obj) +{ + int i; + + for (i = 0; i < state->num_private_objs; i++) + if (obj == state->private_objs[i].ptr) + return state->private_objs[i].new_state; + + return NULL; +} +EXPORT_SYMBOL(drm_atomic_get_new_private_obj_state); + /** * drm_atomic_get_connector_state - get connector state * @state: global atomic state object @@ -1236,4 +1280,3 @@ int drm_atomic_debugfs_init(struct drm_minor *minor) minor->debugfs_root, minor); } #endif - diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 824a5ed4e216..e937ff2beb04 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -452,6 +452,12 @@ void drm_atomic_private_obj_fini(struct drm_private_obj *obj); struct drm_private_state * __must_check drm_atomic_get_private_obj_state(struct drm_atomic_state *state, struct drm_private_obj *obj); +struct drm_private_state * +drm_atomic_get_old_private_obj_state(struct drm_atomic_state *state, + struct drm_private_obj *obj); +struct drm_private_state * +drm_atomic_get_new_private_obj_state(struct drm_atomic_state *state, + struct drm_private_obj *obj); /** * drm_atomic_get_existing_crtc_state - get crtc state, if it exists -- cgit v1.2.3 From 8d537d3bcb35b159daa2dc0bbe7b46e461c932dd Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:05:51 +0000 Subject: drm/komeda: Add komeda_pipeline/component_get_state_and_set_user get_state_and_set_user packed get_state and set_user into one function, which get pipeline/component state for a specific pipeline/component, if success set the user to it. v2: - Rebase. - Applied commit: b962a12050a3 ("drm/atomic: integrate modeset lock with private objects") And delete our private modeset lock for pipeline. Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/Makefile | 1 + .../drm/arm/display/komeda/komeda_pipeline_state.c | 144 +++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile b/drivers/gpu/drm/arm/display/komeda/Makefile index d593125236ae..62bd1bff66a3 100644 --- a/drivers/gpu/drm/arm/display/komeda/Makefile +++ b/drivers/gpu/drm/arm/display/komeda/Makefile @@ -9,6 +9,7 @@ komeda-y := \ komeda_dev.o \ komeda_format_caps.o \ komeda_pipeline.o \ + komeda_pipeline_state.o \ komeda_framebuffer.o \ komeda_kms.o \ komeda_crtc.o \ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c new file mode 100644 index 000000000000..dd020b035d76 --- /dev/null +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) COPYRIGHT 2018 ARM Limited. All rights reserved. + * Author: James.Qian.Wang + * + */ + +#include +#include +#include "komeda_dev.h" +#include "komeda_kms.h" +#include "komeda_pipeline.h" + +static inline bool is_switching_user(void *old, void *new) +{ + if (!old || !new) + return false; + + return old != new; +} + +struct komeda_pipeline_state * +komeda_pipeline_get_state(struct komeda_pipeline *pipe, + struct drm_atomic_state *state) +{ + struct drm_private_state *priv_st; + + priv_st = drm_atomic_get_private_obj_state(state, &pipe->obj); + if (IS_ERR(priv_st)) + return ERR_CAST(priv_st); + + return priv_to_pipe_st(priv_st); +} + +/* Assign pipeline for crtc */ +struct komeda_pipeline_state * +komeda_pipeline_get_state_and_set_crtc(struct komeda_pipeline *pipe, + struct drm_atomic_state *state, + struct drm_crtc *crtc) +{ + struct komeda_pipeline_state *st; + + st = komeda_pipeline_get_state(pipe, state); + if (IS_ERR(st)) + return st; + + if (is_switching_user(crtc, st->crtc)) { + DRM_DEBUG_ATOMIC("CRTC%d required pipeline%d is busy.\n", + drm_crtc_index(crtc), pipe->id); + return ERR_PTR(-EBUSY); + } + + /* pipeline only can be disabled when the it is free or unused */ + if (!crtc && st->active_comps) { + DRM_DEBUG_ATOMIC("Disabling a busy pipeline:%d.\n", pipe->id); + return ERR_PTR(-EBUSY); + } + + st->crtc = crtc; + + if (crtc) { + struct komeda_crtc_state *kcrtc_st; + + kcrtc_st = to_kcrtc_st(drm_atomic_get_new_crtc_state(state, + crtc)); + + kcrtc_st->active_pipes |= BIT(pipe->id); + kcrtc_st->affected_pipes |= BIT(pipe->id); + } + return st; +} + +static struct komeda_component_state * +komeda_component_get_state(struct komeda_component *c, + struct drm_atomic_state *state) +{ + struct drm_private_state *priv_st; + + WARN_ON(!drm_modeset_is_locked(&c->pipeline->obj.lock)); + + priv_st = drm_atomic_get_private_obj_state(state, &c->obj); + if (IS_ERR(priv_st)) + return ERR_CAST(priv_st); + + return priv_to_comp_st(priv_st); +} + +/** + * komeda_component_get_state_and_set_user() + * + * @c: component to get state and set user + * @state: global atomic state + * @user: direct user, the binding user + * @crtc: the CRTC user, the big boss :) + * + * This function accepts two users: + * - The direct user: can be plane/crtc/wb_connector depends on component + * - The big boss (CRTC) + * CRTC is the big boss (the final user), because all component resources + * eventually will be assigned to CRTC, like the layer will be binding to + * kms_plane, but kms plane will be binding to a CRTC eventually. + * + * The big boss (CRTC) is for pipeline assignment, since &komeda_component isn't + * independent and can be assigned to CRTC freely, but belongs to a specific + * pipeline, only pipeline can be shared between crtc, and pipeline as a whole + * (include all the internal components) assigned to a specific CRTC. + * + * So when set a user to komeda_component, need first to check the status of + * component->pipeline to see if the pipeline is available on this specific + * CRTC. if the pipeline is busy (assigned to another CRTC), even the required + * component is free, the component still cannot be assigned to the direct user. + */ +struct komeda_component_state * +komeda_component_get_state_and_set_user(struct komeda_component *c, + struct drm_atomic_state *state, + void *user, + struct drm_crtc *crtc) +{ + struct komeda_pipeline_state *pipe_st; + struct komeda_component_state *st; + + /* First check if the pipeline is available */ + pipe_st = komeda_pipeline_get_state_and_set_crtc(c->pipeline, + state, crtc); + if (IS_ERR(pipe_st)) + return ERR_CAST(pipe_st); + + st = komeda_component_get_state(c, state); + if (IS_ERR(st)) + return st; + + /* check if the component has been occupied */ + if (is_switching_user(user, st->binding_user)) { + DRM_DEBUG_ATOMIC("required %s is busy.\n", c->name); + return ERR_PTR(-EBUSY); + } + + st->binding_user = user; + /* mark the component as active if user is valid */ + if (st->binding_user) + pipe_st->active_comps |= BIT(c->id); + + return st; +} -- cgit v1.2.3 From ee6b73d6b09d23e83be0605ff6467ade09077439 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:06:01 +0000 Subject: drm/komeda: Initialize komeda component as drm private object Initialize koemda_layer, komeda_compiz, komeda_improc and komeda_timing_ctrlr as drm private object, then track komeda private component state by drm_atomic_state. v2: - Update code after Applied commit: b962a12050a3 ("drm/atomic: integrate modeset lock with private objects") Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 3 +- drivers/gpu/drm/arm/display/komeda/komeda_kms.h | 2 +- .../drm/arm/display/komeda/komeda_private_obj.c | 220 +++++++++++++++++++-- 3 files changed, 208 insertions(+), 17 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index b214edbfbbc6..55b103ae3e2f 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -184,6 +184,7 @@ uninstall_irq: drm_irq_uninstall(drm); cleanup_mode_config: drm_mode_config_cleanup(drm); + komeda_kms_cleanup_private_objs(kms); free_kms: kfree(kms); return ERR_PTR(err); @@ -198,7 +199,7 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) drm_dev_unregister(drm); drm_irq_uninstall(drm); component_unbind_all(mdev->dev, drm); - komeda_kms_cleanup_private_objs(mdev); + komeda_kms_cleanup_private_objs(kms); drm_mode_config_cleanup(drm); drm->dev_private = NULL; drm_dev_put(drm); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index 15ac8b85506c..beb94ff110d7 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -108,7 +108,7 @@ int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev); int komeda_kms_add_planes(struct komeda_kms_dev *kms, struct komeda_dev *mdev); int komeda_kms_add_private_objs(struct komeda_kms_dev *kms, struct komeda_dev *mdev); -void komeda_kms_cleanup_private_objs(struct komeda_dev *mdev); +void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms); void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, struct komeda_events *evts); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c index f1c9e3fefa86..a54878cbd6e4 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c @@ -7,6 +7,188 @@ #include "komeda_dev.h" #include "komeda_kms.h" +static void +komeda_component_state_reset(struct komeda_component_state *st) +{ + st->binding_user = NULL; + st->affected_inputs = st->active_inputs; + st->active_inputs = 0; + st->changed_active_inputs = 0; +} + +static struct drm_private_state * +komeda_layer_atomic_duplicate_state(struct drm_private_obj *obj) +{ + struct komeda_layer_state *st; + + st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); + if (!st) + return NULL; + + komeda_component_state_reset(&st->base); + __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); + + return &st->base.obj; +} + +static void +komeda_layer_atomic_destroy_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + struct komeda_layer_state *st = to_layer_st(priv_to_comp_st(state)); + + kfree(st); +} + +static const struct drm_private_state_funcs komeda_layer_obj_funcs = { + .atomic_duplicate_state = komeda_layer_atomic_duplicate_state, + .atomic_destroy_state = komeda_layer_atomic_destroy_state, +}; + +static int komeda_layer_obj_add(struct komeda_kms_dev *kms, + struct komeda_layer *layer) +{ + struct komeda_layer_state *st; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (!st) + return -ENOMEM; + + st->base.component = &layer->base; + drm_atomic_private_obj_init(&kms->base, &layer->base.obj, &st->base.obj, + &komeda_layer_obj_funcs); + return 0; +} + +static struct drm_private_state * +komeda_compiz_atomic_duplicate_state(struct drm_private_obj *obj) +{ + struct komeda_compiz_state *st; + + st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); + if (!st) + return NULL; + + komeda_component_state_reset(&st->base); + __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); + + return &st->base.obj; +} + +static void +komeda_compiz_atomic_destroy_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + kfree(to_compiz_st(priv_to_comp_st(state))); +} + +static const struct drm_private_state_funcs komeda_compiz_obj_funcs = { + .atomic_duplicate_state = komeda_compiz_atomic_duplicate_state, + .atomic_destroy_state = komeda_compiz_atomic_destroy_state, +}; + +static int komeda_compiz_obj_add(struct komeda_kms_dev *kms, + struct komeda_compiz *compiz) +{ + struct komeda_compiz_state *st; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (!st) + return -ENOMEM; + + st->base.component = &compiz->base; + drm_atomic_private_obj_init(&kms->base, &compiz->base.obj, &st->base.obj, + &komeda_compiz_obj_funcs); + + return 0; +} + +static struct drm_private_state * +komeda_improc_atomic_duplicate_state(struct drm_private_obj *obj) +{ + struct komeda_improc_state *st; + + st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); + if (!st) + return NULL; + + komeda_component_state_reset(&st->base); + __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); + + return &st->base.obj; +} + +static void +komeda_improc_atomic_destroy_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + kfree(to_improc_st(priv_to_comp_st(state))); +} + +static const struct drm_private_state_funcs komeda_improc_obj_funcs = { + .atomic_duplicate_state = komeda_improc_atomic_duplicate_state, + .atomic_destroy_state = komeda_improc_atomic_destroy_state, +}; + +static int komeda_improc_obj_add(struct komeda_kms_dev *kms, + struct komeda_improc *improc) +{ + struct komeda_improc_state *st; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (!st) + return -ENOMEM; + + st->base.component = &improc->base; + drm_atomic_private_obj_init(&kms->base, &improc->base.obj, &st->base.obj, + &komeda_improc_obj_funcs); + + return 0; +} + +static struct drm_private_state * +komeda_timing_ctrlr_atomic_duplicate_state(struct drm_private_obj *obj) +{ + struct komeda_timing_ctrlr_state *st; + + st = kmemdup(obj->state, sizeof(*st), GFP_KERNEL); + if (!st) + return NULL; + + komeda_component_state_reset(&st->base); + __drm_atomic_helper_private_obj_duplicate_state(obj, &st->base.obj); + + return &st->base.obj; +} + +static void +komeda_timing_ctrlr_atomic_destroy_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + kfree(to_ctrlr_st(priv_to_comp_st(state))); +} + +static const struct drm_private_state_funcs komeda_timing_ctrlr_obj_funcs = { + .atomic_duplicate_state = komeda_timing_ctrlr_atomic_duplicate_state, + .atomic_destroy_state = komeda_timing_ctrlr_atomic_destroy_state, +}; + +static int komeda_timing_ctrlr_obj_add(struct komeda_kms_dev *kms, + struct komeda_timing_ctrlr *ctrlr) +{ + struct komeda_compiz_state *st; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (!st) + return -ENOMEM; + + st->base.component = &ctrlr->base; + drm_atomic_private_obj_init(&kms->base, &ctrlr->base.obj, &st->base.obj, + &komeda_timing_ctrlr_obj_funcs); + + return 0; +} + static struct drm_private_state * komeda_pipeline_atomic_duplicate_state(struct drm_private_obj *obj) { @@ -55,7 +237,7 @@ int komeda_kms_add_private_objs(struct komeda_kms_dev *kms, struct komeda_dev *mdev) { struct komeda_pipeline *pipe; - int i, err; + int i, j, err; for (i = 0; i < mdev->n_pipelines; i++) { pipe = mdev->pipelines[i]; @@ -64,25 +246,33 @@ int komeda_kms_add_private_objs(struct komeda_kms_dev *kms, if (err) return err; - /* Add component */ + for (j = 0; j < pipe->n_layers; j++) { + err = komeda_layer_obj_add(kms, pipe->layers[j]); + if (err) + return err; + } + + err = komeda_compiz_obj_add(kms, pipe->compiz); + if (err) + return err; + + err = komeda_improc_obj_add(kms, pipe->improc); + if (err) + return err; + + err = komeda_timing_ctrlr_obj_add(kms, pipe->ctrlr); + if (err) + return err; } return 0; } -void komeda_kms_cleanup_private_objs(struct komeda_dev *mdev) +void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms) { - struct komeda_pipeline *pipe; - struct komeda_component *c; - int i, id; + struct drm_mode_config *config = &kms->base.mode_config; + struct drm_private_obj *obj, *next; - for (i = 0; i < mdev->n_pipelines; i++) { - pipe = mdev->pipelines[i]; - dp_for_each_set_bit(id, pipe->avail_comps) { - c = komeda_pipeline_get_component(pipe, id); - - drm_atomic_private_obj_fini(&c->obj); - } - drm_atomic_private_obj_fini(&pipe->obj); - } + list_for_each_entry_safe(obj, next, &config->privobj_list, head) + drm_atomic_private_obj_fini(obj); } -- cgit v1.2.3 From 11bb22ee77575e4c5beff48233fdf91ba839c8b6 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:06:12 +0000 Subject: drm/komeda: Add komeda_build_layer_data_flow build_layer_data_flow builds a input pipeline according to plane_state. and in this initial stage only added this simplest pipeline usage: Layer -> compiz The scaler and layer_split will be added in the future. v2: - Rebase. - Introduce struct komeda_data_flow_cfg - Add a function komeda_component_validate_private to replace the MACRO component_validate_private Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- .../gpu/drm/arm/display/komeda/komeda_pipeline.h | 24 ++ .../drm/arm/display/komeda/komeda_pipeline_state.c | 266 ++++++++++++++++++++- 2 files changed, 289 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index c30a790d0712..16d7ae891e81 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -278,6 +278,22 @@ struct komeda_timing_ctrlr_state { struct komeda_component_state base; }; +/* Why define A separated structure but not use plane_state directly ? + * 1. Komeda supports layer_split which means a plane_state can be split and + * handled by two layers, one layer only handle half of plane image. + * 2. Fix up the user properties according to HW's capabilities, like user + * set rotation to R180, but HW only supports REFLECT_X+Y. the rot here is + * after drm_rotation_simplify() + */ +struct komeda_data_flow_cfg { + struct komeda_component_output input; + u16 in_x, in_y, in_w, in_h; + u32 out_x, out_y, out_w, out_h; + u32 rot; + int blending_zorder; + u8 pixel_blend_mode, layer_alpha; +}; + /** struct komeda_pipeline_funcs */ struct komeda_pipeline_funcs { /* dump_register: Optional, dump registers to seq_file */ @@ -382,4 +398,12 @@ komeda_component_add(struct komeda_pipeline *pipe, void komeda_component_destroy(struct komeda_dev *mdev, struct komeda_component *c); +struct komeda_plane_state; +struct komeda_crtc_state; + +int komeda_build_layer_data_flow(struct komeda_layer *layer, + struct komeda_plane_state *kplane_st, + struct komeda_crtc_state *kcrtc_st, + struct komeda_data_flow_cfg *dflow); + #endif /* _KOMEDA_PIPELINE_H_*/ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index dd020b035d76..9470c8b6468f 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -10,6 +10,7 @@ #include "komeda_dev.h" #include "komeda_kms.h" #include "komeda_pipeline.h" +#include "komeda_framebuffer.h" static inline bool is_switching_user(void *old, void *new) { @@ -85,6 +86,18 @@ komeda_component_get_state(struct komeda_component *c, return priv_to_comp_st(priv_st); } +static struct komeda_component_state * +komeda_component_get_old_state(struct komeda_component *c, + struct drm_atomic_state *state) +{ + struct drm_private_state *priv_st; + + priv_st = drm_atomic_get_old_private_obj_state(state, &c->obj); + if (priv_st) + return priv_to_comp_st(priv_st); + return NULL; +} + /** * komeda_component_get_state_and_set_user() * @@ -110,7 +123,7 @@ komeda_component_get_state(struct komeda_component *c, * CRTC. if the pipeline is busy (assigned to another CRTC), even the required * component is free, the component still cannot be assigned to the direct user. */ -struct komeda_component_state * +static struct komeda_component_state * komeda_component_get_state_and_set_user(struct komeda_component *c, struct drm_atomic_state *state, void *user, @@ -142,3 +155,254 @@ komeda_component_get_state_and_set_user(struct komeda_component *c, return st; } + +static void +komeda_component_add_input(struct komeda_component_state *state, + struct komeda_component_output *input, + int idx) +{ + struct komeda_component *c = state->component; + + WARN_ON((idx < 0 || idx >= c->max_active_inputs)); + + /* since the inputs[i] is only valid when it is active. So if a input[i] + * is a newly enabled input which switches from disable to enable, then + * the old inputs[i] is undefined (NOT zeroed), we can not rely on + * memcmp, but directly mark it changed + */ + if (!has_bit(idx, state->affected_inputs) || + memcmp(&state->inputs[idx], input, sizeof(*input))) { + memcpy(&state->inputs[idx], input, sizeof(*input)); + state->changed_active_inputs |= BIT(idx); + } + state->active_inputs |= BIT(idx); + state->affected_inputs |= BIT(idx); +} + +static int +komeda_component_check_input(struct komeda_component_state *state, + struct komeda_component_output *input, + int idx) +{ + struct komeda_component *c = state->component; + + if ((idx < 0) || (idx >= c->max_active_inputs)) { + DRM_DEBUG_ATOMIC("%s invalid input id: %d.\n", c->name, idx); + return -EINVAL; + } + + if (has_bit(idx, state->active_inputs)) { + DRM_DEBUG_ATOMIC("%s required input_id: %d has been occupied already.\n", + c->name, idx); + return -EINVAL; + } + + return 0; +} + +static void +komeda_component_set_output(struct komeda_component_output *output, + struct komeda_component *comp, + u8 output_port) +{ + output->component = comp; + output->output_port = output_port; +} + +static int +komeda_component_validate_private(struct komeda_component *c, + struct komeda_component_state *st) +{ + int err; + + if (!c->funcs->validate) + return 0; + + err = c->funcs->validate(c, st); + if (err) + DRM_DEBUG_ATOMIC("%s validate private failed.\n", c->name); + + return err; +} + +static int +komeda_layer_check_cfg(struct komeda_layer *layer, + struct komeda_plane_state *kplane_st, + struct komeda_data_flow_cfg *dflow) +{ + if (!in_range(&layer->hsize_in, dflow->in_w)) { + DRM_DEBUG_ATOMIC("src_w: %d is out of range.\n", dflow->in_w); + return -EINVAL; + } + + if (!in_range(&layer->vsize_in, dflow->in_h)) { + DRM_DEBUG_ATOMIC("src_h: %d is out of range.\n", dflow->in_h); + return -EINVAL; + } + + return 0; +} + +static int +komeda_layer_validate(struct komeda_layer *layer, + struct komeda_plane_state *kplane_st, + struct komeda_data_flow_cfg *dflow) +{ + struct drm_plane_state *plane_st = &kplane_st->base; + struct drm_framebuffer *fb = plane_st->fb; + struct komeda_fb *kfb = to_kfb(fb); + struct komeda_component_state *c_st; + struct komeda_layer_state *st; + int i, err; + + err = komeda_layer_check_cfg(layer, kplane_st, dflow); + if (err) + return err; + + c_st = komeda_component_get_state_and_set_user(&layer->base, + plane_st->state, plane_st->plane, plane_st->crtc); + if (IS_ERR(c_st)) + return PTR_ERR(c_st); + + st = to_layer_st(c_st); + + st->rot = dflow->rot; + st->hsize = kfb->aligned_w; + st->vsize = kfb->aligned_h; + + for (i = 0; i < fb->format->num_planes; i++) + st->addr[i] = komeda_fb_get_pixel_addr(kfb, dflow->in_x, + dflow->in_y, i); + + err = komeda_component_validate_private(&layer->base, c_st); + if (err) + return err; + + /* update the data flow for the next stage */ + komeda_component_set_output(&dflow->input, &layer->base, 0); + + return 0; +} + +static void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st, + u16 *hsize, u16 *vsize) +{ + struct drm_display_mode *m = &kcrtc_st->base.adjusted_mode; + + if (hsize) + *hsize = m->hdisplay; + if (vsize) + *vsize = m->vdisplay; +} + +static int +komeda_compiz_set_input(struct komeda_compiz *compiz, + struct komeda_crtc_state *kcrtc_st, + struct komeda_data_flow_cfg *dflow) +{ + struct drm_atomic_state *drm_st = kcrtc_st->base.state; + struct komeda_component_state *c_st, *old_st; + struct komeda_compiz_input_cfg *cin; + u16 compiz_w, compiz_h; + int idx = dflow->blending_zorder; + + pipeline_composition_size(kcrtc_st, &compiz_w, &compiz_h); + /* check display rect */ + if ((dflow->out_x + dflow->out_w > compiz_w) || + (dflow->out_y + dflow->out_h > compiz_h) || + dflow->out_w == 0 || dflow->out_h == 0) { + DRM_DEBUG_ATOMIC("invalid disp rect [x=%d, y=%d, w=%d, h=%d]\n", + dflow->out_x, dflow->out_y, + dflow->out_w, dflow->out_h); + return -EINVAL; + } + + c_st = komeda_component_get_state_and_set_user(&compiz->base, drm_st, + kcrtc_st->base.crtc, kcrtc_st->base.crtc); + if (IS_ERR(c_st)) + return PTR_ERR(c_st); + + if (komeda_component_check_input(c_st, &dflow->input, idx)) + return -EINVAL; + + cin = &(to_compiz_st(c_st)->cins[idx]); + + cin->hsize = dflow->out_w; + cin->vsize = dflow->out_h; + cin->hoffset = dflow->out_x; + cin->voffset = dflow->out_y; + cin->pixel_blend_mode = dflow->pixel_blend_mode; + cin->layer_alpha = dflow->layer_alpha; + + old_st = komeda_component_get_old_state(&compiz->base, drm_st); + WARN_ON(!old_st); + + /* compare with old to check if this input has been changed */ + if (memcmp(&(to_compiz_st(old_st)->cins[idx]), cin, sizeof(*cin))) + c_st->changed_active_inputs |= BIT(idx); + + komeda_component_add_input(c_st, &dflow->input, idx); + + return 0; +} + +int +komeda_compiz_validate(struct komeda_compiz *compiz, + struct komeda_crtc_state *state, + struct komeda_data_flow_cfg *dflow) +{ + struct komeda_component_state *c_st; + struct komeda_compiz_state *st; + + c_st = komeda_component_get_state_and_set_user(&compiz->base, + state->base.state, state->base.crtc, state->base.crtc); + if (IS_ERR(c_st)) + return PTR_ERR(c_st); + + st = to_compiz_st(c_st); + + pipeline_composition_size(state, &st->hsize, &st->vsize); + + komeda_component_set_output(&dflow->input, &compiz->base, 0); + + /* compiz output dflow will be fed to the next pipeline stage, prepare + * the data flow configuration for the next stage + */ + if (dflow) { + dflow->in_w = st->hsize; + dflow->in_h = st->vsize; + dflow->out_w = dflow->in_w; + dflow->out_h = dflow->in_h; + /* the output data of compiz doesn't have alpha, it only can be + * used as bottom layer when blend it with master layers + */ + dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE; + dflow->layer_alpha = 0xFF; + dflow->blending_zorder = 0; + } + + return 0; +} + +int komeda_build_layer_data_flow(struct komeda_layer *layer, + struct komeda_plane_state *kplane_st, + struct komeda_crtc_state *kcrtc_st, + struct komeda_data_flow_cfg *dflow) +{ + struct drm_plane *plane = kplane_st->base.plane; + struct komeda_pipeline *pipe = layer->base.pipeline; + int err; + + DRM_DEBUG_ATOMIC("%s handling [PLANE:%d:%s]: src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]", + layer->base.name, plane->base.id, plane->name, + dflow->in_x, dflow->in_y, dflow->in_w, dflow->in_h, + dflow->out_x, dflow->out_y, dflow->out_w, dflow->out_h); + + err = komeda_layer_validate(layer, kplane_st, dflow); + if (err) + return err; + + err = komeda_compiz_set_input(pipe->compiz, kcrtc_st, dflow); + + return err; +} -- cgit v1.2.3 From 9e560309417638507398fd6239e04f47cc907f70 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:06:22 +0000 Subject: drm/komeda: Add komeda_plane/plane_helper_funcs Per komeda design KMS-plane maps to komeda layer input pipeline. komeda_plane_atomic_check is for building a komeda layer input pipeline. And KMS-plane is only a user of komeda resources. so there is no real HW update for plane, but all HW update will be handled in crtc->flush. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 129 ++++++++++++++++++++++ 1 file changed, 129 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index 0a4953a9a909..ffcd3d08b5d3 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -7,10 +7,86 @@ #include #include #include +#include #include "komeda_dev.h" #include "komeda_kms.h" +static int +komeda_plane_init_data_flow(struct drm_plane_state *st, + struct komeda_data_flow_cfg *dflow) +{ + struct drm_framebuffer *fb = st->fb; + + memset(dflow, 0, sizeof(*dflow)); + + dflow->blending_zorder = st->zpos; + + /* if format doesn't have alpha, fix blend mode to PIXEL_NONE */ + dflow->pixel_blend_mode = fb->format->has_alpha ? + st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE; + dflow->layer_alpha = st->alpha >> 8; + + dflow->out_x = st->crtc_x; + dflow->out_y = st->crtc_y; + dflow->out_w = st->crtc_w; + dflow->out_h = st->crtc_h; + + dflow->in_x = st->src_x >> 16; + dflow->in_y = st->src_y >> 16; + dflow->in_w = st->src_w >> 16; + dflow->in_h = st->src_h >> 16; + + return 0; +} + +int komeda_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct komeda_plane *kplane = to_kplane(plane); + struct komeda_plane_state *kplane_st = to_kplane_st(state); + struct komeda_layer *layer = kplane->layer; + struct drm_crtc_state *crtc_st; + struct komeda_crtc *kcrtc; + struct komeda_crtc_state *kcrtc_st; + struct komeda_data_flow_cfg dflow; + int err; + + if (!state->crtc || !state->fb) + return 0; + + crtc_st = drm_atomic_get_crtc_state(state->state, state->crtc); + if (!crtc_st->enable) { + DRM_DEBUG_ATOMIC("Cannot update plane on a disabled CRTC.\n"); + return -EINVAL; + } + + /* crtc is inactive, skip the resource assignment */ + if (!crtc_st->active) + return 0; + + kcrtc = to_kcrtc(state->crtc); + kcrtc_st = to_kcrtc_st(crtc_st); + + err = komeda_plane_init_data_flow(state, &dflow); + if (err) + return err; + + err = komeda_build_layer_data_flow(layer, kplane_st, kcrtc_st, &dflow); + + return err; +} + +/* plane doesn't represent a real HW, so there is no HW update for plane. + * komeda handles all the HW update in crtc->atomic_flush + */ +void komeda_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ +} + static const struct drm_plane_helper_funcs komeda_plane_helper_funcs = { + .atomic_check = komeda_plane_atomic_check, + .atomic_update = komeda_plane_atomic_update, }; static void komeda_plane_destroy(struct drm_plane *plane) @@ -20,7 +96,60 @@ static void komeda_plane_destroy(struct drm_plane *plane) kfree(to_kplane(plane)); } +static void komeda_plane_reset(struct drm_plane *plane) +{ + struct komeda_plane_state *state; + struct komeda_plane *kplane = to_kplane(plane); + + if (plane->state) + __drm_atomic_helper_plane_destroy_state(plane->state); + + kfree(plane->state); + plane->state = NULL; + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (state) { + state->base.rotation = DRM_MODE_ROTATE_0; + state->base.pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; + state->base.alpha = DRM_BLEND_ALPHA_OPAQUE; + state->base.zpos = kplane->layer->base.id; + plane->state = &state->base; + plane->state->plane = plane; + } +} + +static struct drm_plane_state * +komeda_plane_atomic_duplicate_state(struct drm_plane *plane) +{ + struct komeda_plane_state *new; + + if (WARN_ON(!plane->state)) + return NULL; + + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + + __drm_atomic_helper_plane_duplicate_state(plane, &new->base); + + return &new->base; +} + +static void +komeda_plane_atomic_destroy_state(struct drm_plane *plane, + struct drm_plane_state *state) +{ + __drm_atomic_helper_plane_destroy_state(state); + kfree(to_kplane_st(state)); +} + static const struct drm_plane_funcs komeda_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = komeda_plane_destroy, + .reset = komeda_plane_reset, + .atomic_duplicate_state = komeda_plane_atomic_duplicate_state, + .atomic_destroy_state = komeda_plane_atomic_destroy_state, }; /* for komeda, which is pipeline can be share between crtcs */ -- cgit v1.2.3 From c3015342b3f9aee7ca3ee7c7d61b0eb094488a09 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:10:30 +0000 Subject: drm/komeda: Add komeda_build_display_data_flow This function builds a display output pipeline according to crtc_state. And this change only added single pipeline support, the dual pipeline with slave enabled data flow support will be added in the following change. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- .../gpu/drm/arm/display/komeda/komeda_pipeline.h | 3 + .../drm/arm/display/komeda/komeda_pipeline_state.c | 76 +++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index 16d7ae891e81..22ad4dfc3e8d 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -400,10 +400,13 @@ void komeda_component_destroy(struct komeda_dev *mdev, struct komeda_plane_state; struct komeda_crtc_state; +struct komeda_crtc; int komeda_build_layer_data_flow(struct komeda_layer *layer, struct komeda_plane_state *kplane_st, struct komeda_crtc_state *kcrtc_st, struct komeda_data_flow_cfg *dflow); +int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, + struct komeda_crtc_state *kcrtc_st); #endif /* _KOMEDA_PIPELINE_H_*/ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 9470c8b6468f..8d25ce17e517 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -346,7 +346,7 @@ komeda_compiz_set_input(struct komeda_compiz *compiz, return 0; } -int +static int komeda_compiz_validate(struct komeda_compiz *compiz, struct komeda_crtc_state *state, struct komeda_data_flow_cfg *dflow) @@ -384,6 +384,53 @@ komeda_compiz_validate(struct komeda_compiz *compiz, return 0; } +static int +komeda_improc_validate(struct komeda_improc *improc, + struct komeda_crtc_state *kcrtc_st, + struct komeda_data_flow_cfg *dflow) +{ + struct drm_crtc *crtc = kcrtc_st->base.crtc; + struct komeda_component_state *c_st; + struct komeda_improc_state *st; + + c_st = komeda_component_get_state_and_set_user(&improc->base, + kcrtc_st->base.state, crtc, crtc); + if (IS_ERR(c_st)) + return PTR_ERR(c_st); + + st = to_improc_st(c_st); + + st->hsize = dflow->in_w; + st->vsize = dflow->in_h; + + komeda_component_add_input(&st->base, &dflow->input, 0); + komeda_component_set_output(&dflow->input, &improc->base, 0); + + return 0; +} + +static int +komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr, + struct komeda_crtc_state *kcrtc_st, + struct komeda_data_flow_cfg *dflow) +{ + struct drm_crtc *crtc = kcrtc_st->base.crtc; + struct komeda_timing_ctrlr_state *st; + struct komeda_component_state *c_st; + + c_st = komeda_component_get_state_and_set_user(&ctrlr->base, + kcrtc_st->base.state, crtc, crtc); + if (IS_ERR(c_st)) + return PTR_ERR(c_st); + + st = to_ctrlr_st(c_st); + + komeda_component_add_input(&st->base, &dflow->input, 0); + komeda_component_set_output(&dflow->input, &ctrlr->base, 0); + + return 0; +} + int komeda_build_layer_data_flow(struct komeda_layer *layer, struct komeda_plane_state *kplane_st, struct komeda_crtc_state *kcrtc_st, @@ -406,3 +453,30 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer, return err; } + +/* build display output data flow, the data path is: + * compiz -> improc -> timing_ctrlr + */ +int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, + struct komeda_crtc_state *kcrtc_st) +{ + struct komeda_pipeline *master = kcrtc->master; + struct komeda_data_flow_cfg m_dflow; /* master data flow */ + int err; + + memset(&m_dflow, 0, sizeof(m_dflow)); + + err = komeda_compiz_validate(master->compiz, kcrtc_st, &m_dflow); + if (err) + return err; + + err = komeda_improc_validate(master->improc, kcrtc_st, &m_dflow); + if (err) + return err; + + err = komeda_timing_ctrlr_validate(master->ctrlr, kcrtc_st, &m_dflow); + if (err) + return err; + + return 0; +} -- cgit v1.2.3 From 552b831cd5e1d8ee0cf71e8af08734ef2b5aa7e4 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:10:39 +0000 Subject: drm/komeda: Add komeda_release_unclaimed_resources Komeda driver treats KMS-CRTC/PLANE as user which will acquire pipeline resources, but we still need to release the unclaimed resources. crtc_atomic_check is the final check stage, so beside build a display data pipeline according the crtc_state, but still needs to release/disable the unclaimed pipeline resources. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 27 ++++++++++ .../gpu/drm/arm/display/komeda/komeda_pipeline.h | 3 ++ .../drm/arm/display/komeda/komeda_pipeline_state.c | 58 ++++++++++++++++++++++ 3 files changed, 88 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index f88a14927be9..18209cae287c 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -18,6 +18,32 @@ #include "komeda_dev.h" #include "komeda_kms.h" +/* crtc_atomic_check is the final check stage, so beside build a display data + * pipeline according the crtc_state, but still needs to release/disable the + * unclaimed pipeline resources. + */ +static int +komeda_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state); + int err; + + if (state->active) { + err = komeda_build_display_data_flow(kcrtc, kcrtc_st); + if (err) + return err; + } + + /* release unclaimed pipeline resources */ + err = komeda_release_unclaimed_resources(kcrtc->master, kcrtc_st); + if (err) + return err; + + return 0; +} + void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, struct komeda_events *evts) { @@ -37,6 +63,7 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, } struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { + .atomic_check = komeda_crtc_atomic_check, }; static const struct drm_crtc_funcs komeda_crtc_funcs = { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index 22ad4dfc3e8d..54b646128760 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -409,4 +409,7 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer, int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, struct komeda_crtc_state *kcrtc_st); +int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, + struct komeda_crtc_state *kcrtc_st); + #endif /* _KOMEDA_PIPELINE_H_*/ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 8d25ce17e517..10137297b004 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -33,6 +33,18 @@ komeda_pipeline_get_state(struct komeda_pipeline *pipe, return priv_to_pipe_st(priv_st); } +struct komeda_pipeline_state * +komeda_pipeline_get_new_state(struct komeda_pipeline *pipe, + struct drm_atomic_state *state) +{ + struct drm_private_state *priv_st; + + priv_st = drm_atomic_get_new_private_obj_state(state, &pipe->obj); + if (priv_st) + return priv_to_pipe_st(priv_st); + return NULL; +} + /* Assign pipeline for crtc */ struct komeda_pipeline_state * komeda_pipeline_get_state_and_set_crtc(struct komeda_pipeline *pipe, @@ -480,3 +492,49 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, return 0; } + +void komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, + struct komeda_pipeline_state *new) +{ + struct drm_atomic_state *drm_st = new->obj.state; + struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state); + struct komeda_component_state *c_st; + struct komeda_component *c; + u32 disabling_comps, id; + + WARN_ON(!old); + + disabling_comps = (~new->active_comps) & old->active_comps; + + /* unbound all disabling component */ + dp_for_each_set_bit(id, disabling_comps) { + c = komeda_pipeline_get_component(pipe, id); + c_st = komeda_component_get_state_and_set_user(c, + drm_st, NULL, new->crtc); + WARN_ON(IS_ERR(c_st)); + } +} + +/* release unclaimed pipeline resource */ +int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, + struct komeda_crtc_state *kcrtc_st) +{ + struct drm_atomic_state *drm_st = kcrtc_st->base.state; + struct komeda_pipeline_state *st; + + /* ignore the pipeline which is not affected */ + if (!pipe || !has_bit(pipe->id, kcrtc_st->affected_pipes)) + return 0; + + if (has_bit(pipe->id, kcrtc_st->active_pipes)) + st = komeda_pipeline_get_new_state(pipe, drm_st); + else + st = komeda_pipeline_get_state_and_set_crtc(pipe, drm_st, NULL); + + if (WARN_ON(IS_ERR_OR_NULL(st))) + return -EINVAL; + + komeda_pipeline_unbound_components(pipe, st); + + return 0; +} -- cgit v1.2.3 From 59dd6d58a5332daa7af9a4c14defe0a80a9e195d Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:10:48 +0000 Subject: drm/komeda: Add komeda_crtc_atomic_flush A komeda flush is comprised two steps: 1. update pipeline/component state to HW. 2. call dev_func->flush to notify HW to kickoff the update. Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 11 +++++++ drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 33 +++++++++++++++++++ drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 3 ++ .../gpu/drm/arm/display/komeda/komeda_pipeline.h | 5 +++ .../drm/arm/display/komeda/komeda_pipeline_state.c | 37 ++++++++++++++++++++++ 5 files changed, 89 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c index 72631d673f85..12eda3b99e4c 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c @@ -243,6 +243,16 @@ static int d71_disable_irq(struct komeda_dev *mdev) return 0; } +static void d71_flush(struct komeda_dev *mdev, + int master_pipe, u32 active_pipes) +{ + struct d71_dev *d71 = mdev->chip_data; + u32 reg_offset = (master_pipe == 0) ? + GCU_CONFIG_VALID0 : GCU_CONFIG_VALID1; + + malidp_write32(d71->gcu_addr, reg_offset, GCU_CONFIG_CVAL); +} + static int d71_reset(struct d71_dev *d71) { u32 __iomem *gcu = d71->gcu_addr; @@ -459,6 +469,7 @@ static struct komeda_dev_funcs d71_chip_funcs = { .irq_handler = d71_irq_handler, .enable_irq = d71_enable_irq, .disable_irq = d71_disable_irq, + .flush = d71_flush, }; struct komeda_dev_funcs * diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 18209cae287c..40ee45d36ad6 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -62,8 +62,41 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, DRM_DEBUG("FLIP Done.\n"); } +static void +komeda_crtc_do_flush(struct drm_crtc *crtc, + struct drm_crtc_state *old) +{ + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc->state); + struct komeda_dev *mdev = kcrtc->base.dev->dev_private; + struct komeda_pipeline *master = kcrtc->master; + + DRM_DEBUG_ATOMIC("CRTC%d_FLUSH: active_pipes: 0x%x, affected: 0x%x.\n", + drm_crtc_index(crtc), + kcrtc_st->active_pipes, kcrtc_st->affected_pipes); + + /* step 1: update the pipeline/component state to HW */ + if (has_bit(master->id, kcrtc_st->affected_pipes)) + komeda_pipeline_update(master, old->state); + + /* step 2: notify the HW to kickoff the update */ + mdev->funcs->flush(mdev, master->id, kcrtc_st->active_pipes); +} + +static void +komeda_crtc_atomic_flush(struct drm_crtc *crtc, + struct drm_crtc_state *old) +{ + /* commit with modeset will be handled in enable/disable */ + if (drm_atomic_crtc_needs_modeset(crtc->state)) + return; + + komeda_crtc_do_flush(crtc, old); +} + struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { .atomic_check = komeda_crtc_atomic_check, + .atomic_flush = komeda_crtc_atomic_flush, }; static const struct drm_crtc_funcs komeda_crtc_funcs = { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h index 8eae2620ce77..0bd38bdf0518 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h @@ -106,6 +106,9 @@ struct komeda_dev_funcs { /** @dump_register: Optional, dump registers to seq_file */ void (*dump_register)(struct komeda_dev *mdev, struct seq_file *seq); + /** @flush: Notify the HW to flush or kickoff the update */ + void (*flush)(struct komeda_dev *mdev, + int master_pipe, u32 active_pipes); }; /** diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index 54b646128760..3d7a9ee550b2 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -412,4 +412,9 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, struct komeda_crtc_state *kcrtc_st); +void komeda_pipeline_disable(struct komeda_pipeline *pipe, + struct drm_atomic_state *old_state); +void komeda_pipeline_update(struct komeda_pipeline *pipe, + struct drm_atomic_state *old_state); + #endif /* _KOMEDA_PIPELINE_H_*/ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 10137297b004..a05165128ca2 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -33,6 +33,18 @@ komeda_pipeline_get_state(struct komeda_pipeline *pipe, return priv_to_pipe_st(priv_st); } +struct komeda_pipeline_state * +komeda_pipeline_get_old_state(struct komeda_pipeline *pipe, + struct drm_atomic_state *state) +{ + struct drm_private_state *priv_st; + + priv_st = drm_atomic_get_old_private_obj_state(state, &pipe->obj); + if (priv_st) + return priv_to_pipe_st(priv_st); + return NULL; +} + struct komeda_pipeline_state * komeda_pipeline_get_new_state(struct komeda_pipeline *pipe, struct drm_atomic_state *state) @@ -538,3 +550,28 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, return 0; } + +void komeda_pipeline_update(struct komeda_pipeline *pipe, + struct drm_atomic_state *old_state) +{ + struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state); + struct komeda_pipeline_state *old; + struct komeda_component *c; + u32 id, changed_comps = 0; + + old = komeda_pipeline_get_old_state(pipe, old_state); + + changed_comps = new->active_comps | old->active_comps; + + DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n", + pipe->id, new->active_comps, changed_comps); + + dp_for_each_set_bit(id, changed_comps) { + c = komeda_pipeline_get_component(pipe, id); + + if (new->active_comps & BIT(c->id)) + c->funcs->update(c, priv_to_comp_st(c->obj.state)); + else + c->funcs->disable(c); + } +} -- cgit v1.2.3 From a2491b900d63e3d9774cb1f8baae2ee1fbb75651 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:10:57 +0000 Subject: drm/komeda: Add komeda_crtc_mode_valid/fixup komeda_crtc_mode_valid compares the input mode->clk with main engine clk and AXI clk, and reject the mode if the required pixel clk can not be satisfied by main engine clk and AXI-clk. Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 40ee45d36ad6..902f3992083e 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -94,9 +94,61 @@ komeda_crtc_atomic_flush(struct drm_crtc *crtc, komeda_crtc_do_flush(crtc, old); } +static enum drm_mode_status +komeda_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *m) +{ + struct komeda_dev *mdev = crtc->dev->dev_private; + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + struct komeda_pipeline *master = kcrtc->master; + long mode_clk, pxlclk; + + if (m->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; + + /* main clock/AXI clk must be faster than pxlclk*/ + mode_clk = m->clock * 1000; + pxlclk = clk_round_rate(master->pxlclk, mode_clk); + if (pxlclk != mode_clk) { + DRM_DEBUG_ATOMIC("pxlclk doesn't support %ld Hz\n", mode_clk); + + return MODE_NOCLOCK; + } + + if (clk_round_rate(mdev->mclk, mode_clk) < pxlclk) { + DRM_DEBUG_ATOMIC("mclk can't satisfy the requirement of %s-clk: %ld.\n", + m->name, pxlclk); + + return MODE_CLOCK_HIGH; + } + + if (clk_round_rate(master->aclk, mode_clk) < pxlclk) { + DRM_DEBUG_ATOMIC("aclk can't satisfy the requirement of %s-clk: %ld.\n", + m->name, pxlclk); + + return MODE_CLOCK_HIGH; + } + + return MODE_OK; +} + +static bool komeda_crtc_mode_fixup(struct drm_crtc *crtc, + const struct drm_display_mode *m, + struct drm_display_mode *adjusted_mode) +{ + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + struct komeda_pipeline *master = kcrtc->master; + long mode_clk = m->clock * 1000; + + adjusted_mode->clock = clk_round_rate(master->pxlclk, mode_clk) / 1000; + + return true; +} + struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { .atomic_check = komeda_crtc_atomic_check, .atomic_flush = komeda_crtc_atomic_flush, + .mode_valid = komeda_crtc_mode_valid, + .mode_fixup = komeda_crtc_mode_fixup, }; static const struct drm_crtc_funcs komeda_crtc_funcs = { -- cgit v1.2.3 From 20d84aa841791075edc07e0a7417cea443abe889 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:11:07 +0000 Subject: drm/komeda: Add komeda_crtc_prepare/unprepare These two function will be used by komeda_crtc_enable/disable to do some prepartion works when enable/disable a crtc. like enable a crtc: 1. Adjust display operation mode. 2. Enable/prepare needed clk. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 32 +++++++ drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 104 +++++++++++++++++++++++ drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 2 + drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 26 ++++++ 4 files changed, 164 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c index 12eda3b99e4c..fd43177895c4 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c @@ -243,6 +243,37 @@ static int d71_disable_irq(struct komeda_dev *mdev) return 0; } +static int to_d71_opmode(int core_mode) +{ + switch (core_mode) { + case KOMEDA_MODE_DISP0: + return DO0_ACTIVE_MODE; + case KOMEDA_MODE_DISP1: + return DO1_ACTIVE_MODE; + case KOMEDA_MODE_DUAL_DISP: + return DO01_ACTIVE_MODE; + case KOMEDA_MODE_INACTIVE: + return INACTIVE_MODE; + default: + WARN(1, "Unknown operation mode"); + return INACTIVE_MODE; + } +} + +static int d71_change_opmode(struct komeda_dev *mdev, int new_mode) +{ + struct d71_dev *d71 = mdev->chip_data; + u32 opmode = to_d71_opmode(new_mode); + int ret; + + malidp_write32_mask(d71->gcu_addr, BLK_CONTROL, 0x7, opmode); + + ret = dp_wait_cond(((malidp_read32(d71->gcu_addr, BLK_CONTROL) & 0x7) == opmode), + 100, 1000, 10000); + + return ret > 0 ? 0 : -ETIMEDOUT; +} + static void d71_flush(struct komeda_dev *mdev, int master_pipe, u32 active_pipes) { @@ -469,6 +500,7 @@ static struct komeda_dev_funcs d71_chip_funcs = { .irq_handler = d71_irq_handler, .enable_irq = d71_enable_irq, .disable_irq = d71_disable_irq, + .change_opmode = d71_change_opmode, .flush = d71_flush, }; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 902f3992083e..ef902bf3bba4 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -44,6 +44,110 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc, return 0; } +u32 komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st) +{ + unsigned long mclk = kcrtc_st->base.adjusted_mode.clock * 1000; + + return mclk; +} + +/* For active a crtc, mainly need two parts of preparation + * 1. adjust display operation mode. + * 2. enable needed clk + */ +int +komeda_crtc_prepare(struct komeda_crtc *kcrtc) +{ + struct komeda_dev *mdev = kcrtc->base.dev->dev_private; + struct komeda_pipeline *master = kcrtc->master; + struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(kcrtc->base.state); + unsigned long pxlclk_rate = kcrtc_st->base.adjusted_mode.clock * 1000; + u32 new_mode; + int err; + + mutex_lock(&mdev->lock); + + new_mode = mdev->dpmode | BIT(master->id); + if (WARN_ON(new_mode == mdev->dpmode)) { + err = 0; + goto unlock; + } + + err = mdev->funcs->change_opmode(mdev, new_mode); + if (err) { + DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,", + mdev->dpmode, new_mode); + goto unlock; + } + + mdev->dpmode = new_mode; + /* Only need to enable mclk on single display mode, but no need to + * enable mclk it on dual display mode, since the dual mode always + * switch from single display mode, the mclk already enabled, no need + * to enable it again. + */ + if (new_mode != KOMEDA_MODE_DUAL_DISP) { + err = clk_set_rate(mdev->mclk, komeda_calc_mclk(kcrtc_st)); + if (err) + DRM_ERROR("failed to set mclk.\n"); + err = clk_prepare_enable(mdev->mclk); + if (err) + DRM_ERROR("failed to enable mclk.\n"); + } + + err = clk_prepare_enable(master->aclk); + if (err) + DRM_ERROR("failed to enable axi clk for pipe%d.\n", master->id); + err = clk_set_rate(master->pxlclk, pxlclk_rate); + if (err) + DRM_ERROR("failed to set pxlclk for pipe%d\n", master->id); + err = clk_prepare_enable(master->pxlclk); + if (err) + DRM_ERROR("failed to enable pxl clk for pipe%d.\n", master->id); + +unlock: + mutex_unlock(&mdev->lock); + + return err; +} + +int +komeda_crtc_unprepare(struct komeda_crtc *kcrtc) +{ + struct komeda_dev *mdev = kcrtc->base.dev->dev_private; + struct komeda_pipeline *master = kcrtc->master; + u32 new_mode; + int err; + + mutex_lock(&mdev->lock); + + new_mode = mdev->dpmode & (~BIT(master->id)); + + if (WARN_ON(new_mode == mdev->dpmode)) { + err = 0; + goto unlock; + } + + err = mdev->funcs->change_opmode(mdev, new_mode); + if (err) { + DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,", + mdev->dpmode, new_mode); + goto unlock; + } + + mdev->dpmode = new_mode; + + clk_disable_unprepare(master->pxlclk); + clk_disable_unprepare(master->aclk); + if (new_mode == KOMEDA_MODE_INACTIVE) + clk_disable_unprepare(mdev->mclk); + +unlock: + mutex_unlock(&mdev->lock); + + return err; +} + void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, struct komeda_events *evts) { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index 24548b87e182..131f26692a3d 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -151,6 +151,8 @@ struct komeda_dev *komeda_dev_create(struct device *dev) if (!mdev) return ERR_PTR(-ENOMEM); + mutex_init(&mdev->lock); + mdev->dev = dev; mdev->reg_base = devm_ioremap_resource(dev, io_res); if (IS_ERR(mdev->reg_base)) { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h index 0bd38bdf0518..1ad1f6e49854 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h @@ -106,11 +106,34 @@ struct komeda_dev_funcs { /** @dump_register: Optional, dump registers to seq_file */ void (*dump_register)(struct komeda_dev *mdev, struct seq_file *seq); + /** + * @change_opmode: + * + * Notify HW to switch to a new display operation mode. + */ + int (*change_opmode)(struct komeda_dev *mdev, int new_mode); /** @flush: Notify the HW to flush or kickoff the update */ void (*flush)(struct komeda_dev *mdev, int master_pipe, u32 active_pipes); }; +/** + * DISPLAY_MODE describes how many display been enabled, and which will be + * passed to CHIP by &komeda_dev_funcs->change_opmode(), then CHIP can do the + * pipeline resources assignment according to this usage hint. + * - KOMEDA_MODE_DISP0: Only one display enabled, pipeline-0 work as master. + * - KOMEDA_MODE_DISP1: Only one display enabled, pipeline-0 work as master. + * - KOMEDA_MODE_DUAL_DISP: Dual display mode, both display has been enabled. + * And D71 supports assign two pipelines to one single display on mode + * KOMEDA_MODE_DISP0/DISP1 + */ +enum { + KOMEDA_MODE_INACTIVE = 0, + KOMEDA_MODE_DISP0 = BIT(0), + KOMEDA_MODE_DISP1 = BIT(1), + KOMEDA_MODE_DUAL_DISP = KOMEDA_MODE_DISP0 | KOMEDA_MODE_DISP1, +}; + /** * struct komeda_dev * @@ -133,6 +156,9 @@ struct komeda_dev { /** @irq: irq number */ int irq; + struct mutex lock; /* used to protect dpmode */ + u32 dpmode; /* current display mode */ + int n_pipelines; struct komeda_pipeline *pipelines[KOMEDA_MAX_PIPELINES]; -- cgit v1.2.3 From b7925b61bd311015e48fdfc8983572d0009e3909 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:11:16 +0000 Subject: drm/komeda: Add komeda_crtc_atomic_enable/disable Pass enable/disable command to komeda and adjust komeda hardware for enable/disable a display instance. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 106 ++++++++++++++++++++- drivers/gpu/drm/arm/display/komeda/komeda_kms.h | 3 + .../gpu/drm/arm/display/komeda/komeda_pipeline.h | 3 + .../drm/arm/display/komeda/komeda_pipeline_state.c | 32 +++++++ 4 files changed, 139 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index ef902bf3bba4..6c85d36208e0 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -55,7 +55,7 @@ u32 komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st) * 1. adjust display operation mode. * 2. enable needed clk */ -int +static int komeda_crtc_prepare(struct komeda_crtc *kcrtc) { struct komeda_dev *mdev = kcrtc->base.dev->dev_private; @@ -111,7 +111,7 @@ unlock: return err; } -int +static int komeda_crtc_unprepare(struct komeda_crtc *kcrtc) { struct komeda_dev *mdev = kcrtc->base.dev->dev_private; @@ -161,9 +161,28 @@ void komeda_crtc_handle_event(struct komeda_crtc *kcrtc, if (events & KOMEDA_EVENT_EOW) DRM_DEBUG("EOW.\n"); - /* will handle it with crtc->flush */ - if (events & KOMEDA_EVENT_FLIP) - DRM_DEBUG("FLIP Done.\n"); + if (events & KOMEDA_EVENT_FLIP) { + unsigned long flags; + struct drm_pending_vblank_event *event; + + spin_lock_irqsave(&crtc->dev->event_lock, flags); + if (kcrtc->disable_done) { + complete_all(kcrtc->disable_done); + kcrtc->disable_done = NULL; + } else if (crtc->state->event) { + event = crtc->state->event; + /* + * Consume event before notifying drm core that flip + * happened. + */ + crtc->state->event = NULL; + drm_crtc_send_vblank_event(crtc, event); + } else { + DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n", + drm_crtc_index(&kcrtc->base)); + } + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + } } static void @@ -187,6 +206,81 @@ komeda_crtc_do_flush(struct drm_crtc *crtc, mdev->funcs->flush(mdev, master->id, kcrtc_st->active_pipes); } +static void +komeda_crtc_atomic_enable(struct drm_crtc *crtc, + struct drm_crtc_state *old) +{ + komeda_crtc_prepare(to_kcrtc(crtc)); + drm_crtc_vblank_on(crtc); + komeda_crtc_do_flush(crtc, old); +} + +static void +komeda_crtc_atomic_disable(struct drm_crtc *crtc, + struct drm_crtc_state *old) +{ + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + struct komeda_crtc_state *old_st = to_kcrtc_st(old); + struct komeda_dev *mdev = crtc->dev->dev_private; + struct komeda_pipeline *master = kcrtc->master; + struct completion *disable_done = &crtc->state->commit->flip_done; + struct completion temp; + int timeout; + + DRM_DEBUG_ATOMIC("CRTC%d_DISABLE: active_pipes: 0x%x, affected: 0x%x.\n", + drm_crtc_index(crtc), + old_st->active_pipes, old_st->affected_pipes); + + if (has_bit(master->id, old_st->active_pipes)) + komeda_pipeline_disable(master, old->state); + + /* crtc_disable has two scenarios according to the state->active switch. + * 1. active -> inactive + * this commit is a disable commit. and the commit will be finished + * or done after the disable operation. on this case we can directly + * use the crtc->state->event to tracking the HW disable operation. + * 2. active -> active + * the crtc->commit is not for disable, but a modeset operation when + * crtc is active, such commit actually has been completed by 3 + * DRM operations: + * crtc_disable, update_planes(crtc_flush), crtc_enable + * so on this case the crtc->commit is for the whole process. + * we can not use it for tracing the disable, we need a temporary + * flip_done for tracing the disable. and crtc->state->event for + * the crtc_enable operation. + * That's also the reason why skip modeset commit in + * komeda_crtc_atomic_flush() + */ + if (crtc->state->active) { + struct komeda_pipeline_state *pipe_st; + /* clear the old active_comps to zero */ + pipe_st = komeda_pipeline_get_old_state(master, old->state); + pipe_st->active_comps = 0; + + init_completion(&temp); + kcrtc->disable_done = &temp; + disable_done = &temp; + } + + mdev->funcs->flush(mdev, master->id, 0); + + /* wait the disable take affect.*/ + timeout = wait_for_completion_timeout(disable_done, HZ); + if (timeout == 0) { + DRM_ERROR("disable pipeline%d timeout.\n", kcrtc->master->id); + if (crtc->state->active) { + unsigned long flags; + + spin_lock_irqsave(&crtc->dev->event_lock, flags); + kcrtc->disable_done = NULL; + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + } + } + + drm_crtc_vblank_off(crtc); + komeda_crtc_unprepare(kcrtc); +} + static void komeda_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old) @@ -251,6 +345,8 @@ static bool komeda_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { .atomic_check = komeda_crtc_atomic_check, .atomic_flush = komeda_crtc_atomic_flush, + .atomic_enable = komeda_crtc_atomic_enable, + .atomic_disable = komeda_crtc_atomic_disable, .mode_valid = komeda_crtc_mode_valid, .mode_fixup = komeda_crtc_mode_fixup, }; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index beb94ff110d7..7ec571d3c240 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -70,6 +70,9 @@ struct komeda_crtc { * merge into the master. */ struct komeda_pipeline *slave; + + /* this flip_done is for tracing the disable */ + struct completion *disable_done; }; /** struct komeda_crtc_state */ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index 3d7a9ee550b2..233e512319e8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -412,6 +412,9 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc, int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, struct komeda_crtc_state *kcrtc_st); +struct komeda_pipeline_state * +komeda_pipeline_get_old_state(struct komeda_pipeline *pipe, + struct drm_atomic_state *state); void komeda_pipeline_disable(struct komeda_pipeline *pipe, struct drm_atomic_state *old_state); void komeda_pipeline_update(struct komeda_pipeline *pipe, diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index a05165128ca2..ae1c3773c4ef 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -551,6 +551,38 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe, return 0; } +void komeda_pipeline_disable(struct komeda_pipeline *pipe, + struct drm_atomic_state *old_state) +{ + struct komeda_pipeline_state *old; + struct komeda_component *c; + struct komeda_component_state *c_st; + u32 id, disabling_comps = 0; + + old = komeda_pipeline_get_old_state(pipe, old_state); + + disabling_comps = old->active_comps; + DRM_DEBUG_ATOMIC("PIPE%d: disabling_comps: 0x%x.\n", + pipe->id, disabling_comps); + + dp_for_each_set_bit(id, disabling_comps) { + c = komeda_pipeline_get_component(pipe, id); + c_st = priv_to_comp_st(c->obj.state); + + /* + * If we disabled a component then all active_inputs should be + * put in the list of changed_active_inputs, so they get + * re-enabled. + * This usually happens during a modeset when the pipeline is + * first disabled and then the actual state gets committed + * again. + */ + c_st->changed_active_inputs |= c_st->active_inputs; + + c->funcs->disable(c); + } +} + void komeda_pipeline_update(struct komeda_pipeline *pipe, struct drm_atomic_state *old_state) { -- cgit v1.2.3 From 98fe3f93a9ca58e937376074c6d3c680a1e54906 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:11:25 +0000 Subject: drm/komeda: Add komeda_crtc_vblank_enable/disable Add a new komeda_dev_func->on_off_vblank to enable/disable HW vblank event Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 10 ++++++++++ drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 19 +++++++++++++++++++ drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 3 +++ 3 files changed, 32 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c index fd43177895c4..b01b628019ba 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c @@ -243,6 +243,15 @@ static int d71_disable_irq(struct komeda_dev *mdev) return 0; } +static void d71_on_off_vblank(struct komeda_dev *mdev, int master_pipe, bool on) +{ + struct d71_dev *d71 = mdev->chip_data; + struct d71_pipeline *pipe = d71->pipes[master_pipe]; + + malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK, + DOU_IRQ_PL0, on ? DOU_IRQ_PL0 : 0); +} + static int to_d71_opmode(int core_mode) { switch (core_mode) { @@ -500,6 +509,7 @@ static struct komeda_dev_funcs d71_chip_funcs = { .irq_handler = d71_irq_handler, .enable_irq = d71_enable_irq, .disable_irq = d71_disable_irq, + .on_off_vblank = d71_on_off_vblank, .change_opmode = d71_change_opmode, .flush = d71_flush, }; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 6c85d36208e0..015ae217ebc3 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -351,7 +351,26 @@ struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { .mode_fixup = komeda_crtc_mode_fixup, }; +static int komeda_crtc_vblank_enable(struct drm_crtc *crtc) +{ + struct komeda_dev *mdev = crtc->dev->dev_private; + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + + mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, true); + return 0; +} + +static void komeda_crtc_vblank_disable(struct drm_crtc *crtc) +{ + struct komeda_dev *mdev = crtc->dev->dev_private; + struct komeda_crtc *kcrtc = to_kcrtc(crtc); + + mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, false); +} + static const struct drm_crtc_funcs komeda_crtc_funcs = { + .enable_vblank = komeda_crtc_vblank_enable, + .disable_vblank = komeda_crtc_vblank_disable, }; int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h index 1ad1f6e49854..8acd25afb3e9 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h @@ -103,6 +103,9 @@ struct komeda_dev_funcs { int (*enable_irq)(struct komeda_dev *mdev); /** @disable_irq: disable irq */ int (*disable_irq)(struct komeda_dev *mdev); + /** @on_off_vblank: notify HW to on/off vblank */ + void (*on_off_vblank)(struct komeda_dev *mdev, + int master_pipe, bool on); /** @dump_register: Optional, dump registers to seq_file */ void (*dump_register)(struct komeda_dev *mdev, struct seq_file *seq); -- cgit v1.2.3 From d29da5d8cd43e316bac8428c1b23a28016a1a9c4 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:11:35 +0000 Subject: drm/komeda: Add komeda_crtc_funcs Added functions: - komeda_crtc_reset - komeda_crtc_vblank_enable - komeda_crtc_vblank_disable Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 48 ++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 015ae217ebc3..053b1e3e74be 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -351,6 +351,47 @@ struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = { .mode_fixup = komeda_crtc_mode_fixup, }; +static void komeda_crtc_reset(struct drm_crtc *crtc) +{ + struct komeda_crtc_state *state; + + if (crtc->state) + __drm_atomic_helper_crtc_destroy_state(crtc->state); + + kfree(to_kcrtc_st(crtc->state)); + crtc->state = NULL; + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (state) { + crtc->state = &state->base; + crtc->state->crtc = crtc; + } +} + +static struct drm_crtc_state * +komeda_crtc_atomic_duplicate_state(struct drm_crtc *crtc) +{ + struct komeda_crtc_state *old = to_kcrtc_st(crtc->state); + struct komeda_crtc_state *new; + + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + + __drm_atomic_helper_crtc_duplicate_state(crtc, &new->base); + + new->affected_pipes = old->active_pipes; + + return &new->base; +} + +static void komeda_crtc_atomic_destroy_state(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + __drm_atomic_helper_crtc_destroy_state(state); + kfree(to_kcrtc_st(state)); +} + static int komeda_crtc_vblank_enable(struct drm_crtc *crtc) { struct komeda_dev *mdev = crtc->dev->dev_private; @@ -369,6 +410,13 @@ static void komeda_crtc_vblank_disable(struct drm_crtc *crtc) } static const struct drm_crtc_funcs komeda_crtc_funcs = { + .gamma_set = drm_atomic_helper_legacy_gamma_set, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .reset = komeda_crtc_reset, + .atomic_duplicate_state = komeda_crtc_atomic_duplicate_state, + .atomic_destroy_state = komeda_crtc_atomic_destroy_state, .enable_vblank = komeda_crtc_vblank_enable, .disable_vblank = komeda_crtc_vblank_disable, }; -- cgit v1.2.3 From 42c729418d9ce8f212ee691a8a91d93bfe9f34de Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:11:44 +0000 Subject: drm/komeda: Add komeda_kms_check Implement komeda_kms_check to add all affected_planes (even unchanged) to drm_atomic_state. since komeda need to re-calculate the resources assumption in every commit. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 30 ++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 55b103ae3e2f..e8573b03021f 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -100,9 +100,37 @@ static const struct drm_mode_config_helper_funcs komeda_mode_config_helpers = { .atomic_commit_tail = komeda_kms_commit_tail, }; +static int komeda_kms_check(struct drm_device *dev, + struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_st, *new_crtc_st; + int i, err; + + err = drm_atomic_helper_check_modeset(dev, state); + if (err) + return err; + + /* komeda need to re-calculate resource assumption in every commit + * so need to add all affected_planes (even unchanged) to + * drm_atomic_state. + */ + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_st, new_crtc_st, i) { + err = drm_atomic_add_affected_planes(state, crtc); + if (err) + return err; + } + + err = drm_atomic_helper_check_planes(dev, state); + if (err) + return err; + + return 0; +} + static const struct drm_mode_config_funcs komeda_mode_config_funcs = { .fb_create = komeda_fb_create, - .atomic_check = drm_atomic_helper_check, + .atomic_check = komeda_kms_check, .atomic_commit = drm_atomic_helper_commit, }; -- cgit v1.2.3 From 11f874c041f0476ec9fc44387478d3bbb3c74b73 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 26 Apr 2019 22:48:11 +0100 Subject: drm/amd/display: fix incorrect null check on pointer Currently an allocation is being made but the allocation failure check is being performed on another pointer. Fix this by checking the correct pointer. Also use the normal kernel idiom for null pointer checks. Addresses-Coverity: ("Resource leak") Fixes: 43e3ac8389ef ("drm/amd/display: Add function to copy DC streams") Signed-off-by: Colin Ian King Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index 6200df3edcd0..96e97d25d639 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -168,7 +168,7 @@ struct dc_stream_state *dc_copy_stream(const struct dc_stream_state *stream) struct dc_stream_state *new_stream; new_stream = kzalloc(sizeof(struct dc_stream_state), GFP_KERNEL); - if (stream == NULL) + if (!new_stream) return NULL; memcpy(new_stream, stream, sizeof(struct dc_stream_state)); -- cgit v1.2.3 From a66d186c888526ced3582e07ebc6e6fe818ea1f0 Mon Sep 17 00:00:00 2001 From: hersen wu Date: Wed, 3 Apr 2019 16:14:08 -0400 Subject: drm/amd/powerplay: raven 4k@60hz dp monitor always flicking [WHY] clock unit mis-match between caller DC and SMU interface. dc pass lock in mhz. the same unit as smu. no covert is needed. [HOW] remove covert_10k_to_mhz in smu interface this fixes corruption issue with 4k @60 display and stutter mode enable Reviewed-by: Kenneth Feng Signed-off-by: hersen wu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index 5f5dec9b97e2..9a595f7525e6 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -205,18 +205,13 @@ static int smu10_set_clock_limit(struct pp_hwmgr *hwmgr, const void *input) return 0; } -static inline uint32_t convert_10k_to_mhz(uint32_t clock) -{ - return (clock + 99) / 100; -} - static int smu10_set_min_deep_sleep_dcefclk(struct pp_hwmgr *hwmgr, uint32_t clock) { struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); if (smu10_data->need_min_deep_sleep_dcefclk && - smu10_data->deep_sleep_dcefclk != convert_10k_to_mhz(clock)) { - smu10_data->deep_sleep_dcefclk = convert_10k_to_mhz(clock); + smu10_data->deep_sleep_dcefclk != clock) { + smu10_data->deep_sleep_dcefclk = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk, smu10_data->deep_sleep_dcefclk); @@ -229,8 +224,8 @@ static int smu10_set_hard_min_dcefclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t c struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); if (smu10_data->dcf_actual_hard_min_freq && - smu10_data->dcf_actual_hard_min_freq != convert_10k_to_mhz(clock)) { - smu10_data->dcf_actual_hard_min_freq = convert_10k_to_mhz(clock); + smu10_data->dcf_actual_hard_min_freq != clock) { + smu10_data->dcf_actual_hard_min_freq = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinDcefclkByFreq, smu10_data->dcf_actual_hard_min_freq); @@ -243,8 +238,8 @@ static int smu10_set_hard_min_fclk_by_freq(struct pp_hwmgr *hwmgr, uint32_t cloc struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); if (smu10_data->f_actual_hard_min_freq && - smu10_data->f_actual_hard_min_freq != convert_10k_to_mhz(clock)) { - smu10_data->f_actual_hard_min_freq = convert_10k_to_mhz(clock); + smu10_data->f_actual_hard_min_freq != clock) { + smu10_data->f_actual_hard_min_freq = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinFclkByFreq, smu10_data->f_actual_hard_min_freq); -- cgit v1.2.3 From beac93e6f8101227df2e48d789bde7b6a0895e29 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 25 Apr 2019 11:20:38 +0800 Subject: drm/amdgpu: update Vega20 sdma golden settings Update Vega20 sdma golden settings. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 1ec60f54b992..348249185fb2 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -156,7 +156,6 @@ static const struct soc15_reg_golden golden_settings_sdma0_4_2[] = SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0), - SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xFE000000, 0x00000000), }; static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = { @@ -186,7 +185,6 @@ static const struct soc15_reg_golden golden_settings_sdma1_4_2[] = { SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_RPTR_ADDR_LO, 0xfffffffd, 0x00000001), SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_RLC7_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_PAGE, 0x000003ff, 0x000003c0), - SOC15_REG_GOLDEN_VALUE(SDMA1, 0, mmSDMA1_UTCL1_WATERMK, 0xFE000000, 0x00000000), }; static const struct soc15_reg_golden golden_settings_sdma_rv1[] = -- cgit v1.2.3 From edf1e0008264ca7ad70d13576d7f204c1cf5abab Mon Sep 17 00:00:00 2001 From: Wentao Lou Date: Thu, 25 Apr 2019 12:43:04 +0800 Subject: drm/amdgpu: value of amdgpu_sriov_vf cannot be set into F32_POLL_ENABLE amdgpu_sriov_vf would return 0x0 or 0x4 to indicate if sriov. but F32_POLL_ENABLE need 0x0 or 0x1 to determine if enabled. set 0x4 into F32_POLL_ENABLE would make SDMA0_GFX_RB_WPTR_POLL_CNTL not working. Signed-off-by: Wentao Lou Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 348249185fb2..9c88ce513d78 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -849,7 +849,7 @@ static void sdma_v4_0_gfx_resume(struct amdgpu_device *adev, unsigned int i) wptr_poll_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL); wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, - F32_POLL_ENABLE, amdgpu_sriov_vf(adev)); + F32_POLL_ENABLE, amdgpu_sriov_vf(adev)? 1 : 0); WREG32_SDMA(i, mmSDMA0_GFX_RB_WPTR_POLL_CNTL, wptr_poll_cntl); /* enable DMA RB */ @@ -940,7 +940,7 @@ static void sdma_v4_0_page_resume(struct amdgpu_device *adev, unsigned int i) wptr_poll_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL); wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_PAGE_RB_WPTR_POLL_CNTL, - F32_POLL_ENABLE, amdgpu_sriov_vf(adev)); + F32_POLL_ENABLE, amdgpu_sriov_vf(adev)? 1 : 0); WREG32_SDMA(i, mmSDMA0_PAGE_RB_WPTR_POLL_CNTL, wptr_poll_cntl); /* enable DMA RB */ -- cgit v1.2.3 From d6ef9b4175e870b52468fed4fd77b0d3d54e20fc Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Fri, 5 Apr 2019 09:35:14 -0400 Subject: drm/amd/display: Refactor CRTC interrupt toggling logic [Why] The vblank and pageflip interrupts should only be enabled for a CRTC that's enabled and has active planes. The current logic takes care of this, but isn't setup to handle the case where the active plane count goes to zero but the stream remains enabled. We currently block this case since we don't allow commits that enable a CRTC with no active planes, but shouldn't be any reason we can't support this from a hardware perspective and many userspace applications expect to be able to do it (like IGT). [How] The count_crtc_active_planes function fills in the number of "active_planes" on the dm_crtc_state. This should be the same as DC's plane_count on the stream_status but easier to access since we don't need to lock the private atomic state with the DC context. Add the "interrupts_enabled" flag to the dm_crtc_state and set it based on whether the stream exists and if there are active planes on the stream. Update the disable and enable logic to make use of this new flag. There shouldn't be any functional change (yet) with this patch. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 86 +++++++++++++++++------ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 + 2 files changed, 68 insertions(+), 21 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index a3dc7ab523de..c82048cb901d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3438,6 +3438,8 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) dc_stream_retain(state->stream); } + state->active_planes = cur->active_planes; + state->interrupts_enabled = cur->interrupts_enabled; state->vrr_params = cur->vrr_params; state->vrr_infopacket = cur->vrr_infopacket; state->abm_level = cur->abm_level; @@ -3862,7 +3864,7 @@ static void dm_crtc_helper_disable(struct drm_crtc *crtc) { } -static bool does_crtc_have_active_plane(struct drm_crtc_state *new_crtc_state) +static int count_crtc_active_planes(struct drm_crtc_state *new_crtc_state) { struct drm_atomic_state *state = new_crtc_state->state; struct drm_plane *plane; @@ -3891,7 +3893,32 @@ static bool does_crtc_have_active_plane(struct drm_crtc_state *new_crtc_state) num_active += (new_plane_state->fb != NULL); } - return num_active > 0; + return num_active; +} + +/* + * Sets whether interrupts should be enabled on a specific CRTC. + * We require that the stream be enabled and that there exist active + * DC planes on the stream. + */ +static void +dm_update_crtc_interrupt_state(struct drm_crtc *crtc, + struct drm_crtc_state *new_crtc_state) +{ + struct dm_crtc_state *dm_new_crtc_state = + to_dm_crtc_state(new_crtc_state); + + dm_new_crtc_state->active_planes = 0; + dm_new_crtc_state->interrupts_enabled = false; + + if (!dm_new_crtc_state->stream) + return; + + dm_new_crtc_state->active_planes = + count_crtc_active_planes(new_crtc_state); + + dm_new_crtc_state->interrupts_enabled = + dm_new_crtc_state->active_planes > 0; } static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, @@ -3902,6 +3929,14 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(state); int ret = -EINVAL; + /* + * Update interrupt state for the CRTC. This needs to happen whenever + * the CRTC has changed or whenever any of its planes have changed. + * Atomic check satisfies both of these requirements since the CRTC + * is added to the state by DRM during drm_atomic_helper_check_planes. + */ + dm_update_crtc_interrupt_state(crtc, state); + if (unlikely(!dm_crtc_state->stream && modeset_required(state, NULL, dm_crtc_state->stream))) { WARN_ON(1); @@ -3914,7 +3949,7 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, /* We want at least one hardware plane enabled to use the stream. */ if (state->enable && state->active && - !does_crtc_have_active_plane(state)) + dm_crtc_state->active_planes == 0) return -EINVAL; if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK) @@ -5390,24 +5425,33 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev, int i; /* - * We evade vblanks and pflips on crtc that - * should be changed. We do it here to flush & disable - * interrupts before drm_swap_state is called in drm_atomic_helper_commit - * it will update crtc->dm_crtc_state->stream pointer which is used in - * the ISRs. + * We evade vblank and pflip interrupts on CRTCs that are undergoing + * a modeset, being disabled, or have no active planes. + * + * It's done in atomic commit rather than commit tail for now since + * some of these interrupt handlers access the current CRTC state and + * potentially the stream pointer itself. + * + * Since the atomic state is swapped within atomic commit and not within + * commit tail this would leave to new state (that hasn't been committed yet) + * being accesssed from within the handlers. + * + * TODO: Fix this so we can do this in commit tail and not have to block + * in atomic check. */ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { struct dm_crtc_state *dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); - if (drm_atomic_crtc_needs_modeset(new_crtc_state) - && dm_old_crtc_state->stream) { + if (dm_old_crtc_state->interrupts_enabled && + (!dm_new_crtc_state->interrupts_enabled || + drm_atomic_crtc_needs_modeset(new_crtc_state))) { /* * If the stream is removed and CRC capture was * enabled on the CRTC the extra vblank reference - * needs to be dropped since CRC capture will be - * disabled. + * needs to be dropped since CRC capture will not + * be re-enabled. */ if (!dm_new_crtc_state->stream && dm_new_crtc_state->crc_enabled) { @@ -5635,13 +5679,14 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) pre_update_freesync_state_on_stream(dm, dm_new_crtc_state); } + /* + * Enable interrupts on CRTCs that are newly active, undergone + * a modeset, or have active planes again. + */ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - /* - * loop to enable interrupts on newly arrived crtc - */ struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); - bool modeset_needed; + bool enable; if (old_crtc_state->active && !new_crtc_state->active) crtc_disable_count++; @@ -5653,12 +5698,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, dm_new_crtc_state); - modeset_needed = modeset_required( - new_crtc_state, - dm_new_crtc_state->stream, - dm_old_crtc_state->stream); + enable = dm_new_crtc_state->interrupts_enabled && + (!dm_old_crtc_state->interrupts_enabled || + drm_atomic_crtc_needs_modeset(new_crtc_state)); - if (dm_new_crtc_state->stream == NULL || !modeset_needed) + if (!enable) continue; manage_dm_interrupts(adev, acrtc, true); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 3a0b6164c755..978ff14a7d45 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -271,6 +271,9 @@ struct dm_crtc_state { struct drm_crtc_state base; struct dc_stream_state *stream; + int active_planes; + bool interrupts_enabled; + int crc_skip_count; bool crc_enabled; -- cgit v1.2.3 From 8ad278062de4eae53f68ec835c20147efcec81a8 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 8 Apr 2019 10:37:44 -0400 Subject: drm/amd/display: Disable cursors before disabling planes [Why] We can't do cursor programming after the planes have been disabled since there won't be any pipes - leading to lock warnings and the wrong cursor state being left in the registers. When we re-enable the planes after the previous cursor state will also remain if we don't have a cursor plane. [How] If we're disabling the planes then do the cursor programming first. If we're not disabling the planes then do the cursor programming after. Introduce the amdgpu_dm_commit_cursors helper to avoid code duplication for both of these cases. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 34 +++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c82048cb901d..6bd7da6b25b5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5158,6 +5158,22 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, } } +static void amdgpu_dm_commit_cursors(struct drm_atomic_state *state) +{ + struct drm_plane *plane; + struct drm_plane_state *old_plane_state, *new_plane_state; + int i; + + /* + * TODO: Make this per-stream so we don't issue redundant updates for + * commits with multiple streams. + */ + for_each_oldnew_plane_in_state(state, plane, old_plane_state, + new_plane_state, i) + if (plane->type == DRM_PLANE_TYPE_CURSOR) + handle_cursor_update(plane, old_plane_state); +} + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct dc_state *dc_state, struct drm_device *dev, @@ -5197,6 +5213,14 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, goto cleanup; } + /* + * Disable the cursor first if we're disabling all the planes. + * It'll remain on the screen after the planes are re-enabled + * if we don't. + */ + if (acrtc_state->active_planes == 0) + amdgpu_dm_commit_cursors(state); + /* update planes when needed */ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { struct drm_crtc *crtc = new_plane_state->crtc; @@ -5393,9 +5417,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, mutex_unlock(&dm->dc_lock); } - for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) - if (plane->type == DRM_PLANE_TYPE_CURSOR) - handle_cursor_update(plane, old_plane_state); + /* + * Update cursor state *after* programming all the planes. + * This avoids redundant programming in the case where we're going + * to be disabling a single plane - those pipes are being disabled. + */ + if (acrtc_state->active_planes) + amdgpu_dm_commit_cursors(state); cleanup: kfree(bundle); -- cgit v1.2.3 From e39575b9c3661844e4746fa9e32d58354ffe0b50 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 8 Apr 2019 12:31:25 -0400 Subject: drm/amd/display: Fix CRC vblank refs when changing interrupts [Why] We only currently drop the vblank reference when the stream is being removed from the context. We should be dropping it whenever we disable interrupts and reaquiring it after we re-enable them. We also never get the extra reference correctly when re-enabling interrupts, since grabbing the reference has the following condition: if (!crtc_state->crc_enabled && enable) drm_crtc_vblank_get(crtc); This means that crc_enabled must be *false* in order to grab the extra reference. [How] Always drop the ref whenever we're disabling interrupts. Only disable CRC capture when the stream is being removed. Always grab the ref by setting dm_new_crtc_state->crc_enabled = false before the call to re-enable CRC capture. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 6bd7da6b25b5..4c19e187e4cb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5476,16 +5476,18 @@ static int amdgpu_dm_atomic_commit(struct drm_device *dev, (!dm_new_crtc_state->interrupts_enabled || drm_atomic_crtc_needs_modeset(new_crtc_state))) { /* - * If the stream is removed and CRC capture was - * enabled on the CRTC the extra vblank reference - * needs to be dropped since CRC capture will not - * be re-enabled. + * Drop the extra vblank reference added by CRC + * capture if applicable. */ - if (!dm_new_crtc_state->stream - && dm_new_crtc_state->crc_enabled) { + if (dm_new_crtc_state->crc_enabled) drm_crtc_vblank_put(crtc); + + /* + * Only keep CRC capture enabled if there's + * still a stream for the CRTC. + */ + if (!dm_new_crtc_state->stream) dm_new_crtc_state->crc_enabled = false; - } manage_dm_interrupts(adev, acrtc, false); } @@ -5737,8 +5739,10 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) #ifdef CONFIG_DEBUG_FS /* The stream has changed so CRC capture needs to re-enabled. */ - if (dm_new_crtc_state->crc_enabled) + if (dm_new_crtc_state->crc_enabled) { + dm_new_crtc_state->crc_enabled = false; amdgpu_dm_crtc_set_crc_source(crtc, "auto"); + } #endif } -- cgit v1.2.3 From b5e83f6fe1f003f95fcdbde8a3364f776c18d28d Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 8 Apr 2019 11:18:31 -0400 Subject: drm/amd/display: Split enabling CRTC interrupts into two passes [Why] When disabling all the pipes for a CRTC the page-flip interrupt also gets disabled on Raven. We can't re-enable the page-flip interrupt unless we give DC at least one active DC plane. We currently enable interrupts after the call to dc_commit_state since there's currently no valid sequence that should disable all the planes or re-enable planes for a CRTC without first going through dc_commit_state. If we were to allow for a CRTC to be enabled with no primary plane this would not be the case - the call to dc_commit_updates_for_stream would enable the planes when going from zero to at least one active plane, but manage_dm_interrupts would have been called too early. This results in a page-flip timeout on any subsequent commits since we think the page-flip are now enabled when they're actually disabled. We need to enable interrupts after the call to dc_commit_updates_for_stream. [How] Split enabling interrupts into two passes. One pass before dc_commit_updates_for_stream and one after it. Shifting all the interrupts to be strictly below the call doesn't currently work even though it should in theory. We end up queuing off the vblank event to be handle by the flip handler before it's actually enabled in some cases, particularly: old_crtc_state->active = false -> new_crtc_state->active = true The framebuffer states haven't changed and we can technically still do a "pageflip" in this case and send back the event. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 95 +++++++++++++++-------- 1 file changed, 63 insertions(+), 32 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 4c19e187e4cb..33248c6b2062 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5429,6 +5429,63 @@ cleanup: kfree(bundle); } +/* + * Enable interrupts on CRTCs that are newly active, undergone + * a modeset, or have active planes again. + * + * Done in two passes, based on the for_modeset flag: + * Pass 1: For CRTCs going through modeset + * Pass 2: For CRTCs going from 0 to n active planes + * + * Interrupts can only be enabled after the planes are programmed, + * so this requires a two-pass approach since we don't want to + * just defer the interrupts until after commit planes every time. + */ +static void amdgpu_dm_enable_crtc_interrupts(struct drm_device *dev, + struct drm_atomic_state *state, + bool for_modeset) +{ + struct amdgpu_device *adev = dev->dev_private; + struct drm_crtc *crtc; + struct drm_crtc_state *old_crtc_state, *new_crtc_state; + int i; + + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + struct dm_crtc_state *dm_new_crtc_state = + to_dm_crtc_state(new_crtc_state); + struct dm_crtc_state *dm_old_crtc_state = + to_dm_crtc_state(old_crtc_state); + bool modeset = drm_atomic_crtc_needs_modeset(new_crtc_state); + bool run_pass; + + run_pass = (for_modeset && modeset) || + (!for_modeset && !modeset && + !dm_old_crtc_state->interrupts_enabled); + + if (!run_pass) + continue; + + /* Handle vrr on->off / off->on transitions */ + amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, + dm_new_crtc_state); + + if (!dm_new_crtc_state->interrupts_enabled) + continue; + + manage_dm_interrupts(adev, acrtc, true); + +#ifdef CONFIG_DEBUG_FS + /* The stream has changed so CRC capture needs to re-enabled. */ + if (dm_new_crtc_state->crc_enabled) { + dm_new_crtc_state->crc_enabled = false; + amdgpu_dm_crtc_set_crc_source(crtc, "auto"); + } +#endif + } +} + /* * amdgpu_dm_crtc_copy_transient_flags - copy mirrored flags from DRM to DC * @crtc_state: the DRM CRTC state @@ -5709,42 +5766,14 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) pre_update_freesync_state_on_stream(dm, dm_new_crtc_state); } - /* - * Enable interrupts on CRTCs that are newly active, undergone - * a modeset, or have active planes again. - */ + /* Count number of newly disabled CRTCs for dropping PM refs later. */ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) { - struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); - bool enable; - + new_crtc_state, i) if (old_crtc_state->active && !new_crtc_state->active) crtc_disable_count++; - dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); - dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); - - /* Handle vrr on->off / off->on transitions */ - amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, - dm_new_crtc_state); - - enable = dm_new_crtc_state->interrupts_enabled && - (!dm_old_crtc_state->interrupts_enabled || - drm_atomic_crtc_needs_modeset(new_crtc_state)); - - if (!enable) - continue; - - manage_dm_interrupts(adev, acrtc, true); - -#ifdef CONFIG_DEBUG_FS - /* The stream has changed so CRC capture needs to re-enabled. */ - if (dm_new_crtc_state->crc_enabled) { - dm_new_crtc_state->crc_enabled = false; - amdgpu_dm_crtc_set_crc_source(crtc, "auto"); - } -#endif - } + /* Enable interrupts for CRTCs going through a modeset. */ + amdgpu_dm_enable_crtc_interrupts(dev, state, true); for_each_new_crtc_in_state(state, crtc, new_crtc_state, j) if (new_crtc_state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) @@ -5759,6 +5788,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) dm, crtc, wait_for_vblank); } + /* Enable interrupts for CRTCs going from 0 to n active planes. */ + amdgpu_dm_enable_crtc_interrupts(dev, state, false); /* * send vblank event on all events not handled in flip and -- cgit v1.2.3 From bc92c06525e5865c94256ef0227bfe870c095823 Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Thu, 4 Apr 2019 11:00:53 -0400 Subject: drm/amd/display: Allow commits with no planes active [Why] Many userspace applications (and IGT) seem to expect that most drivers can keep a CRTC active and enabled if there are no primary or overlay planes. DC is setup to handle this but only in the case where there are absolutely no planes on the CRTC - no primary, cursor, or overlay. [How] Add a check to reject commits that have cursor planes enabled and nothing else on CRTCs since we can't handle that. The new helper does_crtc_have_active_cursor is used for this. In atomic commit tail, we need to let DC know that there are zero planes enabled when doing stream updates to let it disable and blank pipes as appropriate. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 33248c6b2062..4e7af5594459 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3864,6 +3864,19 @@ static void dm_crtc_helper_disable(struct drm_crtc *crtc) { } +static bool does_crtc_have_active_cursor(struct drm_crtc_state *new_crtc_state) +{ + struct drm_device *dev = new_crtc_state->crtc->dev; + struct drm_plane *plane; + + drm_for_each_plane_mask(plane, dev, new_crtc_state->plane_mask) { + if (plane->type == DRM_PLANE_TYPE_CURSOR) + return true; + } + + return false; +} + static int count_crtc_active_planes(struct drm_crtc_state *new_crtc_state) { struct drm_atomic_state *state = new_crtc_state->state; @@ -3947,8 +3960,12 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, if (!dm_crtc_state->stream) return 0; - /* We want at least one hardware plane enabled to use the stream. */ + /* + * We want at least one hardware plane enabled to use + * the stream with a cursor enabled. + */ if (state->enable && state->active && + does_crtc_have_active_cursor(state) && dm_crtc_state->active_planes == 0) return -EINVAL; @@ -5394,7 +5411,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, } } - if (planes_count) { + /* Update the planes if changed or disable if we don't have any. */ + if (planes_count || acrtc_state->active_planes == 0) { if (new_pcrtc_state->mode_changed) { bundle->stream_update.src = acrtc_state->stream->src; bundle->stream_update.dst = acrtc_state->stream->dst; -- cgit v1.2.3 From 91f287566d494a4b28135f51e4698593feedc886 Mon Sep 17 00:00:00 2001 From: Yongqiang Sun Date: Fri, 29 Mar 2019 14:36:57 -0400 Subject: drm/amd/display: Refactor watermark programming * Replace certain register writes with register sets that overwrites the the entire register, instead of only a field within the register. * Add program_watermarks() entry to hubbub vtable. Hook it up to existing functions that program watermarks. * Add additional watermark registers. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Leo Li Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c | 49 +++++++++++------ .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h | 63 ++++++++++++++++++---- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 8 ++- drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h | 6 +++ 4 files changed, 97 insertions(+), 29 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c index 295cbd5b843f..0db2a6e96fc0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -283,7 +283,8 @@ void hubbub1_program_watermarks( hubbub1->watermarks.a.urgent_ns = watermarks->a.urgent_ns; prog_wm_value = convert_and_clamp(watermarks->a.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); + REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, 0, + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", @@ -310,7 +311,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, 0, + DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -323,7 +325,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->a.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, 0, + DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n", watermarks->a.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -337,7 +340,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->a.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, 0, + DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_A calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->a.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -348,7 +352,8 @@ void hubbub1_program_watermarks( hubbub1->watermarks.b.urgent_ns = watermarks->b.urgent_ns; prog_wm_value = convert_and_clamp(watermarks->b.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); + REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, 0, + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", @@ -375,7 +380,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, 0, + DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -388,7 +394,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->b.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, 0, + DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n", watermarks->b.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -402,7 +409,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->b.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, 0, + DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_B calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->b.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -413,7 +421,8 @@ void hubbub1_program_watermarks( hubbub1->watermarks.c.urgent_ns = watermarks->c.urgent_ns; prog_wm_value = convert_and_clamp(watermarks->c.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); + REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, 0, + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", @@ -440,7 +449,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, 0, + DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -453,7 +463,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->c.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, 0, + DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n", watermarks->c.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -467,7 +478,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->c.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, 0, + DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_C calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->c.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -478,7 +490,8 @@ void hubbub1_program_watermarks( hubbub1->watermarks.d.urgent_ns = watermarks->d.urgent_ns; prog_wm_value = convert_and_clamp(watermarks->d.urgent_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); + REG_SET(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, 0, + DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("URGENCY_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", @@ -505,7 +518,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, 0, + DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_ENTER_EXIT_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.cstate_pstate.cstate_enter_plus_exit_ns, prog_wm_value); @@ -518,7 +532,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->d.cstate_pstate.cstate_exit_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, 0, + DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("SR_EXIT_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n", watermarks->d.cstate_pstate.cstate_exit_ns, prog_wm_value); @@ -532,7 +547,8 @@ void hubbub1_program_watermarks( prog_wm_value = convert_and_clamp( watermarks->d.cstate_pstate.pstate_change_ns, refclk_mhz, 0x1fffff); - REG_WRITE(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); + REG_SET(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, 0, + DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, prog_wm_value); DC_LOG_BANDWIDTH_CALCS("DRAM_CLK_CHANGE_WATERMARK_D calculated =%d\n" "HW register value = 0x%x\n\n", watermarks->d.cstate_pstate.pstate_change_ns, prog_wm_value); @@ -867,6 +883,7 @@ static const struct hubbub_funcs hubbub1_funcs = { .dcc_support_pixel_format = hubbub1_dcc_support_pixel_format, .get_dcc_compression_cap = hubbub1_get_dcc_compression_cap, .wm_read_state = hubbub1_wm_read_state, + .program_watermarks = hubbub1_program_watermarks, }; void hubbub1_construct(struct hubbub *hubbub, diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h index 9cd4a5194154..85811b24a497 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h @@ -32,18 +32,14 @@ #define TO_DCN10_HUBBUB(hubbub)\ container_of(hubbub, struct dcn10_hubbub, base) -#define HUBHUB_REG_LIST_DCN()\ +#define HUBBUB_REG_LIST_DCN_COMMON()\ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A),\ - SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A),\ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B),\ - SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B),\ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C),\ - SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C),\ SR(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D),\ - SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D),\ SR(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D),\ SR(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL),\ SR(DCHUBBUB_ARB_DRAM_STATE_CNTL),\ @@ -54,6 +50,12 @@ SR(DCHUBBUB_TEST_DEBUG_DATA),\ SR(DCHUBBUB_SOFT_RESET) +#define HUBBUB_VM_REG_LIST() \ + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_A),\ + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_B),\ + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_C),\ + SR(DCHUBBUB_ARB_PTE_META_URGENCY_WATERMARK_D) + #define HUBBUB_SR_WATERMARK_REG_LIST()\ SR(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A),\ SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A),\ @@ -65,7 +67,8 @@ SR(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D) #define HUBBUB_REG_LIST_DCN10(id)\ - HUBHUB_REG_LIST_DCN(), \ + HUBBUB_REG_LIST_DCN_COMMON(), \ + HUBBUB_VM_REG_LIST(), \ HUBBUB_SR_WATERMARK_REG_LIST(), \ SR(DCHUBBUB_SDPIF_FB_TOP),\ SR(DCHUBBUB_SDPIF_FB_BASE),\ @@ -122,8 +125,7 @@ struct dcn_hubbub_registers { #define HUBBUB_SF(reg_name, field_name, post_fix)\ .field_name = reg_name ## __ ## field_name ## post_fix - -#define HUBBUB_MASK_SH_LIST_DCN(mask_sh)\ +#define HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh)\ HUBBUB_SF(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, mask_sh), \ HUBBUB_SF(DCHUBBUB_SOFT_RESET, DCHUBBUB_GLOBAL_SOFT_RESET, mask_sh), \ HUBBUB_SF(DCHUBBUB_ARB_WATERMARK_CHANGE_CNTL, DCHUBBUB_ARB_WATERMARK_CHANGE_REQUEST, mask_sh), \ @@ -133,10 +135,29 @@ struct dcn_hubbub_registers { HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_VALUE, mask_sh), \ HUBBUB_SF(DCHUBBUB_ARB_DRAM_STATE_CNTL, DCHUBBUB_ARB_ALLOW_PSTATE_CHANGE_FORCE_ENABLE, mask_sh), \ HUBBUB_SF(DCHUBBUB_ARB_SAT_LEVEL, DCHUBBUB_ARB_SAT_LEVEL, mask_sh), \ - HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh) + HUBBUB_SF(DCHUBBUB_ARB_DF_REQ_OUTSTAND, DCHUBBUB_ARB_MIN_REQ_OUTSTAND, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D, mask_sh) + +#define HUBBUB_MASK_SH_LIST_STUTTER(mask_sh) \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C, mask_sh), \ + HUBBUB_SF(DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D, mask_sh) #define HUBBUB_MASK_SH_LIST_DCN10(mask_sh)\ - HUBBUB_MASK_SH_LIST_DCN(mask_sh), \ + HUBBUB_MASK_SH_LIST_DCN_COMMON(mask_sh), \ + HUBBUB_MASK_SH_LIST_STUTTER(mask_sh), \ HUBBUB_SF(DCHUBBUB_SDPIF_FB_TOP, SDPIF_FB_TOP, mask_sh), \ HUBBUB_SF(DCHUBBUB_SDPIF_FB_BASE, SDPIF_FB_BASE, mask_sh), \ HUBBUB_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh), \ @@ -167,15 +188,35 @@ struct dcn_hubbub_registers { type FB_OFFSET;\ type AGP_BOT;\ type AGP_TOP;\ - type AGP_BASE + type AGP_BASE;\ + type DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_A;\ + type DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_B;\ + type DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_C;\ + type DCHUBBUB_ARB_DATA_URGENCY_WATERMARK_D;\ + type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_A;\ + type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_B;\ + type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_C;\ + type DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D + +#define HUBBUB_STUTTER_REG_FIELD_LIST(type) \ + type DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_A;\ + type DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_B;\ + type DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_C;\ + type DCHUBBUB_ARB_ALLOW_SR_ENTER_WATERMARK_D;\ + type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_A;\ + type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_B;\ + type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_C;\ + type DCHUBBUB_ARB_ALLOW_SR_EXIT_WATERMARK_D struct dcn_hubbub_shift { DCN_HUBBUB_REG_FIELD_LIST(uint8_t); + HUBBUB_STUTTER_REG_FIELD_LIST(uint8_t); }; struct dcn_hubbub_mask { DCN_HUBBUB_REG_FIELD_LIST(uint32_t); + HUBBUB_STUTTER_REG_FIELD_LIST(uint32_t); }; struct dc; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index f0cc7c9c9de3..549836c60220 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -2438,6 +2438,8 @@ static void dcn10_prepare_bandwidth( struct dc *dc, struct dc_state *context) { + struct hubbub *hubbub = dc->res_pool->hubbub; + if (dc->debug.sanity_checks) dcn10_verify_allow_pstate_change_high(dc); @@ -2451,7 +2453,7 @@ static void dcn10_prepare_bandwidth( false); } - hubbub1_program_watermarks(dc->res_pool->hubbub, + hubbub->funcs->program_watermarks(hubbub, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, true); @@ -2468,6 +2470,8 @@ static void dcn10_optimize_bandwidth( struct dc *dc, struct dc_state *context) { + struct hubbub *hubbub = dc->res_pool->hubbub; + if (dc->debug.sanity_checks) dcn10_verify_allow_pstate_change_high(dc); @@ -2481,7 +2485,7 @@ static void dcn10_optimize_bandwidth( true); } - hubbub1_program_watermarks(dc->res_pool->hubbub, + hubbub->funcs->program_watermarks(hubbub, &context->bw_ctx.bw.dcn.watermarks, dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000, true); diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h index 5e8fead3c09a..93667e8b23b3 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dchubbub.h @@ -77,6 +77,12 @@ struct hubbub_funcs { void (*get_dchub_ref_freq)(struct hubbub *hubbub, unsigned int dccg_ref_freq_inKhz, unsigned int *dchub_ref_freq_inKhz); + + void (*program_watermarks)( + struct hubbub *hubbub, + struct dcn_watermark_set *watermarks, + unsigned int refclk_mhz, + bool safe_to_lower); }; struct hubbub { -- cgit v1.2.3 From 27eaa4927dc3be669ed70670241597ac73595caf Mon Sep 17 00:00:00 2001 From: Thomas Lim Date: Wed, 10 Apr 2019 17:06:07 -0400 Subject: drm/amd/display: Add power down display on boot flag [Why] Due to the generic introduction of seamless boot, the display is no longer blanked upon boot. However, this causes corruption on some systems that does not lock the memory in the non-secure boot case, resulting in brief corruption on boot due to garbage being written into the frame buffer. [How] Add a flag, read during DC init, to determine whether display should be blanked on boot. Default to true. Signed-off-by: Thomas Lim Reviewed-by: Aric Cyr Acked-by: Anthony Koo Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++ drivers/gpu/drm/amd/display/dc/dc.h | 1 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 4e7af5594459..a7e6f45a375c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -534,6 +534,8 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) if (amdgpu_dc_feature_mask & DC_FBC_MASK) init_data.flags.fbc_support = true; + init_data.flags.power_down_display_on_boot = true; + /* Display Core create. */ adev->dm.dc = dc_create(&init_data); diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index aa2954dda129..70edd9ea5afe 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -204,6 +204,7 @@ struct dc_config { bool optimize_edp_link_rate; bool disable_fractional_pwm; bool allow_seamless_boot_optimization; + bool power_down_display_on_boot; }; enum visual_confirm { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 549836c60220..7e173c74907c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1118,7 +1118,7 @@ static void dcn10_init_hw(struct dc *dc) * Otherwise, if taking control is not possible, we need to power * everything down. */ - if (dcb->funcs->is_accelerated_mode(dcb)) { + if (dcb->funcs->is_accelerated_mode(dcb) || dc->config.power_down_display_on_boot) { for (i = 0; i < dc->res_pool->pipe_count; i++) { struct hubp *hubp = dc->res_pool->hubps[i]; struct dpp *dpp = dc->res_pool->dpps[i]; -- cgit v1.2.3 From a0867053408ec4623687f574d8931286c54d514f Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Wed, 10 Apr 2019 14:08:53 -0400 Subject: drm/amd/display: remove deprecated pplib interface [Why] The new interface now replaces the old interface for all known configurations. Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Leo Li Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c | 27 +++++----------------- drivers/gpu/drm/amd/display/dc/dm_pp_smu.h | 23 ------------------ drivers/gpu/drm/amd/display/dc/inc/core_types.h | 1 - 3 files changed, 6 insertions(+), 45 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c index 0d9bee8d5ab9..2b2de1d913c9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_clk_mgr.c @@ -151,9 +151,6 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, struct dc *dc = clk_mgr->ctx->dc; struct dc_debug_options *debug = &dc->debug; struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; - struct pp_smu_display_requirement_rv *smu_req_cur = - &dc->res_pool->pp_smu_req; - struct pp_smu_display_requirement_rv smu_req = *smu_req_cur; struct pp_smu_funcs_rv *pp_smu = NULL; bool send_request_to_increase = false; bool send_request_to_lower = false; @@ -175,8 +172,6 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, */ if (pp_smu && pp_smu->set_display_count) pp_smu->set_display_count(&pp_smu->pp_smu, display_count); - - smu_req.display_count = display_count; } if (new_clocks->dispclk_khz > clk_mgr->clks.dispclk_khz @@ -187,7 +182,6 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, if (should_set_clock(safe_to_lower, new_clocks->phyclk_khz, clk_mgr->clks.phyclk_khz)) { clk_mgr->clks.phyclk_khz = new_clocks->phyclk_khz; - send_request_to_lower = true; } @@ -197,24 +191,18 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, if (should_set_clock(safe_to_lower, new_clocks->fclk_khz, clk_mgr->clks.fclk_khz)) { clk_mgr->clks.fclk_khz = new_clocks->fclk_khz; - smu_req.hard_min_fclk_mhz = new_clocks->fclk_khz / 1000; - send_request_to_lower = true; } //DCF Clock if (should_set_clock(safe_to_lower, new_clocks->dcfclk_khz, clk_mgr->clks.dcfclk_khz)) { clk_mgr->clks.dcfclk_khz = new_clocks->dcfclk_khz; - smu_req.hard_min_dcefclk_mhz = new_clocks->dcfclk_khz / 1000; - send_request_to_lower = true; } if (should_set_clock(safe_to_lower, new_clocks->dcfclk_deep_sleep_khz, clk_mgr->clks.dcfclk_deep_sleep_khz)) { clk_mgr->clks.dcfclk_deep_sleep_khz = new_clocks->dcfclk_deep_sleep_khz; - smu_req.min_deep_sleep_dcefclk_mhz = (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000; - send_request_to_lower = true; } @@ -227,9 +215,9 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, pp_smu->set_hard_min_dcfclk_by_freq && pp_smu->set_min_deep_sleep_dcfclk) { - pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, smu_req.hard_min_fclk_mhz); - pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, smu_req.hard_min_dcefclk_mhz); - pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, smu_req.min_deep_sleep_dcefclk_mhz); + pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, new_clocks->fclk_khz / 1000); + pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, new_clocks->dcfclk_khz / 1000); + pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); } } @@ -239,7 +227,6 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, || new_clocks->dispclk_khz == clk_mgr->clks.dispclk_khz) { dcn1_ramp_up_dispclk_with_dpp(clk_mgr, new_clocks); clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz; - send_request_to_lower = true; } @@ -249,13 +236,11 @@ static void dcn1_update_clocks(struct clk_mgr *clk_mgr, pp_smu->set_hard_min_dcfclk_by_freq && pp_smu->set_min_deep_sleep_dcfclk) { - pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, smu_req.hard_min_fclk_mhz); - pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, smu_req.hard_min_dcefclk_mhz); - pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, smu_req.min_deep_sleep_dcefclk_mhz); + pp_smu->set_hard_min_fclk_by_freq(&pp_smu->pp_smu, new_clocks->fclk_khz / 1000); + pp_smu->set_hard_min_dcfclk_by_freq(&pp_smu->pp_smu, new_clocks->dcfclk_khz / 1000); + pp_smu->set_min_deep_sleep_dcfclk(&pp_smu->pp_smu, (new_clocks->dcfclk_deep_sleep_khz + 999) / 1000); } } - - *smu_req_cur = smu_req; } static const struct clk_mgr_funcs dcn1_funcs = { .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, diff --git a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h index cc6891b8ea69..4fc4208d1472 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h +++ b/drivers/gpu/drm/amd/display/dc/dm_pp_smu.h @@ -74,29 +74,6 @@ struct pp_smu_wm_range_sets { struct pp_smu_wm_set_range writer_wm_sets[MAX_WATERMARK_SETS]; }; -struct pp_smu_display_requirement_rv { - /* PPSMC_MSG_SetDisplayCount: count - * 0 triggers S0i2 optimization - */ - unsigned int display_count; - - /* PPSMC_MSG_SetHardMinFclkByFreq: mhz - * FCLK will vary with DPM, but never below requested hard min - */ - unsigned int hard_min_fclk_mhz; - - /* PPSMC_MSG_SetHardMinDcefclkByFreq: mhz - * fixed clock at requested freq, either from FCH bypass or DFS - */ - unsigned int hard_min_dcefclk_mhz; - - /* PPSMC_MSG_SetMinDeepSleepDcefclk: mhz - * when DF is in cstate, dcf clock is further divided down - * to just above given frequency - */ - unsigned int min_deep_sleep_dcefclk_mhz; -}; - struct pp_smu_funcs_rv { struct pp_smu pp_smu; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 88a82a23d259..6f5ab05d6467 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -145,7 +145,6 @@ struct resource_pool { struct hubbub *hubbub; struct mpc *mpc; struct pp_smu_funcs *pp_smu; - struct pp_smu_display_requirement_rv pp_smu_req; struct dce_aux *engines[MAX_PIPES]; struct dce_i2c_hw *hw_i2cs[MAX_PIPES]; struct dce_i2c_sw *sw_i2cs[MAX_PIPES]; -- cgit v1.2.3 From cc8d84132a833cc3be469c5d363da769bc69875e Mon Sep 17 00:00:00 2001 From: Charlene Liu Date: Wed, 10 Apr 2019 21:43:23 -0400 Subject: drm/amd/display: Add hubp_init entry to hubp vtable Different HW will need to init HUBP differently. For now, add a vtable entry, and hook a NO-OP for DCN1. In addition, future HW will need to access the HUBPREQ_DEBUG register for hubp_init. Add it to the reg list. Signed-off-by: Charlene Liu Reviewed-by: Jun Lei Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c | 6 +++++- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h | 4 ++++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 1 + drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c index 683829466a44..787a36566fb9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c @@ -1197,6 +1197,10 @@ void hubp1_vtg_sel(struct hubp *hubp, uint32_t otg_inst) REG_UPDATE(DCHUBP_CNTL, HUBP_VTG_SEL, otg_inst); } +void hubp1_init(struct hubp *hubp) +{ + //do nothing +} static const struct hubp_funcs dcn10_hubp_funcs = { .hubp_program_surface_flip_and_addr = hubp1_program_surface_flip_and_addr, @@ -1220,7 +1224,7 @@ static const struct hubp_funcs dcn10_hubp_funcs = { .hubp_clear_underflow = hubp1_clear_underflow, .hubp_disable_control = hubp1_disable_control, .hubp_get_underflow_status = hubp1_get_underflow_status, - + .hubp_init = hubp1_init, }; /*****************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h index db98ba361686..99d2b7e2a578 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h @@ -34,6 +34,7 @@ #define HUBP_REG_LIST_DCN(id)\ SRI(DCHUBP_CNTL, HUBP, id),\ SRI(HUBPREQ_DEBUG_DB, HUBP, id),\ + SRI(HUBPREQ_DEBUG, HUBP, id),\ SRI(DCSURF_ADDR_CONFIG, HUBP, id),\ SRI(DCSURF_TILING_CONFIG, HUBP, id),\ SRI(DCSURF_SURFACE_PITCH, HUBPREQ, id),\ @@ -138,6 +139,7 @@ #define HUBP_COMMON_REG_VARIABLE_LIST \ uint32_t DCHUBP_CNTL; \ uint32_t HUBPREQ_DEBUG_DB; \ + uint32_t HUBPREQ_DEBUG; \ uint32_t DCSURF_ADDR_CONFIG; \ uint32_t DCSURF_TILING_CONFIG; \ uint32_t DCSURF_SURFACE_PITCH; \ @@ -749,4 +751,6 @@ enum cursor_pitch hubp1_get_cursor_pitch(unsigned int pitch); void hubp1_vready_workaround(struct hubp *hubp, struct _vcs_dpi_display_pipe_dest_params_st *pipe_dest); +void hubp1_init(struct hubp *hubp); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 7e173c74907c..33d311cea28c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1123,6 +1123,7 @@ static void dcn10_init_hw(struct dc *dc) struct hubp *hubp = dc->res_pool->hubps[i]; struct dpp *dpp = dc->res_pool->dpps[i]; + hubp->funcs->hubp_init(hubp); dc->res_pool->opps[i]->mpc_tree_params.opp_id = dc->res_pool->opps[i]->inst; plane_atomic_power_down(dc, dpp, hubp); } diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h index 1cd07e94ee63..455df4999797 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h @@ -130,6 +130,7 @@ struct hubp_funcs { void (*hubp_clear_underflow)(struct hubp *hubp); void (*hubp_disable_control)(struct hubp *hubp, bool disable_hubp); unsigned int (*hubp_get_underflow_status)(struct hubp *hubp); + void (*hubp_init)(struct hubp *hubp); }; -- cgit v1.2.3 From ee13cea962b5ab2d70501f51008c05b394cb322e Mon Sep 17 00:00:00 2001 From: John Barberiz Date: Wed, 3 Apr 2019 19:22:55 -0400 Subject: drm/amd/display: Refactor dp vendor parsing logic to a function Refactor dp vendor parsing int to a new function, and call it before get_active_converter_info(). Also, add a flag to skip parsing of Display ID 2.0. Some devices fail on readind DID2, but we shouldn't fail EDID read because of it. Add this flag to facilitate the logic. Signed-off-by: John Barberiz Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 47 +++++++++++++----------- drivers/gpu/drm/amd/display/dc/dc_link.h | 1 + 2 files changed, 27 insertions(+), 21 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 64a309a5e1c9..1ee544a32ebb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -2185,6 +2185,30 @@ static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc) return -1; } +static void read_dp_device_vendor_id(struct dc_link *link) +{ + struct dp_device_vendor_id dp_id; + + /* read IEEE branch device id */ + core_link_read_dpcd( + link, + DP_BRANCH_OUI, + (uint8_t *)&dp_id, + sizeof(dp_id)); + + link->dpcd_caps.branch_dev_id = + (dp_id.ieee_oui[0] << 16) + + (dp_id.ieee_oui[1] << 8) + + dp_id.ieee_oui[2]; + + memmove( + link->dpcd_caps.branch_dev_name, + dp_id.ieee_device_id, + sizeof(dp_id.ieee_device_id)); +} + + + static void get_active_converter_info( uint8_t data, struct dc_link *link) { @@ -2270,27 +2294,6 @@ static void get_active_converter_info( ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type); - { - struct dp_device_vendor_id dp_id; - - /* read IEEE branch device id */ - core_link_read_dpcd( - link, - DP_BRANCH_OUI, - (uint8_t *)&dp_id, - sizeof(dp_id)); - - link->dpcd_caps.branch_dev_id = - (dp_id.ieee_oui[0] << 16) + - (dp_id.ieee_oui[1] << 8) + - dp_id.ieee_oui[2]; - - memmove( - link->dpcd_caps.branch_dev_name, - dp_id.ieee_device_id, - sizeof(dp_id.ieee_device_id)); - } - { struct dp_sink_hw_fw_revision dp_hw_fw_revision; @@ -2455,6 +2458,8 @@ static bool retrieve_link_cap(struct dc_link *link) ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT - DP_DPCD_REV]; + read_dp_device_vendor_id(link); + get_active_converter_info(ds_port.byte, link); dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data)); diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index cc7ffac64c96..7b9429e30d82 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -120,6 +120,7 @@ struct dc_link { /* MST record stream using this link */ struct link_flags { bool dp_keep_receiver_powered; + bool dp_skip_DID2; } wa_flags; struct link_mst_stream_allocation_table mst_stream_alloc_table; -- cgit v1.2.3 From 057be086603feb2669c0eff540d72ac26e2b3fcf Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Mon, 15 Apr 2019 12:18:53 -0400 Subject: drm/amd/display: Do VRR transition before enable_crc_interrupts [Why] Originally we did the amdgpu_dm_handle_vrr_transition call before interrupts were enabled. After the interrupt toggling logic was moved around for support enabling CRTCs with no primary planes active this was no longer being called in the case where there wasn't a modeset. This fixes failures in igt@kms_vrr@* with error "Timed out: Waiting for vblank event". [How] Shift them back into the loop that always ran before interrupts were enabled. Pull out the logic that updated VRR state into the same loop since there's no reason these need to be split. In the case where we're going from VRR off, no planes to VRR on, some active planes we'll still be covered for having the VRR vupdate handler enabled - vblank will be re-enabled at this point, it will see that VRR is active and set the vupdate interrupt on there. Signed-off-by: Nicholas Kazlauskas Reviewed-by: David Francis Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index a7e6f45a375c..078b511499fd 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5487,10 +5487,6 @@ static void amdgpu_dm_enable_crtc_interrupts(struct drm_device *dev, if (!run_pass) continue; - /* Handle vrr on->off / off->on transitions */ - amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, - dm_new_crtc_state); - if (!dm_new_crtc_state->interrupts_enabled) continue; @@ -5780,18 +5776,23 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) mutex_unlock(&dm->dc_lock); } - /* Update freesync state before amdgpu_dm_handle_vrr_transition(). */ - for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { - dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); - pre_update_freesync_state_on_stream(dm, dm_new_crtc_state); - } - /* Count number of newly disabled CRTCs for dropping PM refs later. */ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, - new_crtc_state, i) + new_crtc_state, i) { if (old_crtc_state->active && !new_crtc_state->active) crtc_disable_count++; + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); + + /* Update freesync active state. */ + pre_update_freesync_state_on_stream(dm, dm_new_crtc_state); + + /* Handle vrr on->off / off->on transitions */ + amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, + dm_new_crtc_state); + } + /* Enable interrupts for CRTCs going through a modeset. */ amdgpu_dm_enable_crtc_interrupts(dev, state, true); -- cgit v1.2.3 From 7267a1a9745071d6c7cfec4063895750063b30ac Mon Sep 17 00:00:00 2001 From: Nicholas Kazlauskas Date: Tue, 23 Apr 2019 09:26:43 -0400 Subject: drm/amd/display: Expose DRM_FORMAT_RGB565 on overlay planes RGB565 support isn't restricted to just the primary plane in DC, so also expose support for it on overlays. Signed-off-by: Nicholas Kazlauskas Acked-by: Alex Deucher Reviewed-by: David Francis Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 078b511499fd..645188baa708 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4251,6 +4251,7 @@ static const uint32_t overlay_formats[] = { DRM_FORMAT_RGBA8888, DRM_FORMAT_XBGR8888, DRM_FORMAT_ABGR8888, + DRM_FORMAT_RGB565 }; static const u32 cursor_formats[] = { -- cgit v1.2.3 From dc4a9049f023cff6f3c7f0765a706595444c4bd2 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 26 Apr 2019 23:40:14 +0200 Subject: drm/amd/display: Fix and simplify apply_below_the_range() The comparison of inserted_frame_duration_in_us against a duration calculated from max_refresh_in_uhz is both wrong in its math and not needed, as the min_duration_in_us value is already cached in in_out_vrr for reuse. No need to recalculate it wrongly at each invocation. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 3d867e34f8b3..19b1eaebe484 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -437,10 +437,8 @@ static void apply_below_the_range(struct core_freesync *core_freesync, inserted_frame_duration_in_us = last_render_time_in_us / frames_to_insert; - if (inserted_frame_duration_in_us < - (1000000 / in_out_vrr->max_refresh_in_uhz)) - inserted_frame_duration_in_us = - (1000000 / in_out_vrr->max_refresh_in_uhz); + if (inserted_frame_duration_in_us < in_out_vrr->min_duration_in_us) + inserted_frame_duration_in_us = in_out_vrr->min_duration_in_us; /* Cache the calculated variables */ in_out_vrr->btr.inserted_duration_in_us = -- cgit v1.2.3 From 09aef2c48e799b39d1595038c3a993c0279c292d Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 26 Apr 2019 23:40:16 +0200 Subject: drm/amd/display: Compensate for pre-DCE12 BTR-VRR hw limitations. (v3) Pre-DCE12 needs special treatment for BTR / low framerate compensation for more stable behaviour: According to comments in the code and some testing on DCE-8 and DCE-11, DCE-11 and earlier only apply VTOTAL_MIN/MAX programming with a lag of one frame, so the special BTR hw programming for intermediate fixed duration frames must be done inside the current frame at flip submission in atomic commit tail, ie. one vblank earlier, and the fixed refresh intermediate frame mode must be also terminated one vblank earlier on pre-DCE12 display engines. To achieve proper termination on < DCE-12 shift the point when the switch-back from fixed vblank duration to variable vblank duration happens from the start of VBLANK (vblank irq, as done on DCE-12+) to back-porch or end of VBLANK (handled by vupdate irq handler). We must leave the switch-back code inside VBLANK irq for DCE12+, as before. Doing this, we get much better behaviour of BTR for up-sweeps, ie. going from short to long frame durations (~high to low fps) and for constant framerate flips, as tested on DCE-8 and DCE-11. Behaviour is still not quite as good as on DCN-1 though. On down-sweeps, going from long to short frame durations (low fps to high fps) < DCE-12 is a little bit improved, although by far not as much as for up-sweeps and constant fps. v2: Fix some wrong locking, as pointed out by Nicholas. v3: Simplify if-condition in vupdate-irq - nit by Nicholas. Signed-off-by: Mario Kleiner Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 48 +++++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 645188baa708..6eb2bd554ba1 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -364,6 +364,7 @@ static void dm_vupdate_high_irq(void *interrupt_params) struct amdgpu_device *adev = irq_params->adev; struct amdgpu_crtc *acrtc; struct dm_crtc_state *acrtc_state; + unsigned long flags; acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE); @@ -379,8 +380,25 @@ static void dm_vupdate_high_irq(void *interrupt_params) * page-flip completion events that have been queued to us * if a pageflip happened inside front-porch. */ - if (amdgpu_dm_vrr_active(acrtc_state)) + if (amdgpu_dm_vrr_active(acrtc_state)) { drm_crtc_handle_vblank(&acrtc->base); + + /* BTR processing for pre-DCE12 ASICs */ + if (acrtc_state->stream && + adev->family < AMDGPU_FAMILY_AI) { + spin_lock_irqsave(&adev->ddev->event_lock, flags); + mod_freesync_handle_v_update( + adev->dm.freesync_module, + acrtc_state->stream, + &acrtc_state->vrr_params); + + dc_stream_adjust_vmin_vmax( + adev->dm.dc, + acrtc_state->stream, + &acrtc_state->vrr_params.adjust); + spin_unlock_irqrestore(&adev->ddev->event_lock, flags); + } + } } } @@ -390,6 +408,7 @@ static void dm_crtc_high_irq(void *interrupt_params) struct amdgpu_device *adev = irq_params->adev; struct amdgpu_crtc *acrtc; struct dm_crtc_state *acrtc_state; + unsigned long flags; acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); @@ -412,9 +431,10 @@ static void dm_crtc_high_irq(void *interrupt_params) */ amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); - if (acrtc_state->stream && + if (acrtc_state->stream && adev->family >= AMDGPU_FAMILY_AI && acrtc_state->vrr_params.supported && acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { + spin_lock_irqsave(&adev->ddev->event_lock, flags); mod_freesync_handle_v_update( adev->dm.freesync_module, acrtc_state->stream, @@ -424,6 +444,7 @@ static void dm_crtc_high_irq(void *interrupt_params) adev->dm.dc, acrtc_state->stream, &acrtc_state->vrr_params.adjust); + spin_unlock_irqrestore(&adev->ddev->event_lock, flags); } } } @@ -5054,8 +5075,10 @@ static void update_freesync_state_on_stream( struct dc_plane_state *surface, u32 flip_timestamp_in_us) { - struct mod_vrr_params vrr_params = new_crtc_state->vrr_params; + struct mod_vrr_params vrr_params; struct dc_info_packet vrr_infopacket = {0}; + struct amdgpu_device *adev = dm->adev; + unsigned long flags; if (!new_stream) return; @@ -5068,6 +5091,9 @@ static void update_freesync_state_on_stream( if (!new_stream->timing.h_total || !new_stream->timing.v_total) return; + spin_lock_irqsave(&adev->ddev->event_lock, flags); + vrr_params = new_crtc_state->vrr_params; + if (surface) { mod_freesync_handle_preflip( dm->freesync_module, @@ -5075,6 +5101,12 @@ static void update_freesync_state_on_stream( new_stream, flip_timestamp_in_us, &vrr_params); + + if (adev->family < AMDGPU_FAMILY_AI && + amdgpu_dm_vrr_active(new_crtc_state)) { + mod_freesync_handle_v_update(dm->freesync_module, + new_stream, &vrr_params); + } } mod_freesync_build_vrr_infopacket( @@ -5106,6 +5138,8 @@ static void update_freesync_state_on_stream( new_crtc_state->base.crtc->base.id, (int)new_crtc_state->base.vrr_enabled, (int)vrr_params.state); + + spin_unlock_irqrestore(&adev->ddev->event_lock, flags); } static void pre_update_freesync_state_on_stream( @@ -5113,8 +5147,10 @@ static void pre_update_freesync_state_on_stream( struct dm_crtc_state *new_crtc_state) { struct dc_stream_state *new_stream = new_crtc_state->stream; - struct mod_vrr_params vrr_params = new_crtc_state->vrr_params; + struct mod_vrr_params vrr_params; struct mod_freesync_config config = new_crtc_state->freesync_config; + struct amdgpu_device *adev = dm->adev; + unsigned long flags; if (!new_stream) return; @@ -5126,6 +5162,9 @@ static void pre_update_freesync_state_on_stream( if (!new_stream->timing.h_total || !new_stream->timing.v_total) return; + spin_lock_irqsave(&adev->ddev->event_lock, flags); + vrr_params = new_crtc_state->vrr_params; + if (new_crtc_state->vrr_supported && config.min_refresh_in_uhz && config.max_refresh_in_uhz) { @@ -5146,6 +5185,7 @@ static void pre_update_freesync_state_on_stream( sizeof(vrr_params.adjust)) != 0); new_crtc_state->vrr_params = vrr_params; + spin_unlock_irqrestore(&adev->ddev->event_lock, flags); } static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, -- cgit v1.2.3 From 2c7e78355beca9f20d6e30088d581acd300aae04 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 25 Apr 2019 15:35:17 +0800 Subject: drm/amdgpu: expose VCE 4.0 powergate interface SMU will use this interface to power down the VCE engine. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index aadc3e66ebd7..f3f5938430d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c @@ -382,6 +382,7 @@ static int vce_v4_0_start(struct amdgpu_device *adev) static int vce_v4_0_stop(struct amdgpu_device *adev) { + /* Disable VCPU */ WREG32_P(SOC15_REG_OFFSET(VCE, 0, mmVCE_VCPU_CNTL), 0, ~0x200001); /* hold on ECPU */ @@ -389,8 +390,8 @@ static int vce_v4_0_stop(struct amdgpu_device *adev) VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK); - /* clear BUSY flag */ - WREG32_P(SOC15_REG_OFFSET(VCE, 0, mmVCE_STATUS), 0, ~VCE_STATUS__JOB_BUSY_MASK); + /* clear VCE_STATUS */ + WREG32(SOC15_REG_OFFSET(VCE, 0, mmVCE_STATUS), 0); /* Set Clock-Gating off */ /* if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG) @@ -922,6 +923,7 @@ static int vce_v4_0_set_clockgating_state(void *handle, return 0; } +#endif static int vce_v4_0_set_powergating_state(void *handle, enum amd_powergating_state state) @@ -935,16 +937,11 @@ static int vce_v4_0_set_powergating_state(void *handle, */ struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (!(adev->pg_flags & AMD_PG_SUPPORT_VCE)) - return 0; - if (state == AMD_PG_STATE_GATE) - /* XXX do we need a vce_v4_0_stop()? */ - return 0; + return vce_v4_0_stop(adev); else return vce_v4_0_start(adev); } -#endif static void vce_v4_0_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_job *job, struct amdgpu_ib *ib, uint32_t flags) @@ -1059,7 +1056,7 @@ const struct amd_ip_funcs vce_v4_0_ip_funcs = { .soft_reset = NULL /* vce_v4_0_soft_reset */, .post_soft_reset = NULL /* vce_v4_0_post_soft_reset */, .set_clockgating_state = vce_v4_0_set_clockgating_state, - .set_powergating_state = NULL /* vce_v4_0_set_powergating_state */, + .set_powergating_state = vce_v4_0_set_powergating_state, }; static const struct amdgpu_ring_funcs vce_v4_0_ring_vm_funcs = { -- cgit v1.2.3 From b0fc850fd95f8ecceb601bbb40624da0a8c220a0 Mon Sep 17 00:00:00 2001 From: Evan Quan Date: Thu, 25 Apr 2019 15:38:25 +0800 Subject: drm/amdgpu: power down the Vega20 VCE engine on request Power down the engine also along with disabling its DPM functionality. Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 34f3782ff018..1f5614f04661 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -3452,7 +3452,18 @@ static void vega20_power_gate_vce(struct pp_hwmgr *hwmgr, bool bgate) return ; data->vce_power_gated = bgate; - vega20_enable_disable_vce_dpm(hwmgr, !bgate); + if (bgate) { + vega20_enable_disable_vce_dpm(hwmgr, !bgate); + amdgpu_device_ip_set_powergating_state(hwmgr->adev, + AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_GATE); + } else { + amdgpu_device_ip_set_powergating_state(hwmgr->adev, + AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_UNGATE); + vega20_enable_disable_vce_dpm(hwmgr, !bgate); + } + } static void vega20_power_gate_uvd(struct pp_hwmgr *hwmgr, bool bgate) -- cgit v1.2.3 From 9628e15ca9d5f7595ba886173e98a139d0a56cd1 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Thu, 18 Apr 2019 11:06:34 +0100 Subject: drm/i915/icl: Whitelist GEN9_SLICE_COMMON_ECO_CHICKEN1 WaEnableStateCacheRedirectToCS context workaround configures the L3 cache to benefit 3d workloads but media has different requirements. Remove the workaround and whitelist the register to allow any userspace configure the behaviour to their liking. v2: * Remove the workaround apart from adding the whitelist. Signed-off-by: Tvrtko Ursulin Cc: Lionel Landwerlin Cc: kevin.ma@intel.com Cc: xiaogang.li@intel.com Acked-by: Lionel Landwerlin Acked-by: Anuj Phogat Link: https://patchwork.freedesktop.org/patch/msgid/20190418100634.984-1-tvrtko.ursulin@linux.intel.com Fixes: f63c7b4880aa ("drm/i915/icl: WaEnableStateCacheRedirectToCS") Reviewed-by: Joonas Lahtinen [tursulin: Anuj reported no GPU hangs or performance regressions with old Mesa on patched kernel.] (cherry picked from commit 0fc2273b9ab7f07cdef448e99525e481535e1ab0) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/intel_workarounds.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_workarounds.c b/drivers/gpu/drm/i915/intel_workarounds.c index ccaf63679435..9682dd575152 100644 --- a/drivers/gpu/drm/i915/intel_workarounds.c +++ b/drivers/gpu/drm/i915/intel_workarounds.c @@ -541,10 +541,6 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine) WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2, GEN11_TDL_CLOCK_GATING_FIX_DISABLE); - /* WaEnableStateCacheRedirectToCS:icl */ - WA_SET_BIT_MASKED(GEN9_SLICE_COMMON_ECO_CHICKEN1, - GEN11_STATE_CACHE_REDIRECT_TO_CS); - /* Wa_2006665173:icl (pre-prod) */ if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_A0)) WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3, @@ -1050,6 +1046,9 @@ static void icl_whitelist_build(struct i915_wa_list *w) /* WaAllowUMDToModifySamplerMode:icl */ whitelist_reg(w, GEN10_SAMPLER_MODE); + + /* WaEnableStateCacheRedirectToCS:icl */ + whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1); } void intel_engine_init_whitelist(struct intel_engine_cs *engine) -- cgit v1.2.3 From 307a312df9c43fdea286ad17f748aaf777cc434a Mon Sep 17 00:00:00 2001 From: Jon Derrick Date: Fri, 15 Mar 2019 18:05:15 -0600 Subject: drm/nouveau/bar/nv50: check bar1 vmm return value Check bar1's new vmm creation return value for errors. Signed-off-by: Jon Derrick Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 157b076a1272..8e64b19f3f8a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -168,6 +168,8 @@ nv50_bar_oneinit(struct nvkm_bar *base) ret = nvkm_vmm_new(device, start, limit-- - start, NULL, 0, &bar1_lock, "bar1", &bar->bar1_vmm); + if (ret) + return ret; atomic_inc(&bar->bar1_vmm->engref[NVKM_SUBDEV_BAR]); bar->bar1_vmm->debug = bar->base.subdev.debug; -- cgit v1.2.3 From f10b83de1fd49216a4c657816f48001437e4bdd5 Mon Sep 17 00:00:00 2001 From: Jon Derrick Date: Fri, 15 Mar 2019 18:05:16 -0600 Subject: drm/nouveau/bar/nv50: ensure BAR is mapped If the BAR is zero size, it indicates it was never successfully mapped. Ensure that the BAR is valid during initialization before attempting to use it. Signed-off-by: Jon Derrick Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 8e64b19f3f8a..f23a0ccc2bec 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -109,7 +109,7 @@ nv50_bar_oneinit(struct nvkm_bar *base) struct nvkm_device *device = bar->base.subdev.device; static struct lock_class_key bar1_lock; static struct lock_class_key bar2_lock; - u64 start, limit; + u64 start, limit, size; int ret; ret = nvkm_gpuobj_new(device, 0x20000, 0, false, NULL, &bar->mem); @@ -127,7 +127,10 @@ nv50_bar_oneinit(struct nvkm_bar *base) /* BAR2 */ start = 0x0100000000ULL; - limit = start + device->func->resource_size(device, 3); + size = device->func->resource_size(device, 3); + if (!size) + return -ENOMEM; + limit = start + size; ret = nvkm_vmm_new(device, start, limit-- - start, NULL, 0, &bar2_lock, "bar2", &bar->bar2_vmm); @@ -164,7 +167,10 @@ nv50_bar_oneinit(struct nvkm_bar *base) /* BAR1 */ start = 0x0000000000ULL; - limit = start + device->func->resource_size(device, 1); + size = device->func->resource_size(device, 1); + if (!size) + return -ENOMEM; + limit = start + size; ret = nvkm_vmm_new(device, start, limit-- - start, NULL, 0, &bar1_lock, "bar1", &bar->bar1_vmm); -- cgit v1.2.3 From 12e08beb32d64b6070b718630490db83dd321c8c Mon Sep 17 00:00:00 2001 From: Jon Derrick Date: Fri, 15 Mar 2019 18:05:17 -0600 Subject: drm/nouveau/bar/gf100: ensure BAR is mapped If the BAR is zero size, it indicates it was never successfully mapped. Ensure that the BAR is valid during initialization before attempting to use it. Signed-off-by: Jon Derrick Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index a3ba7f50198b..a3dcb09a40ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -94,6 +94,8 @@ gf100_bar_oneinit_bar(struct gf100_bar *bar, struct gf100_barN *bar_vm, return ret; bar_len = device->func->resource_size(device, bar_nr); + if (!bar_len) + return -ENOMEM; if (bar_nr == 3 && bar->bar2_halve) bar_len >>= 1; -- cgit v1.2.3 From 15516bf9abaa41421a6ded79a5a2fee86f9594e5 Mon Sep 17 00:00:00 2001 From: Jon Derrick Date: Fri, 15 Mar 2019 18:05:18 -0600 Subject: drm/nouveau/mmu: qualify vmm during dtor If the BAR initialization failed it may leave the vmm structure in an unitialized state, leading to a null-pointer-dereference when the vmm is dereferenced during teardown. Signed-off-by: Jon Derrick Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index fa93f964e6a4..41640e0584ac 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -1783,7 +1783,7 @@ nvkm_vmm_get(struct nvkm_vmm *vmm, u8 page, u64 size, struct nvkm_vma **pvma) void nvkm_vmm_part(struct nvkm_vmm *vmm, struct nvkm_memory *inst) { - if (inst && vmm->func->part) { + if (inst && vmm && vmm->func->part) { mutex_lock(&vmm->mutex); vmm->func->part(vmm, inst); mutex_unlock(&vmm->mutex); -- cgit v1.2.3 From 2fbcb5653fc0f548454446ba21769faa48f7711b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 4 Apr 2019 08:49:43 -0500 Subject: drm/nouveau: Remove duplicate ACPI_VIDEO_NOTIFY_PROBE definition Commit 3a6536c51d5d ("drm/nouveau: Intercept ACPI_VIDEO_NOTIFY_PROBE") added a definition of ACPI_VIDEO_NOTIFY_PROBE because didn't supply one. Later, commit eff4a751cce5 ("ACPI / video: Move ACPI_VIDEO_NOTIFY_* defines to acpi/video.h") moved ACPI_VIDEO_NOTIFY_PROBE and other definitions to , so the copy in nouveau_display.c is now unnecessary. Remove the unnecessary definition from nouveau_display.c. Signed-off-by: Bjorn Helgaas CC: Hans de Goede Acked-by: Hans de Goede Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 55c0fa451163..832da8e0020d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -358,15 +358,6 @@ nouveau_display_hpd_work(struct work_struct *work) #ifdef CONFIG_ACPI -/* - * Hans de Goede: This define belongs in acpi/video.h, I've submitted a patch - * to the acpi subsys to move it there from drivers/acpi/acpi_video.c . - * This should be dropped once that is merged. - */ -#ifndef ACPI_VIDEO_NOTIFY_PROBE -#define ACPI_VIDEO_NOTIFY_PROBE 0x81 -#endif - static int nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, void *data) -- cgit v1.2.3 From 342406e4fbba9a174125fbfe6aeac3d64ef90f76 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Tue, 9 Apr 2019 16:23:30 -0400 Subject: drm/nouveau/i2c: Disable i2c bus access after ->fini() For a while, we've had the problem of i2c bus access not grabbing a runtime PM ref when it's being used in userspace by i2c-dev, resulting in nouveau spamming the kernel log with errors if anything attempts to access the i2c bus while the GPU is in runtime suspend. An example: [ 130.078386] nouveau 0000:01:00.0: i2c: aux 000d: begin idle timeout ffffffff Since the GPU is in runtime suspend, the MMIO region that the i2c bus is on isn't accessible. On x86, the standard behavior for accessing an unavailable MMIO region is to just return ~0. Except, that turned out to be a lie. While computers with a clean concious will return ~0 in this scenario, some machines will actually completely hang a CPU on certian bad MMIO accesses. This was witnessed with someone's Lenovo ThinkPad P50, where sensors-detect attempting to access the i2c bus while the GPU was suspended would result in a CPU hang: CPU: 5 PID: 12438 Comm: sensors-detect Not tainted 5.0.0-0.rc4.git3.1.fc30.x86_64 #1 Hardware name: LENOVO 20EQS64N17/20EQS64N17, BIOS N1EET74W (1.47 ) 11/21/2017 RIP: 0010:ioread32+0x2b/0x30 Code: 81 ff ff ff 03 00 77 20 48 81 ff 00 00 01 00 76 05 0f b7 d7 ed c3 48 c7 c6 e1 0c 36 96 e8 2d ff ff ff b8 ff ff ff ff c3 8b 07 0f 1f 40 00 49 89 f0 48 81 fe ff ff 03 00 76 04 40 88 3e c3 48 RSP: 0018:ffffaac3c5007b48 EFLAGS: 00000292 ORIG_RAX: ffffffffffffff13 RAX: 0000000001111000 RBX: 0000000001111000 RCX: 0000043017a97186 RDX: 0000000000000aaa RSI: 0000000000000005 RDI: ffffaac3c400e4e4 RBP: ffff9e6443902c00 R08: ffffaac3c400e4e4 R09: ffffaac3c5007be7 R10: 0000000000000004 R11: 0000000000000001 R12: ffff9e6445dd0000 R13: 000000000000e4e4 R14: 00000000000003c4 R15: 0000000000000000 FS: 00007f253155a740(0000) GS:ffff9e644f600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005630d1500358 CR3: 0000000417c44006 CR4: 00000000003606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: g94_i2c_aux_xfer+0x326/0x850 [nouveau] nvkm_i2c_aux_i2c_xfer+0x9e/0x140 [nouveau] __i2c_transfer+0x14b/0x620 i2c_smbus_xfer_emulated+0x159/0x680 ? _raw_spin_unlock_irqrestore+0x1/0x60 ? rt_mutex_slowlock.constprop.0+0x13d/0x1e0 ? __lock_is_held+0x59/0xa0 __i2c_smbus_xfer+0x138/0x5a0 i2c_smbus_xfer+0x4f/0x80 i2cdev_ioctl_smbus+0x162/0x2d0 [i2c_dev] i2cdev_ioctl+0x1db/0x2c0 [i2c_dev] do_vfs_ioctl+0x408/0x750 ksys_ioctl+0x5e/0x90 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x60/0x1e0 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7f25317f546b Code: 0f 1e fa 48 8b 05 1d da 0c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d ed d9 0c 00 f7 d8 64 89 01 48 RSP: 002b:00007ffc88caab68 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00005630d0fe7260 RCX: 00007f25317f546b RDX: 00005630d1598e80 RSI: 0000000000000720 RDI: 0000000000000003 RBP: 00005630d155b968 R08: 0000000000000001 R09: 00005630d15a1da0 R10: 0000000000000070 R11: 0000000000000246 R12: 00005630d1598e80 R13: 00005630d12f3d28 R14: 0000000000000720 R15: 00005630d12f3ce0 watchdog: BUG: soft lockup - CPU#5 stuck for 23s! [sensors-detect:12438] Yikes! While I wanted to try to make it so that accessing an i2c bus on nouveau would wake up the GPU as needed, airlied pointed out that pretty much any usecase for userspace accessing an i2c bus on a GPU (mainly for the DDC brightness control that some displays have) is going to only be useful while there's at least one display enabled on the GPU anyway, and the GPU never sleeps while there's displays running. Since teaching the i2c bus to wake up the GPU on userspace accesses is a good deal more difficult than it might seem, mostly due to the fact that we have to use the i2c bus during runtime resume of the GPU, we instead opt for the easiest solution: don't let userspace access i2c busses on the GPU at all while it's in runtime suspend. Changes since v1: * Also disable i2c busses that run over DP AUX Signed-off-by: Lyude Paul Cc: stable@vger.kernel.org Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c | 26 ++++++++++++++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 15 +++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c | 21 +++++++++++++++++- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h | 1 + 6 files changed, 65 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h index eef54e9b5d77..7957eafa5f0e 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h @@ -38,6 +38,7 @@ struct nvkm_i2c_bus { struct mutex mutex; struct list_head head; struct i2c_adapter i2c; + u8 enabled; }; int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *); @@ -57,6 +58,7 @@ struct nvkm_i2c_aux { struct mutex mutex; struct list_head head; struct i2c_adapter i2c; + u8 enabled; u32 intr; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c index 4c1f547da463..b4e7404fe660 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c @@ -105,9 +105,15 @@ nvkm_i2c_aux_acquire(struct nvkm_i2c_aux *aux) { struct nvkm_i2c_pad *pad = aux->pad; int ret; + AUX_TRACE(aux, "acquire"); mutex_lock(&aux->mutex); - ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX); + + if (aux->enabled) + ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX); + else + ret = -EIO; + if (ret) mutex_unlock(&aux->mutex); return ret; @@ -145,6 +151,24 @@ nvkm_i2c_aux_del(struct nvkm_i2c_aux **paux) } } +void +nvkm_i2c_aux_init(struct nvkm_i2c_aux *aux) +{ + AUX_TRACE(aux, "init"); + mutex_lock(&aux->mutex); + aux->enabled = true; + mutex_unlock(&aux->mutex); +} + +void +nvkm_i2c_aux_fini(struct nvkm_i2c_aux *aux) +{ + AUX_TRACE(aux, "fini"); + mutex_lock(&aux->mutex); + aux->enabled = false; + mutex_unlock(&aux->mutex); +} + int nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func, struct nvkm_i2c_pad *pad, int id, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h index 7d56c4ba693c..08f6b2ee64ab 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h @@ -16,6 +16,8 @@ int nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *, int nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *, int id, struct nvkm_i2c_aux **); void nvkm_i2c_aux_del(struct nvkm_i2c_aux **); +void nvkm_i2c_aux_init(struct nvkm_i2c_aux *); +void nvkm_i2c_aux_fini(struct nvkm_i2c_aux *); int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type, u32 addr, u8 *data, u8 *size); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 4f197b15acf6..ecacb22834d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c @@ -160,8 +160,18 @@ nvkm_i2c_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_i2c *i2c = nvkm_i2c(subdev); struct nvkm_i2c_pad *pad; + struct nvkm_i2c_bus *bus; + struct nvkm_i2c_aux *aux; u32 mask; + list_for_each_entry(aux, &i2c->aux, head) { + nvkm_i2c_aux_fini(aux); + } + + list_for_each_entry(bus, &i2c->bus, head) { + nvkm_i2c_bus_fini(bus); + } + if ((mask = (1 << i2c->func->aux) - 1), i2c->func->aux_stat) { i2c->func->aux_mask(i2c, NVKM_I2C_ANY, mask, 0); i2c->func->aux_stat(i2c, &mask, &mask, &mask, &mask); @@ -180,6 +190,7 @@ nvkm_i2c_init(struct nvkm_subdev *subdev) struct nvkm_i2c *i2c = nvkm_i2c(subdev); struct nvkm_i2c_bus *bus; struct nvkm_i2c_pad *pad; + struct nvkm_i2c_aux *aux; list_for_each_entry(pad, &i2c->pad, head) { nvkm_i2c_pad_init(pad); @@ -189,6 +200,10 @@ nvkm_i2c_init(struct nvkm_subdev *subdev) nvkm_i2c_bus_init(bus); } + list_for_each_entry(aux, &i2c->aux, head) { + nvkm_i2c_aux_init(aux); + } + return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c index 807a2b67bd64..ed50cc3736b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c @@ -110,6 +110,19 @@ nvkm_i2c_bus_init(struct nvkm_i2c_bus *bus) BUS_TRACE(bus, "init"); if (bus->func->init) bus->func->init(bus); + + mutex_lock(&bus->mutex); + bus->enabled = true; + mutex_unlock(&bus->mutex); +} + +void +nvkm_i2c_bus_fini(struct nvkm_i2c_bus *bus) +{ + BUS_TRACE(bus, "fini"); + mutex_lock(&bus->mutex); + bus->enabled = false; + mutex_unlock(&bus->mutex); } void @@ -126,9 +139,15 @@ nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *bus) { struct nvkm_i2c_pad *pad = bus->pad; int ret; + BUS_TRACE(bus, "acquire"); mutex_lock(&bus->mutex); - ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C); + + if (bus->enabled) + ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C); + else + ret = -EIO; + if (ret) mutex_unlock(&bus->mutex); return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h index bea0dd33961e..465464bba58b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h @@ -18,6 +18,7 @@ int nvkm_i2c_bus_new_(const struct nvkm_i2c_bus_func *, struct nvkm_i2c_pad *, int id, struct nvkm_i2c_bus **); void nvkm_i2c_bus_del(struct nvkm_i2c_bus **); void nvkm_i2c_bus_init(struct nvkm_i2c_bus *); +void nvkm_i2c_bus_fini(struct nvkm_i2c_bus *); int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int); -- cgit v1.2.3 From a2f07d4c1e88d4250b5d1d3b54efcdb3d80f11da Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 18 Apr 2019 17:53:45 +0100 Subject: drm/nouveau/fb/ramgk104: fix spelling mistake "sucessfully" -> "successfully" There is a spelling mistake in a nvkm_debug message. Fix it. Signed-off-by: Colin Ian King Reviewed-by: Mukesh Ojha Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c index 8bcb7e79a0cb..456aed1f2a02 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c @@ -1070,7 +1070,7 @@ gk104_ram_calc_xits(struct gk104_ram *ram, struct nvkm_ram_data *next) nvkm_error(subdev, "unable to calc plls\n"); return -EINVAL; } - nvkm_debug(subdev, "sucessfully calced PLLs for clock %i kHz" + nvkm_debug(subdev, "successfully calced PLLs for clock %i kHz" " (refclock: %i kHz)\n", next->freq, ret); } else { /* calculate refpll coefficients */ -- cgit v1.2.3 From 30df16b93b25fe345e4c5d4e9c789d3f4f337b72 Mon Sep 17 00:00:00 2001 From: Tobias Klausmann Date: Thu, 28 Mar 2019 14:17:31 +0100 Subject: drm/nouveau/nouveau: forward error generated while resuming objects tree On a failed resume we may experience unrecoverable errors. Plumb the error code through to actually let the driver fail. On a reverse-prime setup this helps the drm subsystem to at least recover the integrated gpu. This can especially happen with secboot timing out, leaving the hardware in a non-functioning state. Signed-off-by: Tobias Klausmann Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 6ab9033f49da..22cd45845e07 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -802,10 +802,15 @@ fail_display: static int nouveau_do_resume(struct drm_device *dev, bool runtime) { + int ret = 0; struct nouveau_drm *drm = nouveau_drm(dev); NV_DEBUG(drm, "resuming object tree...\n"); - nvif_client_resume(&drm->master.base); + ret = nvif_client_resume(&drm->master.base); + if (ret) { + NV_ERROR(drm, "Client resume failed with error: %d\n", ret); + return ret; + } NV_DEBUG(drm, "resuming fence...\n"); if (drm->fence && nouveau_fence(drm)->resume) @@ -925,6 +930,7 @@ nouveau_pmops_runtime_resume(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_drm(drm_dev); struct nvif_device *device = &nouveau_drm(drm_dev)->client.device; int ret; @@ -941,6 +947,10 @@ nouveau_pmops_runtime_resume(struct device *dev) pci_set_master(pdev); ret = nouveau_do_resume(drm_dev, true); + if (ret) { + NV_ERROR(drm, "resume failed with: %d\n", ret); + return ret; + } /* do magic */ nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25)); -- cgit v1.2.3 From 5ec776383d5ba119cf1bcf67e1dbcd5e96911e8a Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 16 Apr 2019 13:30:47 +0100 Subject: drm: report consistent errors when checking syncobj capibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We've been somewhat inconsistent when adding the new ioctl and returned ENODEV instead of EOPNOTSUPPORTED upon failing the syncobj capibility. Signed-off-by: Lionel Landwerlin Fixes: ea569910cbab98 ("drm/syncobj: add transition iotcls between binary and timeline v2") Fixes: 01d6c357837918 ("drm/syncobj: add support for timeline point wait v8") Cc: Dave Airlie Cc: Christian König Cc: Chunming Zhou Reviewed-by: Christian König for the series. Reviewed-by: Chunming Zhou Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190416123048.2913-1-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/drm_syncobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index f3ceeb504e6c..d141dee38640 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -741,7 +741,7 @@ drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data, int ret; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; if (args->pad) return -EINVAL; @@ -1092,7 +1092,7 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, int ret = 0; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + return -EOPNOTSUPP; if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL | DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | -- cgit v1.2.3 From 060cebb20cdbcd3185d593e7194fa7a738201817 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Tue, 16 Apr 2019 13:57:50 +0100 Subject: drm: introduce a capability flag for syncobj timeline support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately userspace users of this API cannot be publicly disclosed yet. This commit effectively disables timeline syncobj ioctls for all drivers. Each driver wishing to support this feature will need to expose DRIVER_SYNCOBJ_TIMELINE. v2: Add uAPI capability check (Christian) Signed-off-by: Lionel Landwerlin Reviewed-by: Christian König (v1) Cc: Dave Airlie Cc: Daniel Vetter Cc: Christian König Cc: Chunming Zhou Reviewed-by: Dave Airlie Reviewed-by: Chunming Zhou Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190416125750.31370-1-lionel.g.landwerlin@intel.com --- drivers/gpu/drm/drm_ioctl.c | 3 +++ drivers/gpu/drm/drm_syncobj.c | 10 +++++----- include/drm/drm_drv.h | 7 +++++++ include/uapi/drm/drm.h | 1 + 4 files changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 5878145077d0..2263e3ddd822 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -245,6 +245,9 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ case DRM_CAP_SYNCOBJ: req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ); return 0; + case DRM_CAP_SYNCOBJ_TIMELINE: + req->value = drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE); + return 0; } /* Other caps only work with KMS drivers */ diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index d141dee38640..361a01a08c18 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -740,7 +740,7 @@ drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data, struct drm_syncobj_transfer *args = data; int ret; - if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) return -EOPNOTSUPP; if (args->pad) @@ -1091,7 +1091,7 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, struct drm_syncobj **syncobjs; int ret = 0; - if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) return -EOPNOTSUPP; if (args->flags & ~(DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL | @@ -1195,7 +1195,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, uint32_t i, j; int ret; - if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) return -EOPNOTSUPP; if (args->pad != 0) @@ -1266,8 +1266,8 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, uint32_t i; int ret; - if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) - return -ENODEV; + if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) + return -EOPNOTSUPP; if (args->pad != 0) return -EINVAL; diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 5cc7f728ec73..68ca736c548d 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -91,6 +91,13 @@ enum drm_driver_feature { * submission. */ DRIVER_SYNCOBJ = BIT(5), + /** + * @DRIVER_SYNCOBJ_TIMELINE: + * + * Driver supports the timeline flavor of &drm_syncobj for explicit + * synchronization of command submission. + */ + DRIVER_SYNCOBJ_TIMELINE = BIT(6), /* IMPORTANT: Below are all the legacy flags, add new ones above. */ diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 236b01a1fabf..661d73f9a919 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -649,6 +649,7 @@ struct drm_gem_open { #define DRM_CAP_PAGE_FLIP_TARGET 0x11 #define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12 #define DRM_CAP_SYNCOBJ 0x13 +#define DRM_CAP_SYNCOBJ_TIMELINE 0x14 /** DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap { -- cgit v1.2.3 From 2b76f5be7c2778ee2f6bacddc19248f6a4a467a0 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 19 Dec 2018 15:16:41 +0100 Subject: drm/etnaviv: initialize idle mask before querying the HW db If there is a match in the HW DB, the function is left early, before inititalizing the idle mask. Fix this by doing the init earlier, as only old GPUs, not present in the HW DB need a different idle mask. Signed-off-by: Lucas Stach Reviewed-by: Philipp Zabel --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 6904535475de..72d01e873160 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -365,6 +365,7 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) dev_info(gpu->dev, "model: GC%x, revision: %x\n", gpu->identity.model, gpu->identity.revision); + gpu->idle_mask = ~VIVS_HI_IDLE_STATE_AXI_LP; /* * If there is a match in the HWDB, we aren't interested in the * remaining register values, as they might be wrong. @@ -412,7 +413,7 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) } /* GC600 idle register reports zero bits where modules aren't present */ - if (gpu->identity.model == chipModel_GC600) { + if (gpu->identity.model == chipModel_GC600) gpu->idle_mask = VIVS_HI_IDLE_STATE_TX | VIVS_HI_IDLE_STATE_RA | VIVS_HI_IDLE_STATE_SE | @@ -421,9 +422,6 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) VIVS_HI_IDLE_STATE_PE | VIVS_HI_IDLE_STATE_DE | VIVS_HI_IDLE_STATE_FE; - } else { - gpu->idle_mask = ~VIVS_HI_IDLE_STATE_AXI_LP; - } etnaviv_hw_specs(gpu); } -- cgit v1.2.3 From 6ff408e6dc2072adc3e27d7687dfba19edb05d60 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 24 Apr 2019 15:13:53 +0200 Subject: drm/panfrost: Add sanity checks to submit IOCTL So userspace can get feedback on any error conditions, instead of going ahead and things breaking later. Signed-off-by: Tomeu Vizoso Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20190424131355.62817-1-tomeu.vizoso@collabora.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 35 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index c06af78ab833..0f2863cb8077 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -172,13 +172,27 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, { struct panfrost_device *pfdev = dev->dev_private; struct drm_panfrost_submit *args = data; - struct drm_syncobj *sync_out; + struct drm_syncobj *sync_out = NULL; struct panfrost_job *job; int ret = 0; + if (!args->jc) + return -EINVAL; + + if (args->requirements && args->requirements != PANFROST_JD_REQ_FS) + return -EINVAL; + + if (args->out_sync > 0) { + sync_out = drm_syncobj_find(file, args->out_sync); + if (!sync_out) + return -ENODEV; + } + job = kzalloc(sizeof(*job), GFP_KERNEL); - if (!job) - return -ENOMEM; + if (!job) { + ret = -ENOMEM; + goto fail_out_sync; + } kref_init(&job->refcount); @@ -190,25 +204,24 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, ret = panfrost_copy_in_sync(dev, file, args, job); if (ret) - goto fail; + goto fail_job; ret = panfrost_lookup_bos(dev, file, args, job); if (ret) - goto fail; + goto fail_job; ret = panfrost_job_push(job); if (ret) - goto fail; + goto fail_job; /* Update the return sync object for the job */ - sync_out = drm_syncobj_find(file, args->out_sync); - if (sync_out) { + if (sync_out) drm_syncobj_replace_fence(sync_out, job->render_done_fence); - drm_syncobj_put(sync_out); - } -fail: +fail_job: panfrost_job_put(job); +fail_out_sync: + drm_syncobj_put(sync_out); return ret; } -- cgit v1.2.3 From d9b631f0a0c43ee180845d0a994d2cf4948a2eae Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Fri, 3 May 2019 16:31:42 +0100 Subject: drm/panfrost: Set DMA masks earlier The DMA masks need to be set correctly before any DMA API activity kicks off, and the current point in panfrost_probe() is way too late in that regard. since panfrost_mmu_init() has already set up a live address space and DMA-mapped MMU pagetables. We can't set masks until we've queried the appropriate value from MMU_FEATURES, but as soon as reasonably possible after that should suffice. Signed-off-by: Robin Murphy Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/64361b929a5c61d2ab9580262ecb3d369164cfcb.1556195258.git.robin.murphy@arm.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 5 ----- drivers/gpu/drm/panfrost/panfrost_gpu.c | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 0f2863cb8077..27d04bd4870a 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -3,8 +3,6 @@ /* Copyright 2019 Linaro, Ltd., Rob Herring */ /* Copyright 2019 Collabora ltd. */ -#include -#include #include #include #include @@ -401,9 +399,6 @@ static int panfrost_probe(struct platform_device *pdev) goto err_out0; } - dma_set_mask_and_coherent(pfdev->dev, - DMA_BIT_MASK(FIELD_GET(0xff00, pfdev->features.mmu_features))); - err = panfrost_devfreq_init(pfdev); if (err) { dev_err(&pdev->dev, "Fatal error during devfreq init\n"); diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c index aceaf6e44a09..42511fc1fea0 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -2,8 +2,10 @@ /* Copyright 2018 Marty E. Plummer */ /* Copyright 2019 Linaro, Ltd., Rob Herring */ /* Copyright 2019 Collabora ltd. */ +#include #include #include +#include #include #include #include @@ -332,6 +334,9 @@ int panfrost_gpu_init(struct panfrost_device *pfdev) panfrost_gpu_init_features(pfdev); + dma_set_mask_and_coherent(pfdev->dev, + DMA_BIT_MASK(FIELD_GET(0xff00, pfdev->features.mmu_features))); + irq = platform_get_irq_byname(to_platform_device(pfdev->dev), "gpu"); if (irq <= 0) return -ENODEV; -- cgit v1.2.3 From f4a3c6a44b351fc2cd79b1494606c84c46865024 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Fri, 3 May 2019 16:31:43 +0100 Subject: drm/panfrost: Disable PM on probe failure Make sure to disable runtime PM again if probe fails after we've enabled it. Otherwise, any subsequent attempt to re-probe starts triggering "Unbalanced pm_runtime_enable!" assertions from the driver core. Signed-off-by: Robin Murphy Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/2487391e7646cabbc52e9b4c20182e39d3f61859.1556195258.git.robin.murphy@arm.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 27d04bd4870a..2f5c8867fc1d 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -418,6 +418,7 @@ static int panfrost_probe(struct platform_device *pdev) err_out1: panfrost_device_fini(pfdev); err_out0: + pm_runtime_disable(pfdev->dev); drm_dev_put(ddev); return err; } -- cgit v1.2.3 From 5450f3615c09603f13e81e182d2e0ddec0361082 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Fri, 3 May 2019 16:31:44 +0100 Subject: drm/panfrost: Don't scream about deferred probe Probe deferral is far from "fatal". Signed-off-by: Robin Murphy Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/b6ff1f18ac0612f29fd2e3336d6663b7e02db572.1556195258.git.robin.murphy@arm.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 2f5c8867fc1d..94b0819ad50b 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -395,13 +395,15 @@ static int panfrost_probe(struct platform_device *pdev) err = panfrost_device_init(pfdev); if (err) { - dev_err(&pdev->dev, "Fatal error during GPU init\n"); + if (err != -EPROBE_DEFER) + dev_err(&pdev->dev, "Fatal error during GPU init\n"); goto err_out0; } err = panfrost_devfreq_init(pfdev); if (err) { - dev_err(&pdev->dev, "Fatal error during devfreq init\n"); + if (err != -EPROBE_DEFER) + dev_err(&pdev->dev, "Fatal error during devfreq init\n"); goto err_out1; } -- cgit v1.2.3 From b208146b0c8f84a1d6a3df0cfa45238e2190c8a2 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Fri, 3 May 2019 16:31:45 +0100 Subject: drm/panfrost: Show stored feature registers Re-reading the feature registers for the sake of displaying the raw values seems pointless, and in fact showing the copies that we've already read and stored is arguably more useful in terms of giving exposure to any potential bugs in that part of the process. Signed-off-by: Robin Murphy Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/ce5e414adb008baeed9e2ceb9c88f28d5c74ea42.1556195258.git.robin.murphy@arm.com --- drivers/gpu/drm/panfrost/panfrost_gpu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c index 42511fc1fea0..58ef25573cda 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -278,13 +278,13 @@ static void panfrost_gpu_init_features(struct panfrost_device *pfdev) pfdev->features.hw_issues); dev_info(pfdev->dev, "Features: L2:0x%08x Shader:0x%08x Tiler:0x%08x Mem:0x%0x MMU:0x%08x AS:0x%x JS:0x%x", - gpu_read(pfdev, GPU_L2_FEATURES), - gpu_read(pfdev, GPU_CORE_FEATURES), - gpu_read(pfdev, GPU_TILER_FEATURES), - gpu_read(pfdev, GPU_MEM_FEATURES), - gpu_read(pfdev, GPU_MMU_FEATURES), - gpu_read(pfdev, GPU_AS_PRESENT), - gpu_read(pfdev, GPU_JS_PRESENT)); + pfdev->features.l2_features, + pfdev->features.core_features, + pfdev->features.tiler_features, + pfdev->features.mem_features, + pfdev->features.mmu_features, + pfdev->features.as_present, + pfdev->features.js_present); dev_info(pfdev->dev, "shader_present=0x%0llx l2_present=0x%0llx", pfdev->features.shader_present, pfdev->features.l2_present); -- cgit v1.2.3 From 30d62d4453e49f85dd17b2ba60bbb68b6593dba0 Mon Sep 17 00:00:00 2001 From: Andres Rodriguez Date: Thu, 2 May 2019 15:31:57 -0400 Subject: drm: add non-desktop quirk for Valve HMDs Add vendor/product pairs for the Valve Index HMDs. Signed-off-by: Andres Rodriguez Cc: Dave Airlie Cc: # v4.15 Signed-off-by: Dave Airlie Link: https://patchwork.freedesktop.org/patch/msgid/20190502193157.15692-1-andresx7@gmail.com --- drivers/gpu/drm/drm_edid.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 2c22ea446075..649cfd8b4200 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -162,6 +162,25 @@ static const struct edid_quirk { /* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/ { "ETR", 13896, EDID_QUIRK_FORCE_8BPC }, + /* Valve Index Headset */ + { "VLV", 0x91a8, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b0, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b1, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b2, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b3, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b4, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b5, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b6, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b7, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b8, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91b9, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91ba, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91bb, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91bc, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91bd, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91be, EDID_QUIRK_NON_DESKTOP }, + { "VLV", 0x91bf, EDID_QUIRK_NON_DESKTOP }, + /* HTC Vive and Vive Pro VR Headsets */ { "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP }, { "HVR", 0xaa02, EDID_QUIRK_NON_DESKTOP }, -- cgit v1.2.3 From 55223394d56bab42ebac71ba52e0fd8bfdc6fc07 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:11:53 +0000 Subject: drm/komeda: Add sysfs attribute: core_id and config_id Add two sysfs node: core_id, config_id, user can read them to fetch the HW product information. Also, use memset to initialize config_id, rather than quirky C syntax. Courtesy of Nathan Chancellor . Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Nathan Chancellor [Merged Nathan's patch that uses memset to initialize config_id into original patch as the fixes tag changed due to rebase, reworded the commit to reference the merged patch] Signed-off-by: Liviu Dudau --- .../gpu/drm/arm/display/include/malidp_product.h | 12 ++++++ drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 50 ++++++++++++++++++++++ drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 2 + drivers/gpu/drm/arm/display/komeda/komeda_drv.c | 7 +++ 4 files changed, 71 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h b/drivers/gpu/drm/arm/display/include/malidp_product.h index b35fc5db866b..1053b11352eb 100644 --- a/drivers/gpu/drm/arm/display/include/malidp_product.h +++ b/drivers/gpu/drm/arm/display/include/malidp_product.h @@ -20,4 +20,16 @@ /* Mali-display product IDs */ #define MALIDP_D71_PRODUCT_ID 0x0071 +union komeda_config_id { + struct { + __u32 max_line_sz:16, + n_pipelines:2, + n_scalers:2, /* number of scalers per pipeline */ + n_layers:3, /* number of layers per pipeline */ + n_richs:3, /* number of rich layers per pipeline */ + reserved_bits:6; + }; + __u32 value; +}; + #endif /* _MALIDP_PRODUCT_H_ */ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index 131f26692a3d..ca3599e4a4d3 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -59,6 +59,48 @@ static void komeda_debugfs_init(struct komeda_dev *mdev) } #endif +static ssize_t +core_id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct komeda_dev *mdev = dev_to_mdev(dev); + + return snprintf(buf, PAGE_SIZE, "0x%08x\n", mdev->chip.core_id); +} +static DEVICE_ATTR_RO(core_id); + +static ssize_t +config_id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct komeda_dev *mdev = dev_to_mdev(dev); + struct komeda_pipeline *pipe = mdev->pipelines[0]; + union komeda_config_id config_id; + int i; + + memset(&config_id, 0, sizeof(config_id)); + + config_id.max_line_sz = pipe->layers[0]->hsize_in.end; + config_id.n_pipelines = mdev->n_pipelines; + config_id.n_scalers = pipe->n_scalers; + config_id.n_layers = pipe->n_layers; + config_id.n_richs = 0; + for (i = 0; i < pipe->n_layers; i++) { + if (pipe->layers[i]->layer_type == KOMEDA_FMT_RICH_LAYER) + config_id.n_richs++; + } + return snprintf(buf, PAGE_SIZE, "0x%08x\n", config_id.value); +} +static DEVICE_ATTR_RO(config_id); + +static struct attribute *komeda_sysfs_entries[] = { + &dev_attr_core_id.attr, + &dev_attr_config_id.attr, + NULL, +}; + +static struct attribute_group komeda_sysfs_attr_group = { + .attrs = komeda_sysfs_entries, +}; + static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np) { struct komeda_pipeline *pipe; @@ -207,6 +249,12 @@ struct komeda_dev *komeda_dev_create(struct device *dev) goto err_cleanup; } + err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group); + if (err) { + DRM_ERROR("create sysfs group failed.\n"); + goto err_cleanup; + } + #ifdef CONFIG_DEBUG_FS komeda_debugfs_init(mdev); #endif @@ -224,6 +272,8 @@ void komeda_dev_destroy(struct komeda_dev *mdev) struct komeda_dev_funcs *funcs = mdev->funcs; int i; + sysfs_remove_group(&dev->kobj, &komeda_sysfs_attr_group); + #ifdef CONFIG_DEBUG_FS debugfs_remove_recursive(mdev->debugfs_root); #endif diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h index 8acd25afb3e9..0c3e32b596d9 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h @@ -190,4 +190,6 @@ d71_identify(u32 __iomem *reg, struct komeda_chip_info *chip); struct komeda_dev *komeda_dev_create(struct device *dev); void komeda_dev_destroy(struct komeda_dev *mdev); +struct komeda_dev *dev_to_mdev(struct device *dev); + #endif /*_KOMEDA_DEV_H_*/ diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c index 2bdd189b041d..0285fd37a016 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c @@ -17,6 +17,13 @@ struct komeda_drv { struct komeda_kms_dev *kms; }; +struct komeda_dev *dev_to_mdev(struct device *dev) +{ + struct komeda_drv *mdrv = dev_get_drvdata(dev); + + return mdrv ? mdrv->mdev : NULL; +} + static void komeda_unbind(struct device *dev) { struct komeda_drv *mdrv = dev_get_drvdata(dev); -- cgit v1.2.3 From 8c134d13a07884048756dc5de7cd4526b440483b Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Tue, 22 Jan 2019 11:12:02 +0000 Subject: drm/komeda: Expose bus_width to Komeda-CORE CHIP set bus_width according to the HW configuration, and CORE will use it as buffer alignment. v2: Rebase Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 1 + drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c index b01b628019ba..34506ef7ad40 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c @@ -520,6 +520,7 @@ d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip) chip->arch_id = malidp_read32(reg_base, GLB_ARCH_ID); chip->core_id = malidp_read32(reg_base, GLB_CORE_ID); chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO); + chip->bus_width = D71_BUS_WIDTH_16_BYTES; return &d71_chip_funcs; } diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index e8573b03021f..86f6542afb40 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -26,10 +26,10 @@ static int komeda_gem_cma_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args) { - u32 alignment = 16; /* TODO get alignment from dev */ + struct komeda_dev *mdev = dev->dev_private; + u32 pitch = DIV_ROUND_UP(args->width * args->bpp, 8); - args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8), - alignment); + args->pitch = ALIGN(pitch, mdev->chip.bus_width); return drm_gem_cma_dumb_create_internal(file, dev, args); } -- cgit v1.2.3 From 8c919745ee1c4d8d811a1e015d637d17aa78fe26 Mon Sep 17 00:00:00 2001 From: "james qian wang (Arm Technology China)" Date: Wed, 24 Apr 2019 06:48:11 +0100 Subject: drm/komeda: Fixed warning: Function parameter or member not described Fixed the warnings: Function parameter or member 'xxx' not described when make htmldocs This patch depends on: - https://patchwork.freedesktop.org/series/54448/ - https://patchwork.freedesktop.org/series/54449/ - https://patchwork.freedesktop.org/series/54450/ v2: Rebase and add reporter Reported-by: kbuild test robot Signed-off-by: James Qian Wang (Arm Technology China) Signed-off-by: Liviu Dudau --- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 14 +++++-- drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 16 ++++++-- .../drm/arm/display/komeda/komeda_framebuffer.h | 9 ++++- drivers/gpu/drm/arm/display/komeda/komeda_kms.h | 18 +++++++-- .../gpu/drm/arm/display/komeda/komeda_pipeline.h | 43 ++++++++++++++++------ drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 8 ++++ 6 files changed, 85 insertions(+), 23 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 053b1e3e74be..d335fec1b727 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -18,9 +18,17 @@ #include "komeda_dev.h" #include "komeda_kms.h" -/* crtc_atomic_check is the final check stage, so beside build a display data - * pipeline according the crtc_state, but still needs to release/disable the - * unclaimed pipeline resources. +/** + * komeda_crtc_atomic_check - build display output data flow + * @crtc: DRM crtc + * @state: the crtc state object + * + * crtc_atomic_check is the final check stage, so beside build a display data + * pipeline according to the crtc_state, but still needs to release or disable + * the unclaimed pipeline resources. + * + * RETURNS: + * Zero for success or -errno */ static int komeda_crtc_atomic_check(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h index 0c3e32b596d9..29e03c4e1ffc 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h @@ -120,7 +120,7 @@ struct komeda_dev_funcs { int master_pipe, u32 active_pipes); }; -/** +/* * DISPLAY_MODE describes how many display been enabled, and which will be * passed to CHIP by &komeda_dev_funcs->change_opmode(), then CHIP can do the * pipeline resources assignment according to this usage hint. @@ -145,24 +145,31 @@ enum { * control-abilites of device. */ struct komeda_dev { + /** @dev: the base device structure */ struct device *dev; + /** @reg_base: the base address of komeda io space */ u32 __iomem *reg_base; + /** @chip: the basic chip information */ struct komeda_chip_info chip; /** @fmt_tbl: initialized by &komeda_dev_funcs->init_format_table */ struct komeda_format_caps_table fmt_tbl; /** @pclk: APB clock for register access */ struct clk *pclk; - /** @mck: HW main engine clk */ + /** @mclk: HW main engine clk */ struct clk *mclk; /** @irq: irq number */ int irq; - struct mutex lock; /* used to protect dpmode */ - u32 dpmode; /* current display mode */ + /** @lock: used to protect dpmode */ + struct mutex lock; + /** @dpmode: current display mode */ + u32 dpmode; + /** @n_pipelines: the number of pipe in @pipelines */ int n_pipelines; + /** @pipelines: the komeda pipelines */ struct komeda_pipeline *pipelines[KOMEDA_MAX_PIPELINES]; /** @funcs: chip funcs to access to HW */ @@ -175,6 +182,7 @@ struct komeda_dev { */ void *chip_data; + /** @debugfs_root: root directory of komeda debugfs */ struct dentry *debugfs_root; }; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h index 0de2e4a2afd2..ea2fe190c1e3 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.h @@ -10,11 +10,16 @@ #include #include "komeda_format_caps.h" -/** struct komeda_fb - entend drm_framebuffer with komeda attribute */ +/** + * struct komeda_fb - Entending drm_framebuffer with komeda attribute + */ struct komeda_fb { /** @base: &drm_framebuffer */ struct drm_framebuffer base; - /* @format_caps: &komeda_format_caps */ + /** + * @format_caps: + * extends drm_format_info for komeda specific information + */ const struct komeda_format_caps *format_caps; /** @aligned_w: aligned frame buffer width */ u32 aligned_w; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index 7ec571d3c240..ac3d9209b4d9 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -15,7 +15,9 @@ #include