From 2312f984285495117d559c1e928dee465a32bc49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 5 Dec 2018 20:43:02 +0100 Subject: drm/v3d: fix broken build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I missed one case during the recent revert of the replace_fence interface change. Fixes: 0b258ed1a219 drm: revert "expand replace_fence to support timeline point v2" Signed-off-by: Christian König Acked-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/266134/ --- drivers/gpu/drm/v3d/v3d_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index cb99e53f7607..05ca6319065e 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -716,7 +716,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, /* Update the return sync object */ sync_out = drm_syncobj_find(file_priv, args->out_sync); if (sync_out) { - drm_syncobj_replace_fence(sync_out, 0, sched_done_fence); + drm_syncobj_replace_fence(sync_out, sched_done_fence); drm_syncobj_put(sync_out); } dma_fence_put(sched_done_fence); -- cgit v1.2.3 From b312d8ca3a7cebe19941d969a51f2b7f899b81e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 14 Nov 2018 16:11:06 +0100 Subject: dma-buf: make fence sequence numbers 64 bit v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For a lot of use cases we need 64bit sequence numbers. Currently drivers overload the dma_fence structure to store the additional bits. Stop doing that and make the sequence number in the dma_fence always 64bit. For compatibility with hardware which can do only 32bit sequences the comparisons in __dma_fence_is_later only takes the lower 32bits as significant when the upper 32bits are all zero. v2: change the logic in __dma_fence_is_later Signed-off-by: Christian König Reviewed-by: Chunming Zhou Link: https://patchwork.freedesktop.org/patch/266927/ --- drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | 2 +- drivers/gpu/drm/i915/i915_sw_fence.c | 2 +- drivers/gpu/drm/i915/intel_engine_cs.c | 2 +- drivers/gpu/drm/vgem/vgem_fence.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 12f2bf97611f..bfaf5c6323be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c @@ -388,7 +388,7 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager, soffset, eoffset, eoffset - soffset); if (i->fence) - seq_printf(m, " protected by 0x%08x on context %llu", + seq_printf(m, " protected by 0x%016llx on context %llu", i->fence->seqno, i->fence->context); seq_printf(m, "\n"); diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 6dbeed079ae5..11bcdabd5177 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -393,7 +393,7 @@ static void timer_i915_sw_fence_wake(struct timer_list *t) if (!fence) return; - pr_notice("Asynchronous wait on fence %s:%s:%x timed out (hint:%pS)\n", + pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%pS)\n", cb->dma->ops->get_driver_name(cb->dma), cb->dma->ops->get_timeline_name(cb->dma), cb->dma->seqno, diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 759c0fd58f8c..dfafa79171df 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -1239,7 +1239,7 @@ static void print_request(struct drm_printer *m, x = print_sched_attr(rq->i915, &rq->sched.attr, buf, x, sizeof(buf)); - drm_printf(m, "%s%x%s [%llx:%x]%s @ %dms: %s\n", + drm_printf(m, "%s%x%s [%llx:%llx]%s @ %dms: %s\n", prefix, rq->global_seqno, i915_request_completed(rq) ? "!" : "", diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c index c1c420afe2dd..eb17c0cd3727 100644 --- a/drivers/gpu/drm/vgem/vgem_fence.c +++ b/drivers/gpu/drm/vgem/vgem_fence.c @@ -53,13 +53,13 @@ static void vgem_fence_release(struct dma_fence *base) static void vgem_fence_value_str(struct dma_fence *fence, char *str, int size) { - snprintf(str, size, "%u", fence->seqno); + snprintf(str, size, "%llu", fence->seqno); } static void vgem_fence_timeline_value_str(struct dma_fence *fence, char *str, int size) { - snprintf(str, size, "%u", + snprintf(str, size, "%llu", dma_fence_is_signaled(fence) ? fence->seqno : 0); } -- cgit v1.2.3 From dd847a7069747f1963962aee56a5694fbcc40caf Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 7 Dec 2018 14:34:28 +0200 Subject: drm/i915: Compile fix for 64b dma-fence seqno MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many errs of the form: drivers/gpu/drm/i915/selftests/intel_hangcheck.c: In function ‘__igt_reset_evict_vma’: ./include/linux/kern_levels.h:5:18: error: format ‘%x’ expects argument of type ‘unsigned int’, but argum Fixes: b312d8ca3a7c ("dma-buf: make fence sequence numbers 64 bit v2") Cc: Christian König Cc: Chunming Zhou 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/20181207123428.16257-1-mika.kuoppala@linux.intel.com --- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- drivers/gpu/drm/i915/i915_gem_context.c | 8 ++++---- drivers/gpu/drm/i915/i915_request.c | 12 ++++++------ drivers/gpu/drm/i915/intel_lrc.c | 6 +++--- drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 14 +++++++------- 5 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c55b1f75c980..b70de1a9e899 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3187,7 +3187,7 @@ i915_gem_reset_request(struct intel_engine_cs *engine, */ if (i915_request_completed(request)) { - GEM_TRACE("%s pardoned global=%d (fence %llx:%d), current %d\n", + GEM_TRACE("%s pardoned global=%d (fence %llx:%lld), current %d\n", engine->name, request->global_seqno, request->fence.context, request->fence.seqno, intel_engine_get_seqno(engine)); @@ -3321,7 +3321,7 @@ static void nop_complete_submit_request(struct i915_request *request) { unsigned long flags; - GEM_TRACE("%s fence %llx:%d -> -EIO\n", + GEM_TRACE("%s fence %llx:%lld -> -EIO\n", request->engine->name, request->fence.context, request->fence.seqno); dma_fence_set_error(&request->fence, -EIO); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index b97963db0287..66117a8281ef 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -653,7 +653,7 @@ last_request_on_engine(struct i915_timeline *timeline, rq = i915_gem_active_raw(&timeline->last_request, &engine->i915->drm.struct_mutex); if (rq && rq->engine == engine) { - GEM_TRACE("last request for %s on engine %s: %llx:%d\n", + GEM_TRACE("last request for %s on engine %s: %llx:%llu\n", timeline->name, engine->name, rq->fence.context, rq->fence.seqno); GEM_BUG_ON(rq->timeline != timeline); @@ -690,14 +690,14 @@ static bool engine_has_kernel_context_barrier(struct intel_engine_cs *engine) * switch-to-kernel-context? */ if (!i915_timeline_sync_is_later(barrier, &rq->fence)) { - GEM_TRACE("%s needs barrier for %llx:%d\n", + GEM_TRACE("%s needs barrier for %llx:%lld\n", ring->timeline->name, rq->fence.context, rq->fence.seqno); return false; } - GEM_TRACE("%s has barrier after %llx:%d\n", + GEM_TRACE("%s has barrier after %llx:%lld\n", ring->timeline->name, rq->fence.context, rq->fence.seqno); @@ -753,7 +753,7 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *i915) if (prev->gem_context == i915->kernel_context) continue; - GEM_TRACE("add barrier on %s for %llx:%d\n", + GEM_TRACE("add barrier on %s for %llx:%lld\n", engine->name, prev->fence.context, prev->fence.seqno); diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 71107540581d..191703986c7b 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -267,7 +267,7 @@ static void free_capture_list(struct i915_request *request) static void __retire_engine_request(struct intel_engine_cs *engine, struct i915_request *rq) { - GEM_TRACE("%s(%s) fence %llx:%d, global=%d, current %d\n", + GEM_TRACE("%s(%s) fence %llx:%lld, global=%d, current %d\n", __func__, engine->name, rq->fence.context, rq->fence.seqno, rq->global_seqno, @@ -329,7 +329,7 @@ static void i915_request_retire(struct i915_request *request) { struct i915_gem_active *active, *next; - GEM_TRACE("%s fence %llx:%d, global=%d, current %d\n", + GEM_TRACE("%s fence %llx:%lld, global=%d, current %d\n", request->engine->name, request->fence.context, request->fence.seqno, request->global_seqno, @@ -392,7 +392,7 @@ void i915_request_retire_upto(struct i915_request *rq) struct intel_ring *ring = rq->ring; struct i915_request *tmp; - GEM_TRACE("%s fence %llx:%d, global=%d, current %d\n", + GEM_TRACE("%s fence %llx:%lld, global=%d, current %d\n", rq->engine->name, rq->fence.context, rq->fence.seqno, rq->global_seqno, @@ -433,7 +433,7 @@ void __i915_request_submit(struct i915_request *request) struct intel_engine_cs *engine = request->engine; u32 seqno; - GEM_TRACE("%s fence %llx:%d -> global=%d, current %d\n", + GEM_TRACE("%s fence %llx:%lld -> global=%d, current %d\n", engine->name, request->fence.context, request->fence.seqno, engine->timeline.seqno + 1, @@ -483,7 +483,7 @@ void __i915_request_unsubmit(struct i915_request *request) { struct intel_engine_cs *engine = request->engine; - GEM_TRACE("%s fence %llx:%d <- global=%d, current %d\n", + GEM_TRACE("%s fence %llx:%lld <- global=%d, current %d\n", engine->name, request->fence.context, request->fence.seqno, request->global_seqno, @@ -958,7 +958,7 @@ void i915_request_add(struct i915_request *request) struct i915_request *prev; u32 *cs; - GEM_TRACE("%s fence %llx:%d\n", + GEM_TRACE("%s fence %llx:%lld\n", engine->name, request->fence.context, request->fence.seqno); lockdep_assert_held(&request->i915->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 08fd9b12e4d7..9399db3260ad 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -450,7 +450,7 @@ static void execlists_submit_ports(struct intel_engine_cs *engine) desc = execlists_update_context(rq); GEM_DEBUG_EXEC(port[n].context_id = upper_32_bits(desc)); - GEM_TRACE("%s in[%d]: ctx=%d.%d, global=%d (fence %llx:%d) (current %d), prio=%d\n", + GEM_TRACE("%s in[%d]: ctx=%d.%d, global=%d (fence %llx:%lld) (current %d), prio=%d\n", engine->name, n, port[n].context_id, count, rq->global_seqno, @@ -743,7 +743,7 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) while (num_ports-- && port_isset(port)) { struct i915_request *rq = port_request(port); - GEM_TRACE("%s:port%u global=%d (fence %llx:%d), (current %d)\n", + GEM_TRACE("%s:port%u global=%d (fence %llx:%lld), (current %d)\n", rq->engine->name, (unsigned int)(port - execlists->port), rq->global_seqno, @@ -952,7 +952,7 @@ static void process_csb(struct intel_engine_cs *engine) EXECLISTS_ACTIVE_USER)); rq = port_unpack(port, &count); - GEM_TRACE("%s out[0]: ctx=%d.%d, global=%d (fence %llx:%d) (current %d), prio=%d\n", + GEM_TRACE("%s out[0]: ctx=%d.%d, global=%d (fence %llx:%lld) (current %d), prio=%d\n", engine->name, port->context_id, count, rq ? rq->global_seqno : 0, diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index defe671130ab..33494d922fab 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -478,7 +478,7 @@ static int __igt_reset_engine(struct drm_i915_private *i915, bool active) if (!wait_until_running(&h, rq)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s: Failed to start request %x, at %x\n", + pr_err("%s: Failed to start request %llx, at %x\n", __func__, rq->fence.seqno, hws_seqno(&h, rq)); intel_engine_dump(engine, &p, "%s\n", engine->name); @@ -579,7 +579,7 @@ static int active_request_put(struct i915_request *rq) return 0; if (i915_request_wait(rq, 0, 5 * HZ) < 0) { - GEM_TRACE("%s timed out waiting for completion of fence %llx:%d, seqno %d.\n", + GEM_TRACE("%s timed out waiting for completion of fence %llx:%lld, seqno %d.\n", rq->engine->name, rq->fence.context, rq->fence.seqno, @@ -756,7 +756,7 @@ static int __igt_reset_engines(struct drm_i915_private *i915, if (!wait_until_running(&h, rq)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s: Failed to start request %x, at %x\n", + pr_err("%s: Failed to start request %llx, at %x\n", __func__, rq->fence.seqno, hws_seqno(&h, rq)); intel_engine_dump(engine, &p, "%s\n", engine->name); @@ -955,7 +955,7 @@ static int igt_reset_wait(void *arg) if (!wait_until_running(&h, rq)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s: Failed to start request %x, at %x\n", + pr_err("%s: Failed to start request %llx, at %x\n", __func__, rq->fence.seqno, hws_seqno(&h, rq)); intel_engine_dump(rq->engine, &p, "%s\n", rq->engine->name); @@ -1134,7 +1134,7 @@ static int __igt_reset_evict_vma(struct drm_i915_private *i915, if (!wait_until_running(&h, rq)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s: Failed to start request %x, at %x\n", + pr_err("%s: Failed to start request %llx, at %x\n", __func__, rq->fence.seqno, hws_seqno(&h, rq)); intel_engine_dump(rq->engine, &p, "%s\n", rq->engine->name); @@ -1329,7 +1329,7 @@ static int igt_reset_queue(void *arg) if (!wait_until_running(&h, prev)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s(%s): Failed to start request %x, at %x\n", + pr_err("%s(%s): Failed to start request %llx, at %x\n", __func__, engine->name, prev->fence.seqno, hws_seqno(&h, prev)); intel_engine_dump(engine, &p, @@ -1440,7 +1440,7 @@ static int igt_handle_error(void *arg) if (!wait_until_running(&h, rq)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s: Failed to start request %x, at %x\n", + pr_err("%s: Failed to start request %llx, at %x\n", __func__, rq->fence.seqno, hws_seqno(&h, rq)); intel_engine_dump(rq->engine, &p, "%s\n", rq->engine->name); -- cgit v1.2.3 From 2aa34fd5c7754824cf5488b61ac644f30d3c5c85 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 3 Dec 2018 14:24:34 -0800 Subject: drm/v3d: Drop unused v3d_flush_caches(). Now that I've specified how the end-of-pipeline flushing should work, we're never going to use this function. Signed-off-by: Eric Anholt Reviewed-by: Dave Emett Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-2-eric@anholt.net --- drivers/gpu/drm/v3d/v3d_drv.h | 1 - drivers/gpu/drm/v3d/v3d_gem.c | 21 --------------------- 2 files changed, 22 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index dcb772a19191..fdda3037f7af 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -308,7 +308,6 @@ void v3d_exec_put(struct v3d_exec_info *exec); void v3d_tfu_job_put(struct v3d_tfu_job *exec); void v3d_reset(struct v3d_dev *v3d); void v3d_invalidate_caches(struct v3d_dev *v3d); -void v3d_flush_caches(struct v3d_dev *v3d); /* v3d_irq.c */ void v3d_irq_init(struct v3d_dev *v3d); diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 05ca6319065e..dec94dc89659 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -175,20 +175,6 @@ v3d_invalidate_slices(struct v3d_dev *v3d, int core) V3D_SET_FIELD(0xf, V3D_SLCACTL_ICC)); } -/* Invalidates texture L2 cachelines */ -static void -v3d_invalidate_l2t(struct v3d_dev *v3d, int core) -{ - V3D_CORE_WRITE(core, - V3D_CTL_L2TCACTL, - V3D_L2TCACTL_L2TFLS | - V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAR, V3D_L2TCACTL_FLM)); - if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & - V3D_L2TCACTL_L2TFLS), 100)) { - DRM_ERROR("Timeout waiting for L2T invalidate\n"); - } -} - void v3d_invalidate_caches(struct v3d_dev *v3d) { @@ -199,13 +185,6 @@ v3d_invalidate_caches(struct v3d_dev *v3d) v3d_flush_l2t(v3d, 0); } -void -v3d_flush_caches(struct v3d_dev *v3d) -{ - v3d_invalidate_l1td(v3d, 0); - v3d_invalidate_l2t(v3d, 0); -} - static void v3d_attach_object_fences(struct v3d_bo **bos, int bo_count, struct dma_fence *fence) -- cgit v1.2.3 From 2e6dc3bd80478212e84addf1cafd6ec60674b884 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 3 Dec 2018 14:24:35 -0800 Subject: drm/v3d: Don't bother flushing L1TD at job start. This is the write combiner for TMU writes. You're supposed to flush that at job end if you had dirtied any cachelines. Flushing it at job start then doesn't make any sense. Signed-off-by: Eric Anholt Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") Reviewed-by: Dave Emett Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-3-eric@anholt.net --- drivers/gpu/drm/v3d/v3d_gem.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index dec94dc89659..f82c1ccfaeed 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -139,22 +139,10 @@ v3d_invalidate_l2(struct v3d_dev *v3d, int core) V3D_L2CACTL_L2CENA); } -static void -v3d_invalidate_l1td(struct v3d_dev *v3d, int core) -{ - V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); - if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & - V3D_L2TCACTL_L2TFLS), 100)) { - DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); - } -} - /* Invalidates texture L2 cachelines */ static void v3d_flush_l2t(struct v3d_dev *v3d, int core) { - v3d_invalidate_l1td(v3d, core); - V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_L2TFLS | V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); -- cgit v1.2.3 From 51c1b6f9eb3dbdec91b0e3c89f623e634c996bbb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 3 Dec 2018 14:24:36 -0800 Subject: drm/v3d: Drop the wait for L2T flush to complete. According to Dave, once you've started an L2T flush, all L2T accesses will be blocked until the flush completes. This fixes a consistent 3-4ms stall between the ioctl and running the job, and 3DMMES Taiji goes from 27fps to 110fps. v2: Leave a note about why we don't need to wait for completion. Signed-off-by: Eric Anholt Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") Reviewed-by: Dave Emett Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-4-eric@anholt.net --- drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index f82c1ccfaeed..2b378de23fbd 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -143,13 +143,13 @@ v3d_invalidate_l2(struct v3d_dev *v3d, int core) static void v3d_flush_l2t(struct v3d_dev *v3d, int core) { + /* While there is a busy bit (V3D_L2TCACTL_L2TFLS), we don't + * need to wait for completion before dispatching the job -- + * L2T accesses will be stalled until the flush has completed. + */ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_L2TFLS | V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM)); - if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & - V3D_L2TCACTL_L2TFLS), 100)) { - DRM_ERROR("Timeout waiting for L2T flush\n"); - } } /* Invalidates the slice caches. These are read-only caches. */ -- cgit v1.2.3 From 7b9d2fe4350a9c12f66ad8cc78c1098226f6c3c2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 3 Dec 2018 14:24:37 -0800 Subject: drm/v3d: Stop trying to flush L2C on V3D 3.3+ This cache was replaced with the slice accessing the L2T in the newer generations. Noted by Dave during review. Signed-off-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-5-eric@anholt.net Reviewed-by: Dave Emett --- drivers/gpu/drm/v3d/v3d_gem.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 2b378de23fbd..06525ea9ec50 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -130,10 +130,15 @@ v3d_flush_l3(struct v3d_dev *v3d) } } -/* Invalidates the (read-only) L2 cache. */ +/* Invalidates the (read-only) L2C cache. This was the L2 cache for + * uniforms and instructions on V3D 3.2. + */ static void -v3d_invalidate_l2(struct v3d_dev *v3d, int core) +v3d_invalidate_l2c(struct v3d_dev *v3d, int core) { + if (v3d->ver > 32) + return; + V3D_CORE_WRITE(core, V3D_CTL_L2CACTL, V3D_L2CACTL_L2CCLR | V3D_L2CACTL_L2CENA); @@ -168,7 +173,7 @@ v3d_invalidate_caches(struct v3d_dev *v3d) { v3d_flush_l3(v3d); - v3d_invalidate_l2(v3d, 0); + v3d_invalidate_l2c(v3d, 0); v3d_invalidate_slices(v3d, 0); v3d_flush_l2t(v3d, 0); } -- cgit v1.2.3 From aa5beec32e8b78bfcf621e3c3daebfb1644b6365 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 3 Dec 2018 14:24:38 -0800 Subject: drm/v3d: Invalidate the caches from the outside in. This would be a fairly obscure race, but let's make sure we don't ever lose it. Signed-off-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20181203222438.25417-6-eric@anholt.net Reviewed-by: Dave Emett --- drivers/gpu/drm/v3d/v3d_gem.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 06525ea9ec50..803f31467ec1 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -171,11 +171,15 @@ v3d_invalidate_slices(struct v3d_dev *v3d, int core) void v3d_invalidate_caches(struct v3d_dev *v3d) { + /* Invalidate the caches from the outside in. That way if + * another CL's concurrent use of nearby memory were to pull + * an invalidated cacheline back in, we wouldn't leave stale + * data in the inner cache. + */ v3d_flush_l3(v3d); - v3d_invalidate_l2c(v3d, 0); - v3d_invalidate_slices(v3d, 0); v3d_flush_l2t(v3d, 0); + v3d_invalidate_slices(v3d, 0); } static void -- cgit v1.2.3 From 8e75d582db02bcb171d65ec71eecbd3072a5fd3a Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 7 Dec 2018 09:36:05 +0100 Subject: drm/vc4: Fix negative X/Y positioning on SAND planes Commit 3e407417b192 ("drm/vc4: Fix X/Y positioning of planes using T_TILES modifier") fixed the problem with T_TILES format, but left things in a non-working state for SAND formats. Address that now. Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20181207083606.15449-1-boris.brezillon@bootlin.com --- drivers/gpu/drm/vc4/vc4_plane.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 75db62cbe468..fb1214b91a25 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -595,6 +595,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, case DRM_FORMAT_MOD_BROADCOM_SAND128: case DRM_FORMAT_MOD_BROADCOM_SAND256: { uint32_t param = fourcc_mod_broadcom_param(fb->modifier); + u32 tile_w, tile, x_off, pix_per_tile; /* Column-based NV12 or RGBA. */ @@ -614,12 +615,15 @@ static int vc4_plane_mode_set(struct drm_plane *plane, switch (base_format_mod) { case DRM_FORMAT_MOD_BROADCOM_SAND64: tiling = SCALER_CTL0_TILING_64B; + tile_w = 64; break; case DRM_FORMAT_MOD_BROADCOM_SAND128: tiling = SCALER_CTL0_TILING_128B; + tile_w = 128; break; case DRM_FORMAT_MOD_BROADCOM_SAND256: tiling = SCALER_CTL0_TILING_256B_OR_T; + tile_w = 256; break; default: break; @@ -630,6 +634,23 @@ static int vc4_plane_mode_set(struct drm_plane *plane, return -EINVAL; } + pix_per_tile = tile_w / fb->format->cpp[0]; + tile = vc4_state->src_x / pix_per_tile; + x_off = vc4_state->src_x % pix_per_tile; + + /* Adjust the base pointer to the first pixel to be scanned + * out. + */ + for (i = 0; i < num_planes; i++) { + vc4_state->offsets[i] += param * tile_w * tile; + vc4_state->offsets[i] += vc4_state->src_y / + (i ? v_subsample : 1) * + tile_w; + vc4_state->offsets[i] += x_off / + (i ? h_subsample : 1) * + fb->format->cpp[i]; + } + pitch0 = VC4_SET_FIELD(param, SCALER_TILE_HEIGHT); break; } -- cgit v1.2.3 From 7cd3cf3540a37072c647b8b5120a80de5bb3d199 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 7 Dec 2018 09:36:06 +0100 Subject: drm/vc4: Add support for X/Y reflection Add support for X/Y reflection when the plane is using linear or T-tiled formats. X/Y reflection hasn't been tested on SAND formats, so we reject them until proper testing/debugging has been done. Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20181207083606.15449-2-boris.brezillon@bootlin.com --- drivers/gpu/drm/vc4/vc4_plane.c | 59 ++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index fb1214b91a25..283abd7d1e9b 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -492,8 +492,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane, bool mix_plane_alpha; bool covers_screen; u32 scl0, scl1, pitch0; - u32 tiling; + u32 tiling, src_y; u32 hvs_format = format->hvs; + unsigned int rotation; int ret, i; if (vc4_state->dlist_initialized) @@ -520,6 +521,16 @@ static int vc4_plane_mode_set(struct drm_plane *plane, h_subsample = drm_format_horz_chroma_subsampling(format->drm); v_subsample = drm_format_vert_chroma_subsampling(format->drm); + rotation = drm_rotation_simplify(state->rotation, + DRM_MODE_ROTATE_0 | + DRM_MODE_REFLECT_X | + DRM_MODE_REFLECT_Y); + + /* We must point to the last line when Y reflection is enabled. */ + src_y = vc4_state->src_y; + if (rotation & DRM_MODE_REFLECT_Y) + src_y += vc4_state->src_h[0] - 1; + switch (base_format_mod) { case DRM_FORMAT_MOD_LINEAR: tiling = SCALER_CTL0_TILING_LINEAR; @@ -529,9 +540,10 @@ static int vc4_plane_mode_set(struct drm_plane *plane, * out. */ for (i = 0; i < num_planes; i++) { - vc4_state->offsets[i] += vc4_state->src_y / + vc4_state->offsets[i] += src_y / (i ? v_subsample : 1) * fb->pitches[i]; + vc4_state->offsets[i] += vc4_state->src_x / (i ? h_subsample : 1) * fb->format->cpp[i]; @@ -557,22 +569,38 @@ static int vc4_plane_mode_set(struct drm_plane *plane, u32 tiles_w = fb->pitches[0] >> (tile_size_shift - tile_h_shift); u32 tiles_l = vc4_state->src_x >> tile_w_shift; u32 tiles_r = tiles_w - tiles_l; - u32 tiles_t = vc4_state->src_y >> tile_h_shift; + u32 tiles_t = src_y >> tile_h_shift; /* Intra-tile offsets, which modify the base address (the * SCALER_PITCH0_TILE_Y_OFFSET tells HVS how to walk from that * base address). */ - u32 tile_y = (vc4_state->src_y >> 4) & 1; - u32 subtile_y = (vc4_state->src_y >> 2) & 3; - u32 utile_y = vc4_state->src_y & 3; + u32 tile_y = (src_y >> 4) & 1; + u32 subtile_y = (src_y >> 2) & 3; + u32 utile_y = src_y & 3; u32 x_off = vc4_state->src_x & tile_w_mask; - u32 y_off = vc4_state->src_y & tile_h_mask; + u32 y_off = src_y & tile_h_mask; + + /* When Y reflection is requested we must set the + * SCALER_PITCH0_TILE_LINE_DIR flag to tell HVS that all lines + * after the initial one should be fetched in descending order, + * which makes sense since we start from the last line and go + * backward. + * Don't know why we need y_off = max_y_off - y_off, but it's + * definitely required (I guess it's also related to the "going + * backward" situation). + */ + if (rotation & DRM_MODE_REFLECT_Y) { + y_off = tile_h_mask - y_off; + pitch0 = SCALER_PITCH0_TILE_LINE_DIR; + } else { + pitch0 = 0; + } tiling = SCALER_CTL0_TILING_256B_OR_T; - pitch0 = (VC4_SET_FIELD(x_off, SCALER_PITCH0_SINK_PIX) | - VC4_SET_FIELD(y_off, SCALER_PITCH0_TILE_Y_OFFSET) | - VC4_SET_FIELD(tiles_l, SCALER_PITCH0_TILE_WIDTH_L) | - VC4_SET_FIELD(tiles_r, SCALER_PITCH0_TILE_WIDTH_R)); + pitch0 |= (VC4_SET_FIELD(x_off, SCALER_PITCH0_SINK_PIX) | + VC4_SET_FIELD(y_off, SCALER_PITCH0_TILE_Y_OFFSET) | + VC4_SET_FIELD(tiles_l, SCALER_PITCH0_TILE_WIDTH_L) | + VC4_SET_FIELD(tiles_r, SCALER_PITCH0_TILE_WIDTH_R)); vc4_state->offsets[0] += tiles_t * (tiles_w << tile_size_shift); vc4_state->offsets[0] += subtile_y << 8; vc4_state->offsets[0] += utile_y << 4; @@ -643,7 +671,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane, */ for (i = 0; i < num_planes; i++) { vc4_state->offsets[i] += param * tile_w * tile; - vc4_state->offsets[i] += vc4_state->src_y / + vc4_state->offsets[i] += src_y / (i ? v_subsample : 1) * tile_w; vc4_state->offsets[i] += x_off / @@ -664,6 +692,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane, /* Control word */ vc4_dlist_write(vc4_state, SCALER_CTL0_VALID | + (rotation & DRM_MODE_REFLECT_X ? SCALER_CTL0_HFLIP : 0) | + (rotation & DRM_MODE_REFLECT_Y ? SCALER_CTL0_VFLIP : 0) | VC4_SET_FIELD(SCALER_CTL0_RGBA_EXPAND_ROUND, SCALER_CTL0_RGBA_EXPAND) | (format->pixel_order << SCALER_CTL0_ORDER_SHIFT) | (hvs_format << SCALER_CTL0_PIXEL_FORMAT_SHIFT) | @@ -1144,6 +1174,11 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, drm_plane_helper_add(plane, &vc4_plane_helper_funcs); drm_plane_create_alpha_property(plane); + drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, + DRM_MODE_ROTATE_0 | + DRM_MODE_ROTATE_180 | + DRM_MODE_REFLECT_X | + DRM_MODE_REFLECT_Y); return plane; } -- cgit v1.2.3 From 16bff572cc660f19e58c99941368dea050b36a05 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 28 Nov 2018 23:12:34 +0100 Subject: drm/dp-mst-helper: Remove hotplug callback When everyone implements it exactly the same way, among all 4 implementations, there's not really a need to overwrite this at all. Aside: drm_kms_helper_hotplug_event is pretty much core functionality at this point. Probably should move it there. Reviewed-by: Lyude Paul Acked-by: Alex Deucher Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181128221234.15054-1-daniel.vetter@ffwll.ch --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 9 --------- drivers/gpu/drm/drm_dp_mst_topology.c | 7 ++++--- drivers/gpu/drm/i915/intel_dp_mst.c | 10 ---------- drivers/gpu/drm/nouveau/dispnv50/disp.c | 8 -------- drivers/gpu/drm/radeon/radeon_dp_mst.c | 9 --------- 5 files changed, 4 insertions(+), 39 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index d02c32a1039c..9fdeca096407 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -396,14 +396,6 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, drm_connector_put(connector); } -static void dm_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) -{ - struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); - struct drm_device *dev = master->base.dev; - - drm_kms_helper_hotplug_event(dev); -} - static void dm_dp_mst_register_connector(struct drm_connector *connector) { struct drm_device *dev = connector->dev; @@ -420,7 +412,6 @@ static void dm_dp_mst_register_connector(struct drm_connector *connector) static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { .add_connector = dm_dp_add_mst_connector, .destroy_connector = dm_dp_destroy_mst_connector, - .hotplug = dm_dp_mst_hotplug, .register_connector = dm_dp_mst_register_connector }; diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 529414556962..a9b684f14d14 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -33,6 +33,7 @@ #include #include #include +#include /** * DOC: dp mst helper @@ -1639,7 +1640,7 @@ static void drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, for (i = 0; i < txmsg->reply.u.link_addr.nports; i++) { drm_dp_add_port(mstb, mgr->dev, &txmsg->reply.u.link_addr.ports[i]); } - (*mgr->cbs->hotplug)(mgr); + drm_kms_helper_hotplug_event(mgr->dev); } } else { mstb->link_address_sent = false; @@ -2412,7 +2413,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) drm_dp_update_port(mstb, &msg.u.conn_stat); DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", msg.u.conn_stat.port_number, msg.u.conn_stat.legacy_device_plug_status, msg.u.conn_stat.displayport_device_plug_status, msg.u.conn_stat.message_capability_status, msg.u.conn_stat.input_port, msg.u.conn_stat.peer_device_type); - (*mgr->cbs->hotplug)(mgr); + drm_kms_helper_hotplug_event(mgr->dev); } else if (msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, msg.req_type, seqno, false); @@ -3109,7 +3110,7 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) send_hotplug = true; } if (send_hotplug) - (*mgr->cbs->hotplug)(mgr); + drm_kms_helper_hotplug_event(mgr->dev); } static struct drm_private_state * diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 4de247ddf05f..f05427b74e34 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -517,20 +517,10 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, drm_connector_put(connector); } -static void intel_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) -{ - struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; - - drm_kms_helper_hotplug_event(dev); -} - static const struct drm_dp_mst_topology_cbs mst_cbs = { .add_connector = intel_dp_add_mst_connector, .register_connector = intel_dp_register_mst_connector, .destroy_connector = intel_dp_destroy_mst_connector, - .hotplug = intel_dp_mst_hotplug, }; static struct intel_dp_mst_encoder * diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 6cbbae3f438b..4a56841958c8 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1055,13 +1055,6 @@ nv50_mstm_prepare(struct nv50_mstm *mstm) } } -static void -nv50_mstm_hotplug(struct drm_dp_mst_topology_mgr *mgr) -{ - struct nv50_mstm *mstm = nv50_mstm(mgr); - drm_kms_helper_hotplug_event(mstm->outp->base.base.dev); -} - static void nv50_mstm_destroy_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_connector *connector) @@ -1113,7 +1106,6 @@ nv50_mstm = { .add_connector = nv50_mstm_add_connector, .register_connector = nv50_mstm_register_connector, .destroy_connector = nv50_mstm_destroy_connector, - .hotplug = nv50_mstm_hotplug, }; void diff --git a/drivers/gpu/drm/radeon/radeon_dp_mst.c b/drivers/gpu/drm/radeon/radeon_dp_mst.c index 84b3ad2172a3..a0c70e27ab65 100644 --- a/drivers/gpu/drm/radeon/radeon_dp_mst.c +++ b/drivers/gpu/drm/radeon/radeon_dp_mst.c @@ -320,19 +320,10 @@ static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, DRM_DEBUG_KMS("\n"); } -static void radeon_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr) -{ - struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr); - struct drm_device *dev = master->base.dev; - - drm_kms_helper_hotplug_event(dev); -} - static const struct drm_dp_mst_topology_cbs mst_cbs = { .add_connector = radeon_dp_add_mst_connector, .register_connector = radeon_dp_register_mst_connector, .destroy_connector = radeon_dp_destroy_mst_connector, - .hotplug = radeon_dp_mst_hotplug, }; static struct -- cgit v1.2.3 From 32658d2c8073699473c28b67f14ad51403ccec5d Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 8 Dec 2018 08:36:25 +0000 Subject: drm/ast: Remove set but not used variable 'bo' Fixes gcc '-Wunused-but-set-variable' warning: drivers/gpu/drm/ast/ast_fb.c: In function 'astfb_create': drivers/gpu/drm/ast/ast_fb.c:194:17: warning: variable 'bo' set but not used [-Wunused-but-set-variable] It never used since introduction in commit 312fec1405dd ("drm: Initial KMS driver for AST (ASpeed Technologies) 2000 series (v2)") Signed-off-by: YueHaibing Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/1544258185-50430-1-git-send-email-yuehaibing@huawei.com --- drivers/gpu/drm/ast/ast_fb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index 0cd827e11fa2..a80bca1a857f 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c @@ -191,7 +191,6 @@ static int astfb_create(struct drm_fb_helper *helper, int size, ret; void *sysram; struct drm_gem_object *gobj = NULL; - struct ast_bo *bo = NULL; mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7)/8); @@ -206,7 +205,6 @@ static int astfb_create(struct drm_fb_helper *helper, DRM_ERROR("failed to create fbcon backing object %d\n", ret); return ret; } - bo = gem_to_ast_bo(gobj); sysram = vmalloc(size); if (!sysram) -- cgit v1.2.3 From c978ae9bde582e82a04c63a4071701691dd8b35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 28 Sep 2018 21:03:59 +0300 Subject: drm/dp/mst: Configure no_stop_bit correctly for remote i2c xfers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We aren't supposed to force a stop+start between every i2c msg when performing multi message transfers. This should eg. cause the DDC segment address to be reset back to 0 between writing the segment address and reading the actual EDID extension block. To quote the E-DDC spec: "... this standard requires that the segment pointer be reset to 00h when a NO ACK or a STOP condition is received." Since we're going to touch this might as well consult the I2C_M_STOP flag to determine whether we want to force the stop or not. Cc: Brian Vincent References: https://bugs.freedesktop.org/show_bug.cgi?id=108081 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180928180403.22499-1-ville.syrjala@linux.intel.com Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/drm_dp_mst_topology.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index a9b684f14d14..229ad6026314 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3287,6 +3287,7 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs msg.u.i2c_read.transactions[i].i2c_dev_id = msgs[i].addr; msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len; msg.u.i2c_read.transactions[i].bytes = msgs[i].buf; + msg.u.i2c_read.transactions[i].no_stop_bit = !(msgs[i].flags & I2C_M_STOP); } msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr; msg.u.i2c_read.num_bytes_read = msgs[num - 1].len; -- cgit v1.2.3 From cb8ce7111117e16a87f3f55c014ccd1f19f81016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 28 Sep 2018 21:04:00 +0300 Subject: drm/dp/mst: Validate REMOTE_I2C_READ harder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure i2c msgs we're asked to transfer conform to the requirements of REMOTE_I2C_READ. We were only checking that the last message is a read, but we must also check that the preceding messages are all writes. Also check that the length of each message isn't too long. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180928180403.22499-2-ville.syrjala@linux.intel.com Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/drm_dp_mst_topology.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 229ad6026314..f0cbd5fad8fc 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3250,6 +3250,23 @@ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr) } EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy); +static bool remote_i2c_read_ok(const struct i2c_msg msgs[], int num) +{ + int i; + + if (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS) + return false; + + for (i = 0; i < num - 1; i++) { + if (msgs[i].flags & I2C_M_RD || + msgs[i].len > 0xff) + return false; + } + + return msgs[num - 1].flags & I2C_M_RD && + msgs[num - 1].len <= 0xff; +} + /* I2C device */ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) @@ -3259,7 +3276,6 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs struct drm_dp_mst_branch *mstb; struct drm_dp_mst_topology_mgr *mgr = port->mgr; unsigned int i; - bool reading = false; struct drm_dp_sideband_msg_req_body msg; struct drm_dp_sideband_msg_tx *txmsg = NULL; int ret; @@ -3268,12 +3284,7 @@ static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs if (!mstb) return -EREMOTEIO; - /* construct i2c msg */ - /* see if last msg is a read */ - if (msgs[num - 1].flags & I2C_M_RD) - reading = true; - - if (!reading || (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) { + if (!remote_i2c_read_ok(msgs, num)) { DRM_DEBUG_KMS("Unsupported I2C transaction for MST device\n"); ret = -EIO; goto out; -- cgit v1.2.3 From b962a12050a387e4bbf3a48745afe1d29d396b0d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 22 Oct 2018 14:31:22 +0200 Subject: drm/atomic: integrate modeset lock with private objects Follow the same pattern of locking as with other state objects. This avoids boilerplate in the driver. Signed-off-by: Rob Clark Signed-off-by: Boris Brezillon Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181022123122.30468-1-boris.brezillon@bootlin.com --- drivers/gpu/drm/drm_atomic.c | 19 +++++++++++++++---- drivers/gpu/drm/drm_dp_mst_topology.c | 2 +- drivers/gpu/drm/drm_mode_config.c | 1 + drivers/gpu/drm/drm_modeset_lock.c | 8 ++++++++ drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 2 +- drivers/gpu/drm/tegra/hub.c | 2 +- drivers/gpu/drm/vc4/vc4_kms.c | 3 ++- 7 files changed, 29 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 9ac26437051b..008224f376fe 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -676,6 +676,7 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, /** * drm_atomic_private_obj_init - initialize private object + * @dev: DRM device this object will be attached to * @obj: private object * @state: initial private object state * @funcs: pointer to the struct of function pointers that identify the object @@ -685,14 +686,18 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, * driver private object that needs its own atomic state. */ void -drm_atomic_private_obj_init(struct drm_private_obj *obj, +drm_atomic_private_obj_init(struct drm_device *dev, + struct drm_private_obj *obj, struct drm_private_state *state, const struct drm_private_state_funcs *funcs) { memset(obj, 0, sizeof(*obj)); + drm_modeset_lock_init(&obj->lock); + obj->state = state; obj->funcs = funcs; + list_add_tail(&obj->head, &dev->mode_config.privobj_list); } EXPORT_SYMBOL(drm_atomic_private_obj_init); @@ -705,7 +710,9 @@ EXPORT_SYMBOL(drm_atomic_private_obj_init); void drm_atomic_private_obj_fini(struct drm_private_obj *obj) { + list_del(&obj->head); obj->funcs->atomic_destroy_state(obj, obj->state); + drm_modeset_lock_fini(&obj->lock); } EXPORT_SYMBOL(drm_atomic_private_obj_fini); @@ -715,8 +722,8 @@ EXPORT_SYMBOL(drm_atomic_private_obj_fini); * @obj: private object to get the state for * * This function returns the private object state for the given private object, - * allocating the state if needed. It does not grab any locks as the caller is - * expected to care of any required locking. + * allocating the state if needed. It will also grab the relevant private + * object lock to make sure that the state is consistent. * * RETURNS: * @@ -726,7 +733,7 @@ struct drm_private_state * drm_atomic_get_private_obj_state(struct drm_atomic_state *state, struct drm_private_obj *obj) { - int index, num_objs, i; + int index, num_objs, i, ret; size_t size; struct __drm_private_objs_state *arr; struct drm_private_state *obj_state; @@ -735,6 +742,10 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, if (obj == state->private_objs[i].ptr) return state->private_objs[i].state; + ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); + if (ret) + return ERR_PTR(ret); + num_objs = state->num_private_objs + 1; size = sizeof(*state->private_objs) * num_objs; arr = krealloc(state->private_objs, size, GFP_KERNEL); diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index f0cbd5fad8fc..5a73a0b1c9cd 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3221,7 +3221,7 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, /* max. time slots - one slot for MTP header */ mst_state->avail_slots = 63; - drm_atomic_private_obj_init(&mgr->base, + drm_atomic_private_obj_init(dev, &mgr->base, &mst_state->base, &mst_state_funcs); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index ee80788f2c40..931523c5bc9d 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -381,6 +381,7 @@ void drm_mode_config_init(struct drm_device *dev) INIT_LIST_HEAD(&dev->mode_config.property_list); INIT_LIST_HEAD(&dev->mode_config.property_blob_list); INIT_LIST_HEAD(&dev->mode_config.plane_list); + INIT_LIST_HEAD(&dev->mode_config.privobj_list); idr_init(&dev->mode_config.crtc_idr); idr_init(&dev->mode_config.tile_idr); ida_init(&dev->mode_config.connector_ida); diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 51f534db9107..81dd11901ffd 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -22,6 +22,7 @@ */ #include +#include #include #include @@ -394,6 +395,7 @@ EXPORT_SYMBOL(drm_modeset_unlock); int drm_modeset_lock_all_ctx(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx) { + struct drm_private_obj *privobj; struct drm_crtc *crtc; struct drm_plane *plane; int ret; @@ -414,6 +416,12 @@ int drm_modeset_lock_all_ctx(struct drm_device *dev, return ret; } + drm_for_each_privobj(privobj, dev) { + ret = drm_modeset_lock(&privobj->lock, ctx); + if (ret) + return ret; + } + return 0; } EXPORT_SYMBOL(drm_modeset_lock_all_ctx); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index bddd625ab91b..f71d8cf2261b 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -144,7 +144,7 @@ static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms) state->mdp5_kms = mdp5_kms; - drm_atomic_private_obj_init(&mdp5_kms->glob_state, + drm_atomic_private_obj_init(mdp5_kms->dev, &mdp5_kms->glob_state, &state->base, &mdp5_global_state_funcs); return 0; diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index 6112d9042979..3e26be5359cf 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -716,7 +716,7 @@ static int tegra_display_hub_init(struct host1x_client *client) if (!state) return -ENOMEM; - drm_atomic_private_obj_init(&hub->base, &state->base, + drm_atomic_private_obj_init(drm, &hub->base, &state->base, &tegra_display_hub_state_funcs); tegra->hub = hub; diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 1f94b9affe4b..0490edb192a1 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -432,7 +432,8 @@ int vc4_kms_load(struct drm_device *dev) ctm_state = kzalloc(sizeof(*ctm_state), GFP_KERNEL); if (!ctm_state) return -ENOMEM; - drm_atomic_private_obj_init(&vc4->ctm_manager, &ctm_state->base, + + drm_atomic_private_obj_init(dev, &vc4->ctm_manager, &ctm_state->base, &vc4_ctm_state_funcs); drm_mode_config_reset(dev); -- cgit v1.2.3 From 3415701a5eae5c34d07e4b39ae7086eca66e94aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 7 Dec 2018 20:10:17 +0100 Subject: drm/etnaviv: fix for 64bit seqno change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fence seqno is now 64bit, fixes build warning. Signed-off-by: Christian König Acked-by: Lucas Stach Acked-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/267136/ --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 1fa74226db91..5c48915f492d 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -449,7 +449,7 @@ static void etnaviv_gem_describe_fence(struct dma_fence *fence, const char *type, struct seq_file *m) { if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) - seq_printf(m, "\t%9s: %s %s seq %u\n", + seq_printf(m, "\t%9s: %s %s seq %llu\n", type, fence->ops->get_driver_name(fence), fence->ops->get_timeline_name(fence), -- cgit v1.2.3 From 61a98b1b9a8c7a21a2d666a090dcf5f1c70c659f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 11 Dec 2018 18:34:41 +0800 Subject: drm/syncobj: remove drm_syncobj_cb and cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This completes "drm/syncobj: Drop add/remove_callback from driver interface" and cleans up the implementation a bit. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Link: https://patchwork.freedesktop.org/patch/266255/ --- drivers/gpu/drm/drm_syncobj.c | 91 ++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 61 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index db30a0e89db8..e19525af0cce 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -56,6 +56,16 @@ #include "drm_internal.h" #include +struct syncobj_wait_entry { + struct list_head node; + struct task_struct *task; + struct dma_fence *fence; + struct dma_fence_cb fence_cb; +}; + +static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, + struct syncobj_wait_entry *wait); + /** * drm_syncobj_find - lookup and reference a sync object. * @file_private: drm file private pointer @@ -82,58 +92,33 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, } EXPORT_SYMBOL(drm_syncobj_find); -static void drm_syncobj_add_callback_locked(struct drm_syncobj *syncobj, - struct drm_syncobj_cb *cb, - drm_syncobj_func_t func) +static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj, + struct syncobj_wait_entry *wait) { - cb->func = func; - list_add_tail(&cb->node, &syncobj->cb_list); -} - -static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj, - struct dma_fence **fence, - struct drm_syncobj_cb *cb, - drm_syncobj_func_t func) -{ - int ret; - - *fence = drm_syncobj_fence_get(syncobj); - if (*fence) - return 1; + if (wait->fence) + return; spin_lock(&syncobj->lock); /* We've already tried once to get a fence and failed. Now that we * have the lock, try one more time just to be sure we don't add a * callback when a fence has already been set. */ - if (syncobj->fence) { - *fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, - lockdep_is_held(&syncobj->lock))); - ret = 1; - } else { - *fence = NULL; - drm_syncobj_add_callback_locked(syncobj, cb, func); - ret = 0; - } + if (syncobj->fence) + wait->fence = dma_fence_get( + rcu_dereference_protected(syncobj->fence, 1)); + else + list_add_tail(&wait->node, &syncobj->cb_list); spin_unlock(&syncobj->lock); - - return ret; } -void drm_syncobj_add_callback(struct drm_syncobj *syncobj, - struct drm_syncobj_cb *cb, - drm_syncobj_func_t func) +static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj, + struct syncobj_wait_entry *wait) { - spin_lock(&syncobj->lock); - drm_syncobj_add_callback_locked(syncobj, cb, func); - spin_unlock(&syncobj->lock); -} + if (!wait->node.next) + return; -void drm_syncobj_remove_callback(struct drm_syncobj *syncobj, - struct drm_syncobj_cb *cb) -{ spin_lock(&syncobj->lock); - list_del_init(&cb->node); + list_del_init(&wait->node); spin_unlock(&syncobj->lock); } @@ -148,7 +133,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, struct dma_fence *fence) { struct dma_fence *old_fence; - struct drm_syncobj_cb *cur, *tmp; + struct syncobj_wait_entry *cur, *tmp; if (fence) dma_fence_get(fence); @@ -162,7 +147,7 @@ void drm_syncobj_replace_fence(struct drm_syncobj *syncobj, if (fence != old_fence) { list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node) { list_del_init(&cur->node); - cur->func(syncobj, cur); + syncobj_wait_syncobj_func(syncobj, cur); } } @@ -608,13 +593,6 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, &args->handle); } -struct syncobj_wait_entry { - struct task_struct *task; - struct dma_fence *fence; - struct dma_fence_cb fence_cb; - struct drm_syncobj_cb syncobj_cb; -}; - static void syncobj_wait_fence_func(struct dma_fence *fence, struct dma_fence_cb *cb) { @@ -625,11 +603,8 @@ static void syncobj_wait_fence_func(struct dma_fence *fence, } static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, - struct drm_syncobj_cb *cb) + struct syncobj_wait_entry *wait) { - struct syncobj_wait_entry *wait = - container_of(cb, struct syncobj_wait_entry, syncobj_cb); - /* This happens inside the syncobj lock */ wait->fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, lockdep_is_held(&syncobj->lock))); @@ -688,12 +663,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, */ if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { - for (i = 0; i < count; ++i) { - drm_syncobj_fence_get_or_add_callback(syncobjs[i], - &entries[i].fence, - &entries[i].syncobj_cb, - syncobj_wait_syncobj_func); - } + for (i = 0; i < count; ++i) + drm_syncobj_fence_add_wait(syncobjs[i], &entries[i]); } do { @@ -742,9 +713,7 @@ done_waiting: cleanup_entries: for (i = 0; i < count; ++i) { - if (entries[i].syncobj_cb.func) - drm_syncobj_remove_callback(syncobjs[i], - &entries[i].syncobj_cb); + drm_syncobj_remove_wait(syncobjs[i], &entries[i]); if (entries[i].fence_cb.func) dma_fence_remove_callback(entries[i].fence, &entries[i].fence_cb); -- cgit v1.2.3 From 7ce5362815bb55a200b93ca3f267eda90fc28130 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 10 Dec 2018 11:03:57 +0100 Subject: drm/qxl: Don't set the dpms hook Doesn't do anything with atomic. Signed-off-by: Daniel Vetter Cc: Dave Airlie Cc: Gerd Hoffmann Cc: virtualization@lists.linux-foundation.org Cc: spice-devel@lists.freedesktop.org Reviewed-by: Gerd Hoffmann Reviewed-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/msgid/20181210100359.22507-6-daniel.vetter@ffwll.ch --- drivers/gpu/drm/qxl/qxl_display.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index ce0b9c40fc21..72a1784dae54 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -1010,7 +1010,6 @@ static void qxl_conn_destroy(struct drm_connector *connector) } static const struct drm_connector_funcs qxl_connector_funcs = { - .dpms = drm_helper_connector_dpms, .detect = qxl_conn_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = qxl_conn_destroy, -- cgit v1.2.3 From cad5290a2f79c7eaeda11bba02dd1cb6d096359a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 10 Dec 2018 11:03:58 +0100 Subject: drm/xen: Don't set the dpms hook Doesn't do anything for atomic. Signed-off-by: Daniel Vetter Cc: Oleksandr Andrushchenko Cc: xen-devel@lists.xen.org Reviewed-by: Alex Deucher Reviewed-by: Oleksandr Andrushchenko Link: https://patchwork.freedesktop.org/patch/msgid/20181210100359.22507-7-daniel.vetter@ffwll.ch --- drivers/gpu/drm/xen/xen_drm_front_conn.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/xen/xen_drm_front_conn.c b/drivers/gpu/drm/xen/xen_drm_front_conn.c index c91ae532fa55..54af2669b1b3 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_conn.c +++ b/drivers/gpu/drm/xen/xen_drm_front_conn.c @@ -89,7 +89,6 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = { }; static const struct drm_connector_funcs connector_funcs = { - .dpms = drm_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = drm_connector_cleanup, .reset = drm_atomic_helper_connector_reset, -- cgit v1.2.3 From 63d5e06aa38182da47bccde16fac058b0b2d53c7 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 30 Nov 2018 11:24:49 +0100 Subject: drm/rockchip: Add implicit fencing support for planes Render like lima will attach a fence to the framebuffer dma_buf, so the display driver should wait for it to finish before showing the framebufferto prevent tearing. Generally tested on rk3188, rk3288, rk3328 and rk3399 and together with an actual lima-based kmscube on rk3188 and rk3328. Suggested-by: Qiang Yu Signed-off-by: Heiko Stuebner Reviewed-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20181130102449.6430-1-heiko@sntech.de --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index fb70fb486fbf..db8358e6d230 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #ifdef CONFIG_DRM_ANALOGIX_DP #include @@ -823,6 +824,7 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = { .atomic_check = vop_plane_atomic_check, .atomic_update = vop_plane_atomic_update, .atomic_disable = vop_plane_atomic_disable, + .prepare_fb = drm_gem_fb_prepare_fb, }; static const struct drm_plane_funcs vop_plane_funcs = { -- cgit v1.2.3 From b5f06893c4992553a12c66ca094a09fb245d280e Mon Sep 17 00:00:00 2001 From: Shayenne da Luz Moura Date: Thu, 13 Dec 2018 19:29:57 -0200 Subject: drm: Rename crtc_idr as object_idr to KMS cleanups This patch solves this TODO task: drm_mode_config.crtc_idr is misnamed, since it contains all KMS object. Should be renamed to drm_mode_config.object_idr. Signed-off-by: Shayenne da Luz Moura [danvet: resolve conflict with addition of privobj_list.] Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181213212957.vkitkyl5cj2qh7qr@smtp.gmail.com --- drivers/gpu/drm/drm_lease.c | 6 +++--- drivers/gpu/drm/drm_mode_config.c | 4 ++-- drivers/gpu/drm/drm_mode_object.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 3650d3c46718..d9b4d3ff06f6 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -218,7 +218,7 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr idr_for_each_entry(leases, entry, object) { error = 0; - if (!idr_find(&dev->mode_config.crtc_idr, object)) + if (!idr_find(&dev->mode_config.object_idr, object)) error = -ENOENT; else if (!_drm_lease_held_master(lessor, object)) error = -EACCES; @@ -439,7 +439,7 @@ static int fill_object_idr(struct drm_device *dev, /* * We're using an IDR to hold the set of leased * objects, but we don't need to point at the object's - * data structure from the lease as the main crtc_idr + * data structure from the lease as the main object_idr * will be used to actually find that. Instead, all we * really want is a 'leased/not-leased' result, for * which any non-NULL pointer will work fine. @@ -687,7 +687,7 @@ int drm_mode_get_lease_ioctl(struct drm_device *dev, if (lessee->lessor == NULL) /* owner can use all objects */ - object_idr = &lessee->dev->mode_config.crtc_idr; + object_idr = &lessee->dev->mode_config.object_idr; else /* lessee can only use allowed object */ object_idr = &lessee->leases; diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 931523c5bc9d..037e243ec863 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -382,7 +382,7 @@ void drm_mode_config_init(struct drm_device *dev) INIT_LIST_HEAD(&dev->mode_config.property_blob_list); INIT_LIST_HEAD(&dev->mode_config.plane_list); INIT_LIST_HEAD(&dev->mode_config.privobj_list); - idr_init(&dev->mode_config.crtc_idr); + idr_init(&dev->mode_config.object_idr); idr_init(&dev->mode_config.tile_idr); ida_init(&dev->mode_config.connector_ida); spin_lock_init(&dev->mode_config.connector_list_lock); @@ -485,7 +485,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) ida_destroy(&dev->mode_config.connector_ida); idr_destroy(&dev->mode_config.tile_idr); - idr_destroy(&dev->mode_config.crtc_idr); + idr_destroy(&dev->mode_config.object_idr); drm_modeset_lock_fini(&dev->mode_config.connection_mutex); } EXPORT_SYMBOL(drm_mode_config_cleanup); diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index cd9bc0ce9be0..bb1dd46496cd 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -38,7 +38,7 @@ int __drm_mode_object_add(struct drm_device *dev, struct drm_mode_object *obj, int ret; mutex_lock(&dev->mode_config.idr_mutex); - ret = idr_alloc(&dev->mode_config.crtc_idr, register_obj ? obj : NULL, + ret = idr_alloc(&dev->mode_config.object_idr, register_obj ? obj : NULL, 1, 0, GFP_KERNEL); if (ret >= 0) { /* @@ -79,7 +79,7 @@ void drm_mode_object_register(struct drm_device *dev, struct drm_mode_object *obj) { mutex_lock(&dev->mode_config.idr_mutex); - idr_replace(&dev->mode_config.crtc_idr, obj, obj->id); + idr_replace(&dev->mode_config.object_idr, obj, obj->id); mutex_unlock(&dev->mode_config.idr_mutex); } @@ -99,7 +99,7 @@ void drm_mode_object_unregister(struct drm_device *dev, { mutex_lock(&dev->mode_config.idr_mutex); if (object->id) { - idr_remove(&dev->mode_config.crtc_idr, object->id); + idr_remove(&dev->mode_config.object_idr, object->id); object->id = 0; } mutex_unlock(&dev->mode_config.idr_mutex); @@ -131,7 +131,7 @@ struct drm_mode_object *__drm_mode_object_find(struct drm_device *dev, struct drm_mode_object *obj = NULL; mutex_lock(&dev->mode_config.idr_mutex); - obj = idr_find(&dev->mode_config.crtc_idr, id); + obj = idr_find(&dev->mode_config.object_idr, id); if (obj && type != DRM_MODE_OBJECT_ANY && obj->type != type) obj = NULL; if (obj && obj->id != id) -- cgit v1.2.3 From f536e00c46d22ccd1b2aada5b22754c35d9487ce Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Tue, 11 Dec 2018 18:50:26 -0500 Subject: drm/dp_mst: Fix memory leak in drm_dp_mst_topology_mgr_destroy() We need to call drm_dp_mst_topology_mgr_set_mst(mgr, false) when destroying the topology manager in order to ensure that the root mstb and all of it's descendents are actually destroyed, and additionally to try to make sure that we leave the hub in a clean state. Signed-off-by: Lyude Paul Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181211235026.21758-1-lyude@redhat.com --- drivers/gpu/drm/drm_dp_mst_topology.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 5a73a0b1c9cd..ad0fb6d003be 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -3235,6 +3235,7 @@ EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init); */ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr) { + drm_dp_mst_topology_mgr_set_mst(mgr, false); flush_work(&mgr->work); flush_work(&mgr->destroy_connector_work); mutex_lock(&mgr->payload_lock); -- cgit v1.2.3 From 48a77d66cb7f557635f4fccd5abfc1ac2f71b9de Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 13 Dec 2018 14:49:15 +0100 Subject: drm/virtio: switch to generic fbdev emulation Signed-off-by: Gerd Hoffmann Reviewed-by: Dave Airlie Link: http://patchwork.freedesktop.org/patch/msgid/20181213134915.24722-1-kraxel@redhat.com --- drivers/gpu/drm/virtio/virtgpu_display.c | 1 - drivers/gpu/drm/virtio/virtgpu_drv.c | 9 +- drivers/gpu/drm/virtio/virtgpu_drv.h | 14 --- drivers/gpu/drm/virtio/virtgpu_fb.c | 191 ------------------------------- drivers/gpu/drm/virtio/virtgpu_kms.c | 8 -- 5 files changed, 8 insertions(+), 215 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index b5580b11a063..e1c223e18d86 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -390,6 +390,5 @@ void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) for (i = 0 ; i < vgdev->num_scanouts; ++i) kfree(vgdev->outputs[i].edid); - virtio_gpu_fbdev_fini(vgdev); drm_mode_config_cleanup(vgdev->ddev); } diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index f7f32a885af7..7df50920c1e0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -42,13 +42,20 @@ module_param_named(modeset, virtio_gpu_modeset, int, 0400); static int virtio_gpu_probe(struct virtio_device *vdev) { + int ret; + if (vgacon_text_force() && virtio_gpu_modeset == -1) return -EINVAL; if (virtio_gpu_modeset == 0) return -EINVAL; - return drm_virtio_init(&driver, vdev); + ret = drm_virtio_init(&driver, vdev); + if (ret) + return ret; + + drm_fbdev_generic_setup(vdev->priv, 32); + return 0; } static void virtio_gpu_remove(struct virtio_device *vdev) diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 1deb41d42ea4..63704915f8ce 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -137,19 +137,10 @@ struct virtio_gpu_framebuffer { #define to_virtio_gpu_framebuffer(x) \ container_of(x, struct virtio_gpu_framebuffer, base) -struct virtio_gpu_fbdev { - struct drm_fb_helper helper; - struct virtio_gpu_framebuffer vgfb; - struct virtio_gpu_device *vgdev; - struct delayed_work work; -}; - struct virtio_gpu_mman { struct ttm_bo_device bdev; }; -struct virtio_gpu_fbdev; - struct virtio_gpu_queue { struct virtqueue *vq; spinlock_t qlock; @@ -180,8 +171,6 @@ struct virtio_gpu_device { struct virtio_gpu_mman mman; - /* pointer to fbdev info structure */ - struct virtio_gpu_fbdev *vgfbdev; struct virtio_gpu_output outputs[VIRTIO_GPU_MAX_SCANOUTS]; uint32_t num_scanouts; @@ -249,9 +238,6 @@ int virtio_gpu_mode_dumb_mmap(struct drm_file *file_priv, uint32_t handle, uint64_t *offset_p); /* virtio_fb */ -#define VIRTIO_GPUFB_CONN_LIMIT 1 -int virtio_gpu_fbdev_init(struct virtio_gpu_device *vgdev); -void virtio_gpu_fbdev_fini(struct virtio_gpu_device *vgdev); int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *qfb, struct drm_clip_rect *clips, unsigned int num_clips); diff --git a/drivers/gpu/drm/virtio/virtgpu_fb.c b/drivers/gpu/drm/virtio/virtgpu_fb.c index fb1cc8b2f119..b07584b1c2bf 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fb.c +++ b/drivers/gpu/drm/virtio/virtgpu_fb.c @@ -27,8 +27,6 @@ #include #include "virtgpu_drv.h" -#define VIRTIO_GPU_FBCON_POLL_PERIOD (HZ / 60) - static int virtio_gpu_dirty_update(struct virtio_gpu_framebuffer *fb, bool store, int x, int y, int width, int height) @@ -150,192 +148,3 @@ int virtio_gpu_surface_dirty(struct virtio_gpu_framebuffer *vgfb, left, top, right - left, bottom - top); return 0; } - -static void virtio_gpu_fb_dirty_work(struct work_struct *work) -{ - struct delayed_work *delayed_work = to_delayed_work(work); - struct virtio_gpu_fbdev *vfbdev = - container_of(delayed_work, struct virtio_gpu_fbdev, work); - struct virtio_gpu_framebuffer *vgfb = &vfbdev->vgfb; - - virtio_gpu_dirty_update(&vfbdev->vgfb, false, vgfb->x1, vgfb->y1, - vgfb->x2 - vgfb->x1, vgfb->y2 - vgfb->y1); -} - -static void virtio_gpu_3d_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - struct virtio_gpu_fbdev *vfbdev = info->par; - - drm_fb_helper_sys_fillrect(info, rect); - virtio_gpu_dirty_update(&vfbdev->vgfb, true, rect->dx, rect->dy, - rect->width, rect->height); - schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); -} - -static void virtio_gpu_3d_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - struct virtio_gpu_fbdev *vfbdev = info->par; - - drm_fb_helper_sys_copyarea(info, area); - virtio_gpu_dirty_update(&vfbdev->vgfb, true, area->dx, area->dy, - area->width, area->height); - schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); -} - -static void virtio_gpu_3d_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - struct virtio_gpu_fbdev *vfbdev = info->par; - - drm_fb_helper_sys_imageblit(info, image); - virtio_gpu_dirty_update(&vfbdev->vgfb, true, image->dx, image->dy, - image->width, image->height); - schedule_delayed_work(&vfbdev->work, VIRTIO_GPU_FBCON_POLL_PERIOD); -} - -static struct fb_ops virtio_gpufb_ops = { - .owner = THIS_MODULE, - DRM_FB_HELPER_DEFAULT_OPS, - .fb_fillrect = virtio_gpu_3d_fillrect, - .fb_copyarea = virtio_gpu_3d_copyarea, - .fb_imageblit = virtio_gpu_3d_imageblit, -}; - -static int virtio_gpufb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct virtio_gpu_fbdev *vfbdev = - container_of(helper, struct virtio_gpu_fbdev, helper); - struct drm_device *dev = helper->dev; - struct virtio_gpu_device *vgdev = dev->dev_private; - struct fb_info *info; - struct drm_framebuffer *fb; - struct drm_mode_fb_cmd2 mode_cmd = {}; - struct virtio_gpu_object *obj; - uint32_t format, size; - int ret; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = mode_cmd.width * 4; - mode_cmd.pixel_format = DRM_FORMAT_HOST_XRGB8888; - - format = virtio_gpu_translate_format(mode_cmd.pixel_format); - if (format == 0) - return -EINVAL; - - size = mode_cmd.pitches[0] * mode_cmd.height; - obj = virtio_gpu_alloc_object(dev, size, false, true); - if (IS_ERR(obj)) - return PTR_ERR(obj); - - virtio_gpu_cmd_create_resource(vgdev, obj, format, - mode_cmd.width, mode_cmd.height); - - ret = virtio_gpu_object_kmap(obj); - if (ret) { - DRM_ERROR("failed to kmap fb %d\n", ret); - goto err_obj_vmap; - } - - /* attach the object to the resource */ - ret = virtio_gpu_object_attach(vgdev, obj, NULL); - if (ret) - goto err_obj_attach; - - info = drm_fb_helper_alloc_fbi(helper); - if (IS_ERR(info)) { - ret = PTR_ERR(info); - goto err_fb_alloc; - } - - info->par = helper; - - ret = virtio_gpu_framebuffer_init(dev, &vfbdev->vgfb, - &mode_cmd, &obj->gem_base); - if (ret) - goto err_fb_alloc; - - fb = &vfbdev->vgfb.base; - - vfbdev->helper.fb = fb; - - strcpy(info->fix.id, "virtiodrmfb"); - info->fbops = &virtio_gpufb_ops; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - - info->screen_buffer = obj->vmap; - info->screen_size = obj->gem_base.size; - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->format->depth); - drm_fb_helper_fill_var(info, &vfbdev->helper, - sizes->fb_width, sizes->fb_height); - - info->fix.mmio_start = 0; - info->fix.mmio_len = 0; - return 0; - -err_fb_alloc: - virtio_gpu_object_detach(vgdev, obj); -err_obj_attach: -err_obj_vmap: - virtio_gpu_gem_free_object(&obj->gem_base); - return ret; -} - -static int virtio_gpu_fbdev_destroy(struct drm_device *dev, - struct virtio_gpu_fbdev *vgfbdev) -{ - struct virtio_gpu_framebuffer *vgfb = &vgfbdev->vgfb; - - drm_fb_helper_unregister_fbi(&vgfbdev->helper); - - if (vgfb->base.obj[0]) - vgfb->base.obj[0] = NULL; - drm_fb_helper_fini(&vgfbdev->helper); - drm_framebuffer_cleanup(&vgfb->base); - - return 0; -} -static const struct drm_fb_helper_funcs virtio_gpu_fb_helper_funcs = { - .fb_probe = virtio_gpufb_create, -}; - -int virtio_gpu_fbdev_init(struct virtio_gpu_device *vgdev) -{ - struct virtio_gpu_fbdev *vgfbdev; - int bpp_sel = 32; /* TODO: parameter from somewhere? */ - int ret; - - vgfbdev = kzalloc(sizeof(struct virtio_gpu_fbdev), GFP_KERNEL); - if (!vgfbdev) - return -ENOMEM; - - vgfbdev->vgdev = vgdev; - vgdev->vgfbdev = vgfbdev; - INIT_DELAYED_WORK(&vgfbdev->work, virtio_gpu_fb_dirty_work); - - drm_fb_helper_prepare(vgdev->ddev, &vgfbdev->helper, - &virtio_gpu_fb_helper_funcs); - ret = drm_fb_helper_init(vgdev->ddev, &vgfbdev->helper, - VIRTIO_GPUFB_CONN_LIMIT); - if (ret) { - kfree(vgfbdev); - return ret; - } - - drm_fb_helper_single_add_all_connectors(&vgfbdev->helper); - drm_fb_helper_initial_config(&vgfbdev->helper, bpp_sel); - return 0; -} - -void virtio_gpu_fbdev_fini(struct virtio_gpu_device *vgdev) -{ - if (!vgdev->vgfbdev) - return; - - virtio_gpu_fbdev_destroy(vgdev->ddev, vgdev->vgfbdev); - kfree(vgdev->vgfbdev); - vgdev->vgfbdev = NULL; -} diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 3af6181c05a8..1072064a0db2 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -28,11 +28,6 @@ #include #include "virtgpu_drv.h" -static int virtio_gpu_fbdev = 1; - -MODULE_PARM_DESC(fbdev, "Disable/Enable framebuffer device & console"); -module_param_named(fbdev, virtio_gpu_fbdev, int, 0400); - static void virtio_gpu_config_changed_work_func(struct work_struct *work) { struct virtio_gpu_device *vgdev = @@ -212,9 +207,6 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) virtio_gpu_cmd_get_display_info(vgdev); wait_event_timeout(vgdev->resp_wq, !vgdev->display_info_pending, 5 * HZ); - if (virtio_gpu_fbdev) - virtio_gpu_fbdev_init(vgdev); - return 0; err_modeset: -- cgit v1.2.3 From fc63668656bdcad7317fbac0ca2b31ae9e81cf74 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 13 Dec 2018 20:25:30 -0500 Subject: drm/dp_mst: Remove bogus conditional in drm_dp_update_payload_part1() There's no reason we need this, it's just confusing looking. Signed-off-by: Lyude Paul Cc: Juston Li Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181214012604.13746-2-lyude@redhat.com --- drivers/gpu/drm/drm_dp_mst_topology.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index ad0fb6d003be..9b1b5c9b1fa0 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1896,9 +1896,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) req_payload.num_slots = 0; } - if (mgr->payloads[i].start_slot != req_payload.start_slot) { - mgr->payloads[i].start_slot = req_payload.start_slot; - } + mgr->payloads[i].start_slot = req_payload.start_slot; /* work out what is required to happen with this payload */ if (mgr->payloads[i].num_slots != req_payload.num_slots) { -- cgit v1.2.3 From 706246c761ddd394e2b02f6dba2357d8eb5a7b5d Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 13 Dec 2018 20:25:31 -0500 Subject: drm/dp_mst: Refactor drm_dp_update_payload_part1() This: - Adds local variables in the first loop, instead of using array indices everywhere - Adds an early continue to reduce the indent level in the second loop There should be no functional changes here Signed-off-by: Lyude Paul Reviewed-by: Daniel Vetter Cc: Juston Li Link: https://patchwork.freedesktop.org/patch/msgid/20181214012604.13746-3-lyude@redhat.com --- drivers/gpu/drm/drm_dp_mst_topology.c | 71 +++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 29 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 9b1b5c9b1fa0..2ab16c9e6243 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1879,39 +1879,48 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) mutex_lock(&mgr->payload_lock); for (i = 0; i < mgr->max_payloads; i++) { + struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i]; + struct drm_dp_payload *payload = &mgr->payloads[i]; + /* solve the current payloads - compare to the hw ones - update the hw view */ req_payload.start_slot = cur_slots; - if (mgr->proposed_vcpis[i]) { - port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); + if (vcpi) { + port = container_of(vcpi, struct drm_dp_mst_port, + vcpi); port = drm_dp_get_validated_port_ref(mgr, port); if (!port) { mutex_unlock(&mgr->payload_lock); return -EINVAL; } - req_payload.num_slots = mgr->proposed_vcpis[i]->num_slots; - req_payload.vcpi = mgr->proposed_vcpis[i]->vcpi; + req_payload.num_slots = vcpi->num_slots; + req_payload.vcpi = vcpi->vcpi; } else { port = NULL; req_payload.num_slots = 0; } - mgr->payloads[i].start_slot = req_payload.start_slot; + payload->start_slot = req_payload.start_slot; /* work out what is required to happen with this payload */ - if (mgr->payloads[i].num_slots != req_payload.num_slots) { + if (payload->num_slots != req_payload.num_slots) { /* need to push an update for this payload */ if (req_payload.num_slots) { - drm_dp_create_payload_step1(mgr, mgr->proposed_vcpis[i]->vcpi, &req_payload); - mgr->payloads[i].num_slots = req_payload.num_slots; - mgr->payloads[i].vcpi = req_payload.vcpi; - } else if (mgr->payloads[i].num_slots) { - mgr->payloads[i].num_slots = 0; - drm_dp_destroy_payload_step1(mgr, port, mgr->payloads[i].vcpi, &mgr->payloads[i]); - req_payload.payload_state = mgr->payloads[i].payload_state; - mgr->payloads[i].start_slot = 0; + drm_dp_create_payload_step1(mgr, vcpi->vcpi, + &req_payload); + payload->num_slots = req_payload.num_slots; + payload->vcpi = req_payload.vcpi; + + } else if (payload->num_slots) { + payload->num_slots = 0; + drm_dp_destroy_payload_step1(mgr, port, + payload->vcpi, + payload); + req_payload.payload_state = + payload->payload_state; + payload->start_slot = 0; } - mgr->payloads[i].payload_state = req_payload.payload_state; + payload->payload_state = req_payload.payload_state; } cur_slots += req_payload.num_slots; @@ -1920,22 +1929,26 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) } for (i = 0; i < mgr->max_payloads; i++) { - if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) { - DRM_DEBUG_KMS("removing payload %d\n", i); - for (j = i; j < mgr->max_payloads - 1; j++) { - memcpy(&mgr->payloads[j], &mgr->payloads[j + 1], sizeof(struct drm_dp_payload)); - mgr->proposed_vcpis[j] = mgr->proposed_vcpis[j + 1]; - if (mgr->proposed_vcpis[j] && mgr->proposed_vcpis[j]->num_slots) { - set_bit(j + 1, &mgr->payload_mask); - } else { - clear_bit(j + 1, &mgr->payload_mask); - } - } - memset(&mgr->payloads[mgr->max_payloads - 1], 0, sizeof(struct drm_dp_payload)); - mgr->proposed_vcpis[mgr->max_payloads - 1] = NULL; - clear_bit(mgr->max_payloads, &mgr->payload_mask); + if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) + continue; + + DRM_DEBUG_KMS("removing payload %d\n", i); + for (j = i; j < mgr->max_payloads - 1; j++) { + mgr->payloads[j] = mgr->payloads[j + 1]; + mgr->proposed_vcpis[j] = mgr->proposed_vcpis[j + 1]; + if (mgr->proposed_vcpis[j] && + mgr->proposed_vcpis[j]->num_slots) { + set_bit(j + 1, &mgr->payload_mask); + } else { + clear_bit(j + 1, &mgr->payload_mask); + } } + + memset(&mgr->payloads[mgr->max_payloads - 1], 0, + sizeof(struct drm_dp_payload)); + mgr->proposed_vcpis[mgr->max_payloads - 1] = NULL; + clear_bit(mgr->max_payloads, &mgr->payload_mask); } mutex_unlock(&mgr->payload_lock); -- cgit v1.2.3 From 705c8160ce88825d2491aa55fa9da4fa79204c10 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 17 Dec 2018 10:00:38 +0300 Subject: drm: Fix an error pointer dereference() The drm_mode_create_tile_group() is only called from drm_parse_tiled_block() and the caller expects it to return a NULL on error. In other words, this function should match drm_mode_get_tile_group(). Signed-off-by: Dan Carpenter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181217065733.GA12159@kadam --- drivers/gpu/drm/drm_connector.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index fa9baacc863b..f0dd3315b1b8 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1960,7 +1960,7 @@ EXPORT_SYMBOL(drm_mode_get_tile_group); * identifier for the tile group. * * RETURNS: - * new tile group or error. + * new tile group or NULL. */ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, char topology[8]) @@ -1970,7 +1970,7 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, tg = kzalloc(sizeof(*tg), GFP_KERNEL); if (!tg) - return ERR_PTR(-ENOMEM); + return NULL; kref_init(&tg->refcount); memcpy(tg->group_data, topology, 8); @@ -1982,7 +1982,7 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, tg->id = ret; } else { kfree(tg); - tg = ERR_PTR(ret); + tg = NULL; } mutex_unlock(&dev->mode_config.idr_mutex); -- cgit v1.2.3 From c27889ca3bb8bdc936bd0477125f0f6ff4c42df3 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 17 Dec 2018 10:03:44 +0300 Subject: drm/ati_pcigart: Fix error code in drm_ati_pcigart_init() The drm_ati_pcigart_init() function was originally suppose to return one on success and zero on failure, but these days it returns a mix of zero, one and -ENOMEM on failure. This patch cleans it up and modifies the caller so now the function returns zero on success and negative error codes on failure. Signed-off-by: Dan Carpenter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181217070344.GC12159@kadam --- drivers/gpu/drm/ati_pcigart.c | 7 ++++--- drivers/gpu/drm/r128/r128_cce.c | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c index 6c4d4b6eba80..2362f07fe1fc 100644 --- a/drivers/gpu/drm/ati_pcigart.c +++ b/drivers/gpu/drm/ati_pcigart.c @@ -103,7 +103,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga unsigned long pages; u32 *pci_gart = NULL, page_base, gart_idx; dma_addr_t bus_address = 0; - int i, j, ret = 0; + int i, j, ret = -ENOMEM; int max_ati_pages, max_real_pages; if (!entry) { @@ -117,7 +117,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { DRM_ERROR("fail to set dma mask to 0x%Lx\n", (unsigned long long)gart_info->table_mask); - ret = 1; + ret = -EFAULT; goto done; } @@ -160,6 +160,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga drm_ati_pcigart_cleanup(dev, gart_info); address = NULL; bus_address = 0; + ret = -ENOMEM; goto done; } page_base = (u32) entry->busaddr[i]; @@ -188,7 +189,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga page_base += ATI_PCIGART_PAGE_SIZE; } } - ret = 1; + ret = 0; #if defined(__i386__) || defined(__x86_64__) wbinvd(); diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c index c9890afe69d6..b91af1bf531b 100644 --- a/drivers/gpu/drm/r128/r128_cce.c +++ b/drivers/gpu/drm/r128/r128_cce.c @@ -560,11 +560,12 @@ static int r128_do_init_cce(struct drm_device *dev, drm_r128_init_t *init) dev_priv->gart_info.addr = NULL; dev_priv->gart_info.bus_addr = 0; dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; - if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { + rc = drm_ati_pcigart_init(dev, &dev_priv->gart_info); + if (rc) { DRM_ERROR("failed to init PCI GART!\n"); dev->dev_private = (void *)dev_priv; r128_do_cleanup_cce(dev); - return -ENOMEM; + return rc; } R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr); #if IS_ENABLED(CONFIG_AGP) -- cgit v1.2.3 From 329e95a7871d8bd52d2f7aabca7daf147a26fdb1 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 16 Dec 2018 18:49:08 +0000 Subject: drm/vkms: set preferred depth to 24 Otherwise DRM_CAP_DUMB_PREFERRED_DEPTH is zero. Signed-off-by: Simon Ser Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/o2SmEP0M6h287Fs5OeL3HtQzTr8uV0PyOhFict_qdxeS7vFvV1Zr8qzRUJh-YnCoJHo13nJgAqqQByzEzTZTqk9R2ExsOszYLj68hQLqBIc=@emersion.fr --- drivers/gpu/drm/vkms/vkms_drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c index 83087877565c..2a16b86196dc 100644 --- a/drivers/gpu/drm/vkms/vkms_drv.c +++ b/drivers/gpu/drm/vkms/vkms_drv.c @@ -95,6 +95,7 @@ static int vkms_modeset_init(struct vkms_device *vkmsdev) dev->mode_config.min_height = YRES_MIN; dev->mode_config.max_width = XRES_MAX; dev->mode_config.max_height = YRES_MAX; + dev->mode_config.preferred_depth = 24; return vkms_output_init(vkmsdev); } -- cgit v1.2.3 From 199d035bb84d0c8b7fb1847943729a114e351a84 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 18 Dec 2018 15:00:24 +0900 Subject: drm: dw-hdmi-i2s: convert to SPDX identifiers This patch updates license to use SPDX-License-Identifier instead of verbose license text. Signed-off-by: Kuninori Morimoto Reviewed-by: Laurent Pinchart Signed-off-by: Andrzej Hajda Link: https://patchwork.freedesktop.org/patch/msgid/87lg4n1izg.wl-kuninori.morimoto.gx@renesas.com --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index 8f9c8a6b46de..2228689d9a5e 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dw-hdmi-i2s-audio.c * * Copyright (c) 2017 Renesas Solutions Corp. * Kuninori Morimoto - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include -- cgit v1.2.3 From eda6887f1961e0d2fb866b1a520b2de5b3828de5 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 6 Dec 2018 15:24:35 +0100 Subject: drm/connector: Fix drm_mode_create_tv_properties() doc The in the kernel-doc header did not match the function name. Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-2-boris.brezillon@bootlin.com --- drivers/gpu/drm/drm_connector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index f0dd3315b1b8..32946eff5488 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1138,7 +1138,7 @@ void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame, EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type); /** - * drm_create_tv_properties - create TV specific connector properties + * drm_mode_create_tv_properties - create TV specific connector properties * @dev: DRM device * @num_modes: number of different TV formats (modes) supported * @modes: array of pointers to strings containing name of each format -- cgit v1.2.3 From 6c4f52dca36f5e3e2354c30591d38e92f4657ed9 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 6 Dec 2018 15:24:37 +0100 Subject: drm/connector: Allow creation of margin props alone TV margins properties can only be added as part of the SDTV TV connector properties creation, but we might need those props for HDMI TVs too, so let's move the margins props creation in a separate function and expose it to drivers. We also add an helper to attach margins props to a connector. Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-4-boris.brezillon@bootlin.com --- drivers/gpu/drm/drm_connector.c | 83 ++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 18 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 32946eff5488..66b2fd20369a 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1137,6 +1137,70 @@ void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame, } EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type); +/** + * drm_mode_attach_tv_margin_properties - attach TV connector margin properties + * @connector: DRM connector + * + * Called by a driver when it needs to attach TV margin props to a connector. + * Typically used on SDTV and HDMI connectors. + */ +void drm_connector_attach_tv_margin_properties(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + + drm_object_attach_property(&connector->base, + dev->mode_config.tv_left_margin_property, + 0); + drm_object_attach_property(&connector->base, + dev->mode_config.tv_right_margin_property, + 0); + drm_object_attach_property(&connector->base, + dev->mode_config.tv_top_margin_property, + 0); + drm_object_attach_property(&connector->base, + dev->mode_config.tv_bottom_margin_property, + 0); +} +EXPORT_SYMBOL(drm_connector_attach_tv_margin_properties); + +/** + * drm_mode_create_tv_margin_properties - create TV connector margin properties + * @dev: DRM device + * + * Called by a driver's HDMI connector initialization routine, this function + * creates the TV margin properties for a given device. No need to call this + * function for an SDTV connector, it's already called from + * drm_mode_create_tv_properties(). + */ +int drm_mode_create_tv_margin_properties(struct drm_device *dev) +{ + if (dev->mode_config.tv_left_margin_property) + return 0; + + dev->mode_config.tv_left_margin_property = + drm_property_create_range(dev, 0, "left margin", 0, 100); + if (!dev->mode_config.tv_left_margin_property) + return -ENOMEM; + + dev->mode_config.tv_right_margin_property = + drm_property_create_range(dev, 0, "right margin", 0, 100); + if (!dev->mode_config.tv_right_margin_property) + return -ENOMEM; + + dev->mode_config.tv_top_margin_property = + drm_property_create_range(dev, 0, "top margin", 0, 100); + if (!dev->mode_config.tv_top_margin_property) + return -ENOMEM; + + dev->mode_config.tv_bottom_margin_property = + drm_property_create_range(dev, 0, "bottom margin", 0, 100); + if (!dev->mode_config.tv_bottom_margin_property) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL(drm_mode_create_tv_margin_properties); + /** * drm_mode_create_tv_properties - create TV specific connector properties * @dev: DRM device @@ -1183,24 +1247,7 @@ int drm_mode_create_tv_properties(struct drm_device *dev, /* * Other, TV specific properties: margins & TV modes. */ - dev->mode_config.tv_left_margin_property = - drm_property_create_range(dev, 0, "left margin", 0, 100); - if (!dev->mode_config.tv_left_margin_property) - goto nomem; - - dev->mode_config.tv_right_margin_property = - drm_property_create_range(dev, 0, "right margin", 0, 100); - if (!dev->mode_config.tv_right_margin_property) - goto nomem; - - dev->mode_config.tv_top_margin_property = - drm_property_create_range(dev, 0, "top margin", 0, 100); - if (!dev->mode_config.tv_top_margin_property) - goto nomem; - - dev->mode_config.tv_bottom_margin_property = - drm_property_create_range(dev, 0, "bottom margin", 0, 100); - if (!dev->mode_config.tv_bottom_margin_property) + if (drm_mode_create_tv_margin_properties(dev)) goto nomem; dev->mode_config.tv_mode_property = -- cgit v1.2.3 From 666e73587f90f42d90385c1bea1009a650bf73f4 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 6 Dec 2018 15:24:38 +0100 Subject: drm/vc4: Take margin setup into account when updating planes Applyin margins is just a matter of scaling all planes appropriately and adjusting the CRTC X/Y offset to account for the left/right/top/bottom borders. Create a vc4_plane_margins_adj() function doing that and call it from vc4_plane_setup_clipping_and_scaling() so that we are ready to attach margins properties to the HDMI connector. Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-5-boris.brezillon@bootlin.com --- drivers/gpu/drm/vc4/vc4_crtc.c | 43 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_drv.h | 3 +++ drivers/gpu/drm/vc4/vc4_plane.c | 50 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 3ce136ba8791..97caf1671dd0 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -49,6 +49,13 @@ struct vc4_crtc_state { struct drm_mm_node mm; bool feed_txp; bool txp_armed; + + struct { + unsigned int left; + unsigned int right; + unsigned int top; + unsigned int bottom; + } margins; }; static inline struct vc4_crtc_state * @@ -624,6 +631,37 @@ static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc, return MODE_OK; } +void vc4_crtc_get_margins(struct drm_crtc_state *state, + unsigned int *left, unsigned int *right, + unsigned int *top, unsigned int *bottom) +{ + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); + struct drm_connector_state *conn_state; + struct drm_connector *conn; + int i; + + *left = vc4_state->margins.left; + *right = vc4_state->margins.right; + *top = vc4_state->margins.top; + *bottom = vc4_state->margins.bottom; + + /* We have to interate over all new connector states because + * vc4_crtc_get_margins() might be called before + * vc4_crtc_atomic_check() which means margins info in vc4_crtc_state + * might be outdated. + */ + for_each_new_connector_in_state(state->state, conn, conn_state, i) { + if (conn_state->crtc != state->crtc) + continue; + + *left = conn_state->tv.margins.left; + *right = conn_state->tv.margins.right; + *top = conn_state->tv.margins.top; + *bottom = conn_state->tv.margins.bottom; + break; + } +} + static int vc4_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { @@ -671,6 +709,10 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc, vc4_state->feed_txp = false; } + vc4_state->margins.left = conn_state->tv.margins.left; + vc4_state->margins.right = conn_state->tv.margins.right; + vc4_state->margins.top = conn_state->tv.margins.top; + vc4_state->margins.bottom = conn_state->tv.margins.bottom; break; } @@ -972,6 +1014,7 @@ static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) old_vc4_state = to_vc4_crtc_state(crtc->state); vc4_state->feed_txp = old_vc4_state->feed_txp; + vc4_state->margins = old_vc4_state->margins; __drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base); return &vc4_state->base; diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 4f87b03f837d..c24b078f0593 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -707,6 +707,9 @@ bool vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, const struct drm_display_mode *mode); void vc4_crtc_handle_vblank(struct vc4_crtc *crtc); void vc4_crtc_txp_armed(struct drm_crtc_state *state); +void vc4_crtc_get_margins(struct drm_crtc_state *state, + unsigned int *right, unsigned int *left, + unsigned int *top, unsigned int *bottom); /* vc4_debugfs.c */ int vc4_debugfs_init(struct drm_minor *minor); diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 283abd7d1e9b..2901ed0c5223 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -258,6 +258,52 @@ static u32 vc4_get_scl_field(struct drm_plane_state *state, int plane) } } +static int vc4_plane_margins_adj(struct drm_plane_state *pstate) +{ + struct vc4_plane_state *vc4_pstate = to_vc4_plane_state(pstate); + unsigned int left, right, top, bottom, adjhdisplay, adjvdisplay; + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_new_crtc_state(pstate->state, + pstate->crtc); + + vc4_crtc_get_margins(crtc_state, &left, &right, &top, &bottom); + if (!left && !right && !top && !bottom) + return 0; + + if (left + right >= crtc_state->mode.hdisplay || + top + bottom >= crtc_state->mode.vdisplay) + return -EINVAL; + + adjhdisplay = crtc_state->mode.hdisplay - (left + right); + vc4_pstate->crtc_x = DIV_ROUND_CLOSEST(vc4_pstate->crtc_x * + adjhdisplay, + crtc_state->mode.hdisplay); + vc4_pstate->crtc_x += left; + if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left) + vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left; + + adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); + vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y * + adjvdisplay, + crtc_state->mode.vdisplay); + vc4_pstate->crtc_y += top; + if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top) + vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top; + + vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w * + adjhdisplay, + crtc_state->mode.hdisplay); + vc4_pstate->crtc_h = DIV_ROUND_CLOSEST(vc4_pstate->crtc_h * + adjvdisplay, + crtc_state->mode.vdisplay); + + if (!vc4_pstate->crtc_w || !vc4_pstate->crtc_h) + return -EINVAL; + + return 0; +} + static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) { struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); @@ -306,6 +352,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) vc4_state->crtc_w = state->dst.x2 - state->dst.x1; vc4_state->crtc_h = state->dst.y2 - state->dst.y1; + ret = vc4_plane_margins_adj(state); + if (ret) + return ret; + vc4_state->x_scaling[0] = vc4_get_scaling_mode(vc4_state->src_w[0], vc4_state->crtc_w); vc4_state->y_scaling[0] = vc4_get_scaling_mode(vc4_state->src_h[0], -- cgit v1.2.3 From db999538fdb0679629d90652f8a1437df1e85a7d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 6 Dec 2018 15:24:39 +0100 Subject: drm/vc4: Attach margin props to the HDMI connector Now that the plane code takes the margins setup into account, we can safely attach margin props to the HDMI connector. We also take care of filling AVI infoframes correctly to expose the top/botton/left/right bar. Note that those margin props match pretty well the overscan_{left,right,top,bottom} properties defined in config.txt and parsed by the VC4 firmware. Signed-off-by: Boris Brezillon Reviewed-by: Eric Anholt Acked-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181206142439.10441-6-boris.brezillon@bootlin.com --- drivers/gpu/drm/vc4/vc4_hdmi.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index fd5522fd179e..2f276222e30f 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -310,6 +310,7 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev, { struct drm_connector *connector; struct vc4_hdmi_connector *hdmi_connector; + int ret; hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector), GFP_KERNEL); @@ -323,6 +324,13 @@ static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev, DRM_MODE_CONNECTOR_HDMIA); drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs); + /* Create and attach TV margin props to this connector. */ + ret = drm_mode_create_tv_margin_properties(dev); + if (ret) + return ERR_PTR(ret); + + drm_connector_attach_tv_margin_properties(connector); + connector->polled = (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT); @@ -408,6 +416,9 @@ static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder, static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) { struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder); + struct vc4_dev *vc4 = encoder->dev->dev_private; + struct vc4_hdmi *hdmi = vc4->hdmi; + struct drm_connector_state *cstate = hdmi->connector->state; struct drm_crtc *crtc = encoder->crtc; const struct drm_display_mode *mode = &crtc->state->adjusted_mode; union hdmi_infoframe frame; @@ -426,6 +437,11 @@ static void vc4_hdmi_set_avi_infoframe(struct drm_encoder *encoder) vc4_encoder->rgb_range_selectable, false); + frame.avi.right_bar = cstate->tv.margins.right; + frame.avi.left_bar = cstate->tv.margins.left; + frame.avi.top_bar = cstate->tv.margins.top; + frame.avi.bottom_bar = cstate->tv.margins.bottom; + vc4_hdmi_write_infoframe(encoder, &frame); } -- cgit v1.2.3 From 70bce993a7aa57c00798d8f13ebbbddd81cbbef9 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 20 Dec 2018 11:11:21 +0100 Subject: drm/bochs: add edid present check Check header before trying to read the complete edid blob, to avoid the log being spammed in case qemu has no edid support (old qemu or edid support turned off). Fixes: 01f23459cf drm/bochs: add edid support. Signed-off-by: Gerd Hoffmann Reviewed-by: Daniel Vetter Reviewed-by: Oleksandr Andrushchenko Link: http://patchwork.freedesktop.org/patch/msgid/20181220101122.16153-1-kraxel@redhat.com --- drivers/gpu/drm/bochs/bochs_hw.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c index c90a0d492fd5..d0b4e1cee83e 100644 --- a/drivers/gpu/drm/bochs/bochs_hw.c +++ b/drivers/gpu/drm/bochs/bochs_hw.c @@ -86,9 +86,16 @@ static int bochs_get_edid_block(void *data, u8 *buf, int bochs_hw_load_edid(struct bochs_device *bochs) { + u8 header[8]; + if (!bochs->mmio) return -1; + /* check header to detect whenever edid support is enabled in qemu */ + bochs_get_edid_block(bochs, header, 0, ARRAY_SIZE(header)); + if (drm_edid_header_is_valid(header) != 8) + return -1; + kfree(bochs->edid); bochs->edid = drm_do_get_edid(&bochs->connector, bochs_get_edid_block, bochs); -- cgit v1.2.3 From 183d9dc49572718d1f2b943d0bdea039a90f766d Mon Sep 17 00:00:00 2001 From: Brajeswar Ghosh Date: Mon, 24 Dec 2018 20:06:36 +0530 Subject: drm/drm_drv.c: Remove duplicate header Remove drm_crtc_internal.h which is included more than once Signed-off-by: Brajeswar Ghosh Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181224143636.GA3237@hp-pavilion-15-notebook-pc-brajeswar --- drivers/gpu/drm/drm_drv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 12e5e2be7890..a5fe91b8c3c9 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -41,7 +41,6 @@ #include "drm_crtc_internal.h" #include "drm_legacy.h" #include "drm_internal.h" -#include "drm_crtc_internal.h" /* * drm_debug: Enable debug output. -- cgit v1.2.3 From ecb2e2fd5a442e8639b9648df54b77a32ca4c906 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 26 Dec 2018 22:03:47 +0100 Subject: drm: move DRM_IF_VERSION to drm_internal.h Move DRM_IF_VERSION out of drmP.h to allow users to get rid of the drmP include. Signed-off-by: Sam Ravnborg Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Sean Paul Cc: David Airlie Cc: Daniel Vetter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181226210353.13993-1-sam@ravnborg.org --- drivers/gpu/drm/drm_internal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h index c7a7d7ce5d1c..331112b2ae88 100644 --- a/drivers/gpu/drm/drm_internal.h +++ b/drivers/gpu/drm/drm_internal.h @@ -26,6 +26,8 @@ #define DRM_IF_MAJOR 1 #define DRM_IF_MINOR 4 +#define DRM_IF_VERSION(maj, min) (maj << 16 | min) + struct drm_prime_file_private; struct dma_buf; -- cgit v1.2.3 From c76426883c8f44bc7d2aee123e28867c67b87384 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 28 Dec 2018 15:04:46 +0200 Subject: drm: un-inline drm_legacy_findmap() Un-inline drm_legacy_findmap() to not depend on struct drm_device definition within drm_legacy.h, so that a forward declaration suffices. Also include drm_hashtab.h in drm_legacy.h to make it more self-contained. Make it easier to drop drmP.h includes. v2: avoid including drm_device.h by un-inlining (Daniel) [Updated commit message per Laurent's review while applying.] Cc: Sam Ravnborg Cc: Daniel Vetter Cc: Laurent Pinchart Reviewed-by: Daniel Vetter Reviewed-by: Laurent Pinchart Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20181228130446.22141-1-jani.nikula@intel.com --- drivers/gpu/drm/drm_bufs.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index d7d10cabb9bb..a39ab2193bfe 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -377,6 +377,17 @@ int drm_legacy_addmap(struct drm_device *dev, resource_size_t offset, } EXPORT_SYMBOL(drm_legacy_addmap); +struct drm_local_map *drm_legacy_findmap(struct drm_device *dev, + unsigned int token) +{ + struct drm_map_list *_entry; + list_for_each_entry(_entry, &dev->maplist, head) + if (_entry->user_token == token) + return _entry->map; + return NULL; +} +EXPORT_SYMBOL(drm_legacy_findmap); + /** * Ioctl to specify a range of memory that is available for mapping by a * non-root process. -- cgit v1.2.3 From 227ad6d957898a88b1746e30234ece64d305f066 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 30 Dec 2018 12:28:42 +0000 Subject: drm: Reorder set_property_atomic to avoid returning with an active ww_ctx Delay the drm_modeset_acquire_init() until after we check for an allocation failure so that we can return immediately upon error without having to unwind. WARNING: lock held when returning to user space! 4.20.0+ #174 Not tainted ------------------------------------------------ syz-executor556/8153 is leaving the kernel with locks still held! 1 lock held by syz-executor556/8153: #0: 000000005100c85c (crtc_ww_class_acquire){+.+.}, at: set_property_atomic+0xb3/0x330 drivers/gpu/drm/drm_mode_object.c:462 Reported-by: syzbot+6ea337c427f5083ebdf2@syzkaller.appspotmail.com Fixes: 144a7999d633 ("drm: Handle properties in the core for atomic drivers") Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Maarten Lankhorst Cc: Sean Paul Cc: David Airlie Cc: # v4.14+ Reviewed-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20181230122842.21917-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/drm_mode_object.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_mode_object.c b/drivers/gpu/drm/drm_mode_object.c index bb1dd46496cd..a9005c1c2384 100644 --- a/drivers/gpu/drm/drm_mode_object.c +++ b/drivers/gpu/drm/drm_mode_object.c @@ -459,12 +459,13 @@ static int set_property_atomic(struct drm_mode_object *obj, struct drm_modeset_acquire_ctx ctx; int ret; - drm_modeset_acquire_init(&ctx, 0); - state = drm_atomic_state_alloc(dev); if (!state) return -ENOMEM; + + drm_modeset_acquire_init(&ctx, 0); state->acquire_ctx = &ctx; + retry: if (prop == state->dev->mode_config.dpms_property) { if (obj->type != DRM_MODE_OBJECT_CONNECTOR) { -- cgit v1.2.3 From c39191feed4540fed98badeb484833dcf659bb96 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 29 Dec 2018 10:49:07 +0800 Subject: drm: Fix error handling in drm_legacy_addctx 'ctx->handle' is unsigned, it never less than zero. This patch use int 'tmp_handle' to handle the err condition. Fixes: 62968144e673 ("drm: convert drm context code to use Linux idr") Signed-off-by: YueHaibing Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20181229024907.12852-1-yuehaibing@huawei.com --- drivers/gpu/drm/drm_context.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index 506663c69b0a..6e8e1a9fcae3 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c @@ -361,23 +361,26 @@ int drm_legacy_addctx(struct drm_device *dev, void *data, { struct drm_ctx_list *ctx_entry; struct drm_ctx *ctx = data; + int tmp_handle; if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) && !drm_core_check_feature(dev, DRIVER_LEGACY)) return -EOPNOTSUPP; - ctx->handle = drm_legacy_ctxbitmap_next(dev); - if (ctx->handle == DRM_KERNEL_CONTEXT) { + tmp_handle = drm_legacy_ctxbitmap_next(dev); + if (tmp_handle == DRM_KERNEL_CONTEXT) { /* Skip kernel's context and get a new one. */ - ctx->handle = drm_legacy_ctxbitmap_next(dev); + tmp_handle = drm_legacy_ctxbitmap_next(dev); } - DRM_DEBUG("%d\n", ctx->handle); - if (ctx->handle < 0) { + DRM_DEBUG("%d\n", tmp_handle); + if (tmp_handle < 0) { DRM_DEBUG("Not enough free contexts.\n"); /* Should this return -EBUSY instead? */ - return -ENOMEM; + return tmp_handle; } + ctx->handle = tmp_handle; + ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL); if (!ctx_entry) { DRM_DEBUG("out of memory\n"); -- cgit v1.2.3