From 812eeeb6b59e15e0f2dece81b4600d2206283cd3 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Wed, 3 Oct 2018 14:36:44 -0400 Subject: [PATCH 01/91] drm/msm: dpu: Add tracing around CTL_FLUSH I found these tracepoints useful for debugging cursor/ctl, someone else might find them useful too Reviewed-by: Jeykumar Sankaran Reviewed-by: Abhinav Kumar Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 26 ++++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 47 ++++++++++++++++++++++ 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index eec1051f2afc..d3f8b929af65 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -15,6 +15,7 @@ #include "dpu_hw_ctl.h" #include "dpu_dbg.h" #include "dpu_kms.h" +#include "dpu_trace.h" #define CTL_LAYER(lm) \ (((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004)) @@ -72,24 +73,39 @@ static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count, return stages; } +static inline u32 dpu_hw_ctl_get_flush_register(struct dpu_hw_ctl *ctx) +{ + struct dpu_hw_blk_reg_map *c = &ctx->hw; + + return DPU_REG_READ(c, CTL_FLUSH); +} + static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx) { + trace_dpu_hw_ctl_trigger_start(ctx->pending_flush_mask, + dpu_hw_ctl_get_flush_register(ctx)); DPU_REG_WRITE(&ctx->hw, CTL_START, 0x1); } static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx) { + trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask, + dpu_hw_ctl_get_flush_register(ctx)); DPU_REG_WRITE(&ctx->hw, CTL_PREPARE, 0x1); } static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx) { + trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask, + dpu_hw_ctl_get_flush_register(ctx)); ctx->pending_flush_mask = 0x0; } static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx, u32 flushbits) { + trace_dpu_hw_ctl_update_pending_flush(flushbits, + ctx->pending_flush_mask); ctx->pending_flush_mask |= flushbits; } @@ -103,17 +119,11 @@ static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx) static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx) { - + trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask, + dpu_hw_ctl_get_flush_register(ctx)); DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } -static inline u32 dpu_hw_ctl_get_flush_register(struct dpu_hw_ctl *ctx) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - - return DPU_REG_READ(c, CTL_FLUSH); -} - static inline uint32_t dpu_hw_ctl_get_bitmask_sspp(struct dpu_hw_ctl *ctx, enum dpu_sspp sspp) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index e12c4cefb742..636b31b0d311 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -1004,6 +1004,53 @@ TRACE_EVENT(dpu_core_perf_update_clk, __entry->stop_req ? "true" : "false", __entry->clk_rate) ); +TRACE_EVENT(dpu_hw_ctl_update_pending_flush, + TP_PROTO(u32 new_bits, u32 pending_mask), + TP_ARGS(new_bits, pending_mask), + TP_STRUCT__entry( + __field( u32, new_bits ) + __field( u32, pending_mask ) + ), + TP_fast_assign( + __entry->new_bits = new_bits; + __entry->pending_mask = pending_mask; + ), + TP_printk("new=%x existing=%x", __entry->new_bits, + __entry->pending_mask) +); + +DECLARE_EVENT_CLASS(dpu_hw_ctl_pending_flush_template, + TP_PROTO(u32 pending_mask, u32 ctl_flush), + TP_ARGS(pending_mask, ctl_flush), + TP_STRUCT__entry( + __field( u32, pending_mask ) + __field( u32, ctl_flush ) + ), + TP_fast_assign( + __entry->pending_mask = pending_mask; + __entry->ctl_flush = ctl_flush; + ), + TP_printk("pending_mask=%x CTL_FLUSH=%x", __entry->pending_mask, + __entry->ctl_flush) +); +DEFINE_EVENT(dpu_hw_ctl_pending_flush_template, dpu_hw_ctl_clear_pending_flush, + TP_PROTO(u32 pending_mask, u32 ctl_flush), + TP_ARGS(pending_mask, ctl_flush) +); +DEFINE_EVENT(dpu_hw_ctl_pending_flush_template, + dpu_hw_ctl_trigger_pending_flush, + TP_PROTO(u32 pending_mask, u32 ctl_flush), + TP_ARGS(pending_mask, ctl_flush) +); +DEFINE_EVENT(dpu_hw_ctl_pending_flush_template, dpu_hw_ctl_trigger_prepare, + TP_PROTO(u32 pending_mask, u32 ctl_flush), + TP_ARGS(pending_mask, ctl_flush) +); +DEFINE_EVENT(dpu_hw_ctl_pending_flush_template, dpu_hw_ctl_trigger_start, + TP_PROTO(u32 pending_mask, u32 ctl_flush), + TP_ARGS(pending_mask, ctl_flush) +); + #define DPU_ATRACE_END(name) trace_tracing_mark_write(current->tgid, name, 0) #define DPU_ATRACE_BEGIN(name) trace_tracing_mark_write(current->tgid, name, 1) #define DPU_ATRACE_FUNC() DPU_ATRACE_BEGIN(__func__) From b2b83523b1768828c3122a2862fa0dd88fb40489 Mon Sep 17 00:00:00 2001 From: Bruce Wang Date: Fri, 5 Oct 2018 17:04:00 -0400 Subject: [PATCH 02/91] drm/msm/dpu: Remove dpu_kms_pm_suspend/resume PM resume was crashing during dpu_kms_pm_resume. This patch removes dpu_kms_pm_suspend/resume so that msm_pm_suspend/resume uses the atomic helpers instead (see next patch). This patch also removes dpu_kms_is_suspend_blocked since it is never called. v2: Reorganized patches in patchset Signed-off-by: Bruce Wang Reviewed-by: Sean Paul Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 123 ------------------------ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 15 --- 2 files changed, 138 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 0a683e65a9f3..ff06b50dfc87 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -709,127 +709,6 @@ static void dpu_kms_destroy(struct msm_kms *kms) _dpu_kms_hw_destroy(dpu_kms); } -static int dpu_kms_pm_suspend(struct device *dev) -{ - struct drm_device *ddev; - struct drm_modeset_acquire_ctx ctx; - struct drm_atomic_state *state; - struct dpu_kms *dpu_kms; - int ret = 0, num_crtcs = 0; - - if (!dev) - return -EINVAL; - - ddev = dev_get_drvdata(dev); - if (!ddev || !ddev_to_msm_kms(ddev)) - return -EINVAL; - - dpu_kms = to_dpu_kms(ddev_to_msm_kms(ddev)); - - /* disable hot-plug polling */ - drm_kms_helper_poll_disable(ddev); - - /* acquire modeset lock(s) */ - drm_modeset_acquire_init(&ctx, 0); - -retry: - DPU_ATRACE_BEGIN("kms_pm_suspend"); - - ret = drm_modeset_lock_all_ctx(ddev, &ctx); - if (ret) - goto unlock; - - /* save current state for resume */ - if (dpu_kms->suspend_state) - drm_atomic_state_put(dpu_kms->suspend_state); - dpu_kms->suspend_state = drm_atomic_helper_duplicate_state(ddev, &ctx); - if (IS_ERR_OR_NULL(dpu_kms->suspend_state)) { - DRM_ERROR("failed to back up suspend state\n"); - dpu_kms->suspend_state = NULL; - goto unlock; - } - - /* create atomic state to disable all CRTCs */ - state = drm_atomic_state_alloc(ddev); - if (IS_ERR_OR_NULL(state)) { - DRM_ERROR("failed to allocate crtc disable state\n"); - goto unlock; - } - - state->acquire_ctx = &ctx; - - /* check for nothing to do */ - if (num_crtcs == 0) { - DRM_DEBUG("all crtcs are already in the off state\n"); - drm_atomic_state_put(state); - goto suspended; - } - - /* commit the "disable all" state */ - ret = drm_atomic_commit(state); - if (ret < 0) { - DRM_ERROR("failed to disable crtcs, %d\n", ret); - drm_atomic_state_put(state); - goto unlock; - } - -suspended: - dpu_kms->suspend_block = true; - -unlock: - if (ret == -EDEADLK) { - drm_modeset_backoff(&ctx); - goto retry; - } - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); - - DPU_ATRACE_END("kms_pm_suspend"); - return 0; -} - -static int dpu_kms_pm_resume(struct device *dev) -{ - struct drm_device *ddev; - struct dpu_kms *dpu_kms; - int ret; - - if (!dev) - return -EINVAL; - - ddev = dev_get_drvdata(dev); - if (!ddev || !ddev_to_msm_kms(ddev)) - return -EINVAL; - - dpu_kms = to_dpu_kms(ddev_to_msm_kms(ddev)); - - DPU_ATRACE_BEGIN("kms_pm_resume"); - - drm_mode_config_reset(ddev); - - drm_modeset_lock_all(ddev); - - dpu_kms->suspend_block = false; - - if (dpu_kms->suspend_state) { - dpu_kms->suspend_state->acquire_ctx = - ddev->mode_config.acquire_ctx; - ret = drm_atomic_commit(dpu_kms->suspend_state); - if (ret < 0) { - DRM_ERROR("failed to restore state, %d\n", ret); - drm_atomic_state_put(dpu_kms->suspend_state); - } - dpu_kms->suspend_state = NULL; - } - drm_modeset_unlock_all(ddev); - - /* enable hot-plug polling */ - drm_kms_helper_poll_enable(ddev); - - DPU_ATRACE_END("kms_pm_resume"); - return 0; -} - static void _dpu_kms_set_encoder_mode(struct msm_kms *kms, struct drm_encoder *encoder, bool cmd_mode) @@ -873,8 +752,6 @@ static const struct msm_kms_funcs kms_funcs = { .check_modified_format = dpu_format_check_modified_format, .get_format = dpu_get_msm_format, .round_pixclk = dpu_kms_round_pixclk, - .pm_suspend = dpu_kms_pm_suspend, - .pm_resume = dpu_kms_pm_resume, .destroy = dpu_kms_destroy, .set_encoder_mode = _dpu_kms_set_encoder_mode, #ifdef CONFIG_DEBUG_FS diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 66d466628e2b..1991cbe424a3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -137,7 +137,6 @@ struct dpu_kms { /* saved atomic state during system suspend */ struct drm_atomic_state *suspend_state; - bool suspend_block; struct dpu_rm rm; bool rm_init; @@ -176,20 +175,6 @@ static inline bool dpu_kms_is_suspend_state(struct drm_device *dev) return to_dpu_kms(ddev_to_msm_kms(dev))->suspend_state != NULL; } -/** - * dpu_kms_is_suspend_blocked - whether or not commits are blocked due to pm - * suspend status - * @dev: Pointer to drm device - * Return: True if commits should be rejected due to pm suspend - */ -static inline bool dpu_kms_is_suspend_blocked(struct drm_device *dev) -{ - if (!dpu_kms_is_suspend_state(dev)) - return false; - - return to_dpu_kms(ddev_to_msm_kms(dev))->suspend_block; -} - /** * Debugfs functions - extra helper functions for debugfs support * From 3750e78c72da3c35292dcf531ebe3062faaa33bc Mon Sep 17 00:00:00 2001 From: Bruce Wang Date: Fri, 5 Oct 2018 17:04:01 -0400 Subject: [PATCH 03/91] drm/msm: Cut dpu_kms hooks from msm_pm_suspend/resume Removes the traces of the non-atomic helper calls in msm_pm_suspend/resume since we just deleted those functions (see patch 1). Also removes the drm_kms_helper_poll_disable/enable calls, since the DRM_CONNECTOR_POLL_CONNECT flag is never set so periodic polling doesn't happen anyways. v2: reorganized patch order v3: made error checks less severe Reviewed-by: Sean Paul Signed-off-by: Bruce Wang Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 27 ++++++++++++--------------- drivers/gpu/drm/msm/msm_kms.h | 3 --- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 5e758d95751a..aa145d6f6469 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1070,18 +1070,15 @@ static int msm_pm_suspend(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); struct msm_drm_private *priv = ddev->dev_private; - struct msm_kms *kms = priv->kms; - /* TODO: Use atomic helper suspend/resume */ - if (kms && kms->funcs && kms->funcs->pm_suspend) - return kms->funcs->pm_suspend(dev); - - drm_kms_helper_poll_disable(ddev); + if (WARN_ON(priv->pm_state)) + drm_atomic_state_put(priv->pm_state); priv->pm_state = drm_atomic_helper_suspend(ddev); if (IS_ERR(priv->pm_state)) { - drm_kms_helper_poll_enable(ddev); - return PTR_ERR(priv->pm_state); + int ret = PTR_ERR(priv->pm_state); + DRM_ERROR("Failed to suspend dpu, %d\n", ret); + return ret; } return 0; @@ -1091,16 +1088,16 @@ static int msm_pm_resume(struct device *dev) { struct drm_device *ddev = dev_get_drvdata(dev); struct msm_drm_private *priv = ddev->dev_private; - struct msm_kms *kms = priv->kms; + int ret; - /* TODO: Use atomic helper suspend/resume */ - if (kms && kms->funcs && kms->funcs->pm_resume) - return kms->funcs->pm_resume(dev); + if (WARN_ON(!priv->pm_state)) + return -ENOENT; - drm_atomic_helper_resume(ddev, priv->pm_state); - drm_kms_helper_poll_enable(ddev); + ret = drm_atomic_helper_resume(ddev, priv->pm_state); + if (!ret) + priv->pm_state = NULL; - return 0; + return ret; } #endif diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index fd88cebb6adb..2b81b43a4bab 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -67,9 +67,6 @@ struct msm_kms_funcs { void (*set_encoder_mode)(struct msm_kms *kms, struct drm_encoder *encoder, bool cmd_mode); - /* pm suspend/resume hooks */ - int (*pm_suspend)(struct device *dev); - int (*pm_resume)(struct device *dev); /* cleanup: */ void (*destroy)(struct msm_kms *kms); #ifdef CONFIG_DEBUG_FS From 7a007a121d342f0948be1f06ad61cdc953f7dab6 Mon Sep 17 00:00:00 2001 From: Bruce Wang Date: Fri, 5 Oct 2018 17:04:02 -0400 Subject: [PATCH 04/91] drm/msm/dpu: Remove suspend state tracking from crtc Since drm core's modeset locks serialize atomic commits, we don't need to track whether or not we're in a suspended state from inside the crtc for dpu_crtc_enable/disable. This patch removes the suspend logic from the crtc and removes the relevant tracing from dpu_trace. Since we removed all calls to dpu_kms_is_suspend_state, we can remove that function and the suspend_state field of dpu_kms as well. v2: added patch to patchset v3: reworded commit body and moved deletion of dpu_kms_is_suspend_state and suspend_state to this patch Reviewed-by: Sean Paul Signed-off-by: Bruce Wang Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 48 ++--------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 16 -------- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 15 +------ 4 files changed, 6 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index d4530d60767b..ac604055a824 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -815,35 +815,6 @@ static void _dpu_crtc_vblank_enable_no_lock( } } -/** - * _dpu_crtc_set_suspend - notify crtc of suspend enable/disable - * @crtc: Pointer to drm crtc object - * @enable: true to enable suspend, false to indicate resume - */ -static void _dpu_crtc_set_suspend(struct drm_crtc *crtc, bool enable) -{ - struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); - - DRM_DEBUG_KMS("crtc%d suspend = %d\n", crtc->base.id, enable); - - mutex_lock(&dpu_crtc->crtc_lock); - - /* - * If the vblank is enabled, release a power reference on suspend - * and take it back during resume (if it is still enabled). - */ - trace_dpu_crtc_set_suspend(DRMID(&dpu_crtc->base), enable, dpu_crtc); - if (dpu_crtc->suspend == enable) - DPU_DEBUG("crtc%d suspend already set to %d, ignoring update\n", - crtc->base.id, enable); - else if (dpu_crtc->enabled && dpu_crtc->vblank_requested) { - _dpu_crtc_vblank_enable_no_lock(dpu_crtc, !enable); - } - - dpu_crtc->suspend = enable; - mutex_unlock(&dpu_crtc->crtc_lock); -} - /** * dpu_crtc_duplicate_state - state duplicate hook * @crtc: Pointer to drm crtc structure @@ -951,9 +922,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) DRM_DEBUG_KMS("crtc%d\n", crtc->base.id); - if (dpu_kms_is_suspend_state(crtc->dev)) - _dpu_crtc_set_suspend(crtc, true); - /* Disable/save vblank irq handling */ drm_crtc_vblank_off(crtc); @@ -966,8 +934,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) atomic_read(&dpu_crtc->frame_pending)); trace_dpu_crtc_disable(DRMID(crtc), false, dpu_crtc); - if (dpu_crtc->enabled && !dpu_crtc->suspend && - dpu_crtc->vblank_requested) { + if (dpu_crtc->enabled && dpu_crtc->vblank_requested) { _dpu_crtc_vblank_enable_no_lock(dpu_crtc, false); } dpu_crtc->enabled = false; @@ -1033,8 +1000,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc); - if (!dpu_crtc->enabled && !dpu_crtc->suspend && - dpu_crtc->vblank_requested) { + if (!dpu_crtc->enabled && dpu_crtc->vblank_requested) { _dpu_crtc_vblank_enable_no_lock(dpu_crtc, true); } dpu_crtc->enabled = true; @@ -1289,17 +1255,11 @@ end: int dpu_crtc_vblank(struct drm_crtc *crtc, bool en) { - struct dpu_crtc *dpu_crtc; - - if (!crtc) { - DPU_ERROR("invalid crtc\n"); - return -EINVAL; - } - dpu_crtc = to_dpu_crtc(crtc); + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_vblank(DRMID(&dpu_crtc->base), en, dpu_crtc); - if (dpu_crtc->enabled && !dpu_crtc->suspend) { + if (dpu_crtc->enabled) { _dpu_crtc_vblank_enable_no_lock(dpu_crtc, en); } dpu_crtc->vblank_requested = en; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 3723b4830335..7dc181aabb4d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -133,7 +133,6 @@ struct dpu_crtc_frame_event { * @play_count : frame count between crtc enable and disable * @vblank_cb_time : ktime at vblank count reset * @vblank_requested : whether the user has requested vblank events - * @suspend : whether or not a suspend operation is in progress * @enabled : whether the DPU CRTC is currently enabled. updated in the * commit-thread, not state-swap time which is earlier, so * safe to make decisions on during VBLANK on/off work @@ -169,7 +168,6 @@ struct dpu_crtc { u64 play_count; ktime_t vblank_cb_time; bool vblank_requested; - bool suspend; bool enabled; struct list_head feature_list; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 1991cbe424a3..2a3625eef6d3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -135,9 +135,6 @@ struct dpu_kms { struct dpu_core_perf perf; - /* saved atomic state during system suspend */ - struct drm_atomic_state *suspend_state; - struct dpu_rm rm; bool rm_init; @@ -162,19 +159,6 @@ struct vsync_info { #define ddev_to_msm_kms(D) ((D) && (D)->dev_private ? \ ((struct msm_drm_private *)((D)->dev_private))->kms : NULL) -/** - * dpu_kms_is_suspend_state - whether or not the system is pm suspended - * @dev: Pointer to drm device - * Return: Suspend status - */ -static inline bool dpu_kms_is_suspend_state(struct drm_device *dev) -{ - if (!ddev_to_msm_kms(dev)) - return false; - - return to_dpu_kms(ddev_to_msm_kms(dev))->suspend_state != NULL; -} - /** * Debugfs functions - extra helper functions for debugfs support * diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index 636b31b0d311..0c122e173892 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -749,7 +749,6 @@ TRACE_EVENT(dpu_crtc_vblank_enable, __field( uint32_t, enc_id ) __field( bool, enable ) __field( bool, enabled ) - __field( bool, suspend ) __field( bool, vblank_requested ) ), TP_fast_assign( @@ -757,15 +756,12 @@ TRACE_EVENT(dpu_crtc_vblank_enable, __entry->enc_id = enc_id; __entry->enable = enable; __entry->enabled = crtc->enabled; - __entry->suspend = crtc->suspend; __entry->vblank_requested = crtc->vblank_requested; ), - TP_printk("id:%u encoder:%u enable:%s state{enabled:%s suspend:%s " - "vblank_req:%s}", + TP_printk("id:%u encoder:%u enable:%s state{enabled:%s vblank_req:%s}", __entry->drm_id, __entry->enc_id, __entry->enable ? "true" : "false", __entry->enabled ? "true" : "false", - __entry->suspend ? "true" : "false", __entry->vblank_requested ? "true" : "false") ); @@ -776,26 +772,19 @@ DECLARE_EVENT_CLASS(dpu_crtc_enable_template, __field( uint32_t, drm_id ) __field( bool, enable ) __field( bool, enabled ) - __field( bool, suspend ) __field( bool, vblank_requested ) ), TP_fast_assign( __entry->drm_id = drm_id; __entry->enable = enable; __entry->enabled = crtc->enabled; - __entry->suspend = crtc->suspend; __entry->vblank_requested = crtc->vblank_requested; ), - TP_printk("id:%u enable:%s state{enabled:%s suspend:%s vblank_req:%s}", + TP_printk("id:%u enable:%s state{enabled:%s vblank_req:%s}", __entry->drm_id, __entry->enable ? "true" : "false", __entry->enabled ? "true" : "false", - __entry->suspend ? "true" : "false", __entry->vblank_requested ? "true" : "false") ); -DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_set_suspend, - TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc), - TP_ARGS(drm_id, enable, crtc) -); DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_enable, TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc), TP_ARGS(drm_id, enable, crtc) From 9a5e3fce4b74035ef8d5d3c5b9795e8859c69c67 Mon Sep 17 00:00:00 2001 From: Bruce Wang Date: Fri, 5 Oct 2018 17:04:03 -0400 Subject: [PATCH 05/91] drm/msm/dpu: Replace dpu_crtc_reset by atomic helper Since we removed all suspend logic from the crtc code (see patch 3/4), dpu_crtc_reset does the same things as drm_atomic_helper_crtc_reset, so let's just replace it with a call to the atomic helper. v3: added patch to patchset Reviewed-by: Sean Paul Signed-off-by: Bruce Wang Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 39 +----------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ac604055a824..c5ba753d441c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -844,43 +844,6 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc) return &cstate->base; } -/** - * dpu_crtc_reset - reset hook for CRTCs - * Resets the atomic state for @crtc by freeing the state pointer (which might - * be NULL, e.g. at driver load time) and allocating a new empty state object. - * @crtc: Pointer to drm crtc structure - */ -static void dpu_crtc_reset(struct drm_crtc *crtc) -{ - struct dpu_crtc *dpu_crtc; - struct dpu_crtc_state *cstate; - - if (!crtc) { - DPU_ERROR("invalid crtc\n"); - return; - } - - /* revert suspend actions, if necessary */ - if (dpu_kms_is_suspend_state(crtc->dev)) - _dpu_crtc_set_suspend(crtc, false); - - /* remove previous state, if present */ - if (crtc->state) { - dpu_crtc_destroy_state(crtc, crtc->state); - crtc->state = 0; - } - - dpu_crtc = to_dpu_crtc(crtc); - cstate = kzalloc(sizeof(*cstate), GFP_KERNEL); - if (!cstate) { - DPU_ERROR("failed to allocate state\n"); - return; - } - - cstate->base.crtc = crtc; - crtc->state = &cstate->base; -} - static void dpu_crtc_handle_power_event(u32 event_type, void *arg) { struct drm_crtc *crtc = arg; @@ -1499,7 +1462,7 @@ static const struct drm_crtc_funcs dpu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = dpu_crtc_destroy, .page_flip = drm_atomic_helper_page_flip, - .reset = dpu_crtc_reset, + .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = dpu_crtc_duplicate_state, .atomic_destroy_state = dpu_crtc_destroy_state, .late_register = dpu_crtc_late_register, From 01b09d53ad5b7e183386887cbc536dfda9f6ce65 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 20 Sep 2018 10:58:13 -0400 Subject: [PATCH 06/91] drm/msm: Remove dpu_encoder_phys_ops->hw_reset() We call out of the virt encoder into phys only to call back into the virt for hw reset. So remove the indirection and just call the virt function directly. Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 ++---- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 12 ------------ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 - 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 96cdf06e7da2..bb69a5c9b471 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1507,7 +1507,7 @@ static int dpu_encoder_helper_wait_event_timeout( return rc; } -void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc) +static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc) { struct dpu_encoder_virt *dpu_enc; struct dpu_hw_ctl *ctl; @@ -1803,9 +1803,7 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, if (needs_hw_reset) { trace_dpu_enc_prepare_kickoff_reset(DRMID(drm_enc)); for (i = 0; i < dpu_enc->num_phys_encs; i++) { - phys = dpu_enc->phys_encs[i]; - if (phys && phys->ops.hw_reset) - phys->ops.hw_reset(phys); + dpu_encoder_helper_hw_reset(dpu_enc->phys_encs[i]); } } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 964efcc757a4..3a67bb9f9d9d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -114,8 +114,6 @@ struct dpu_encoder_virt_ops { * @handle_post_kickoff: Do any work necessary post-kickoff work * @trigger_start: Process start event on physical encoder * @needs_single_flush: Whether encoder slaves need to be flushed - * @hw_reset: Issue HW recovery such as CTL reset and clear - * DPU_ENC_ERR_NEEDS_HW_RESET state * @irq_control: Handler to enable/disable all the encoder IRQs * @prepare_idle_pc: phys encoder can update the vsync_enable status * on idle power collapse prepare @@ -151,7 +149,6 @@ struct dpu_encoder_phys_ops { void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc); void (*trigger_start)(struct dpu_encoder_phys *phys_enc); bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc); - void (*hw_reset)(struct dpu_encoder_phys *phys_enc); void (*irq_control)(struct dpu_encoder_phys *phys, bool enable); void (*prepare_idle_pc)(struct dpu_encoder_phys *phys_enc); void (*restore)(struct dpu_encoder_phys *phys); @@ -342,15 +339,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( */ void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc); -/** - * dpu_encoder_helper_hw_reset - issue ctl hw reset - * This helper function may be optionally specified by physical - * encoders if they require ctl hw reset. If state is currently - * DPU_ENC_ERR_NEEDS_HW_RESET, it is set back to DPU_ENC_ENABLED. - * @phys_enc: Pointer to physical encoder structure - */ -void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc); - static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( struct dpu_encoder_phys *phys_enc) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index b2d7f0ded24c..c30ae05b3349 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -776,7 +776,6 @@ static void dpu_encoder_phys_cmd_init_ops( ops->wait_for_vblank = dpu_encoder_phys_cmd_wait_for_vblank; ops->trigger_start = dpu_encoder_phys_cmd_trigger_start; ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush; - ops->hw_reset = dpu_encoder_helper_hw_reset; ops->irq_control = dpu_encoder_phys_cmd_irq_control; ops->restore = dpu_encoder_phys_cmd_enable_helper; ops->prepare_idle_pc = dpu_encoder_phys_cmd_prepare_idle_pc; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 84de385a9f62..283a2491f3e3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -766,7 +766,6 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff; ops->handle_post_kickoff = dpu_encoder_phys_vid_handle_post_kickoff; ops->needs_single_flush = dpu_encoder_phys_vid_needs_single_flush; - ops->hw_reset = dpu_encoder_helper_hw_reset; ops->get_line_count = dpu_encoder_phys_vid_get_line_count; } From 37686b5ec41a58ae136f91471d039f2418d8d192 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 20 Sep 2018 10:58:14 -0400 Subject: [PATCH 07/91] drm/msm: dpu: Remove unused functions from msm_media_info.h These functions aren't used anywhere, remove them. Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- .../gpu/drm/msm/disp/dpu1/msm_media_info.h | 171 ------------------ 1 file changed, 171 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h b/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h index 4f12e5c534c8..1a35dfb4a4e5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h +++ b/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h @@ -813,18 +813,6 @@ enum color_fmts { #define COLOR_FMT_P010_UBWC COLOR_FMT_P010_UBWC #define COLOR_FMT_P010 COLOR_FMT_P010 -static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height) -{ - (void)height; - (void)width; - - /* - * In the future, calculate the size based on the w/h but just - * hardcode it for now since 16K satisfies all current usecases. - */ - return 16 * 1024; -} - /* * Function arguments: * @color_fmt @@ -1214,163 +1202,4 @@ invalid_input: return rgb_meta_scanlines; } -/* - * Function arguments: - * @color_fmt - * @width - * Progressive: width - * Interlaced: width - * @height - * Progressive: height - * Interlaced: height - */ -static inline unsigned int VENUS_BUFFER_SIZE( - int color_fmt, int width, int height) -{ - const unsigned int extra_size = VENUS_EXTRADATA_SIZE(width, height); - unsigned int uv_alignment = 0, size = 0; - unsigned int y_plane, uv_plane, y_stride, - uv_stride, y_sclines, uv_sclines; - unsigned int y_ubwc_plane = 0, uv_ubwc_plane = 0; - unsigned int y_meta_stride = 0, y_meta_scanlines = 0; - unsigned int uv_meta_stride = 0, uv_meta_scanlines = 0; - unsigned int y_meta_plane = 0, uv_meta_plane = 0; - unsigned int rgb_stride = 0, rgb_scanlines = 0; - unsigned int rgb_plane = 0, rgb_ubwc_plane = 0, rgb_meta_plane = 0; - unsigned int rgb_meta_stride = 0, rgb_meta_scanlines = 0; - - if (!width || !height) - goto invalid_input; - - y_stride = VENUS_Y_STRIDE(color_fmt, width); - uv_stride = VENUS_UV_STRIDE(color_fmt, width); - y_sclines = VENUS_Y_SCANLINES(color_fmt, height); - uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); - rgb_stride = VENUS_RGB_STRIDE(color_fmt, width); - rgb_scanlines = VENUS_RGB_SCANLINES(color_fmt, height); - - switch (color_fmt) { - case COLOR_FMT_NV21: - case COLOR_FMT_NV12: - case COLOR_FMT_P010: - uv_alignment = 4096; - y_plane = y_stride * y_sclines; - uv_plane = uv_stride * uv_sclines + uv_alignment; - size = y_plane + uv_plane + - MSM_MEDIA_MAX(extra_size, 8 * y_stride); - size = MSM_MEDIA_ALIGN(size, 4096); - break; - case COLOR_FMT_NV12_MVTB: - uv_alignment = 4096; - y_plane = y_stride * y_sclines; - uv_plane = uv_stride * uv_sclines + uv_alignment; - size = y_plane + uv_plane; - size = 2 * size + extra_size; - size = MSM_MEDIA_ALIGN(size, 4096); - break; - case COLOR_FMT_NV12_UBWC: - y_sclines = VENUS_Y_SCANLINES(color_fmt, (height+1)>>1); - y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); - uv_sclines = VENUS_UV_SCANLINES(color_fmt, (height+1)>>1); - uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); - y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); - y_meta_scanlines = - VENUS_Y_META_SCANLINES(color_fmt, (height+1)>>1); - y_meta_plane = MSM_MEDIA_ALIGN( - y_meta_stride * y_meta_scanlines, 4096); - uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); - uv_meta_scanlines = - VENUS_UV_META_SCANLINES(color_fmt, (height+1)>>1); - uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * - uv_meta_scanlines, 4096); - - size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane + - uv_meta_plane)*2 + - MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride); - size = MSM_MEDIA_ALIGN(size, 4096); - break; - case COLOR_FMT_NV12_BPP10_UBWC: - y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); - uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); - y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); - y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); - y_meta_plane = MSM_MEDIA_ALIGN( - y_meta_stride * y_meta_scanlines, 4096); - uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); - uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); - uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * - uv_meta_scanlines, 4096); - - size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + - uv_meta_plane + - MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride); - size = MSM_MEDIA_ALIGN(size, 4096); - break; - case COLOR_FMT_P010_UBWC: - y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); - uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); - y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); - y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height); - y_meta_plane = MSM_MEDIA_ALIGN( - y_meta_stride * y_meta_scanlines, 4096); - uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); - uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height); - uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * - uv_meta_scanlines, 4096); - - size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + - uv_meta_plane; - size = MSM_MEDIA_ALIGN(size, 4096); - break; - case COLOR_FMT_RGBA8888: - rgb_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, 4096); - size = rgb_plane; - size = MSM_MEDIA_ALIGN(size, 4096); - break; - case COLOR_FMT_RGBA8888_UBWC: - case COLOR_FMT_RGBA1010102_UBWC: - case COLOR_FMT_RGB565_UBWC: - rgb_ubwc_plane = MSM_MEDIA_ALIGN(rgb_stride * rgb_scanlines, - 4096); - rgb_meta_stride = VENUS_RGB_META_STRIDE(color_fmt, width); - rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color_fmt, - height); - rgb_meta_plane = MSM_MEDIA_ALIGN(rgb_meta_stride * - rgb_meta_scanlines, 4096); - size = rgb_ubwc_plane + rgb_meta_plane; - size = MSM_MEDIA_ALIGN(size, 4096); - break; - default: - break; - } -invalid_input: - return size; -} - -static inline unsigned int VENUS_VIEW2_OFFSET( - int color_fmt, int width, int height) -{ - unsigned int offset = 0; - unsigned int y_plane, uv_plane, y_stride, - uv_stride, y_sclines, uv_sclines; - if (!width || !height) - goto invalid_input; - - y_stride = VENUS_Y_STRIDE(color_fmt, width); - uv_stride = VENUS_UV_STRIDE(color_fmt, width); - y_sclines = VENUS_Y_SCANLINES(color_fmt, height); - uv_sclines = VENUS_UV_SCANLINES(color_fmt, height); - switch (color_fmt) { - case COLOR_FMT_NV12_MVTB: - y_plane = y_stride * y_sclines; - uv_plane = uv_stride * uv_sclines; - offset = y_plane + uv_plane; - break; - default: - break; - } -invalid_input: - return offset; -} - #endif From bf711751c882e5f406ad484111285b258fb012c4 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 20 Sep 2018 10:58:15 -0400 Subject: [PATCH 08/91] drm/msm: dpu: Remove _dpu_encoder_power_enable() It's unused, remove it. Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 33 --------------------- 1 file changed, 33 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index bb69a5c9b471..7b9620dc9c54 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -210,39 +210,6 @@ struct dpu_encoder_virt { }; #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base) -static inline int _dpu_encoder_power_enable(struct dpu_encoder_virt *dpu_enc, - bool enable) -{ - struct drm_encoder *drm_enc; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - - if (!dpu_enc) { - DPU_ERROR("invalid dpu enc\n"); - return -EINVAL; - } - - drm_enc = &dpu_enc->base; - if (!drm_enc->dev || !drm_enc->dev->dev_private) { - DPU_ERROR("drm device invalid\n"); - return -EINVAL; - } - - priv = drm_enc->dev->dev_private; - if (!priv->kms) { - DPU_ERROR("invalid kms\n"); - return -EINVAL; - } - - dpu_kms = to_dpu_kms(priv->kms); - - if (enable) - pm_runtime_get_sync(&dpu_kms->pdev->dev); - else - pm_runtime_put_sync(&dpu_kms->pdev->dev); - - return 0; -} void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc, enum dpu_intr_idx intr_idx) From 58fba464eaeff6533236d334cf2a2df24241dc76 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 20 Sep 2018 10:58:16 -0400 Subject: [PATCH 09/91] drm/msm: dpu: Remove 'inline' from several functions Per chapter 15 of coding-style, removing 'inline' keyword from functions that are larger than a typical macro. In a couple of cases I've simplified the function and kept the inline. Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 16 ++----------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++-- .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 6 ++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 12 +++------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 6 ++--- .../gpu/drm/msm/disp/dpu1/msm_media_info.h | 24 +++++++++---------- 9 files changed, 29 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index c5ba753d441c..ae63590ad2d3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -53,7 +53,7 @@ static inline int _dpu_crtc_get_mixer_width(struct dpu_crtc_state *cstate, return mode->hdisplay / cstate->num_mixers; } -static inline struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) +static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) { struct msm_drm_private *priv = crtc->dev->dev_private; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 7dc181aabb4d..4822602402f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -264,13 +264,7 @@ static inline int dpu_crtc_get_mixer_height(struct dpu_crtc *dpu_crtc, */ static inline int dpu_crtc_frame_pending(struct drm_crtc *crtc) { - struct dpu_crtc *dpu_crtc; - - if (!crtc) - return -EINVAL; - - dpu_crtc = to_dpu_crtc(crtc); - return atomic_read(&dpu_crtc->frame_pending); + return crtc ? atomic_read(&to_dpu_crtc(crtc)->frame_pending) : -EINVAL; } /** @@ -327,13 +321,7 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc); static inline enum dpu_crtc_client_type dpu_crtc_get_client_type( struct drm_crtc *crtc) { - struct dpu_crtc_state *cstate = - crtc ? to_dpu_crtc_state(crtc->state) : NULL; - - if (!cstate) - return NRT_CLIENT; - - return RT_CLIENT; + return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; } /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 7b9620dc9c54..82c55efb500f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1374,7 +1374,7 @@ static void dpu_encoder_off_work(struct kthread_work *work) * phys: Pointer to physical encoder structure * extra_flush_bits: Additional bit mask to include in flush trigger */ -static inline void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, +static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, struct dpu_encoder_phys *phys, uint32_t extra_flush_bits) { struct dpu_hw_ctl *ctl; @@ -1417,7 +1417,7 @@ static inline void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, * _dpu_encoder_trigger_start - trigger start for a physical encoder * phys: Pointer to physical encoder structure */ -static inline void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys) +static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys) { if (!phys) { DPU_ERROR("invalid argument(s)\n"); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 283a2491f3e3..b3c68c4fcc8e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -110,7 +110,7 @@ static void drm_mode_to_intf_timing_params( */ } -static inline u32 get_horizontal_total(const struct intf_timing_params *timing) +static u32 get_horizontal_total(const struct intf_timing_params *timing) { u32 active = timing->xres; u32 inactive = @@ -119,7 +119,7 @@ static inline u32 get_horizontal_total(const struct intf_timing_params *timing) return active + inactive; } -static inline u32 get_vertical_total(const struct intf_timing_params *timing) +static u32 get_vertical_total(const struct intf_timing_params *timing) { u32 active = timing->yres; u32 inactive = diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index d3f8b929af65..8fa601a9abbf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -124,7 +124,7 @@ static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx) DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } -static inline uint32_t dpu_hw_ctl_get_bitmask_sspp(struct dpu_hw_ctl *ctx, +static uint32_t dpu_hw_ctl_get_bitmask_sspp(struct dpu_hw_ctl *ctx, enum dpu_sspp sspp) { uint32_t flushbits = 0; @@ -179,7 +179,7 @@ static inline uint32_t dpu_hw_ctl_get_bitmask_sspp(struct dpu_hw_ctl *ctx, return flushbits; } -static inline uint32_t dpu_hw_ctl_get_bitmask_mixer(struct dpu_hw_ctl *ctx, +static uint32_t dpu_hw_ctl_get_bitmask_mixer(struct dpu_hw_ctl *ctx, enum dpu_lm lm) { uint32_t flushbits = 0; @@ -212,7 +212,7 @@ static inline uint32_t dpu_hw_ctl_get_bitmask_mixer(struct dpu_hw_ctl *ctx, return flushbits; } -static inline int dpu_hw_ctl_get_bitmask_intf(struct dpu_hw_ctl *ctx, +static int dpu_hw_ctl_get_bitmask_intf(struct dpu_hw_ctl *ctx, u32 *flushbits, enum dpu_intf intf) { switch (intf) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index acb8dc8acaa5..dbe48e006414 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -64,16 +64,10 @@ static struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer, static inline int _stage_offset(struct dpu_hw_mixer *ctx, enum dpu_stage stage) { const struct dpu_lm_sub_blks *sblk = ctx->cap->sblk; - int rc; + if (stage != DPU_STAGE_BASE && stage <= sblk->maxblendstages) + return sblk->blendstage_base[stage - DPU_STAGE_0]; - if (stage == DPU_STAGE_BASE) - rc = -EINVAL; - else if (stage <= sblk->maxblendstages) - rc = sblk->blendstage_base[stage - DPU_STAGE_0]; - else - rc = -EINVAL; - - return rc; + return -EINVAL; } static void dpu_hw_lm_setup_out(struct dpu_hw_mixer *ctx, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index c25b52a6b219..8745018ffdd6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -141,7 +141,7 @@ /* traffic shaper clock in Hz */ #define TS_CLK 19200000 -static inline int _sspp_subblk_offset(struct dpu_hw_pipe *ctx, +static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx, int s_id, u32 *idx) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d77a8cb15404..e61c3b6fd725 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -137,7 +137,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane) * @src_wdith: width of source buffer * Return: fill level corresponding to the source buffer/format or 0 if error */ -static inline int _dpu_plane_calc_fill_level(struct drm_plane *plane, +static int _dpu_plane_calc_fill_level(struct drm_plane *plane, const struct dpu_format *fmt, u32 src_width) { struct dpu_plane *pdpu, *tmp; @@ -441,7 +441,7 @@ static inline struct msm_gem_address_space *_dpu_plane_get_aspace( return kms->base.aspace; } -static inline void _dpu_plane_set_scanout(struct drm_plane *plane, +static void _dpu_plane_set_scanout(struct drm_plane *plane, struct dpu_plane_state *pstate, struct dpu_hw_pipe_cfg *pipe_cfg, struct drm_framebuffer *fb) @@ -525,7 +525,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu, scale_cfg->enable = 1; } -static inline void _dpu_plane_setup_csc(struct dpu_plane *pdpu) +static void _dpu_plane_setup_csc(struct dpu_plane *pdpu) { static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = { { diff --git a/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h b/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h index 1a35dfb4a4e5..75470ee5b18f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h +++ b/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h @@ -820,7 +820,7 @@ enum color_fmts { * Progressive: width * Interlaced: width */ -static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width) +static unsigned int VENUS_Y_STRIDE(int color_fmt, int width) { unsigned int alignment, stride = 0; @@ -862,7 +862,7 @@ invalid_input: * Progressive: width * Interlaced: width */ -static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width) +static unsigned int VENUS_UV_STRIDE(int color_fmt, int width) { unsigned int alignment, stride = 0; @@ -904,7 +904,7 @@ invalid_input: * Progressive: height * Interlaced: (height+1)>>1 */ -static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) +static unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) { unsigned int alignment, sclines = 0; @@ -938,7 +938,7 @@ invalid_input: * Progressive: height * Interlaced: (height+1)>>1 */ -static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) +static unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) { unsigned int alignment, sclines = 0; @@ -974,7 +974,7 @@ invalid_input: * Progressive: width * Interlaced: width */ -static inline unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width) +static unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width) { int y_tile_width = 0, y_meta_stride = 0; @@ -1007,7 +1007,7 @@ invalid_input: * Progressive: height * Interlaced: (height+1)>>1 */ -static inline unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height) +static unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height) { int y_tile_height = 0, y_meta_scanlines = 0; @@ -1040,7 +1040,7 @@ invalid_input: * Progressive: width * Interlaced: width */ -static inline unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width) +static unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width) { int uv_tile_width = 0, uv_meta_stride = 0; @@ -1073,7 +1073,7 @@ invalid_input: * Progressive: height * Interlaced: (height+1)>>1 */ -static inline unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height) +static unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height) { int uv_tile_height = 0, uv_meta_scanlines = 0; @@ -1099,7 +1099,7 @@ invalid_input: return uv_meta_scanlines; } -static inline unsigned int VENUS_RGB_STRIDE(int color_fmt, int width) +static unsigned int VENUS_RGB_STRIDE(int color_fmt, int width) { unsigned int alignment = 0, stride = 0, bpp = 4; @@ -1128,7 +1128,7 @@ invalid_input: return stride; } -static inline unsigned int VENUS_RGB_SCANLINES(int color_fmt, int height) +static unsigned int VENUS_RGB_SCANLINES(int color_fmt, int height) { unsigned int alignment = 0, scanlines = 0; @@ -1154,7 +1154,7 @@ invalid_input: return scanlines; } -static inline unsigned int VENUS_RGB_META_STRIDE(int color_fmt, int width) +static unsigned int VENUS_RGB_META_STRIDE(int color_fmt, int width) { int rgb_tile_width = 0, rgb_meta_stride = 0; @@ -1178,7 +1178,7 @@ invalid_input: return rgb_meta_stride; } -static inline unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height) +static unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height) { int rgb_tile_height = 0, rgb_meta_scanlines = 0; From 0841851f3b22bc1da09683aa458efe9f9e2abf51 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 20 Sep 2018 10:58:17 -0400 Subject: [PATCH 10/91] drm/msm: dpu: Remove empty/useless labels I noticed an empty label while driving by and decided to use coccinelle to see if there were any more. Here's the spatch and the invocation: --- @@ identifier lbl; expression E; @@ - goto lbl; + return E; ... - lbl: return E; @@ identifier lbl; @@ - goto lbl; + return; ... - lbl: - return; --- spatch --allow-inconsistent-paths --sp-file file.spatch --dir drivers/gpu/drm/msm/disp/dpu1 --in-place --- Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 5 ++--- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 8 ++------ drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 5 ++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 15 ++++++--------- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 4 +--- 7 files changed, 15 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 41c5191f9056..affc9738e2b5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -68,7 +68,7 @@ static bool _dpu_core_video_mode_intf_connected(struct drm_crtc *crtc) bool intf_connected = false; if (!crtc) - goto end; + return intf_connected; drm_for_each_crtc(tmp_crtc, crtc->dev) { if ((dpu_crtc_get_intf_mode(tmp_crtc) == INTF_MODE_VIDEO) && @@ -76,11 +76,10 @@ static bool _dpu_core_video_mode_intf_connected(struct drm_crtc *crtc) DPU_DEBUG("video interface connected crtc:%d\n", tmp_crtc->base.id); intf_connected = true; - goto end; + return intf_connected; } } -end: return intf_connected; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index c30ae05b3349..24a98f4e1f44 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -496,14 +496,11 @@ static void dpu_encoder_phys_cmd_enable_helper( _dpu_encoder_phys_cmd_pingpong_config(phys_enc); if (!dpu_encoder_phys_cmd_is_master(phys_enc)) - goto skip_flush; + return; ctl = phys_enc->hw_ctl; ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->intf_idx); ctl->ops.update_pending_flush(ctl, flush_mask); - -skip_flush: - return; } static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc) @@ -797,7 +794,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( if (!cmd_enc) { ret = -ENOMEM; DPU_ERROR("failed to allocate\n"); - goto fail; + return ERR_PTR(ret); } phys_enc = &cmd_enc->base; phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; @@ -855,6 +852,5 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( return phys_enc; -fail: return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c index bfcd165e96df..0aa9b8e1ae70 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c @@ -921,7 +921,7 @@ static int _dpu_format_populate_addrs_ubwc( + layout->plane_size[2] + layout->plane_size[3]; if (!meta) - goto done; + return 0; /* configure Y metadata plane */ layout->plane_addr[2] = base_addr; @@ -952,12 +952,11 @@ static int _dpu_format_populate_addrs_ubwc( layout->plane_addr[1] = 0; if (!meta) - goto done; + return 0; layout->plane_addr[2] = base_addr; layout->plane_addr[3] = 0; } -done: return 0; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index cc3a623903f4..52fca13da176 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -177,7 +177,7 @@ static u32 dpu_hw_pp_get_line_count(struct dpu_hw_pingpong *pp) height = DPU_REG_READ(c, PP_SYNC_CONFIG_HEIGHT) & 0xFFFF; if (height < init) - goto line_count_exit; + return line; line = DPU_REG_READ(c, PP_INT_COUNT_VAL) & 0xFFFF; @@ -186,7 +186,6 @@ static u32 dpu_hw_pp_get_line_count(struct dpu_hw_pingpong *pp) else line -= init; -line_count_exit: return line; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index ff06b50dfc87..985c855796ae 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -856,20 +856,20 @@ static int dpu_kms_hw_init(struct msm_kms *kms) if (!kms) { DPU_ERROR("invalid kms\n"); - goto end; + return rc; } dpu_kms = to_dpu_kms(kms); dev = dpu_kms->dev; if (!dev) { DPU_ERROR("invalid device\n"); - goto end; + return rc; } rc = dpu_dbg_init(&dpu_kms->pdev->dev); if (rc) { DRM_ERROR("failed to init dpu dbg: %d\n", rc); - goto end; + return rc; } priv = dev->dev_private; @@ -1050,7 +1050,6 @@ error: _dpu_kms_hw_destroy(dpu_kms); dbg_destroy: dpu_dbg_destroy(); -end: return rc; } @@ -1155,7 +1154,7 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev) ddev = dpu_kms->dev; if (!ddev) { DPU_ERROR("invalid drm_device\n"); - goto exit; + return rc; } rc = dpu_power_resource_enable(&dpu_kms->phandle, @@ -1167,7 +1166,6 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev) if (rc) DPU_ERROR("clock disable failed rc:%d\n", rc); -exit: return rc; } @@ -1182,13 +1180,13 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) ddev = dpu_kms->dev; if (!ddev) { DPU_ERROR("invalid drm_device\n"); - goto exit; + return rc; } rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); if (rc) { DPU_ERROR("clock enable failed rc:%d\n", rc); - goto exit; + return rc; } rc = dpu_power_resource_enable(&dpu_kms->phandle, @@ -1196,7 +1194,6 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) if (rc) DPU_ERROR("resource enable failed: %d\n", rc); -exit: return rc; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index e61c3b6fd725..7ed8f566e0e9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1537,7 +1537,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, if (!pdpu) { DPU_ERROR("[%u]failed to allocate local plane struct\n", pipe); ret = -ENOMEM; - goto exit; + return ERR_PTR(ret); } /* cache local stuff for later */ @@ -1623,6 +1623,5 @@ clean_sspp: dpu_hw_sspp_destroy(pdpu->pipe_hw); clean_plane: kfree(pdpu); -exit: return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c index 295528292296..ff5091d2555d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c @@ -191,7 +191,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, ot_lim = _dpu_vbif_get_ot_limit(vbif, params) & 0xFF; if (ot_lim == 0) - goto exit; + return; trace_dpu_perf_set_ot(params->num, params->xin_id, ot_lim, params->vbif_idx); @@ -210,8 +210,6 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, if (forced_on) mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false); -exit: - return; } void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, From aa4df9bf2862956b88d3f63b7c55911e93c15e45 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 20 Sep 2018 10:58:18 -0400 Subject: [PATCH 11/91] drm/msm: dpu: Clean up _dpu_core_video_mode_intf_connected() Local variable is not needed and condition can't be hit. Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index affc9738e2b5..22e84b3d7f98 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -65,22 +65,17 @@ static bool _dpu_core_perf_crtc_is_power_on(struct drm_crtc *crtc) static bool _dpu_core_video_mode_intf_connected(struct drm_crtc *crtc) { struct drm_crtc *tmp_crtc; - bool intf_connected = false; - - if (!crtc) - return intf_connected; drm_for_each_crtc(tmp_crtc, crtc->dev) { if ((dpu_crtc_get_intf_mode(tmp_crtc) == INTF_MODE_VIDEO) && _dpu_core_perf_crtc_is_power_on(tmp_crtc)) { DPU_DEBUG("video interface connected crtc:%d\n", tmp_crtc->base.id); - intf_connected = true; - return intf_connected; + return true; } } - return intf_connected; + return false; } static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms, From 84511abc47bd79e1e4a550cb7a662c09bcddd92b Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 4 Oct 2018 14:09:45 -0400 Subject: [PATCH 12/91] drm/msm: dpu: Remove checks from dpu_plane_destroy_state() They're not needed. Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 7ed8f566e0e9..f7d9bab80dad 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1191,19 +1191,8 @@ static void dpu_plane_destroy(struct drm_plane *plane) static void dpu_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - struct dpu_plane_state *pstate; - - if (!plane || !state) { - DPU_ERROR("invalid arg(s), plane %d state %d\n", - plane != 0, state != 0); - return; - } - - pstate = to_dpu_plane_state(state); - __drm_atomic_helper_plane_destroy_state(state); - - kfree(pstate); + kfree(to_dpu_plane_state(state)); } static struct drm_plane_state * From 6a41da17e87dee2936645d9a51fccf932fa42981 Mon Sep 17 00:00:00 2001 From: Mamta Shukla Date: Sat, 20 Oct 2018 23:19:26 +0530 Subject: [PATCH 13/91] drm: msm: Use DRM_DEV_* instead of dev_* Use DRM_DEV_INFO/ERROR/WARN instead of dev_info/err/debug to generate drm-formatted specific log messages so that it will be easy to differentiate in case of multiple instances of driver. Signed-off-by: Mamta Shukla Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 4 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 4 +- drivers/gpu/drm/msm/adreno/a5xx_debugfs.c | 2 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 10 ++--- drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 4 +- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 38 ++++++++-------- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 +- drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 14 +++--- drivers/gpu/drm/msm/adreno/adreno_device.c | 6 +-- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 22 +++++----- drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c | 28 ++++++------ drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c | 8 ++-- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 2 +- .../gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c | 12 ++--- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 44 +++++++++---------- .../gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 22 +++++----- drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c | 8 ++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 4 +- .../gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c | 10 ++--- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 8 ++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c | 16 +++---- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 30 ++++++------- drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c | 10 ++--- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 8 ++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c | 4 +- drivers/gpu/drm/msm/dsi/dsi.c | 10 ++--- drivers/gpu/drm/msm/dsi/dsi_host.c | 22 +++++----- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 28 ++++++------ drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 6 +-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 6 +-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c | 2 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 2 +- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 2 +- drivers/gpu/drm/msm/dsi/pll/dsi_pll.c | 2 +- drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 8 ++-- drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c | 12 ++--- drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c | 16 +++---- .../gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c | 10 ++--- drivers/gpu/drm/msm/edp/edp.c | 8 ++-- drivers/gpu/drm/msm/hdmi/hdmi.c | 32 +++++++------- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 10 ++--- drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 10 ++--- drivers/gpu/drm/msm/hdmi/hdmi_i2c.c | 2 +- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 12 ++--- drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 6 +-- drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c | 4 +- drivers/gpu/drm/msm/msm_debugfs.c | 6 +-- drivers/gpu/drm/msm/msm_drv.c | 27 ++++++------ drivers/gpu/drm/msm/msm_fb.c | 8 ++-- drivers/gpu/drm/msm/msm_fbdev.c | 8 ++-- drivers/gpu/drm/msm/msm_gem.c | 12 ++--- drivers/gpu/drm/msm/msm_gpu.c | 30 ++++++------- 52 files changed, 313 insertions(+), 310 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 669c2d4b070d..c3b4bc6e4155 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -481,7 +481,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) int ret; if (!pdev) { - dev_err(dev->dev, "no a3xx device\n"); + DRM_DEV_ERROR(dev->dev, "no a3xx device\n"); ret = -ENXIO; goto fail; } @@ -528,7 +528,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) * to not be possible to restrict access, then we must * implement a cmdstream validator. */ - dev_err(dev->dev, "No memory protection without IOMMU\n"); + DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); ret = -ENXIO; goto fail; } diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 7c4e6dc1ed59..18f9a8e0bf3b 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -561,7 +561,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) int ret; if (!pdev) { - dev_err(dev->dev, "no a4xx device\n"); + DRM_DEV_ERROR(dev->dev, "no a4xx device\n"); ret = -ENXIO; goto fail; } @@ -608,7 +608,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) * to not be possible to restrict access, then we must * implement a cmdstream validator. */ - dev_err(dev->dev, "No memory protection without IOMMU\n"); + DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n"); ret = -ENXIO; goto fail; } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c index d2127b1c4ece..6983cd9102bd 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c @@ -173,7 +173,7 @@ int a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor) minor->debugfs_root, minor); if (ret) { - dev_err(dev->dev, "could not install a5xx_debugfs_list\n"); + DRM_DEV_ERROR(dev->dev, "could not install a5xx_debugfs_list\n"); return ret; } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 8edd80bb0428..1b9c724cbdfe 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -514,7 +514,7 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) if (IS_ERR(a5xx_gpu->pm4_bo)) { ret = PTR_ERR(a5xx_gpu->pm4_bo); a5xx_gpu->pm4_bo = NULL; - dev_err(gpu->dev->dev, "could not allocate PM4: %d\n", + DRM_DEV_ERROR(gpu->dev->dev, "could not allocate PM4: %d\n", ret); return ret; } @@ -527,7 +527,7 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) if (IS_ERR(a5xx_gpu->pfp_bo)) { ret = PTR_ERR(a5xx_gpu->pfp_bo); a5xx_gpu->pfp_bo = NULL; - dev_err(gpu->dev->dev, "could not allocate PFP: %d\n", + DRM_DEV_ERROR(gpu->dev->dev, "could not allocate PFP: %d\n", ret); return ret; } @@ -1028,7 +1028,7 @@ static void a5xx_fault_detect_irq(struct msm_gpu *gpu) struct msm_drm_private *priv = dev->dev_private; struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu); - dev_err(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", + DRM_DEV_ERROR(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n", ring ? ring->id : -1, ring ? ring->seqno : 0, gpu_read(gpu, REG_A5XX_RBBM_STATUS), gpu_read(gpu, REG_A5XX_CP_RB_RPTR), @@ -1134,7 +1134,7 @@ static const u32 a5xx_registers[] = { static void a5xx_dump(struct msm_gpu *gpu) { - dev_info(gpu->dev->dev, "status: %08x\n", + DRM_DEV_INFO(gpu->dev->dev, "status: %08x\n", gpu_read(gpu, REG_A5XX_RBBM_STATUS)); adreno_dump(gpu); } @@ -1505,7 +1505,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) int ret; if (!pdev) { - dev_err(dev->dev, "No A5XX device is defined\n"); + DRM_DEV_ERROR(dev->dev, "No A5XX device is defined\n"); return ERR_PTR(-ENXIO); } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c index 4c357ead1be6..fdb08fc68c2c 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -92,7 +92,7 @@ static void a5xx_preempt_timer(struct timer_list *t) if (!try_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED, PREEMPT_FAULTED)) return; - dev_err(dev->dev, "%s: preemption timed out\n", gpu->name); + DRM_DEV_ERROR(dev->dev, "%s: preemption timed out\n", gpu->name); queue_work(priv->wq, &gpu->recover_work); } @@ -188,7 +188,7 @@ void a5xx_preempt_irq(struct msm_gpu *gpu) status = gpu_read(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL); if (unlikely(status)) { set_preempt_state(a5xx_gpu, PREEMPT_FAULTED); - dev_err(dev->dev, "%s: Preemption failed to complete\n", + DRM_DEV_ERROR(dev->dev, "%s: Preemption failed to complete\n", gpu->name); queue_work(priv->wq, &gpu->recover_work); return; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index d4e98e5876bc..0a0ceb76e2ba 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -153,7 +153,7 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu) val == 0xbabeface, 100, 10000); if (ret) - dev_err(gmu->dev, "GMU firmware initialization timed out\n"); + DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n"); return ret; } @@ -168,7 +168,7 @@ static int a6xx_gmu_hfi_start(struct a6xx_gmu *gmu) ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_HFI_CTRL_STATUS, val, val & 1, 100, 10000); if (ret) - dev_err(gmu->dev, "Unable to start the HFI queues\n"); + DRM_DEV_ERROR(gmu->dev, "Unable to start the HFI queues\n"); return ret; } @@ -209,7 +209,7 @@ int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state) val & (1 << ack), 100, 10000); if (ret) - dev_err(gmu->dev, + DRM_DEV_ERROR(gmu->dev, "Timeout waiting for GMU OOB set %s: 0x%x\n", name, gmu_read(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO)); @@ -251,7 +251,7 @@ static int a6xx_sptprac_enable(struct a6xx_gmu *gmu) (val & 0x38) == 0x28, 1, 100); if (ret) { - dev_err(gmu->dev, "Unable to power on SPTPRAC: 0x%x\n", + DRM_DEV_ERROR(gmu->dev, "Unable to power on SPTPRAC: 0x%x\n", gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS)); } @@ -273,7 +273,7 @@ static void a6xx_sptprac_disable(struct a6xx_gmu *gmu) (val & 0x04), 100, 10000); if (ret) - dev_err(gmu->dev, "failed to power off SPTPRAC: 0x%x\n", + DRM_DEV_ERROR(gmu->dev, "failed to power off SPTPRAC: 0x%x\n", gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS)); } @@ -317,7 +317,7 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu) /* Check to see if the GMU really did slumber */ if (gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE) != 0x0f) { - dev_err(gmu->dev, "The GMU did not go into slumber\n"); + DRM_DEV_ERROR(gmu->dev, "The GMU did not go into slumber\n"); ret = -ETIMEDOUT; } } @@ -339,7 +339,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu) ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val, val & (1 << 1), 100, 10000); if (ret) { - dev_err(gmu->dev, "Unable to power on the GPU RSC\n"); + DRM_DEV_ERROR(gmu->dev, "Unable to power on the GPU RSC\n"); return ret; } @@ -354,7 +354,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu) return 0; } - dev_err(gmu->dev, "GPU RSC sequence stuck while waking up the GPU\n"); + DRM_DEV_ERROR(gmu->dev, "GPU RSC sequence stuck while waking up the GPU\n"); return ret; } @@ -368,7 +368,7 @@ static void a6xx_rpmh_stop(struct a6xx_gmu *gmu) ret = gmu_poll_timeout(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, val, val & (1 << 16), 100, 10000); if (ret) - dev_err(gmu->dev, "Unable to power off the GPU RSC\n"); + DRM_DEV_ERROR(gmu->dev, "Unable to power off the GPU RSC\n"); gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0); } @@ -520,7 +520,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state) /* Sanity check the size of the firmware that was loaded */ if (adreno_gpu->fw[ADRENO_FW_GMU]->size > 0x8000) { - dev_err(gmu->dev, + DRM_DEV_ERROR(gmu->dev, "GMU firmware is bigger than the available region\n"); return -EINVAL; } @@ -764,7 +764,7 @@ int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu) */ if (ret) - dev_err(gmu->dev, + DRM_DEV_ERROR(gmu->dev, "Unable to slumber GMU: status = 0%x/0%x\n", gmu_read(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS), @@ -843,7 +843,7 @@ static struct a6xx_gmu_bo *a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, IOMMU_READ | IOMMU_WRITE); if (ret) { - dev_err(gmu->dev, "Unable to map GMU buffer object\n"); + DRM_DEV_ERROR(gmu->dev, "Unable to map GMU buffer object\n"); for (i = i - 1 ; i >= 0; i--) iommu_unmap(gmu->domain, @@ -969,12 +969,12 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, } if (j == pri_count) { - dev_err(dev, + DRM_DEV_ERROR(dev, "Level %u not found in in the RPMh list\n", level); - dev_err(dev, "Available levels:\n"); + DRM_DEV_ERROR(dev, "Available levels:\n"); for (j = 0; j < pri_count; j++) - dev_err(dev, " %u\n", pri[j]); + DRM_DEV_ERROR(dev, " %u\n", pri[j]); return -EINVAL; } @@ -1081,7 +1081,7 @@ static int a6xx_gmu_pwrlevels_probe(struct a6xx_gmu *gmu) */ ret = dev_pm_opp_of_add_table(gmu->dev); if (ret) { - dev_err(gmu->dev, "Unable to set the OPP table for the GMU\n"); + DRM_DEV_ERROR(gmu->dev, "Unable to set the OPP table for the GMU\n"); return ret; } @@ -1122,13 +1122,13 @@ static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev, IORESOURCE_MEM, name); if (!res) { - dev_err(&pdev->dev, "Unable to find the %s registers\n", name); + DRM_DEV_ERROR(&pdev->dev, "Unable to find the %s registers\n", name); return ERR_PTR(-EINVAL); } ret = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!ret) { - dev_err(&pdev->dev, "Unable to map the %s registers\n", name); + DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s registers\n", name); return ERR_PTR(-EINVAL); } @@ -1145,7 +1145,7 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev, ret = devm_request_irq(&pdev->dev, irq, handler, IRQF_TRIGGER_HIGH, name, gmu); if (ret) { - dev_err(&pdev->dev, "Unable to get interrupt %s\n", name); + DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s\n", name); return ret; } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 631257c297fd..38b7a5a92bfb 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -481,7 +481,7 @@ out: static void a6xx_dump(struct msm_gpu *gpu) { - dev_info(&gpu->pdev->dev, "status: %08x\n", + DRM_DEV_INFO(&gpu->pdev->dev, "status: %08x\n", gpu_read(gpu, REG_A6XX_RBBM_STATUS)); adreno_dump(gpu); } @@ -498,7 +498,7 @@ static void a6xx_recover(struct msm_gpu *gpu) adreno_dump_info(gpu); for (i = 0; i < 8; i++) - dev_info(&gpu->pdev->dev, "CP_SCRATCH_REG%d: %u\n", i, + DRM_DEV_INFO(&gpu->pdev->dev, "CP_SCRATCH_REG%d: %u\n", i, gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(i))); if (hang_debug) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c index 6ff9baec2658..eda11abc5f01 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c @@ -91,7 +91,7 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum, val & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ, 100, 5000); if (ret) { - dev_err(gmu->dev, + DRM_DEV_ERROR(gmu->dev, "Message %s id %d timed out waiting for response\n", a6xx_hfi_msg_id[id], seqnum); return -ETIMEDOUT; @@ -110,7 +110,7 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum, /* If the queue is empty our response never made it */ if (!ret) { - dev_err(gmu->dev, + DRM_DEV_ERROR(gmu->dev, "The HFI response queue is unexpectedly empty\n"); return -ENOENT; @@ -120,20 +120,20 @@ static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum, struct a6xx_hfi_msg_error *error = (struct a6xx_hfi_msg_error *) &resp; - dev_err(gmu->dev, "GMU firmware error %d\n", + DRM_DEV_ERROR(gmu->dev, "GMU firmware error %d\n", error->code); continue; } if (seqnum != HFI_HEADER_SEQNUM(resp.ret_header)) { - dev_err(gmu->dev, + DRM_DEV_ERROR(gmu->dev, "Unexpected message id %d on the response queue\n", HFI_HEADER_SEQNUM(resp.ret_header)); continue; } if (resp.error) { - dev_err(gmu->dev, + DRM_DEV_ERROR(gmu->dev, "Message %s id %d returned error %d\n", a6xx_hfi_msg_id[id], seqnum, resp.error); return -EINVAL; @@ -163,7 +163,7 @@ static int a6xx_hfi_send_msg(struct a6xx_gmu *gmu, int id, ret = a6xx_hfi_queue_write(gmu, queue, data, dwords); if (ret) { - dev_err(gmu->dev, "Unable to send message %s id %d\n", + DRM_DEV_ERROR(gmu->dev, "Unable to send message %s id %d\n", a6xx_hfi_msg_id[id], seqnum); return ret; } @@ -317,7 +317,7 @@ void a6xx_hfi_stop(struct a6xx_gmu *gmu) continue; if (queue->header->read_index != queue->header->write_index) - dev_err(gmu->dev, "HFI queue %d is not empty\n", i); + DRM_DEV_ERROR(gmu->dev, "HFI queue %d is not empty\n", i); queue->header->read_index = 0; queue->header->write_index = 0; diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 86abdb2b3a9c..fb77c87da690 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -196,7 +196,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) { - dev_err(dev->dev, "Couldn't power up the GPU: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret); return NULL; } @@ -205,7 +205,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); pm_runtime_put_autosuspend(&pdev->dev); if (ret) { - dev_err(dev->dev, "gpu hw init failed: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret); return NULL; } @@ -253,7 +253,7 @@ static int find_chipid(struct device *dev, struct adreno_rev *rev) /* and if that fails, fall back to legacy "qcom,chipid" property: */ ret = of_property_read_u32(node, "qcom,chipid", &chipid); if (ret) { - dev_err(dev, "could not parse qcom,chipid: %d\n", ret); + DRM_DEV_ERROR(dev, "could not parse qcom,chipid: %d\n", ret); return ret; } diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 93d70f4a2154..cada3e634f92 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -89,12 +89,12 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname) ret = request_firmware_direct(&fw, newname, drm->dev); if (!ret) { - dev_info(drm->dev, "loaded %s from new location\n", + DRM_DEV_INFO(drm->dev, "loaded %s from new location\n", newname); adreno_gpu->fwloc = FW_LOCATION_NEW; goto out; } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { - dev_err(drm->dev, "failed to load %s: %d\n", + DRM_DEV_ERROR(drm->dev, "failed to load %s: %d\n", newname, ret); fw = ERR_PTR(ret); goto out; @@ -109,12 +109,12 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname) ret = request_firmware_direct(&fw, fwname, drm->dev); if (!ret) { - dev_info(drm->dev, "loaded %s from legacy location\n", + DRM_DEV_INFO(drm->dev, "loaded %s from legacy location\n", newname); adreno_gpu->fwloc = FW_LOCATION_LEGACY; goto out; } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { - dev_err(drm->dev, "failed to load %s: %d\n", + DRM_DEV_ERROR(drm->dev, "failed to load %s: %d\n", fwname, ret); fw = ERR_PTR(ret); goto out; @@ -130,19 +130,19 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname) ret = request_firmware(&fw, newname, drm->dev); if (!ret) { - dev_info(drm->dev, "loaded %s with helper\n", + DRM_DEV_INFO(drm->dev, "loaded %s with helper\n", newname); adreno_gpu->fwloc = FW_LOCATION_HELPER; goto out; } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { - dev_err(drm->dev, "failed to load %s: %d\n", + DRM_DEV_ERROR(drm->dev, "failed to load %s: %d\n", newname, ret); fw = ERR_PTR(ret); goto out; } } - dev_err(drm->dev, "failed to load %s\n", fwname); + DRM_DEV_ERROR(drm->dev, "failed to load %s\n", fwname); fw = ERR_PTR(-ENOENT); out: kfree(newname); @@ -212,7 +212,7 @@ int adreno_hw_init(struct msm_gpu *gpu) ret = msm_gem_get_iova(ring->bo, gpu->aspace, &ring->iova); if (ret) { ring->iova = 0; - dev_err(gpu->dev->dev, + DRM_DEV_ERROR(gpu->dev->dev, "could not map ringbuffer %d: %d\n", i, ret); return ret; } @@ -277,7 +277,7 @@ void adreno_recover(struct msm_gpu *gpu) ret = msm_gpu_hw_init(gpu); if (ret) { - dev_err(dev->dev, "gpu hw init failed: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret); /* hmm, oh well? */ } } @@ -635,7 +635,7 @@ static int adreno_get_legacy_pwrlevels(struct device *dev) node = of_get_compatible_child(dev->of_node, "qcom,gpu-pwrlevels"); if (!node) { - dev_err(dev, "Could not find the GPU powerlevels\n"); + DRM_DEV_ERROR(dev, "Could not find the GPU powerlevels\n"); return -ENXIO; } @@ -674,7 +674,7 @@ static int adreno_get_pwrlevels(struct device *dev, else { ret = dev_pm_opp_of_add_table(dev); if (ret) - dev_err(dev, "Unable to set the OPP table\n"); + DRM_DEV_ERROR(dev, "Unable to set the OPP table\n"); } if (!ret) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c index ae2aee7ed9e1..a85078123119 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c @@ -144,7 +144,7 @@ static struct dpu_dbg_base { static void _dpu_debug_bus_xbar_dump(void __iomem *mem_base, struct dpu_debug_bus_entry *entry, u32 val) { - dev_err(dpu_dbg_base.dev, "xbar 0x%x %d %d 0x%x\n", + DRM_DEV_ERROR(dpu_dbg_base.dev, "xbar 0x%x %d %d 0x%x\n", entry->wr_addr, entry->block_id, entry->test_id, val); } @@ -154,7 +154,7 @@ static void _dpu_debug_bus_lm_dump(void __iomem *mem_base, if (!(val & 0xFFF000)) return; - dev_err(dpu_dbg_base.dev, "lm 0x%x %d %d 0x%x\n", + DRM_DEV_ERROR(dpu_dbg_base.dev, "lm 0x%x %d %d 0x%x\n", entry->wr_addr, entry->block_id, entry->test_id, val); } @@ -164,7 +164,7 @@ static void _dpu_debug_bus_ppb0_dump(void __iomem *mem_base, if (!(val & BIT(15))) return; - dev_err(dpu_dbg_base.dev, "ppb0 0x%x %d %d 0x%x\n", + DRM_DEV_ERROR(dpu_dbg_base.dev, "ppb0 0x%x %d %d 0x%x\n", entry->wr_addr, entry->block_id, entry->test_id, val); } @@ -174,7 +174,7 @@ static void _dpu_debug_bus_ppb1_dump(void __iomem *mem_base, if (!(val & BIT(15))) return; - dev_err(dpu_dbg_base.dev, "ppb1 0x%x %d %d 0x%x\n", + DRM_DEV_ERROR(dpu_dbg_base.dev, "ppb1 0x%x %d %d 0x%x\n", entry->wr_addr, entry->block_id, entry->test_id, val); } @@ -1994,7 +1994,7 @@ static void _dpu_dbg_dump_dpu_dbg_bus(struct dpu_dbg_dpu_debug_bus *bus) if (!in_log && !in_mem) return; - dev_info(dpu_dbg_base.dev, "======== start %s dump =========\n", + DRM_DEV_INFO(dpu_dbg_base.dev, "======== start %s dump =========\n", bus->cmn.name); if (in_mem) { @@ -2004,7 +2004,7 @@ static void _dpu_dbg_dump_dpu_dbg_bus(struct dpu_dbg_dpu_debug_bus *bus) if (*dump_mem) { dump_addr = *dump_mem; - dev_info(dpu_dbg_base.dev, + DRM_DEV_INFO(dpu_dbg_base.dev, "%s: start_addr:0x%pK len:0x%x\n", __func__, dump_addr, list_size); } else { @@ -2032,7 +2032,7 @@ static void _dpu_dbg_dump_dpu_dbg_bus(struct dpu_dbg_dpu_debug_bus *bus) status = readl_relaxed(mem_base + offset); if (in_log) - dev_info(dpu_dbg_base.dev, + DRM_DEV_INFO(dpu_dbg_base.dev, "waddr=0x%x blk=%d tst=%d val=0x%x\n", head->wr_addr, head->block_id, head->test_id, status); @@ -2055,7 +2055,7 @@ static void _dpu_dbg_dump_dpu_dbg_bus(struct dpu_dbg_dpu_debug_bus *bus) } _dpu_dbg_enable_power(false); - dev_info(dpu_dbg_base.dev, "======== end %s dump =========\n", + DRM_DEV_INFO(dpu_dbg_base.dev, "======== end %s dump =========\n", bus->cmn.name); } @@ -2086,7 +2086,7 @@ static void _dpu_dbg_dump_vbif_debug_bus_entry( *dump_addr++ = val; } if (in_log) - dev_info(dpu_dbg_base.dev, + DRM_DEV_INFO(dpu_dbg_base.dev, "testpoint:%x arb/xin id=%d index=%d val=0x%x\n", head->block_bus_addr, i, j, val); } @@ -2127,7 +2127,7 @@ static void _dpu_dbg_dump_vbif_dbg_bus(struct dpu_dbg_vbif_debug_bus *bus) list_size = bus->cmn.entries_size; dump_mem = &bus->cmn.dumped_content; - dev_info(dpu_dbg_base.dev, "======== start %s dump =========\n", + DRM_DEV_INFO(dpu_dbg_base.dev, "======== start %s dump =========\n", bus->cmn.name); if (!dump_mem || !dbg_bus || !bus_size || !list_size) @@ -2155,7 +2155,7 @@ static void _dpu_dbg_dump_vbif_dbg_bus(struct dpu_dbg_vbif_debug_bus *bus) if (*dump_mem) { dump_addr = *dump_mem; - dev_info(dpu_dbg_base.dev, + DRM_DEV_INFO(dpu_dbg_base.dev, "%s: start_addr:0x%pK len:0x%x\n", __func__, dump_addr, list_size); } else { @@ -2180,7 +2180,7 @@ static void _dpu_dbg_dump_vbif_dbg_bus(struct dpu_dbg_vbif_debug_bus *bus) reg = readl_relaxed(mem_base + MMSS_VBIF_XIN_HALT_CTRL1); reg1 = readl_relaxed(mem_base + MMSS_VBIF_PND_ERR); reg2 = readl_relaxed(mem_base + MMSS_VBIF_SRC_ERR); - dev_err(dpu_dbg_base.dev, + DRM_DEV_ERROR(dpu_dbg_base.dev, "XIN HALT:0x%lX, PND ERR:0x%lX, SRC ERR:0x%lX\n", reg, reg1, reg2); reg >>= 16; @@ -2194,7 +2194,7 @@ static void _dpu_dbg_dump_vbif_dbg_bus(struct dpu_dbg_vbif_debug_bus *bus) d0 = readl_relaxed(mem_base + MMSS_VBIF_ERR_INFO); d1 = readl_relaxed(mem_base + MMSS_VBIF_ERR_INFO_1); - dev_err(dpu_dbg_base.dev, + DRM_DEV_ERROR(dpu_dbg_base.dev, "Client:%d, errinfo=0x%X, errinfo1=0x%X\n", i, d0, d1); } @@ -2217,7 +2217,7 @@ static void _dpu_dbg_dump_vbif_dbg_bus(struct dpu_dbg_vbif_debug_bus *bus) _dpu_dbg_enable_power(false); - dev_info(dpu_dbg_base.dev, "======== end %s dump =========\n", + DRM_DEV_INFO(dpu_dbg_base.dev, "======== end %s dump =========\n", bus->cmn.name); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c index b557687b1964..78833c2c27f8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_io_util.c @@ -16,6 +16,8 @@ #include #include +#include + #include "dpu_io_util.h" void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk) @@ -164,7 +166,7 @@ int msm_dss_parse_clock(struct platform_device *pdev, "clock-names", i, &clock_name); if (rc) { - dev_err(&pdev->dev, "Failed to get clock name for %d\n", + DRM_DEV_ERROR(&pdev->dev, "Failed to get clock name for %d\n", i); break; } @@ -176,13 +178,13 @@ int msm_dss_parse_clock(struct platform_device *pdev, rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, num_clk); if (rc) { - dev_err(&pdev->dev, "Failed to get clock refs %d\n", rc); + DRM_DEV_ERROR(&pdev->dev, "Failed to get clock refs %d\n", rc); goto err; } rc = of_clk_set_defaults(pdev->dev.of_node, false); if (rc) { - dev_err(&pdev->dev, "Failed to set clock defaults %d\n", rc); + DRM_DEV_ERROR(&pdev->dev, "Failed to set clock defaults %d\n", rc); goto err; } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c index 457c29dba4a1..b91706cee2b8 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -429,7 +429,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, int ret; if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { - dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height); + DRM_DEV_ERROR(dev->dev, "bad cursor size: %dx%d\n", width, height); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c index ba8e587f734b..a8fd14d4846b 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_dtv_encoder.c @@ -45,7 +45,7 @@ static void bs_init(struct mdp4_dtv_encoder *mdp4_dtv_encoder) struct lcdc_platform_data *dtv_pdata = mdp4_find_pdata("dtv.0"); if (!dtv_pdata) { - dev_err(dev->dev, "could not find dtv pdata\n"); + DRM_DEV_ERROR(dev->dev, "could not find dtv pdata\n"); return; } @@ -209,16 +209,16 @@ static void mdp4_dtv_encoder_enable(struct drm_encoder *encoder) ret = clk_set_rate(mdp4_dtv_encoder->mdp_clk, pc); if (ret) - dev_err(dev->dev, "failed to set mdp_clk to %lu: %d\n", + DRM_DEV_ERROR(dev->dev, "failed to set mdp_clk to %lu: %d\n", pc, ret); ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk); if (ret) - dev_err(dev->dev, "failed to enabled mdp_clk: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to enabled mdp_clk: %d\n", ret); ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk); if (ret) - dev_err(dev->dev, "failed to enable hdmi_clk: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to enable hdmi_clk: %d\n", ret); mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1); @@ -258,14 +258,14 @@ struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev) mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk"); if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) { - dev_err(dev->dev, "failed to get hdmi_clk\n"); + DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n"); ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk); goto fail; } mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk"); if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) { - dev_err(dev->dev, "failed to get tv_clk\n"); + DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n"); ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk); goto fail; } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 44d1cda56974..481c0d231149 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -43,7 +43,7 @@ static int mdp4_hw_init(struct msm_kms *kms) DBG("found MDP4 version v%d.%d", major, minor); if (major != 4) { - dev_err(dev->dev, "unexpected MDP version: v%d.%d\n", + DRM_DEV_ERROR(dev->dev, "unexpected MDP version: v%d.%d\n", major, minor); ret = -ENXIO; goto out; @@ -251,7 +251,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, encoder = mdp4_lcdc_encoder_init(dev, panel_node); if (IS_ERR(encoder)) { - dev_err(dev->dev, "failed to construct LCDC encoder\n"); + DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); return PTR_ERR(encoder); } @@ -260,7 +260,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, connector = mdp4_lvds_connector_init(dev, panel_node, encoder); if (IS_ERR(connector)) { - dev_err(dev->dev, "failed to initialize LVDS connector\n"); + DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); return PTR_ERR(connector); } @@ -271,7 +271,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, case DRM_MODE_ENCODER_TMDS: encoder = mdp4_dtv_encoder_init(dev); if (IS_ERR(encoder)) { - dev_err(dev->dev, "failed to construct DTV encoder\n"); + DRM_DEV_ERROR(dev->dev, "failed to construct DTV encoder\n"); return PTR_ERR(encoder); } @@ -282,7 +282,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, /* Construct bridge/connector for HDMI: */ ret = msm_hdmi_modeset_init(priv->hdmi, dev, encoder); if (ret) { - dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to initialize HDMI: %d\n", ret); return ret; } } @@ -300,7 +300,7 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, encoder = mdp4_dsi_encoder_init(dev); if (IS_ERR(encoder)) { ret = PTR_ERR(encoder); - dev_err(dev->dev, + DRM_DEV_ERROR(dev->dev, "failed to construct DSI encoder: %d\n", ret); return ret; } @@ -311,14 +311,14 @@ static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms, ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder); if (ret) { - dev_err(dev->dev, "failed to initialize DSI: %d\n", + DRM_DEV_ERROR(dev->dev, "failed to initialize DSI: %d\n", ret); return ret; } break; default: - dev_err(dev->dev, "Invalid or unsupported interface\n"); + DRM_DEV_ERROR(dev->dev, "Invalid or unsupported interface\n"); return -EINVAL; } @@ -354,7 +354,7 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) for (i = 0; i < ARRAY_SIZE(vg_planes); i++) { plane = mdp4_plane_init(dev, vg_planes[i], false); if (IS_ERR(plane)) { - dev_err(dev->dev, + DRM_DEV_ERROR(dev->dev, "failed to construct plane for VG%d\n", i + 1); ret = PTR_ERR(plane); goto fail; @@ -365,7 +365,7 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) for (i = 0; i < ARRAY_SIZE(mdp4_crtcs); i++) { plane = mdp4_plane_init(dev, rgb_planes[i], true); if (IS_ERR(plane)) { - dev_err(dev->dev, + DRM_DEV_ERROR(dev->dev, "failed to construct plane for RGB%d\n", i + 1); ret = PTR_ERR(plane); goto fail; @@ -374,7 +374,7 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) crtc = mdp4_crtc_init(dev, plane, priv->num_crtcs, i, mdp4_crtcs[i]); if (IS_ERR(crtc)) { - dev_err(dev->dev, "failed to construct crtc for %s\n", + DRM_DEV_ERROR(dev->dev, "failed to construct crtc for %s\n", mdp4_crtc_names[i]); ret = PTR_ERR(crtc); goto fail; @@ -396,7 +396,7 @@ static int modeset_init(struct mdp4_kms *mdp4_kms) for (i = 0; i < ARRAY_SIZE(mdp4_intfs); i++) { ret = mdp4_modeset_init_intf(mdp4_kms, mdp4_intfs[i]); if (ret) { - dev_err(dev->dev, "failed to initialize intf: %d, %d\n", + DRM_DEV_ERROR(dev->dev, "failed to initialize intf: %d, %d\n", i, ret); goto fail; } @@ -419,7 +419,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL); if (!mdp4_kms) { - dev_err(dev->dev, "failed to allocate kms\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate kms\n"); ret = -ENOMEM; goto fail; } @@ -439,7 +439,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = irq; - dev_err(dev->dev, "failed to get irq: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); goto fail; } @@ -456,14 +456,14 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) if (mdp4_kms->vdd) { ret = regulator_enable(mdp4_kms->vdd); if (ret) { - dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to enable regulator vdd: %d\n", ret); goto fail; } } mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk"); if (IS_ERR(mdp4_kms->clk)) { - dev_err(dev->dev, "failed to get core_clk\n"); + DRM_DEV_ERROR(dev->dev, "failed to get core_clk\n"); ret = PTR_ERR(mdp4_kms->clk); goto fail; } @@ -475,14 +475,14 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) // XXX if (rev >= MDP_REV_42) { ??? mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk"); if (IS_ERR(mdp4_kms->lut_clk)) { - dev_err(dev->dev, "failed to get lut_clk\n"); + DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n"); ret = PTR_ERR(mdp4_kms->lut_clk); goto fail; } mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "bus_clk"); if (IS_ERR(mdp4_kms->axi_clk)) { - dev_err(dev->dev, "failed to get axi_clk\n"); + DRM_DEV_ERROR(dev->dev, "failed to get axi_clk\n"); ret = PTR_ERR(mdp4_kms->axi_clk); goto fail; } @@ -519,21 +519,21 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) if (ret) goto fail; } else { - dev_info(dev->dev, "no iommu, fallback to phys " + DRM_DEV_INFO(dev->dev, "no iommu, fallback to phys " "contig buffers for scanout\n"); aspace = NULL; } ret = modeset_init(mdp4_kms); if (ret) { - dev_err(dev->dev, "modeset_init failed: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "modeset_init failed: %d\n", ret); goto fail; } mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC); if (IS_ERR(mdp4_kms->blank_cursor_bo)) { ret = PTR_ERR(mdp4_kms->blank_cursor_bo); - dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); mdp4_kms->blank_cursor_bo = NULL; goto fail; } @@ -541,7 +541,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, kms->aspace, &mdp4_kms->blank_cursor_iova); if (ret) { - dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret); goto fail; } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c index 2bfb39082f54..9e08c2efac24 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c @@ -47,7 +47,7 @@ static void bs_init(struct mdp4_lcdc_encoder *mdp4_lcdc_encoder) struct lcdc_platform_data *lcdc_pdata = mdp4_find_pdata("lvds.0"); if (!lcdc_pdata) { - dev_err(dev->dev, "could not find lvds pdata\n"); + DRM_DEV_ERROR(dev->dev, "could not find lvds pdata\n"); return; } @@ -224,7 +224,7 @@ static void setup_phy(struct drm_encoder *encoder) break; default: - dev_err(dev->dev, "unknown bpp: %d\n", bpp); + DRM_DEV_ERROR(dev->dev, "unknown bpp: %d\n", bpp); return; } @@ -241,7 +241,7 @@ static void setup_phy(struct drm_encoder *encoder) MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN; break; default: - dev_err(dev->dev, "unknown # of channels: %d\n", nchan); + DRM_DEV_ERROR(dev->dev, "unknown # of channels: %d\n", nchan); return; } @@ -361,7 +361,7 @@ static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { ret = regulator_disable(mdp4_lcdc_encoder->regs[i]); if (ret) - dev_err(dev->dev, "failed to disable regulator: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to disable regulator: %d\n", ret); } bs_set(mdp4_lcdc_encoder, 0); @@ -398,16 +398,16 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { ret = regulator_enable(mdp4_lcdc_encoder->regs[i]); if (ret) - dev_err(dev->dev, "failed to enable regulator: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to enable regulator: %d\n", ret); } DBG("setting lcdc_clk=%lu", pc); ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc); if (ret) - dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to configure lcdc_clk: %d\n", ret); ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk); if (ret) - dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret); panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node); if (!IS_ERR(panel)) { @@ -461,7 +461,7 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, /* TODO: do we need different pll in other cases? */ mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev); if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) { - dev_err(dev->dev, "failed to get lvds_clk\n"); + DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n"); ret = PTR_ERR(mdp4_lcdc_encoder->lcdc_clk); goto fail; } @@ -470,7 +470,7 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, reg = devm_regulator_get(dev->dev, "lvds-vccs-3p3v"); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get lvds-vccs-3p3v: %d\n", ret); goto fail; } mdp4_lcdc_encoder->regs[0] = reg; @@ -478,7 +478,7 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, reg = devm_regulator_get(dev->dev, "lvds-pll-vdda"); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get lvds-pll-vdda: %d\n", ret); goto fail; } mdp4_lcdc_encoder->regs[1] = reg; @@ -486,7 +486,7 @@ struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, reg = devm_regulator_get(dev->dev, "lvds-vdda"); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(dev->dev, "failed to get lvds-vdda: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get lvds-vdda: %d\n", ret); goto fail; } mdp4_lcdc_encoder->regs[2] = reg; diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c index 7a499731ce93..005066f7154d 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c @@ -234,22 +234,22 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, format = to_mdp_format(msm_framebuffer_format(fb)); if (src_w > (crtc_w * DOWN_SCALE_MAX)) { - dev_err(dev->dev, "Width down scaling exceeds limits!\n"); + DRM_DEV_ERROR(dev->dev, "Width down scaling exceeds limits!\n"); return -ERANGE; } if (src_h > (crtc_h * DOWN_SCALE_MAX)) { - dev_err(dev->dev, "Height down scaling exceeds limits!\n"); + DRM_DEV_ERROR(dev->dev, "Height down scaling exceeds limits!\n"); return -ERANGE; } if (crtc_w > (src_w * UP_SCALE_MAX)) { - dev_err(dev->dev, "Width up scaling exceeds limits!\n"); + DRM_DEV_ERROR(dev->dev, "Width up scaling exceeds limits!\n"); return -ERANGE; } if (crtc_h > (src_h * UP_SCALE_MAX)) { - dev_err(dev->dev, "Height up scaling exceeds limits!\n"); + DRM_DEV_ERROR(dev->dev, "Height up scaling exceeds limits!\n"); return -ERANGE; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c index 824067d2d427..42f9e4b3da9c 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c @@ -600,7 +600,7 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, } if (major != 1) { - dev_err(dev->dev, "unexpected MDP major version: v%d.%d\n", + DRM_DEV_ERROR(dev->dev, "unexpected MDP major version: v%d.%d\n", major, minor); ret = -ENXIO; goto fail; @@ -615,7 +615,7 @@ struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms, break; } if (unlikely(!mdp5_cfg)) { - dev_err(dev->dev, "unexpected MDP minor revision: v%d.%d\n", + DRM_DEV_ERROR(dev->dev, "unexpected MDP minor revision: v%d.%d\n", major, minor); ret = -ENXIO; goto fail; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c index d6f79dc755b4..c1962f29ec7d 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c @@ -55,20 +55,20 @@ static int pingpong_tearcheck_setup(struct drm_encoder *encoder, int pp_id = mixer->pp; if (IS_ERR_OR_NULL(mdp5_kms->vsync_clk)) { - dev_err(dev, "vsync_clk is not initialized\n"); + DRM_DEV_ERROR(dev, "vsync_clk is not initialized\n"); return -EINVAL; } total_lines_x100 = mode->vtotal * mode->vrefresh; if (!total_lines_x100) { - dev_err(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n", + DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n", __func__, mode->vtotal, mode->vrefresh); return -EINVAL; } vsync_clk_speed = clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE); if (vsync_clk_speed <= 0) { - dev_err(dev, "vsync_clk round rate failed %ld\n", + DRM_DEV_ERROR(dev, "vsync_clk round rate failed %ld\n", vsync_clk_speed); return -EINVAL; } @@ -102,13 +102,13 @@ static int pingpong_tearcheck_enable(struct drm_encoder *encoder) ret = clk_set_rate(mdp5_kms->vsync_clk, clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE)); if (ret) { - dev_err(encoder->dev->dev, + DRM_DEV_ERROR(encoder->dev->dev, "vsync_clk clk_set_rate failed, %d\n", ret); return ret; } ret = clk_prepare_enable(mdp5_kms->vsync_clk); if (ret) { - dev_err(encoder->dev->dev, + DRM_DEV_ERROR(encoder->dev->dev, "vsync_clk clk_prepare_enable failed, %d\n", ret); return ret; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index b1da9ce54379..413b52211017 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -662,7 +662,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, ret = mdp5_crtc_setup_pipeline(crtc, state, need_right_mixer); if (ret) { - dev_err(dev->dev, "couldn't assign mixers %d\n", ret); + DRM_DEV_ERROR(dev->dev, "couldn't assign mixers %d\n", ret); return ret; } @@ -679,7 +679,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, * and that we don't have conflicting mixer stages: */ if ((cnt + start - 1) >= hw_cfg->lm.nb_stages) { - dev_err(dev->dev, "too many planes! cnt=%d, start stage=%d\n", + DRM_DEV_ERROR(dev->dev, "too many planes! cnt=%d, start stage=%d\n", cnt, start); return -EINVAL; } @@ -879,7 +879,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, } if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { - dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height); + DRM_DEV_ERROR(dev->dev, "bad cursor size: %dx%d\n", width, height); return -EINVAL; } @@ -924,7 +924,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, set_cursor: ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable); if (ret) { - dev_err(dev->dev, "failed to %sable cursor: %d\n", + DRM_DEV_ERROR(dev->dev, "failed to %sable cursor: %d\n", cursor_enable ? "en" : "dis", ret); goto end; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c index f93d5681267c..65a871f9f0d9 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_ctl.c @@ -262,13 +262,13 @@ int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline, struct mdp5_hw_mixer *mixer = pipeline->mixer; if (unlikely(WARN_ON(!mixer))) { - dev_err(ctl_mgr->dev->dev, "CTL %d cannot find LM", + DRM_DEV_ERROR(ctl_mgr->dev->dev, "CTL %d cannot find LM", ctl->id); return -EINVAL; } if (pipeline->r_mixer) { - dev_err(ctl_mgr->dev->dev, "unsupported configuration"); + DRM_DEV_ERROR(ctl_mgr->dev->dev, "unsupported configuration"); return -EINVAL; } @@ -604,10 +604,10 @@ int mdp5_ctl_pair(struct mdp5_ctl *ctlx, struct mdp5_ctl *ctly, bool enable) mdp5_write(mdp5_kms, REG_MDP5_SPARE_0, 0); return 0; } else if ((ctlx->pair != NULL) || (ctly->pair != NULL)) { - dev_err(ctl_mgr->dev->dev, "CTLs already paired\n"); + DRM_DEV_ERROR(ctl_mgr->dev->dev, "CTLs already paired\n"); return -EINVAL; } else if (!(ctlx->status & ctly->status & CTL_STAT_BOOKED)) { - dev_err(ctl_mgr->dev->dev, "Only pair booked CTLs\n"); + DRM_DEV_ERROR(ctl_mgr->dev->dev, "Only pair booked CTLs\n"); return -EINVAL; } @@ -652,7 +652,7 @@ struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr, if ((ctl_mgr->ctls[c].status & checkm) == match) goto found; - dev_err(ctl_mgr->dev->dev, "No more CTL available!"); + DRM_DEV_ERROR(ctl_mgr->dev->dev, "No more CTL available!"); goto unlock; found: @@ -698,13 +698,13 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, ctl_mgr = kzalloc(sizeof(*ctl_mgr), GFP_KERNEL); if (!ctl_mgr) { - dev_err(dev->dev, "failed to allocate CTL manager\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate CTL manager\n"); ret = -ENOMEM; goto fail; } if (unlikely(WARN_ON(ctl_cfg->count > MAX_CTL))) { - dev_err(dev->dev, "Increase static pool size to at least %d\n", + DRM_DEV_ERROR(dev->dev, "Increase static pool size to at least %d\n", ctl_cfg->count); ret = -ENOSPC; goto fail; @@ -723,7 +723,7 @@ struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev, struct mdp5_ctl *ctl = &ctl_mgr->ctls[c]; if (WARN_ON(!ctl_cfg->base[c])) { - dev_err(dev->dev, "CTL_%d: base is null!\n", c); + DRM_DEV_ERROR(dev->dev, "CTL_%d: base is null!\n", c); ret = -EINVAL; spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags); goto fail; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index bddd625ab91b..d27e35a217bd 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -264,7 +264,7 @@ static int mdp5_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) minor->debugfs_root, minor); if (ret) { - dev_err(dev->dev, "could not install mdp5_debugfs_list\n"); + DRM_DEV_ERROR(dev->dev, "could not install mdp5_debugfs_list\n"); return ret; } @@ -337,7 +337,7 @@ static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms, encoder = mdp5_encoder_init(dev, intf, ctl); if (IS_ERR(encoder)) { - dev_err(dev->dev, "failed to construct encoder\n"); + DRM_DEV_ERROR(dev->dev, "failed to construct encoder\n"); return encoder; } @@ -418,7 +418,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, int dsi_id = get_dsi_id_from_intf(hw_cfg, intf->num); if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) { - dev_err(dev->dev, "failed to find dsi from intf %d\n", + DRM_DEV_ERROR(dev->dev, "failed to find dsi from intf %d\n", intf->num); ret = -EINVAL; break; @@ -443,7 +443,7 @@ static int modeset_init_intf(struct mdp5_kms *mdp5_kms, break; } default: - dev_err(dev->dev, "unknown intf: %d\n", intf->type); + DRM_DEV_ERROR(dev->dev, "unknown intf: %d\n", intf->type); ret = -EINVAL; break; } @@ -500,7 +500,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) plane = mdp5_plane_init(dev, type); if (IS_ERR(plane)) { ret = PTR_ERR(plane); - dev_err(dev->dev, "failed to construct plane %d (%d)\n", i, ret); + DRM_DEV_ERROR(dev->dev, "failed to construct plane %d (%d)\n", i, ret); goto fail; } priv->planes[priv->num_planes++] = plane; @@ -517,7 +517,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) crtc = mdp5_crtc_init(dev, primary[i], cursor[i], i); if (IS_ERR(crtc)) { ret = PTR_ERR(crtc); - dev_err(dev->dev, "failed to construct crtc %d (%d)\n", i, ret); + DRM_DEV_ERROR(dev->dev, "failed to construct crtc %d (%d)\n", i, ret); goto fail; } priv->crtcs[priv->num_crtcs++] = crtc; @@ -552,7 +552,7 @@ static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms, *major = FIELD(version, MDP5_HW_VERSION_MAJOR); *minor = FIELD(version, MDP5_HW_VERSION_MINOR); - dev_info(dev, "MDP5 version v%d.%d", *major, *minor); + DRM_DEV_INFO(dev, "MDP5 version v%d.%d", *major, *minor); } static int get_clk(struct platform_device *pdev, struct clk **clkp, @@ -561,7 +561,7 @@ static int get_clk(struct platform_device *pdev, struct clk **clkp, struct device *dev = &pdev->dev; struct clk *clk = msm_clk_get(pdev, name); if (IS_ERR(clk) && mandatory) { - dev_err(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk)); + DRM_DEV_ERROR(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk)); return PTR_ERR(clk); } if (IS_ERR(clk)) @@ -688,7 +688,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) irq = irq_of_parse_and_map(pdev->dev.of_node, 0); if (irq < 0) { ret = irq; - dev_err(&pdev->dev, "failed to get irq: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to get irq: %d\n", ret); goto fail; } @@ -724,12 +724,12 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) ret = aspace->mmu->funcs->attach(aspace->mmu, iommu_ports, ARRAY_SIZE(iommu_ports)); if (ret) { - dev_err(&pdev->dev, "failed to attach iommu: %d\n", + DRM_DEV_ERROR(&pdev->dev, "failed to attach iommu: %d\n", ret); goto fail; } } else { - dev_info(&pdev->dev, + DRM_DEV_INFO(&pdev->dev, "no iommu, fallback to phys contig buffers for scanout\n"); aspace = NULL; } @@ -738,7 +738,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) ret = modeset_init(mdp5_kms); if (ret) { - dev_err(&pdev->dev, "modeset_init failed: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "modeset_init failed: %d\n", ret); goto fail; } @@ -795,7 +795,7 @@ static int construct_pipes(struct mdp5_kms *mdp5_kms, int cnt, hwpipe = mdp5_pipe_init(pipes[i], offsets[i], caps); if (IS_ERR(hwpipe)) { ret = PTR_ERR(hwpipe); - dev_err(dev->dev, "failed to construct pipe for %s (%d)\n", + DRM_DEV_ERROR(dev->dev, "failed to construct pipe for %s (%d)\n", pipe2name(pipes[i]), ret); return ret; } @@ -867,7 +867,7 @@ static int hwmixer_init(struct mdp5_kms *mdp5_kms) mixer = mdp5_mixer_init(&hw_cfg->lm.instances[i]); if (IS_ERR(mixer)) { ret = PTR_ERR(mixer); - dev_err(dev->dev, "failed to construct LM%d (%d)\n", + DRM_DEV_ERROR(dev->dev, "failed to construct LM%d (%d)\n", i, ret); return ret; } @@ -897,7 +897,7 @@ static int interface_init(struct mdp5_kms *mdp5_kms) intf = kzalloc(sizeof(*intf), GFP_KERNEL); if (!intf) { - dev_err(dev->dev, "failed to construct INTF%d\n", i); + DRM_DEV_ERROR(dev->dev, "failed to construct INTF%d\n", i); return -ENOMEM; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c index 1cc4e57f0226..889c2940692c 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c @@ -132,7 +132,7 @@ static int mdss_irq_domain_init(struct mdp5_mdss *mdp5_mdss) d = irq_domain_add_linear(dev->of_node, 32, &mdss_hw_irqdomain_ops, mdp5_mdss); if (!d) { - dev_err(dev, "mdss irq domain add failed\n"); + DRM_DEV_ERROR(dev, "mdss irq domain add failed\n"); return -ENXIO; } @@ -246,7 +246,7 @@ int mdp5_mdss_init(struct drm_device *dev) ret = msm_mdss_get_clocks(mdp5_mdss); if (ret) { - dev_err(dev->dev, "failed to get clocks: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get clocks: %d\n", ret); goto fail; } @@ -259,7 +259,7 @@ int mdp5_mdss_init(struct drm_device *dev) ret = regulator_enable(mdp5_mdss->vdd); if (ret) { - dev_err(dev->dev, "failed to enable regulator vdd: %d\n", + DRM_DEV_ERROR(dev->dev, "failed to enable regulator vdd: %d\n", ret); goto fail; } @@ -267,13 +267,13 @@ int mdp5_mdss_init(struct drm_device *dev) ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0), mdss_irq, 0, "mdss_isr", mdp5_mdss); if (ret) { - dev_err(dev->dev, "failed to init irq: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to init irq: %d\n", ret); goto fail_irq; } ret = mdss_irq_domain_init(mdp5_mdss); if (ret) { - dev_err(dev->dev, "failed to init sub-block irqs: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to init sub-block irqs: %d\n", ret); goto fail_irq; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 310459541e48..be13140967b4 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -125,7 +125,7 @@ static int mdp5_plane_atomic_set_property(struct drm_plane *plane, SET_PROPERTY(zpos, ZPOS, uint8_t); - dev_err(dev->dev, "Invalid property\n"); + DRM_DEV_ERROR(dev->dev, "Invalid property\n"); ret = -EINVAL; done: return ret; @@ -153,7 +153,7 @@ static int mdp5_plane_atomic_get_property(struct drm_plane *plane, GET_PROPERTY(zpos, ZPOS, uint8_t); - dev_err(dev->dev, "Invalid property\n"); + DRM_DEV_ERROR(dev->dev, "Invalid property\n"); ret = -EINVAL; done: return ret; @@ -658,7 +658,7 @@ static int calc_scalex_steps(struct drm_plane *plane, ret = calc_phase_step(src, dest, &phasex_step); if (ret) { - dev_err(dev, "X scaling (%d->%d) failed: %d\n", src, dest, ret); + DRM_DEV_ERROR(dev, "X scaling (%d->%d) failed: %d\n", src, dest, ret); return ret; } @@ -683,7 +683,7 @@ static int calc_scaley_steps(struct drm_plane *plane, ret = calc_phase_step(src, dest, &phasey_step); if (ret) { - dev_err(dev, "Y scaling (%d->%d) failed: %d\n", src, dest, ret); + DRM_DEV_ERROR(dev, "Y scaling (%d->%d) failed: %d\n", src, dest, ret); return ret; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c index 96c2b828dba4..7cebcb2b3a37 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c @@ -88,7 +88,7 @@ static int smp_request_block(struct mdp5_smp *smp, avail = cnt - bitmap_weight(state->state, cnt); if (nblks > avail) { - dev_err(smp->dev->dev, "out of blks (req=%d > avail=%d)\n", + DRM_DEV_ERROR(smp->dev->dev, "out of blks (req=%d > avail=%d)\n", nblks, avail); return -ENOSPC; } @@ -188,7 +188,7 @@ int mdp5_smp_assign(struct mdp5_smp *smp, struct mdp5_smp_state *state, DBG("%s[%d]: request %d SMP blocks", pipe2name(pipe), i, n); ret = smp_request_block(smp, state, cid, n); if (ret) { - dev_err(dev->dev, "Cannot allocate %d SMP blocks: %d\n", + DRM_DEV_ERROR(dev->dev, "Cannot allocate %d SMP blocks: %d\n", n, ret); return ret; } diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index a9768f823290..7b2a1e6a8810 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -29,7 +29,7 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi) phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); if (!phy_node) { - dev_err(&pdev->dev, "cannot find phy device\n"); + DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n"); return -ENXIO; } @@ -40,7 +40,7 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi) of_node_put(phy_node); if (!phy_pdev || !msm_dsi->phy) { - dev_err(&pdev->dev, "%s: phy driver is not ready\n", __func__); + DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); return -EPROBE_DEFER; } @@ -210,7 +210,7 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, ret = msm_dsi_host_modeset_init(msm_dsi->host, dev); if (ret) { - dev_err(dev->dev, "failed to modeset init host: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to modeset init host: %d\n", ret); goto fail; } @@ -222,7 +222,7 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, msm_dsi->bridge = msm_dsi_manager_bridge_init(msm_dsi->id); if (IS_ERR(msm_dsi->bridge)) { ret = PTR_ERR(msm_dsi->bridge); - dev_err(dev->dev, "failed to create dsi bridge: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to create dsi bridge: %d\n", ret); msm_dsi->bridge = NULL; goto fail; } @@ -244,7 +244,7 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, if (IS_ERR(msm_dsi->connector)) { ret = PTR_ERR(msm_dsi->connector); - dev_err(dev->dev, + DRM_DEV_ERROR(dev->dev, "failed to create dsi connector: %d\n", ret); msm_dsi->connector = NULL; goto fail; diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 9c6c523eacdc..eba901584035 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1050,7 +1050,7 @@ static void dsi_wait4video_done(struct msm_dsi_host *msm_host) msecs_to_jiffies(70)); if (ret <= 0) - dev_err(dev, "wait for video done timed out\n"); + DRM_DEV_ERROR(dev, "wait for video done timed out\n"); dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0); } @@ -1673,7 +1673,7 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, prop = of_find_property(ep, "data-lanes", &len); if (!prop) { - dev_dbg(dev, + DRM_DEV_DEBUG(dev, "failed to find data lane mapping, using default\n"); return 0; } @@ -1681,7 +1681,7 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, num_lanes = len / sizeof(u32); if (num_lanes < 1 || num_lanes > 4) { - dev_err(dev, "bad number of data lanes\n"); + DRM_DEV_ERROR(dev, "bad number of data lanes\n"); return -EINVAL; } @@ -1690,7 +1690,7 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, ret = of_property_read_u32_array(ep, "data-lanes", lane_map, num_lanes); if (ret) { - dev_err(dev, "failed to read lane data\n"); + DRM_DEV_ERROR(dev, "failed to read lane data\n"); return ret; } @@ -1711,7 +1711,7 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, */ for (j = 0; j < num_lanes; j++) { if (lane_map[j] < 0 || lane_map[j] > 3) - dev_err(dev, "bad physical lane entry %u\n", + DRM_DEV_ERROR(dev, "bad physical lane entry %u\n", lane_map[j]); if (swap[lane_map[j]] != j) @@ -1742,13 +1742,13 @@ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) */ endpoint = of_graph_get_endpoint_by_regs(np, 1, -1); if (!endpoint) { - dev_dbg(dev, "%s: no endpoint\n", __func__); + DRM_DEV_DEBUG(dev, "%s: no endpoint\n", __func__); return 0; } ret = dsi_host_parse_lane_data(msm_host, endpoint); if (ret) { - dev_err(dev, "%s: invalid lane configuration %d\n", + DRM_DEV_ERROR(dev, "%s: invalid lane configuration %d\n", __func__, ret); ret = -EINVAL; goto err; @@ -1757,7 +1757,7 @@ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) /* Get panel node from the output port's endpoint data */ device_node = of_graph_get_remote_node(np, 1, 0); if (!device_node) { - dev_dbg(dev, "%s: no valid device\n", __func__); + DRM_DEV_DEBUG(dev, "%s: no valid device\n", __func__); ret = -ENODEV; goto err; } @@ -1768,7 +1768,7 @@ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host) msm_host->sfpb = syscon_regmap_lookup_by_phandle(np, "syscon-sfpb"); if (IS_ERR(msm_host->sfpb)) { - dev_err(dev, "%s: failed to get sfpb regmap\n", + DRM_DEV_ERROR(dev, "%s: failed to get sfpb regmap\n", __func__); ret = PTR_ERR(msm_host->sfpb); } @@ -1918,7 +1918,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); if (msm_host->irq < 0) { ret = msm_host->irq; - dev_err(dev->dev, "failed to get irq: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); return ret; } @@ -1926,7 +1926,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "dsi_isr", msm_host); if (ret < 0) { - dev_err(&pdev->dev, "failed to request IRQ%u: %d\n", + DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n", msm_host->irq, ret); return ret; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 9a9fa0c75a13..1760483b247e 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -404,7 +404,7 @@ static int dsi_phy_regulator_init(struct msm_dsi_phy *phy) ret = devm_regulator_bulk_get(dev, num, s); if (ret < 0) { - dev_err(dev, "%s: failed to init regulator, ret=%d\n", + DRM_DEV_ERROR(dev, "%s: failed to init regulator, ret=%d\n", __func__, ret); return ret; } @@ -441,7 +441,7 @@ static int dsi_phy_regulator_enable(struct msm_dsi_phy *phy) ret = regulator_set_load(s[i].consumer, regs[i].enable_load); if (ret < 0) { - dev_err(dev, + DRM_DEV_ERROR(dev, "regulator %d set op mode failed, %d\n", i, ret); goto fail; @@ -451,7 +451,7 @@ static int dsi_phy_regulator_enable(struct msm_dsi_phy *phy) ret = regulator_bulk_enable(num, s); if (ret < 0) { - dev_err(dev, "regulator enable failed, %d\n", ret); + DRM_DEV_ERROR(dev, "regulator enable failed, %d\n", ret); goto fail; } @@ -472,7 +472,7 @@ static int dsi_phy_enable_resource(struct msm_dsi_phy *phy) ret = clk_prepare_enable(phy->ahb_clk); if (ret) { - dev_err(dev, "%s: can't enable ahb clk, %d\n", __func__, ret); + DRM_DEV_ERROR(dev, "%s: can't enable ahb clk, %d\n", __func__, ret); pm_runtime_put_sync(dev); } @@ -543,7 +543,7 @@ int msm_dsi_phy_init_common(struct msm_dsi_phy *phy) phy->reg_base = msm_ioremap(pdev, "dsi_phy_regulator", "DSI_PHY_REG"); if (IS_ERR(phy->reg_base)) { - dev_err(&pdev->dev, "%s: failed to map phy regulator base\n", + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy regulator base\n", __func__); ret = -ENOMEM; goto fail; @@ -574,7 +574,7 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) phy->id = dsi_phy_get_id(phy); if (phy->id < 0) { ret = phy->id; - dev_err(dev, "%s: couldn't identify PHY index, %d\n", + DRM_DEV_ERROR(dev, "%s: couldn't identify PHY index, %d\n", __func__, ret); goto fail; } @@ -584,20 +584,20 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) phy->base = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); if (IS_ERR(phy->base)) { - dev_err(dev, "%s: failed to map phy base\n", __func__); + DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); ret = -ENOMEM; goto fail; } ret = dsi_phy_regulator_init(phy); if (ret) { - dev_err(dev, "%s: failed to init regulator\n", __func__); + DRM_DEV_ERROR(dev, "%s: failed to init regulator\n", __func__); goto fail; } phy->ahb_clk = msm_clk_get(pdev, "iface"); if (IS_ERR(phy->ahb_clk)) { - dev_err(dev, "%s: Unable to get ahb clk\n", __func__); + DRM_DEV_ERROR(dev, "%s: Unable to get ahb clk\n", __func__); ret = PTR_ERR(phy->ahb_clk); goto fail; } @@ -617,7 +617,7 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) phy->pll = msm_dsi_pll_init(pdev, phy->cfg->type, phy->id); if (IS_ERR_OR_NULL(phy->pll)) - dev_info(dev, + DRM_DEV_INFO(dev, "%s: pll init failed: %ld, need separate pll clk driver\n", __func__, PTR_ERR(phy->pll)); @@ -675,21 +675,21 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, ret = dsi_phy_enable_resource(phy); if (ret) { - dev_err(dev, "%s: resource enable failed, %d\n", + DRM_DEV_ERROR(dev, "%s: resource enable failed, %d\n", __func__, ret); goto res_en_fail; } ret = dsi_phy_regulator_enable(phy); if (ret) { - dev_err(dev, "%s: regulator enable failed, %d\n", + DRM_DEV_ERROR(dev, "%s: regulator enable failed, %d\n", __func__, ret); goto reg_en_fail; } ret = phy->cfg->ops.enable(phy, src_pll_id, clk_req); if (ret) { - dev_err(dev, "%s: phy enable failed, %d\n", __func__, ret); + DRM_DEV_ERROR(dev, "%s: phy enable failed, %d\n", __func__, ret); goto phy_en_fail; } @@ -702,7 +702,7 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, if (phy->usecase != MSM_DSI_PHY_SLAVE) { ret = msm_dsi_pll_restore_state(phy->pll); if (ret) { - dev_err(dev, "%s: failed to restore pll state, %d\n", + DRM_DEV_ERROR(dev, "%s: failed to restore pll state, %d\n", __func__, ret); goto pll_restor_fail; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index b3fffc8dbb2a..44959e79ce28 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -93,7 +93,7 @@ static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, DBG(""); if (msm_dsi_dphy_timing_calc_v3(timing, clk_req)) { - dev_err(&phy->pdev->dev, + DRM_DEV_ERROR(&phy->pdev->dev, "%s: D-PHY timing calculation failed\n", __func__); return -EINVAL; } @@ -172,7 +172,7 @@ static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, ret = msm_dsi_pll_set_usecase(phy->pll, phy->usecase); if (ret) { - dev_err(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", + DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", __func__, ret); return ret; } @@ -196,7 +196,7 @@ static int dsi_10nm_phy_init(struct msm_dsi_phy *phy) phy->lane_base = msm_ioremap(pdev, "dsi_phy_lane", "DSI_PHY_LANE"); if (IS_ERR(phy->lane_base)) { - dev_err(&pdev->dev, "%s: failed to map phy lane base\n", + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy lane base\n", __func__); return -ENOMEM; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 513f4234adc1..a172c667e8bc 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -64,7 +64,7 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, void __iomem *lane_base = phy->lane_base; if (msm_dsi_dphy_timing_calc_v2(timing, clk_req)) { - dev_err(&phy->pdev->dev, + DRM_DEV_ERROR(&phy->pdev->dev, "%s: D-PHY timing calculation failed\n", __func__); return -EINVAL; } @@ -115,7 +115,7 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, ret = msm_dsi_pll_set_usecase(phy->pll, phy->usecase); if (ret) { - dev_err(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", + DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", __func__, ret); return ret; } @@ -142,7 +142,7 @@ static int dsi_14nm_phy_init(struct msm_dsi_phy *phy) phy->lane_base = msm_ioremap(pdev, "dsi_phy_lane", "DSI_PHY_LANE"); if (IS_ERR(phy->lane_base)) { - dev_err(&pdev->dev, "%s: failed to map phy lane base\n", + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map phy lane base\n", __func__); return -ENOMEM; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c index 1ca6c69516f5..9ea9478d3707 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c @@ -82,7 +82,7 @@ static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, DBG(""); if (msm_dsi_dphy_timing_calc(timing, clk_req)) { - dev_err(&phy->pdev->dev, + DRM_DEV_ERROR(&phy->pdev->dev, "%s: D-PHY timing calculation failed\n", __func__); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 4972b52cbe44..c79505d97fe8 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -76,7 +76,7 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, DBG(""); if (msm_dsi_dphy_timing_calc(timing, clk_req)) { - dev_err(&phy->pdev->dev, + DRM_DEV_ERROR(&phy->pdev->dev, "%s: D-PHY timing calculation failed\n", __func__); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 398004463498..98790b44da48 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -132,7 +132,7 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, DBG(""); if (msm_dsi_dphy_timing_calc(timing, clk_req)) { - dev_err(&phy->pdev->dev, + DRM_DEV_ERROR(&phy->pdev->dev, "%s: D-PHY timing calculation failed\n", __func__); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c index 613e206fa4fc..7a1fb4da2ad3 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c @@ -175,7 +175,7 @@ struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev, } if (IS_ERR(pll)) { - dev_err(dev, "%s: failed to init DSI PLL\n", __func__); + DRM_DEV_ERROR(dev, "%s: failed to init DSI PLL\n", __func__); return pll; } diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c index 4c03f0b7343e..f8819ccdc25c 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c @@ -760,7 +760,7 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, pll_10nm->hw_data); if (ret) { - dev_err(dev, "failed to register clk provider: %d\n", ret); + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); return ret; } @@ -788,13 +788,13 @@ struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) pll_10nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); if (IS_ERR_OR_NULL(pll_10nm->phy_cmn_mmio)) { - dev_err(&pdev->dev, "failed to map CMN PHY base\n"); + DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); return ERR_PTR(-ENOMEM); } pll_10nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); if (IS_ERR_OR_NULL(pll_10nm->mmio)) { - dev_err(&pdev->dev, "failed to map PLL base\n"); + DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); return ERR_PTR(-ENOMEM); } @@ -813,7 +813,7 @@ struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) ret = pll_10nm_register(pll_10nm); if (ret) { - dev_err(&pdev->dev, "failed to register PLL: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c index 71fe60e5f01f..0e18cddd6f22 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c @@ -783,7 +783,7 @@ static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll) POLL_TIMEOUT_US); if (unlikely(!locked)) - dev_err(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); + DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); else DBG("DSI PLL lock success"); @@ -829,7 +829,7 @@ static int dsi_pll_14nm_restore_state(struct msm_dsi_pll *pll) ret = dsi_pll_14nm_vco_set_rate(&pll->clk_hw, cached_state->vco_rate, 0); if (ret) { - dev_err(&pll_14nm->pdev->dev, + DRM_DEV_ERROR(&pll_14nm->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } @@ -1039,7 +1039,7 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm) ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, pll_14nm->hw_data); if (ret) { - dev_err(dev, "failed to register clk provider: %d\n", ret); + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); return ret; } @@ -1067,13 +1067,13 @@ struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id) pll_14nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); if (IS_ERR_OR_NULL(pll_14nm->phy_cmn_mmio)) { - dev_err(&pdev->dev, "failed to map CMN PHY base\n"); + DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); return ERR_PTR(-ENOMEM); } pll_14nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); if (IS_ERR_OR_NULL(pll_14nm->mmio)) { - dev_err(&pdev->dev, "failed to map PLL base\n"); + DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); return ERR_PTR(-ENOMEM); } @@ -1096,7 +1096,7 @@ struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id) ret = pll_14nm_register(pll_14nm); if (ret) { - dev_err(&pdev->dev, "failed to register PLL: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c index 26e3a01a99c2..dcbbaeb1b1fb 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c @@ -156,7 +156,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (rate <= lpfr_lut[i].vco_rate) break; if (i == LPFR_LUT_SIZE) { - dev_err(dev, "unable to get loop filter resistance. vco=%lu\n", + DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n", rate); return -EINVAL; } @@ -386,7 +386,7 @@ static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll) } if (unlikely(!locked)) - dev_err(dev, "DSI PLL lock failed\n"); + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); else DBG("DSI PLL Lock success"); @@ -429,7 +429,7 @@ static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll) locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); if (unlikely(!locked)) - dev_err(dev, "DSI PLL lock failed\n"); + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); else DBG("DSI PLL lock success"); @@ -468,7 +468,7 @@ static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll) ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw, cached_state->vco_rate, 0); if (ret) { - dev_err(&pll_28nm->pdev->dev, + DRM_DEV_ERROR(&pll_28nm->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } @@ -581,7 +581,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &pll_28nm->clk_data); if (ret) { - dev_err(dev, "failed to register clk provider: %d\n", ret); + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); return ret; } @@ -607,7 +607,7 @@ struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev, pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); if (IS_ERR_OR_NULL(pll_28nm->mmio)) { - dev_err(&pdev->dev, "%s: failed to map pll base\n", __func__); + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); return ERR_PTR(-ENOMEM); } @@ -633,13 +633,13 @@ struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev, pll->en_seq_cnt = 1; pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_lp; } else { - dev_err(&pdev->dev, "phy type (%d) is not 28nm\n", type); + DRM_DEV_ERROR(&pdev->dev, "phy type (%d) is not 28nm\n", type); return ERR_PTR(-EINVAL); } ret = pll_28nm_register(pll_28nm); if (ret) { - dev_err(&pdev->dev, "failed to register PLL: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c index 49008451085b..d6897464755f 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c @@ -327,7 +327,7 @@ static int dsi_pll_28nm_enable_seq(struct msm_dsi_pll *pll) locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); if (unlikely(!locked)) - dev_err(dev, "DSI PLL lock failed\n"); + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); else DBG("DSI PLL lock success"); @@ -368,7 +368,7 @@ static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll) ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw, cached_state->vco_rate, 0); if (ret) { - dev_err(&pll_28nm->pdev->dev, + DRM_DEV_ERROR(&pll_28nm->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } @@ -482,7 +482,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &pll_28nm->clk_data); if (ret) { - dev_err(dev, "failed to register clk provider: %d\n", ret); + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); return ret; } @@ -508,7 +508,7 @@ struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev, pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); if (IS_ERR_OR_NULL(pll_28nm->mmio)) { - dev_err(&pdev->dev, "%s: failed to map pll base\n", __func__); + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); return ERR_PTR(-ENOMEM); } @@ -526,7 +526,7 @@ struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev, ret = pll_28nm_register(pll_28nm); if (ret) { - dev_err(&pdev->dev, "failed to register PLL: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c index 0940e84b2821..6a63aba98a30 100644 --- a/drivers/gpu/drm/msm/edp/edp.c +++ b/drivers/gpu/drm/msm/edp/edp.c @@ -157,7 +157,7 @@ int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, edp->bridge = msm_edp_bridge_init(edp); if (IS_ERR(edp->bridge)) { ret = PTR_ERR(edp->bridge); - dev_err(dev->dev, "failed to create eDP bridge: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to create eDP bridge: %d\n", ret); edp->bridge = NULL; goto fail; } @@ -165,7 +165,7 @@ int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, edp->connector = msm_edp_connector_init(edp); if (IS_ERR(edp->connector)) { ret = PTR_ERR(edp->connector); - dev_err(dev->dev, "failed to create eDP connector: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to create eDP connector: %d\n", ret); edp->connector = NULL; goto fail; } @@ -173,7 +173,7 @@ int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, edp->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); if (edp->irq < 0) { ret = edp->irq; - dev_err(dev->dev, "failed to get IRQ: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get IRQ: %d\n", ret); goto fail; } @@ -181,7 +181,7 @@ int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, edp_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "edp_isr", edp); if (ret < 0) { - dev_err(dev->dev, "failed to request IRQ%u: %d\n", + DRM_DEV_ERROR(dev->dev, "failed to request IRQ%u: %d\n", edp->irq, ret); goto fail; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 23670907a29d..f0725761b327 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -98,7 +98,7 @@ static int msm_hdmi_get_phy(struct hdmi *hdmi) phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); if (!phy_node) { - dev_err(&pdev->dev, "cannot find phy device\n"); + DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n"); return -ENXIO; } @@ -109,7 +109,7 @@ static int msm_hdmi_get_phy(struct hdmi *hdmi) of_node_put(phy_node); if (!phy_pdev || !hdmi->phy) { - dev_err(&pdev->dev, "phy driver is not ready\n"); + DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n"); return -EPROBE_DEFER; } @@ -153,7 +153,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) hdmi->qfprom_mmio = msm_ioremap(pdev, config->qfprom_mmio_name, "HDMI_QFPROM"); if (IS_ERR(hdmi->qfprom_mmio)) { - dev_info(&pdev->dev, "can't find qfprom resource\n"); + DRM_DEV_INFO(&pdev->dev, "can't find qfprom resource\n"); hdmi->qfprom_mmio = NULL; } @@ -172,7 +172,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) config->hpd_reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(&pdev->dev, "failed to get hpd regulator: %s (%d)\n", + DRM_DEV_ERROR(&pdev->dev, "failed to get hpd regulator: %s (%d)\n", config->hpd_reg_names[i], ret); goto fail; } @@ -195,7 +195,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) config->pwr_reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(&pdev->dev, "failed to get pwr regulator: %s (%d)\n", + DRM_DEV_ERROR(&pdev->dev, "failed to get pwr regulator: %s (%d)\n", config->pwr_reg_names[i], ret); goto fail; } @@ -217,7 +217,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) clk = msm_clk_get(pdev, config->hpd_clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); - dev_err(&pdev->dev, "failed to get hpd clk: %s (%d)\n", + DRM_DEV_ERROR(&pdev->dev, "failed to get hpd clk: %s (%d)\n", config->hpd_clk_names[i], ret); goto fail; } @@ -239,7 +239,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) clk = msm_clk_get(pdev, config->pwr_clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); - dev_err(&pdev->dev, "failed to get pwr clk: %s (%d)\n", + DRM_DEV_ERROR(&pdev->dev, "failed to get pwr clk: %s (%d)\n", config->pwr_clk_names[i], ret); goto fail; } @@ -254,14 +254,14 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) hdmi->i2c = msm_hdmi_i2c_init(hdmi); if (IS_ERR(hdmi->i2c)) { ret = PTR_ERR(hdmi->i2c); - dev_err(&pdev->dev, "failed to get i2c: %d\n", ret); + DRM_DEV_ERROR(&pdev->dev, "failed to get i2c: %d\n", ret); hdmi->i2c = NULL; goto fail; } ret = msm_hdmi_get_phy(hdmi); if (ret) { - dev_err(&pdev->dev, "failed to get phy\n"); + DRM_DEV_ERROR(&pdev->dev, "failed to get phy\n"); goto fail; } @@ -303,7 +303,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, hdmi->bridge = msm_hdmi_bridge_init(hdmi); if (IS_ERR(hdmi->bridge)) { ret = PTR_ERR(hdmi->bridge); - dev_err(dev->dev, "failed to create HDMI bridge: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to create HDMI bridge: %d\n", ret); hdmi->bridge = NULL; goto fail; } @@ -311,7 +311,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, hdmi->connector = msm_hdmi_connector_init(hdmi); if (IS_ERR(hdmi->connector)) { ret = PTR_ERR(hdmi->connector); - dev_err(dev->dev, "failed to create HDMI connector: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n", ret); hdmi->connector = NULL; goto fail; } @@ -319,7 +319,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); if (hdmi->irq < 0) { ret = hdmi->irq; - dev_err(dev->dev, "failed to get irq: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); goto fail; } @@ -327,7 +327,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, msm_hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "hdmi_isr", hdmi); if (ret < 0) { - dev_err(dev->dev, "failed to request IRQ%u: %d\n", + DRM_DEV_ERROR(dev->dev, "failed to request IRQ%u: %d\n", hdmi->irq, ret); goto fail; } @@ -476,7 +476,7 @@ static int msm_hdmi_audio_hw_params(struct device *dev, void *data, unsigned int level_shift = 0; /* 0dB */ bool down_mix = false; - dev_dbg(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate, + DRM_DEV_DEBUG(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate, params->sample_width, params->cea.channels); switch (params->cea.channels) { @@ -527,7 +527,7 @@ static int msm_hdmi_audio_hw_params(struct device *dev, void *data, rate = HDMI_SAMPLE_RATE_192KHZ; break; default: - dev_err(dev, "rate[%d] not supported!\n", + DRM_DEV_ERROR(dev, "rate[%d] not supported!\n", params->sample_rate); return -EINVAL; } @@ -579,7 +579,7 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) hdmi_cfg = (struct hdmi_platform_config *) of_device_get_match_data(dev); if (!hdmi_cfg) { - dev_err(dev, "unknown hdmi_cfg: %pOFn\n", of_node); + DRM_DEV_ERROR(dev, "unknown hdmi_cfg: %pOFn\n", of_node); return -ENXIO; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 7e357077ed26..98d61c690260 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -40,7 +40,7 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge) for (i = 0; i < config->pwr_reg_cnt; i++) { ret = regulator_enable(hdmi->pwr_regs[i]); if (ret) { - dev_err(dev->dev, "failed to enable pwr regulator: %s (%d)\n", + DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %s (%d)\n", config->pwr_reg_names[i], ret); } } @@ -49,7 +49,7 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge) DBG("pixclock: %lu", hdmi->pixclock); ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock); if (ret) { - dev_err(dev->dev, "failed to set pixel clk: %s (%d)\n", + DRM_DEV_ERROR(dev->dev, "failed to set pixel clk: %s (%d)\n", config->pwr_clk_names[0], ret); } } @@ -57,7 +57,7 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge) for (i = 0; i < config->pwr_clk_cnt; i++) { ret = clk_prepare_enable(hdmi->pwr_clks[i]); if (ret) { - dev_err(dev->dev, "failed to enable pwr clk: %s (%d)\n", + DRM_DEV_ERROR(dev->dev, "failed to enable pwr clk: %s (%d)\n", config->pwr_clk_names[i], ret); } } @@ -82,7 +82,7 @@ static void power_off(struct drm_bridge *bridge) for (i = 0; i < config->pwr_reg_cnt; i++) { ret = regulator_disable(hdmi->pwr_regs[i]); if (ret) { - dev_err(dev->dev, "failed to disable pwr regulator: %s (%d)\n", + DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %s (%d)\n", config->pwr_reg_names[i], ret); } } @@ -105,7 +105,7 @@ static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi) len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); if (len < 0) { - dev_err(&hdmi->pdev->dev, + DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to configure avi infoframe\n"); return; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index e9c9a0af508e..99f2f1038258 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -90,7 +90,7 @@ static int gpio_config(struct hdmi *hdmi, bool on) if (gpio.num != -1) { ret = gpio_request(gpio.num, gpio.label); if (ret) { - dev_err(dev, + DRM_DEV_ERROR(dev, "'%s'(%d) gpio_request failed: %d\n", gpio.label, gpio.num, ret); goto err; @@ -156,7 +156,7 @@ static void enable_hpd_clocks(struct hdmi *hdmi, bool enable) ret = clk_prepare_enable(hdmi->hpd_clks[i]); if (ret) { - dev_err(dev, + DRM_DEV_ERROR(dev, "failed to enable hpd clk: %s (%d)\n", config->hpd_clk_names[i], ret); } @@ -179,7 +179,7 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) for (i = 0; i < config->hpd_reg_cnt; i++) { ret = regulator_enable(hdmi->hpd_regs[i]); if (ret) { - dev_err(dev, "failed to enable hpd regulator: %s (%d)\n", + DRM_DEV_ERROR(dev, "failed to enable hpd regulator: %s (%d)\n", config->hpd_reg_names[i], ret); goto fail; } @@ -187,13 +187,13 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) ret = pinctrl_pm_select_default_state(dev); if (ret) { - dev_err(dev, "pinctrl state chg failed: %d\n", ret); + DRM_DEV_ERROR(dev, "pinctrl state chg failed: %d\n", ret); goto fail; } ret = gpio_config(hdmi, true); if (ret) { - dev_err(dev, "failed to configure GPIOs: %d\n", ret); + DRM_DEV_ERROR(dev, "failed to configure GPIOs: %d\n", ret); goto fail; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c index 73e20219d431..25d2fe2c60e8 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c @@ -66,7 +66,7 @@ static int ddc_clear_irq(struct hdmi_i2c_adapter *hdmi_i2c) } while ((ddc_int_ctrl & HDMI_DDC_INT_CTRL_SW_DONE_INT) && retry); if (!retry) { - dev_err(dev->dev, "timeout waiting for DDC\n"); + DRM_DEV_ERROR(dev->dev, "timeout waiting for DDC\n"); return -ETIMEDOUT; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c index 4157722d6b4d..1f4331ed69bd 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c @@ -37,7 +37,7 @@ static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy) reg = devm_regulator_get(dev, cfg->reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); - dev_err(dev, "failed to get phy regulator: %s (%d)\n", + DRM_DEV_ERROR(dev, "failed to get phy regulator: %s (%d)\n", cfg->reg_names[i], ret); return ret; } @@ -51,7 +51,7 @@ static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy) clk = msm_clk_get(phy->pdev, cfg->clk_names[i]); if (IS_ERR(clk)) { ret = PTR_ERR(clk); - dev_err(dev, "failed to get phy clock: %s (%d)\n", + DRM_DEV_ERROR(dev, "failed to get phy clock: %s (%d)\n", cfg->clk_names[i], ret); return ret; } @@ -73,14 +73,14 @@ int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy) for (i = 0; i < cfg->num_regs; i++) { ret = regulator_enable(phy->regs[i]); if (ret) - dev_err(dev, "failed to enable regulator: %s (%d)\n", + DRM_DEV_ERROR(dev, "failed to enable regulator: %s (%d)\n", cfg->reg_names[i], ret); } for (i = 0; i < cfg->num_clks; i++) { ret = clk_prepare_enable(phy->clks[i]); if (ret) - dev_err(dev, "failed to enable clock: %s (%d)\n", + DRM_DEV_ERROR(dev, "failed to enable clock: %s (%d)\n", cfg->clk_names[i], ret); } @@ -159,7 +159,7 @@ static int msm_hdmi_phy_probe(struct platform_device *pdev) phy->mmio = msm_ioremap(pdev, "hdmi_phy", "HDMI_PHY"); if (IS_ERR(phy->mmio)) { - dev_err(dev, "%s: failed to map phy base\n", __func__); + DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); return -ENOMEM; } @@ -177,7 +177,7 @@ static int msm_hdmi_phy_probe(struct platform_device *pdev) ret = msm_hdmi_phy_pll_init(pdev, phy->cfg->type); if (ret) { - dev_err(dev, "couldn't init PLL\n"); + DRM_DEV_ERROR(dev, "couldn't init PLL\n"); msm_hdmi_phy_resource_disable(phy); return ret; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c index 0df504c61833..318708f26731 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c @@ -725,7 +725,7 @@ int msm_hdmi_pll_8996_init(struct platform_device *pdev) pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); if (IS_ERR(pll->mmio_qserdes_com)) { - dev_err(dev, "failed to map pll base\n"); + DRM_DEV_ERROR(dev, "failed to map pll base\n"); return -ENOMEM; } @@ -737,7 +737,7 @@ int msm_hdmi_pll_8996_init(struct platform_device *pdev) pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name, label); if (IS_ERR(pll->mmio_qserdes_tx[i])) { - dev_err(dev, "failed to map pll base\n"); + DRM_DEV_ERROR(dev, "failed to map pll base\n"); return -ENOMEM; } } @@ -745,7 +745,7 @@ int msm_hdmi_pll_8996_init(struct platform_device *pdev) clk = devm_clk_register(dev, &pll->clk_hw); if (IS_ERR(clk)) { - dev_err(dev, "failed to register pll clock\n"); + DRM_DEV_ERROR(dev, "failed to register pll clock\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c index 99590758c68b..c6dae6e437f9 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c @@ -445,7 +445,7 @@ int msm_hdmi_pll_8960_init(struct platform_device *pdev) pll->mmio = msm_ioremap(pdev, "hdmi_pll", "HDMI_PLL"); if (IS_ERR(pll->mmio)) { - dev_err(dev, "failed to map pll base\n"); + DRM_DEV_ERROR(dev, "failed to map pll base\n"); return -ENOMEM; } @@ -454,7 +454,7 @@ int msm_hdmi_pll_8960_init(struct platform_device *pdev) clk = devm_clk_register(dev, &pll->clk_hw); if (IS_ERR(clk)) { - dev_err(dev, "failed to register pll clock\n"); + DRM_DEV_ERROR(dev, "failed to register pll clock\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index f0da0d3c8a80..03210f45bf87 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -194,13 +194,13 @@ static int late_init_minor(struct drm_minor *minor) ret = msm_rd_debugfs_init(minor); if (ret) { - dev_err(minor->dev->dev, "could not install rd debugfs\n"); + DRM_DEV_ERROR(minor->dev->dev, "could not install rd debugfs\n"); return ret; } ret = msm_perf_debugfs_init(minor); if (ret) { - dev_err(minor->dev->dev, "could not install perf debugfs\n"); + DRM_DEV_ERROR(minor->dev->dev, "could not install perf debugfs\n"); return ret; } @@ -228,7 +228,7 @@ int msm_debugfs_init(struct drm_minor *minor) minor->debugfs_root, minor); if (ret) { - dev_err(dev->dev, "could not install msm_debugfs_list\n"); + DRM_DEV_ERROR(dev->dev, "could not install msm_debugfs_list\n"); return ret; } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index aa145d6f6469..cf960dc78982 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -170,7 +170,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - dev_err(&pdev->dev, "failed to get memory resource: %s\n", name); + DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name); return ERR_PTR(-EINVAL); } @@ -178,7 +178,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name, ptr = devm_ioremap_nocache(&pdev->dev, res->start, size); if (!ptr) { - dev_err(&pdev->dev, "failed to ioremap: %s\n", name); + DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name); return ERR_PTR(-ENOMEM); } @@ -419,12 +419,12 @@ static int msm_init_vram(struct drm_device *dev) p = dma_alloc_attrs(dev->dev, size, &priv->vram.paddr, GFP_KERNEL, attrs); if (!p) { - dev_err(dev->dev, "failed to allocate VRAM\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate VRAM\n"); priv->vram.paddr = 0; return -ENOMEM; } - dev_info(dev->dev, "VRAM: %08x->%08x\n", + DRM_DEV_INFO(dev->dev, "VRAM: %08x->%08x\n", (uint32_t)priv->vram.paddr, (uint32_t)(priv->vram.paddr + size)); } @@ -444,7 +444,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ddev = drm_dev_alloc(drv, dev); if (IS_ERR(ddev)) { - dev_err(dev, "failed to allocate drm_device\n"); + DRM_DEV_ERROR(dev, "failed to allocate drm_device\n"); return PTR_ERR(ddev); } @@ -519,7 +519,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) * and (for example) use dmabuf/prime to share buffers with * imx drm driver on iMX5 */ - dev_err(dev, "failed to load kms\n"); + DRM_DEV_ERROR(dev, "failed to load kms\n"); ret = PTR_ERR(kms); goto err_msm_uninit; } @@ -530,7 +530,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) if (kms) { ret = kms->funcs->hw_init(kms); if (ret) { - dev_err(dev, "kms hw init failed: %d\n", ret); + DRM_DEV_ERROR(dev, "kms hw init failed: %d\n", ret); goto err_msm_uninit; } } @@ -561,7 +561,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ret); if (IS_ERR(priv->disp_thread[i].thread)) { - dev_err(dev, "failed to create crtc_commit kthread\n"); + DRM_DEV_ERROR(dev, "failed to create crtc_commit kthread\n"); priv->disp_thread[i].thread = NULL; } @@ -573,6 +573,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) kthread_run(kthread_worker_fn, &priv->event_thread[i].worker, "crtc_event:%d", priv->event_thread[i].crtc_id); + /** * event thread should also run at same priority as disp_thread * because it is handling frame_done events. A lower priority @@ -613,7 +614,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ret = drm_vblank_init(ddev, priv->num_crtcs); if (ret < 0) { - dev_err(dev, "failed to initialize vblank\n"); + DRM_DEV_ERROR(dev, "failed to initialize vblank\n"); goto err_msm_uninit; } @@ -622,7 +623,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ret = drm_irq_install(ddev, kms->irq); pm_runtime_put_sync(dev); if (ret < 0) { - dev_err(dev, "failed to install IRQ handler\n"); + DRM_DEV_ERROR(dev, "failed to install IRQ handler\n"); goto err_msm_uninit; } } @@ -1182,7 +1183,7 @@ static int add_components_mdp(struct device *mdp_dev, ret = of_graph_parse_endpoint(ep_node, &ep); if (ret) { - dev_err(mdp_dev, "unable to parse port endpoint\n"); + DRM_DEV_ERROR(mdp_dev, "unable to parse port endpoint\n"); of_node_put(ep_node); return ret; } @@ -1233,13 +1234,13 @@ static int add_display_components(struct device *dev, of_device_is_compatible(dev->of_node, "qcom,sdm845-mdss")) { ret = of_platform_populate(dev->of_node, NULL, NULL, dev); if (ret) { - dev_err(dev, "failed to populate children devices\n"); + DRM_DEV_ERROR(dev, "failed to populate children devices\n"); return ret; } mdp_dev = device_find_child(dev, NULL, compare_name_mdp); if (!mdp_dev) { - dev_err(dev, "failed to find MDSS MDP node\n"); + DRM_DEV_ERROR(dev, "failed to find MDSS MDP node\n"); of_platform_depopulate(dev); return -ENODEV; } diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 2a7348aeb38d..475191fcf412 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -154,7 +154,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, format = kms->funcs->get_format(kms, mode_cmd->pixel_format, mode_cmd->modifier[0]); if (!format) { - dev_err(dev->dev, "unsupported pixel format: %4.4s\n", + DRM_DEV_ERROR(dev->dev, "unsupported pixel format: %4.4s\n", (char *)&mode_cmd->pixel_format); ret = -EINVAL; goto fail; @@ -196,7 +196,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, ret = drm_framebuffer_init(dev, fb, &msm_framebuffer_funcs); if (ret) { - dev_err(dev->dev, "framebuffer init failed: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "framebuffer init failed: %d\n", ret); goto fail; } @@ -233,13 +233,13 @@ msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC); } if (IS_ERR(bo)) { - dev_err(dev->dev, "failed to allocate buffer object\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate buffer object\n"); return ERR_CAST(bo); } fb = msm_framebuffer_init(dev, &mode_cmd, &bo); if (IS_ERR(fb)) { - dev_err(dev->dev, "failed to allocate fb\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n"); /* note: if fb creation failed, we can't rely on fb destroy * to unref the bo: */ diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 456622b46335..f94cbbbf3834 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -91,7 +91,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, sizes->surface_height, pitch, format); if (IS_ERR(fb)) { - dev_err(dev->dev, "failed to allocate fb\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n"); return PTR_ERR(fb); } @@ -106,13 +106,13 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, */ ret = msm_gem_get_iova(bo, priv->kms->aspace, &paddr); if (ret) { - dev_err(dev->dev, "failed to get buffer obj iova: %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret); goto fail_unlock; } fbi = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(fbi)) { - dev_err(dev->dev, "failed to allocate fb info\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate fb info\n"); ret = PTR_ERR(fbi); goto fail_unlock; } @@ -176,7 +176,7 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) ret = drm_fb_helper_init(dev, helper, priv->num_connectors); if (ret) { - dev_err(dev->dev, "could not init fbdev: ret=%d\n", ret); + DRM_DEV_ERROR(dev->dev, "could not init fbdev: ret=%d\n", ret); goto fail; } diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index f59ca27a4a35..00c795ced02c 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -88,7 +88,7 @@ static struct page **get_pages(struct drm_gem_object *obj) p = get_pages_vram(obj, npages); if (IS_ERR(p)) { - dev_err(dev->dev, "could not get pages: %ld\n", + DRM_DEV_ERROR(dev->dev, "could not get pages: %ld\n", PTR_ERR(p)); return p; } @@ -99,7 +99,7 @@ static struct page **get_pages(struct drm_gem_object *obj) if (IS_ERR(msm_obj->sgt)) { void *ptr = ERR_CAST(msm_obj->sgt); - dev_err(dev->dev, "failed to allocate sgt\n"); + DRM_DEV_ERROR(dev->dev, "failed to allocate sgt\n"); msm_obj->sgt = NULL; return ptr; } @@ -280,7 +280,7 @@ static uint64_t mmap_offset(struct drm_gem_object *obj) ret = drm_gem_create_mmap_offset(obj); if (ret) { - dev_err(dev->dev, "could not allocate mmap offset\n"); + DRM_DEV_ERROR(dev->dev, "could not allocate mmap offset\n"); return 0; } @@ -473,7 +473,7 @@ static void *get_vaddr(struct drm_gem_object *obj, unsigned madv) mutex_lock(&msm_obj->lock); if (WARN_ON(msm_obj->madv > madv)) { - dev_err(obj->dev->dev, "Invalid madv state: %u vs %u\n", + DRM_DEV_ERROR(obj->dev->dev, "Invalid madv state: %u vs %u\n", msm_obj->madv, madv); mutex_unlock(&msm_obj->lock); return ERR_PTR(-EBUSY); @@ -864,7 +864,7 @@ static int msm_gem_new_impl(struct drm_device *dev, case MSM_BO_WC: break; default: - dev_err(dev->dev, "invalid cache flag: %x\n", + DRM_DEV_ERROR(dev->dev, "invalid cache flag: %x\n", (flags & MSM_BO_CACHE_MASK)); return -EINVAL; } @@ -990,7 +990,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, /* if we don't have IOMMU, don't bother pretending we can import: */ if (!iommu_present(&platform_bus_type)) { - dev_err(dev->dev, "cannot import without IOMMU\n"); + DRM_DEV_ERROR(dev->dev, "cannot import without IOMMU\n"); return ERR_PTR(-EINVAL); } diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 11aac8337066..98be40747c25 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -107,7 +107,7 @@ static void msm_devfreq_init(struct msm_gpu *gpu) &msm_devfreq_profile, "simple_ondemand", NULL); if (IS_ERR(gpu->devfreq.devfreq)) { - dev_err(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); + DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n"); gpu->devfreq.devfreq = NULL; } @@ -122,7 +122,7 @@ static int enable_pwrrail(struct msm_gpu *gpu) if (gpu->gpu_reg) { ret = regulator_enable(gpu->gpu_reg); if (ret) { - dev_err(dev->dev, "failed to enable 'gpu_reg': %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to enable 'gpu_reg': %d\n", ret); return ret; } } @@ -130,7 +130,7 @@ static int enable_pwrrail(struct msm_gpu *gpu) if (gpu->gpu_cx) { ret = regulator_enable(gpu->gpu_cx); if (ret) { - dev_err(dev->dev, "failed to enable 'gpu_cx': %d\n", ret); + DRM_DEV_ERROR(dev->dev, "failed to enable 'gpu_cx': %d\n", ret); return ret; } } @@ -428,7 +428,7 @@ static void recover_worker(struct work_struct *work) mutex_lock(&dev->struct_mutex); - dev_err(dev->dev, "%s: hangcheck recover!\n", gpu->name); + DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name); submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1); if (submit) { @@ -456,7 +456,7 @@ static void recover_worker(struct work_struct *work) rcu_read_unlock(); if (comm && cmd) { - dev_err(dev->dev, "%s: offending task: %s (%s)\n", + DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n", gpu->name, comm, cmd); msm_rd_dump_submit(priv->hangrd, submit, @@ -539,11 +539,11 @@ static void hangcheck_handler(struct timer_list *t) } else if (fence < ring->seqno) { /* no progress and not done.. hung! */ ring->hangcheck_fence = fence; - dev_err(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n", + DRM_DEV_ERROR(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n", gpu->name, ring->id); - dev_err(dev->dev, "%s: completed fence: %u\n", + DRM_DEV_ERROR(dev->dev, "%s: completed fence: %u\n", gpu->name, fence); - dev_err(dev->dev, "%s: submitted fence: %u\n", + DRM_DEV_ERROR(dev->dev, "%s: submitted fence: %u\n", gpu->name, ring->seqno); queue_work(priv->wq, &gpu->recover_work); @@ -816,11 +816,11 @@ msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev, iommu->geometry.aperture_start = va_start; iommu->geometry.aperture_end = va_end; - dev_info(gpu->dev->dev, "%s: using IOMMU\n", gpu->name); + DRM_DEV_INFO(gpu->dev->dev, "%s: using IOMMU\n", gpu->name); aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu"); if (IS_ERR(aspace)) { - dev_err(gpu->dev->dev, "failed to init iommu: %ld\n", + DRM_DEV_ERROR(gpu->dev->dev, "failed to init iommu: %ld\n", PTR_ERR(aspace)); iommu_domain_free(iommu); return ERR_CAST(aspace); @@ -871,14 +871,14 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, gpu->irq = platform_get_irq_byname(pdev, config->irqname); if (gpu->irq < 0) { ret = gpu->irq; - dev_err(drm->dev, "failed to get irq: %d\n", ret); + DRM_DEV_ERROR(drm->dev, "failed to get irq: %d\n", ret); goto fail; } ret = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, IRQF_TRIGGER_HIGH, gpu->name, gpu); if (ret) { - dev_err(drm->dev, "failed to request IRQ%u: %d\n", gpu->irq, ret); + DRM_DEV_ERROR(drm->dev, "failed to request IRQ%u: %d\n", gpu->irq, ret); goto fail; } @@ -911,7 +911,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, config->va_start, config->va_end); if (gpu->aspace == NULL) - dev_info(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name); + DRM_DEV_INFO(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name); else if (IS_ERR(gpu->aspace)) { ret = PTR_ERR(gpu->aspace); goto fail; @@ -923,7 +923,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, if (IS_ERR(memptrs)) { ret = PTR_ERR(memptrs); - dev_err(drm->dev, "could not allocate memptrs: %d\n", ret); + DRM_DEV_ERROR(drm->dev, "could not allocate memptrs: %d\n", ret); goto fail; } @@ -939,7 +939,7 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, if (IS_ERR(gpu->rb[i])) { ret = PTR_ERR(gpu->rb[i]); - dev_err(drm->dev, + DRM_DEV_ERROR(drm->dev, "could not create ringbuffer %d: %d\n", i, ret); goto fail; } From 01665c64b47597753a57efabfea36e9cb2443cff Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Tue, 27 Nov 2018 15:58:13 -0800 Subject: [PATCH 14/91] drm/msm/dpu: set geometry for iommu domain Specify geometry for DPU iommu domain which sets the address space for gem allocations. Signed-off-by: Jeykumar Sankaran Suggested-by: Jordan Crouse Suggested-by: Vivek Gautam Acked-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 985c855796ae..b57977f30274 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -788,6 +788,9 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) if (!domain) return 0; + domain->geometry.aperture_start = 0x1000; + domain->geometry.aperture_end = 0xffffffff; + aspace = msm_gem_address_space_create(dpu_kms->dev->dev, domain, "dpu1"); if (IS_ERR(aspace)) { From ccdf7e28b4ab4bc8c08912e9466f1686b06f6394 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 2 Dec 2018 13:07:41 -0500 Subject: [PATCH 15/91] drm/msm: update generated headers Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a2xx.xml.h | 298 +++++++++++++++++- drivers/gpu/drm/msm/adreno/a3xx.xml.h | 10 +- drivers/gpu/drm/msm/adreno/a4xx.xml.h | 10 +- drivers/gpu/drm/msm/adreno/a5xx.xml.h | 10 +- drivers/gpu/drm/msm/adreno/a6xx.xml.h | 78 ++++- drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h | 10 +- .../gpu/drm/msm/adreno/adreno_common.xml.h | 19 +- drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h | 18 +- 8 files changed, 408 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h index 12b0ba270b5e..14eb52f3e605 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) @@ -239,7 +239,63 @@ enum sq_tex_swiz { enum sq_tex_filter { SQ_TEX_FILTER_POINT = 0, SQ_TEX_FILTER_BILINEAR = 1, - SQ_TEX_FILTER_BICUBIC = 2, + SQ_TEX_FILTER_BASEMAP = 2, + SQ_TEX_FILTER_USE_FETCH_CONST = 3, +}; + +enum sq_tex_aniso_filter { + SQ_TEX_ANISO_FILTER_DISABLED = 0, + SQ_TEX_ANISO_FILTER_MAX_1_1 = 1, + SQ_TEX_ANISO_FILTER_MAX_2_1 = 2, + SQ_TEX_ANISO_FILTER_MAX_4_1 = 3, + SQ_TEX_ANISO_FILTER_MAX_8_1 = 4, + SQ_TEX_ANISO_FILTER_MAX_16_1 = 5, + SQ_TEX_ANISO_FILTER_USE_FETCH_CONST = 7, +}; + +enum sq_tex_dimension { + SQ_TEX_DIMENSION_1D = 0, + SQ_TEX_DIMENSION_2D = 1, + SQ_TEX_DIMENSION_3D = 2, + SQ_TEX_DIMENSION_CUBE = 3, +}; + +enum sq_tex_border_color { + SQ_TEX_BORDER_COLOR_BLACK = 0, + SQ_TEX_BORDER_COLOR_WHITE = 1, + SQ_TEX_BORDER_COLOR_ACBYCR_BLACK = 2, + SQ_TEX_BORDER_COLOR_ACBCRY_BLACK = 3, +}; + +enum sq_tex_sign { + SQ_TEX_SIGN_UNISIGNED = 0, + SQ_TEX_SIGN_SIGNED = 1, + SQ_TEX_SIGN_UNISIGNED_BIASED = 2, + SQ_TEX_SIGN_GAMMA = 3, +}; + +enum sq_tex_endian { + SQ_TEX_ENDIAN_NONE = 0, + SQ_TEX_ENDIAN_8IN16 = 1, + SQ_TEX_ENDIAN_8IN32 = 2, + SQ_TEX_ENDIAN_16IN32 = 3, +}; + +enum sq_tex_clamp_policy { + SQ_TEX_CLAMP_POLICY_D3D = 0, + SQ_TEX_CLAMP_POLICY_OGL = 1, +}; + +enum sq_tex_num_format { + SQ_TEX_NUM_FORMAT_FRAC = 0, + SQ_TEX_NUM_FORMAT_INT = 1, +}; + +enum sq_tex_type { + SQ_TEX_TYPE_0 = 0, + SQ_TEX_TYPE_1 = 1, + SQ_TEX_TYPE_2 = 2, + SQ_TEX_TYPE_3 = 3, }; #define REG_A2XX_RBBM_PATCH_RELEASE 0x00000001 @@ -323,6 +379,18 @@ static inline uint32_t A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(enum adreno_mmu_cln } #define REG_A2XX_MH_MMU_VA_RANGE 0x00000041 +#define A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS__MASK 0x00000fff +#define A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS__SHIFT 0 +static inline uint32_t A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS(uint32_t val) +{ + return ((val) << A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS__SHIFT) & A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS__MASK; +} +#define A2XX_MH_MMU_VA_RANGE_VA_BASE__MASK 0xfffff000 +#define A2XX_MH_MMU_VA_RANGE_VA_BASE__SHIFT 12 +static inline uint32_t A2XX_MH_MMU_VA_RANGE_VA_BASE(uint32_t val) +{ + return ((val) << A2XX_MH_MMU_VA_RANGE_VA_BASE__SHIFT) & A2XX_MH_MMU_VA_RANGE_VA_BASE__MASK; +} #define REG_A2XX_MH_MMU_PT_BASE 0x00000042 @@ -331,6 +399,8 @@ static inline uint32_t A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(enum adreno_mmu_cln #define REG_A2XX_MH_MMU_TRAN_ERROR 0x00000044 #define REG_A2XX_MH_MMU_INVALIDATE 0x00000045 +#define A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL 0x00000001 +#define A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC 0x00000002 #define REG_A2XX_MH_MMU_MPU_BASE 0x00000046 @@ -389,12 +459,19 @@ static inline uint32_t A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(enum adreno_mmu_cln #define REG_A2XX_RBBM_READ_ERROR 0x000003b3 #define REG_A2XX_RBBM_INT_CNTL 0x000003b4 +#define A2XX_RBBM_INT_CNTL_RDERR_INT_MASK 0x00000001 +#define A2XX_RBBM_INT_CNTL_DISPLAY_UPDATE_INT_MASK 0x00000002 +#define A2XX_RBBM_INT_CNTL_GUI_IDLE_INT_MASK 0x00080000 #define REG_A2XX_RBBM_INT_STATUS 0x000003b5 #define REG_A2XX_RBBM_INT_ACK 0x000003b6 #define REG_A2XX_MASTER_INT_SIGNAL 0x000003b7 +#define A2XX_MASTER_INT_SIGNAL_MH_INT_STAT 0x00000020 +#define A2XX_MASTER_INT_SIGNAL_SQ_INT_STAT 0x04000000 +#define A2XX_MASTER_INT_SIGNAL_CP_INT_STAT 0x40000000 +#define A2XX_MASTER_INT_SIGNAL_RBBM_INT_STAT 0x80000000 #define REG_A2XX_RBBM_PERIPHID1 0x000003f9 @@ -467,6 +544,19 @@ static inline uint32_t A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT(uint32_t val) #define A2XX_MH_ARBITER_CONFIG_RB_CLNT_ENABLE 0x02000000 #define A2XX_MH_ARBITER_CONFIG_PA_CLNT_ENABLE 0x04000000 +#define REG_A2XX_MH_INTERRUPT_MASK 0x00000a42 +#define A2XX_MH_INTERRUPT_MASK_AXI_READ_ERROR 0x00000001 +#define A2XX_MH_INTERRUPT_MASK_AXI_WRITE_ERROR 0x00000002 +#define A2XX_MH_INTERRUPT_MASK_MMU_PAGE_FAULT 0x00000004 + +#define REG_A2XX_MH_INTERRUPT_STATUS 0x00000a43 + +#define REG_A2XX_MH_INTERRUPT_CLEAR 0x00000a44 + +#define REG_A2XX_MH_CLNT_INTF_CTRL_CONFIG1 0x00000a54 + +#define REG_A2XX_MH_CLNT_INTF_CTRL_CONFIG2 0x00000a55 + #define REG_A2XX_A220_VSC_BIN_SIZE 0x00000c01 #define A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK 0x0000001f #define A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT 0 @@ -648,6 +738,18 @@ static inline uint32_t A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT(uint32_t val #define REG_A2XX_RB_DEBUG_DATA 0x00000f27 #define REG_A2XX_RB_SURFACE_INFO 0x00002000 +#define A2XX_RB_SURFACE_INFO_SURFACE_PITCH__MASK 0x00003fff +#define A2XX_RB_SURFACE_INFO_SURFACE_PITCH__SHIFT 0 +static inline uint32_t A2XX_RB_SURFACE_INFO_SURFACE_PITCH(uint32_t val) +{ + return ((val) << A2XX_RB_SURFACE_INFO_SURFACE_PITCH__SHIFT) & A2XX_RB_SURFACE_INFO_SURFACE_PITCH__MASK; +} +#define A2XX_RB_SURFACE_INFO_MSAA_SAMPLES__MASK 0x0000c000 +#define A2XX_RB_SURFACE_INFO_MSAA_SAMPLES__SHIFT 14 +static inline uint32_t A2XX_RB_SURFACE_INFO_MSAA_SAMPLES(uint32_t val) +{ + return ((val) << A2XX_RB_SURFACE_INFO_MSAA_SAMPLES__SHIFT) & A2XX_RB_SURFACE_INFO_MSAA_SAMPLES__MASK; +} #define REG_A2XX_RB_COLOR_INFO 0x00002001 #define A2XX_RB_COLOR_INFO_FORMAT__MASK 0x0000000f @@ -679,7 +781,7 @@ static inline uint32_t A2XX_RB_COLOR_INFO_SWAP(uint32_t val) #define A2XX_RB_COLOR_INFO_BASE__SHIFT 12 static inline uint32_t A2XX_RB_COLOR_INFO_BASE(uint32_t val) { - return ((val >> 10) << A2XX_RB_COLOR_INFO_BASE__SHIFT) & A2XX_RB_COLOR_INFO_BASE__MASK; + return ((val >> 12) << A2XX_RB_COLOR_INFO_BASE__SHIFT) & A2XX_RB_COLOR_INFO_BASE__MASK; } #define REG_A2XX_RB_DEPTH_INFO 0x00002002 @@ -693,7 +795,7 @@ static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum adreno_rb_depth_form #define A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT 12 static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val) { - return ((val >> 10) << A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK; + return ((val >> 12) << A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK; } #define REG_A2XX_A225_RB_COLOR_INFO3 0x00002005 @@ -1757,6 +1859,36 @@ static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_Y(uint32_t val) #define REG_A2XX_COHER_STATUS_PM4 0x00000a2b #define REG_A2XX_SQ_TEX_0 0x00000000 +#define A2XX_SQ_TEX_0_TYPE__MASK 0x00000003 +#define A2XX_SQ_TEX_0_TYPE__SHIFT 0 +static inline uint32_t A2XX_SQ_TEX_0_TYPE(enum sq_tex_type val) +{ + return ((val) << A2XX_SQ_TEX_0_TYPE__SHIFT) & A2XX_SQ_TEX_0_TYPE__MASK; +} +#define A2XX_SQ_TEX_0_SIGN_X__MASK 0x0000000c +#define A2XX_SQ_TEX_0_SIGN_X__SHIFT 2 +static inline uint32_t A2XX_SQ_TEX_0_SIGN_X(enum sq_tex_sign val) +{ + return ((val) << A2XX_SQ_TEX_0_SIGN_X__SHIFT) & A2XX_SQ_TEX_0_SIGN_X__MASK; +} +#define A2XX_SQ_TEX_0_SIGN_Y__MASK 0x00000030 +#define A2XX_SQ_TEX_0_SIGN_Y__SHIFT 4 +static inline uint32_t A2XX_SQ_TEX_0_SIGN_Y(enum sq_tex_sign val) +{ + return ((val) << A2XX_SQ_TEX_0_SIGN_Y__SHIFT) & A2XX_SQ_TEX_0_SIGN_Y__MASK; +} +#define A2XX_SQ_TEX_0_SIGN_Z__MASK 0x000000c0 +#define A2XX_SQ_TEX_0_SIGN_Z__SHIFT 6 +static inline uint32_t A2XX_SQ_TEX_0_SIGN_Z(enum sq_tex_sign val) +{ + return ((val) << A2XX_SQ_TEX_0_SIGN_Z__SHIFT) & A2XX_SQ_TEX_0_SIGN_Z__MASK; +} +#define A2XX_SQ_TEX_0_SIGN_W__MASK 0x00000300 +#define A2XX_SQ_TEX_0_SIGN_W__SHIFT 8 +static inline uint32_t A2XX_SQ_TEX_0_SIGN_W(enum sq_tex_sign val) +{ + return ((val) << A2XX_SQ_TEX_0_SIGN_W__SHIFT) & A2XX_SQ_TEX_0_SIGN_W__MASK; +} #define A2XX_SQ_TEX_0_CLAMP_X__MASK 0x00001c00 #define A2XX_SQ_TEX_0_CLAMP_X__SHIFT 10 static inline uint32_t A2XX_SQ_TEX_0_CLAMP_X(enum sq_tex_clamp val) @@ -1775,14 +1907,46 @@ static inline uint32_t A2XX_SQ_TEX_0_CLAMP_Z(enum sq_tex_clamp val) { return ((val) << A2XX_SQ_TEX_0_CLAMP_Z__SHIFT) & A2XX_SQ_TEX_0_CLAMP_Z__MASK; } -#define A2XX_SQ_TEX_0_PITCH__MASK 0xffc00000 +#define A2XX_SQ_TEX_0_PITCH__MASK 0x7fc00000 #define A2XX_SQ_TEX_0_PITCH__SHIFT 22 static inline uint32_t A2XX_SQ_TEX_0_PITCH(uint32_t val) { return ((val >> 5) << A2XX_SQ_TEX_0_PITCH__SHIFT) & A2XX_SQ_TEX_0_PITCH__MASK; } +#define A2XX_SQ_TEX_0_TILED 0x00000002 #define REG_A2XX_SQ_TEX_1 0x00000001 +#define A2XX_SQ_TEX_1_FORMAT__MASK 0x0000003f +#define A2XX_SQ_TEX_1_FORMAT__SHIFT 0 +static inline uint32_t A2XX_SQ_TEX_1_FORMAT(enum a2xx_sq_surfaceformat val) +{ + return ((val) << A2XX_SQ_TEX_1_FORMAT__SHIFT) & A2XX_SQ_TEX_1_FORMAT__MASK; +} +#define A2XX_SQ_TEX_1_ENDIANNESS__MASK 0x000000c0 +#define A2XX_SQ_TEX_1_ENDIANNESS__SHIFT 6 +static inline uint32_t A2XX_SQ_TEX_1_ENDIANNESS(enum sq_tex_endian val) +{ + return ((val) << A2XX_SQ_TEX_1_ENDIANNESS__SHIFT) & A2XX_SQ_TEX_1_ENDIANNESS__MASK; +} +#define A2XX_SQ_TEX_1_REQUEST_SIZE__MASK 0x00000300 +#define A2XX_SQ_TEX_1_REQUEST_SIZE__SHIFT 8 +static inline uint32_t A2XX_SQ_TEX_1_REQUEST_SIZE(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_1_REQUEST_SIZE__SHIFT) & A2XX_SQ_TEX_1_REQUEST_SIZE__MASK; +} +#define A2XX_SQ_TEX_1_STACKED 0x00000400 +#define A2XX_SQ_TEX_1_CLAMP_POLICY__MASK 0x00000800 +#define A2XX_SQ_TEX_1_CLAMP_POLICY__SHIFT 11 +static inline uint32_t A2XX_SQ_TEX_1_CLAMP_POLICY(enum sq_tex_clamp_policy val) +{ + return ((val) << A2XX_SQ_TEX_1_CLAMP_POLICY__SHIFT) & A2XX_SQ_TEX_1_CLAMP_POLICY__MASK; +} +#define A2XX_SQ_TEX_1_BASE_ADDRESS__MASK 0xfffff000 +#define A2XX_SQ_TEX_1_BASE_ADDRESS__SHIFT 12 +static inline uint32_t A2XX_SQ_TEX_1_BASE_ADDRESS(uint32_t val) +{ + return ((val >> 12) << A2XX_SQ_TEX_1_BASE_ADDRESS__SHIFT) & A2XX_SQ_TEX_1_BASE_ADDRESS__MASK; +} #define REG_A2XX_SQ_TEX_2 0x00000002 #define A2XX_SQ_TEX_2_WIDTH__MASK 0x00001fff @@ -1797,8 +1961,20 @@ static inline uint32_t A2XX_SQ_TEX_2_HEIGHT(uint32_t val) { return ((val) << A2XX_SQ_TEX_2_HEIGHT__SHIFT) & A2XX_SQ_TEX_2_HEIGHT__MASK; } +#define A2XX_SQ_TEX_2_DEPTH__MASK 0xfc000000 +#define A2XX_SQ_TEX_2_DEPTH__SHIFT 26 +static inline uint32_t A2XX_SQ_TEX_2_DEPTH(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_2_DEPTH__SHIFT) & A2XX_SQ_TEX_2_DEPTH__MASK; +} #define REG_A2XX_SQ_TEX_3 0x00000003 +#define A2XX_SQ_TEX_3_NUM_FORMAT__MASK 0x00000001 +#define A2XX_SQ_TEX_3_NUM_FORMAT__SHIFT 0 +static inline uint32_t A2XX_SQ_TEX_3_NUM_FORMAT(enum sq_tex_num_format val) +{ + return ((val) << A2XX_SQ_TEX_3_NUM_FORMAT__SHIFT) & A2XX_SQ_TEX_3_NUM_FORMAT__MASK; +} #define A2XX_SQ_TEX_3_SWIZ_X__MASK 0x0000000e #define A2XX_SQ_TEX_3_SWIZ_X__SHIFT 1 static inline uint32_t A2XX_SQ_TEX_3_SWIZ_X(enum sq_tex_swiz val) @@ -1823,6 +1999,12 @@ static inline uint32_t A2XX_SQ_TEX_3_SWIZ_W(enum sq_tex_swiz val) { return ((val) << A2XX_SQ_TEX_3_SWIZ_W__SHIFT) & A2XX_SQ_TEX_3_SWIZ_W__MASK; } +#define A2XX_SQ_TEX_3_EXP_ADJUST__MASK 0x0007e000 +#define A2XX_SQ_TEX_3_EXP_ADJUST__SHIFT 13 +static inline uint32_t A2XX_SQ_TEX_3_EXP_ADJUST(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_3_EXP_ADJUST__SHIFT) & A2XX_SQ_TEX_3_EXP_ADJUST__MASK; +} #define A2XX_SQ_TEX_3_XY_MAG_FILTER__MASK 0x00180000 #define A2XX_SQ_TEX_3_XY_MAG_FILTER__SHIFT 19 static inline uint32_t A2XX_SQ_TEX_3_XY_MAG_FILTER(enum sq_tex_filter val) @@ -1835,6 +2017,104 @@ static inline uint32_t A2XX_SQ_TEX_3_XY_MIN_FILTER(enum sq_tex_filter val) { return ((val) << A2XX_SQ_TEX_3_XY_MIN_FILTER__SHIFT) & A2XX_SQ_TEX_3_XY_MIN_FILTER__MASK; } +#define A2XX_SQ_TEX_3_MIP_FILTER__MASK 0x01800000 +#define A2XX_SQ_TEX_3_MIP_FILTER__SHIFT 23 +static inline uint32_t A2XX_SQ_TEX_3_MIP_FILTER(enum sq_tex_filter val) +{ + return ((val) << A2XX_SQ_TEX_3_MIP_FILTER__SHIFT) & A2XX_SQ_TEX_3_MIP_FILTER__MASK; +} +#define A2XX_SQ_TEX_3_ANISO_FILTER__MASK 0x0e000000 +#define A2XX_SQ_TEX_3_ANISO_FILTER__SHIFT 25 +static inline uint32_t A2XX_SQ_TEX_3_ANISO_FILTER(enum sq_tex_aniso_filter val) +{ + return ((val) << A2XX_SQ_TEX_3_ANISO_FILTER__SHIFT) & A2XX_SQ_TEX_3_ANISO_FILTER__MASK; +} +#define A2XX_SQ_TEX_3_BORDER_SIZE__MASK 0x80000000 +#define A2XX_SQ_TEX_3_BORDER_SIZE__SHIFT 31 +static inline uint32_t A2XX_SQ_TEX_3_BORDER_SIZE(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_3_BORDER_SIZE__SHIFT) & A2XX_SQ_TEX_3_BORDER_SIZE__MASK; +} + +#define REG_A2XX_SQ_TEX_4 0x00000004 +#define A2XX_SQ_TEX_4_VOL_MAG_FILTER__MASK 0x00000001 +#define A2XX_SQ_TEX_4_VOL_MAG_FILTER__SHIFT 0 +static inline uint32_t A2XX_SQ_TEX_4_VOL_MAG_FILTER(enum sq_tex_filter val) +{ + return ((val) << A2XX_SQ_TEX_4_VOL_MAG_FILTER__SHIFT) & A2XX_SQ_TEX_4_VOL_MAG_FILTER__MASK; +} +#define A2XX_SQ_TEX_4_VOL_MIN_FILTER__MASK 0x00000002 +#define A2XX_SQ_TEX_4_VOL_MIN_FILTER__SHIFT 1 +static inline uint32_t A2XX_SQ_TEX_4_VOL_MIN_FILTER(enum sq_tex_filter val) +{ + return ((val) << A2XX_SQ_TEX_4_VOL_MIN_FILTER__SHIFT) & A2XX_SQ_TEX_4_VOL_MIN_FILTER__MASK; +} +#define A2XX_SQ_TEX_4_MIP_MIN_LEVEL__MASK 0x0000003c +#define A2XX_SQ_TEX_4_MIP_MIN_LEVEL__SHIFT 2 +static inline uint32_t A2XX_SQ_TEX_4_MIP_MIN_LEVEL(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_4_MIP_MIN_LEVEL__SHIFT) & A2XX_SQ_TEX_4_MIP_MIN_LEVEL__MASK; +} +#define A2XX_SQ_TEX_4_MIP_MAX_LEVEL__MASK 0x000003c0 +#define A2XX_SQ_TEX_4_MIP_MAX_LEVEL__SHIFT 6 +static inline uint32_t A2XX_SQ_TEX_4_MIP_MAX_LEVEL(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_4_MIP_MAX_LEVEL__SHIFT) & A2XX_SQ_TEX_4_MIP_MAX_LEVEL__MASK; +} +#define A2XX_SQ_TEX_4_MAX_ANISO_WALK 0x00000400 +#define A2XX_SQ_TEX_4_MIN_ANISO_WALK 0x00000800 +#define A2XX_SQ_TEX_4_LOD_BIAS__MASK 0x003ff000 +#define A2XX_SQ_TEX_4_LOD_BIAS__SHIFT 12 +static inline uint32_t A2XX_SQ_TEX_4_LOD_BIAS(float val) +{ + return ((((int32_t)(val * 32.0))) << A2XX_SQ_TEX_4_LOD_BIAS__SHIFT) & A2XX_SQ_TEX_4_LOD_BIAS__MASK; +} +#define A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_H__MASK 0x07c00000 +#define A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_H__SHIFT 22 +static inline uint32_t A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_H(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_H__SHIFT) & A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_H__MASK; +} +#define A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_V__MASK 0xf8000000 +#define A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_V__SHIFT 27 +static inline uint32_t A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_V(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_V__SHIFT) & A2XX_SQ_TEX_4_GRAD_EXP_ADJUST_V__MASK; +} + +#define REG_A2XX_SQ_TEX_5 0x00000005 +#define A2XX_SQ_TEX_5_BORDER_COLOR__MASK 0x00000003 +#define A2XX_SQ_TEX_5_BORDER_COLOR__SHIFT 0 +static inline uint32_t A2XX_SQ_TEX_5_BORDER_COLOR(enum sq_tex_border_color val) +{ + return ((val) << A2XX_SQ_TEX_5_BORDER_COLOR__SHIFT) & A2XX_SQ_TEX_5_BORDER_COLOR__MASK; +} +#define A2XX_SQ_TEX_5_FORCE_BCW_MAX 0x00000004 +#define A2XX_SQ_TEX_5_TRI_CLAMP__MASK 0x00000018 +#define A2XX_SQ_TEX_5_TRI_CLAMP__SHIFT 3 +static inline uint32_t A2XX_SQ_TEX_5_TRI_CLAMP(uint32_t val) +{ + return ((val) << A2XX_SQ_TEX_5_TRI_CLAMP__SHIFT) & A2XX_SQ_TEX_5_TRI_CLAMP__MASK; +} +#define A2XX_SQ_TEX_5_ANISO_BIAS__MASK 0x000001e0 +#define A2XX_SQ_TEX_5_ANISO_BIAS__SHIFT 5 +static inline uint32_t A2XX_SQ_TEX_5_ANISO_BIAS(float val) +{ + return ((((int32_t)(val * 1.0))) << A2XX_SQ_TEX_5_ANISO_BIAS__SHIFT) & A2XX_SQ_TEX_5_ANISO_BIAS__MASK; +} +#define A2XX_SQ_TEX_5_DIMENSION__MASK 0x00000600 +#define A2XX_SQ_TEX_5_DIMENSION__SHIFT 9 +static inline uint32_t A2XX_SQ_TEX_5_DIMENSION(enum sq_tex_dimension val) +{ + return ((val) << A2XX_SQ_TEX_5_DIMENSION__SHIFT) & A2XX_SQ_TEX_5_DIMENSION__MASK; +} +#define A2XX_SQ_TEX_5_PACKED_MIPS 0x00000800 +#define A2XX_SQ_TEX_5_MIP_ADDRESS__MASK 0xfffff000 +#define A2XX_SQ_TEX_5_MIP_ADDRESS__SHIFT 12 +static inline uint32_t A2XX_SQ_TEX_5_MIP_ADDRESS(uint32_t val) +{ + return ((val >> 12) << A2XX_SQ_TEX_5_MIP_ADDRESS__SHIFT) & A2XX_SQ_TEX_5_MIP_ADDRESS__MASK; +} #endif /* A2XX_XML */ diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h index a89f7bb8b5cc..17059f242a98 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) diff --git a/drivers/gpu/drm/msm/adreno/a4xx.xml.h b/drivers/gpu/drm/msm/adreno/a4xx.xml.h index 858690f52854..9b51e25a9583 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a4xx.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) diff --git a/drivers/gpu/drm/msm/adreno/a5xx.xml.h b/drivers/gpu/drm/msm/adreno/a5xx.xml.h index b4944cc0e62f..cf4fe14ddd6e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a5xx.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) diff --git a/drivers/gpu/drm/msm/adreno/a6xx.xml.h b/drivers/gpu/drm/msm/adreno/a6xx.xml.h index a6f7c40454a6..f44553ec3193 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a6xx.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) @@ -501,7 +501,7 @@ enum a6xx_vfd_perfcounter_select { PERF_VFDP_VS_STAGE_WAVES = 22, }; -enum a6xx_hslq_perfcounter_select { +enum a6xx_hlsq_perfcounter_select { PERF_HLSQ_BUSY_CYCLES = 0, PERF_HLSQ_STALL_CYCLES_UCHE = 1, PERF_HLSQ_STALL_CYCLES_SP_STATE = 2, @@ -2959,6 +2959,8 @@ static inline uint32_t A6XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(uint32_t val) #define A6XX_GRAS_LRZ_CNTL_ENABLE 0x00000001 #define A6XX_GRAS_LRZ_CNTL_LRZ_WRITE 0x00000002 #define A6XX_GRAS_LRZ_CNTL_GREATER 0x00000004 +#define A6XX_GRAS_LRZ_CNTL_UNK3 0x00000008 +#define A6XX_GRAS_LRZ_CNTL_UNK4 0x00000010 #define REG_A6XX_GRAS_UNKNOWN_8101 0x00008101 @@ -2997,6 +2999,13 @@ static inline uint32_t A6XX_GRAS_LRZ_BUFFER_PITCH_ARRAY_PITCH(uint32_t val) #define REG_A6XX_GRAS_UNKNOWN_8110 0x00008110 #define REG_A6XX_GRAS_2D_BLIT_CNTL 0x00008400 +#define A6XX_GRAS_2D_BLIT_CNTL_COLOR_FORMAT__MASK 0x0000ff00 +#define A6XX_GRAS_2D_BLIT_CNTL_COLOR_FORMAT__SHIFT 8 +static inline uint32_t A6XX_GRAS_2D_BLIT_CNTL_COLOR_FORMAT(enum a6xx_color_fmt val) +{ + return ((val) << A6XX_GRAS_2D_BLIT_CNTL_COLOR_FORMAT__SHIFT) & A6XX_GRAS_2D_BLIT_CNTL_COLOR_FORMAT__MASK; +} +#define A6XX_GRAS_2D_BLIT_CNTL_SCISSOR 0x00010000 #define REG_A6XX_GRAS_2D_SRC_TL_X 0x00008401 #define A6XX_GRAS_2D_SRC_TL_X_X__MASK 0x00ffff00 @@ -3449,6 +3458,7 @@ static inline uint32_t A6XX_RB_BLEND_CNTL_ENABLE_BLEND(uint32_t val) return ((val) << A6XX_RB_BLEND_CNTL_ENABLE_BLEND__SHIFT) & A6XX_RB_BLEND_CNTL_ENABLE_BLEND__MASK; } #define A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND 0x00000100 +#define A6XX_RB_BLEND_CNTL_ALPHA_TO_COVERAGE 0x00000400 #define A6XX_RB_BLEND_CNTL_SAMPLE_MASK__MASK 0xffff0000 #define A6XX_RB_BLEND_CNTL_SAMPLE_MASK__SHIFT 16 static inline uint32_t A6XX_RB_BLEND_CNTL_SAMPLE_MASK(uint32_t val) @@ -3642,6 +3652,9 @@ static inline uint32_t A6XX_RB_WINDOW_OFFSET_Y(uint32_t val) #define REG_A6XX_RB_SAMPLE_COUNT_CONTROL 0x00008891 #define A6XX_RB_SAMPLE_COUNT_CONTROL_COPY 0x00000002 +#define REG_A6XX_RB_LRZ_CNTL 0x00008898 +#define A6XX_RB_LRZ_CNTL_ENABLE 0x00000001 + #define REG_A6XX_RB_UNKNOWN_88D0 0x000088d0 #define REG_A6XX_RB_BLIT_SCISSOR_TL 0x000088d1 @@ -3674,6 +3687,14 @@ static inline uint32_t A6XX_RB_BLIT_SCISSOR_BR_Y(uint32_t val) return ((val) << A6XX_RB_BLIT_SCISSOR_BR_Y__SHIFT) & A6XX_RB_BLIT_SCISSOR_BR_Y__MASK; } +#define REG_A6XX_RB_MSAA_CNTL 0x000088d5 +#define A6XX_RB_MSAA_CNTL_SAMPLES__MASK 0x00000018 +#define A6XX_RB_MSAA_CNTL_SAMPLES__SHIFT 3 +static inline uint32_t A6XX_RB_MSAA_CNTL_SAMPLES(enum a3xx_msaa_samples val) +{ + return ((val) << A6XX_RB_MSAA_CNTL_SAMPLES__SHIFT) & A6XX_RB_MSAA_CNTL_SAMPLES__MASK; +} + #define REG_A6XX_RB_BLIT_BASE_GMEM 0x000088d6 #define REG_A6XX_RB_BLIT_DST_INFO 0x000088d7 @@ -3684,6 +3705,12 @@ static inline uint32_t A6XX_RB_BLIT_DST_INFO_TILE_MODE(enum a6xx_tile_mode val) return ((val) << A6XX_RB_BLIT_DST_INFO_TILE_MODE__SHIFT) & A6XX_RB_BLIT_DST_INFO_TILE_MODE__MASK; } #define A6XX_RB_BLIT_DST_INFO_FLAGS 0x00000004 +#define A6XX_RB_BLIT_DST_INFO_SAMPLES__MASK 0x00000018 +#define A6XX_RB_BLIT_DST_INFO_SAMPLES__SHIFT 3 +static inline uint32_t A6XX_RB_BLIT_DST_INFO_SAMPLES(enum a3xx_msaa_samples val) +{ + return ((val) << A6XX_RB_BLIT_DST_INFO_SAMPLES__SHIFT) & A6XX_RB_BLIT_DST_INFO_SAMPLES__MASK; +} #define A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT__MASK 0x00007f80 #define A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT__SHIFT 7 static inline uint32_t A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(enum a6xx_color_fmt val) @@ -3780,6 +3807,9 @@ static inline uint32_t A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT(enum a6xx_color_fmt val { return ((val) << A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT__SHIFT) & A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT__MASK; } +#define A6XX_RB_2D_BLIT_CNTL_SCISSOR 0x00010000 + +#define REG_A6XX_RB_UNKNOWN_8C01 0x00008c01 #define REG_A6XX_RB_2D_DST_INFO 0x00008c17 #define A6XX_RB_2D_DST_INFO_COLOR_FORMAT__MASK 0x000000ff @@ -4465,6 +4495,7 @@ static inline uint32_t A6XX_SP_FS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val) #define REG_A6XX_SP_BLEND_CNTL 0x0000a989 #define A6XX_SP_BLEND_CNTL_ENABLED 0x00000001 #define A6XX_SP_BLEND_CNTL_UNK8 0x00000100 +#define A6XX_SP_BLEND_CNTL_ALPHA_TO_COVERAGE 0x00000400 #define REG_A6XX_SP_SRGB_CNTL 0x0000a98a #define A6XX_SP_SRGB_CNTL_SRGB_MRT0 0x00000001 @@ -4643,6 +4674,8 @@ static inline uint32_t A6XX_SP_FS_CONFIG_NSAMP(uint32_t val) #define REG_A6XX_SP_UNKNOWN_AB20 0x0000ab20 +#define REG_A6XX_SP_UNKNOWN_ACC0 0x0000acc0 + #define REG_A6XX_SP_UNKNOWN_AE00 0x0000ae00 #define REG_A6XX_SP_UNKNOWN_AE03 0x0000ae03 @@ -4700,11 +4733,34 @@ static inline uint32_t A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(enum a3xx_color_swap va return ((val) << A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP__SHIFT) & A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP__MASK; } #define A6XX_SP_PS_2D_SRC_INFO_FLAGS 0x00001000 +#define A6XX_SP_PS_2D_SRC_INFO_FILTER 0x00010000 + +#define REG_A6XX_SP_PS_2D_SRC_SIZE 0x0000b4c1 +#define A6XX_SP_PS_2D_SRC_SIZE_WIDTH__MASK 0x00007fff +#define A6XX_SP_PS_2D_SRC_SIZE_WIDTH__SHIFT 0 +static inline uint32_t A6XX_SP_PS_2D_SRC_SIZE_WIDTH(uint32_t val) +{ + return ((val) << A6XX_SP_PS_2D_SRC_SIZE_WIDTH__SHIFT) & A6XX_SP_PS_2D_SRC_SIZE_WIDTH__MASK; +} +#define A6XX_SP_PS_2D_SRC_SIZE_HEIGHT__MASK 0x3fff8000 +#define A6XX_SP_PS_2D_SRC_SIZE_HEIGHT__SHIFT 15 +static inline uint32_t A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(uint32_t val) +{ + return ((val) << A6XX_SP_PS_2D_SRC_SIZE_HEIGHT__SHIFT) & A6XX_SP_PS_2D_SRC_SIZE_HEIGHT__MASK; +} #define REG_A6XX_SP_PS_2D_SRC_LO 0x0000b4c2 #define REG_A6XX_SP_PS_2D_SRC_HI 0x0000b4c3 +#define REG_A6XX_SP_PS_2D_SRC_PITCH 0x0000b4c4 +#define A6XX_SP_PS_2D_SRC_PITCH_PITCH__MASK 0x01fffe00 +#define A6XX_SP_PS_2D_SRC_PITCH_PITCH__SHIFT 9 +static inline uint32_t A6XX_SP_PS_2D_SRC_PITCH_PITCH(uint32_t val) +{ + return ((val >> 6) << A6XX_SP_PS_2D_SRC_PITCH_PITCH__SHIFT) & A6XX_SP_PS_2D_SRC_PITCH_PITCH__MASK; +} + #define REG_A6XX_SP_PS_2D_SRC_FLAGS_LO 0x0000b4ca #define REG_A6XX_SP_PS_2D_SRC_FLAGS_HI 0x0000b4cb @@ -5033,6 +5089,12 @@ static inline uint32_t A6XX_TEX_CONST_0_MIPLVLS(uint32_t val) { return ((val) << A6XX_TEX_CONST_0_MIPLVLS__SHIFT) & A6XX_TEX_CONST_0_MIPLVLS__MASK; } +#define A6XX_TEX_CONST_0_SAMPLES__MASK 0x00300000 +#define A6XX_TEX_CONST_0_SAMPLES__SHIFT 20 +static inline uint32_t A6XX_TEX_CONST_0_SAMPLES(enum a3xx_msaa_samples val) +{ + return ((val) << A6XX_TEX_CONST_0_SAMPLES__SHIFT) & A6XX_TEX_CONST_0_SAMPLES__MASK; +} #define A6XX_TEX_CONST_0_FMT__MASK 0x3fc00000 #define A6XX_TEX_CONST_0_FMT__SHIFT 22 static inline uint32_t A6XX_TEX_CONST_0_FMT(enum a6xx_tex_fmt val) @@ -5365,5 +5427,9 @@ static inline uint32_t A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1_BYTEL15(uint32_t val) #define REG_A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2 0x00000030 +#define REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0 0x00000001 + +#define REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1 0x00000002 + #endif /* A6XX_XML */ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h index db56f263ed77..1cc1c135236b 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h index 1318959d504d..641d3ba477b6 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) @@ -339,6 +339,15 @@ static inline uint32_t AXXX_SCRATCH_UMSK_SWAP(uint32_t val) #define REG_AXXX_CP_STATE_DEBUG_DATA 0x000001ed #define REG_AXXX_CP_INT_CNTL 0x000001f2 +#define AXXX_CP_INT_CNTL_SW_INT_MASK 0x00080000 +#define AXXX_CP_INT_CNTL_T0_PACKET_IN_IB_MASK 0x00800000 +#define AXXX_CP_INT_CNTL_OPCODE_ERROR_MASK 0x01000000 +#define AXXX_CP_INT_CNTL_PROTECTED_MODE_ERROR_MASK 0x02000000 +#define AXXX_CP_INT_CNTL_RESERVED_BIT_ERROR_MASK 0x04000000 +#define AXXX_CP_INT_CNTL_IB_ERROR_MASK 0x08000000 +#define AXXX_CP_INT_CNTL_IB2_INT_MASK 0x20000000 +#define AXXX_CP_INT_CNTL_IB1_INT_MASK 0x40000000 +#define AXXX_CP_INT_CNTL_RB_INT_MASK 0x80000000 #define REG_AXXX_CP_INT_STATUS 0x000001f3 diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h index 15eb03bed984..79b907ac0b4b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h @@ -10,13 +10,13 @@ git clone https://github.com/freedreno/envytools.git The rules-ng-ng source files this header was generated from are: - /home/robclark/src/envytools/rnndb/adreno.xml ( 501 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/freedreno_copyright.xml ( 1572 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 36805 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 13634 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 42585 bytes, from 2018-10-04 19:06:37) +- /home/robclark/src/envytools/rnndb/adreno/a2xx.xml ( 42463 bytes, from 2018-11-19 13:44:03) +- /home/robclark/src/envytools/rnndb/adreno/adreno_common.xml ( 14201 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/adreno_pm4.xml ( 43052 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a3xx.xml ( 83840 bytes, from 2018-07-03 19:37:13) - /home/robclark/src/envytools/rnndb/adreno/a4xx.xml ( 112086 bytes, from 2018-07-03 19:37:13) -- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-10-04 19:06:37) -- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 139581 bytes, from 2018-10-04 19:06:42) +- /home/robclark/src/envytools/rnndb/adreno/a5xx.xml ( 147240 bytes, from 2018-12-02 17:29:54) +- /home/robclark/src/envytools/rnndb/adreno/a6xx.xml ( 140790 bytes, from 2018-12-02 17:29:54) - /home/robclark/src/envytools/rnndb/adreno/a6xx_gmu.xml ( 10431 bytes, from 2018-09-14 13:03:07) - /home/robclark/src/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2018-07-03 19:37:13) @@ -108,6 +108,13 @@ enum pc_di_src_sel { DI_SRC_SEL_RESERVED = 3, }; +enum pc_di_face_cull_sel { + DI_FACE_CULL_NONE = 0, + DI_FACE_CULL_FETCH = 1, + DI_FACE_BACKFACE_CULL = 2, + DI_FACE_FRONTFACE_CULL = 3, +}; + enum pc_di_index_size { INDEX_SIZE_IGN = 0, INDEX_SIZE_16_BIT = 0, @@ -356,6 +363,7 @@ enum a6xx_render_mode { RM6_GMEM = 4, RM6_BLIT2D = 5, RM6_RESOLVE = 6, + RM6_BLIT2DSCALE = 12, }; enum pseudo_reg { From 546ec7b471bcae78463426a218b8c7f35bbb71f4 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:18 -0600 Subject: [PATCH 16/91] drm/msm/gpu: Allocate the correct size for the GPU memptrs Allocate the correct buffer size for the GPU memptrs. The incorrect size hasn't affected us thus far since the incorrect size was larger than the intended size and we're still stuck on page sized granularity anyway but technically correct is the best kind of correct. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 98be40747c25..c3351ec880ef 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -917,7 +917,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } - memptrs = msm_gem_kernel_new(drm, sizeof(*gpu->memptrs_bo), + memptrs = msm_gem_kernel_new(drm, + sizeof(struct msm_rbmemptrs) * nr_rings, MSM_BO_UNCACHED, gpu->aspace, &gpu->memptrs_bo, &memptrs_iova); From 93f7abf19dad2d0ad3c93597c87bbaff03218cb9 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:19 -0600 Subject: [PATCH 17/91] drm/msm: Gracefully handle failure in _msm_gem_kernel_new If any of the function calls in _msm_gem_kernel_new fail we need to make sure to dereference the GEM object with the appropriate function for the current locking state. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 00c795ced02c..4646e9e45fc2 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1041,23 +1041,29 @@ static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size, if (iova) { ret = msm_gem_get_iova(obj, aspace, iova); - if (ret) { - drm_gem_object_put(obj); - return ERR_PTR(ret); - } + if (ret) + goto err; } vaddr = msm_gem_get_vaddr(obj); if (IS_ERR(vaddr)) { msm_gem_put_iova(obj, aspace); - drm_gem_object_put(obj); - return ERR_CAST(vaddr); + ret = PTR_ERR(vaddr); + goto err; } if (bo) *bo = obj; return vaddr; +err: + if (locked) + drm_gem_object_put(obj); + else + drm_gem_object_put_unlocked(obj); + + return ERR_PTR(ret); + } void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size, From 568692102b6ad52fae27bef66793bc2e5770e429 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:20 -0600 Subject: [PATCH 18/91] drm/msm/gpu: Add per-submission statistics Add infrastructure to track statistics for GPU submissions by sampling certain perfcounters before and after a submission. To store the statistics, the per-ring memptrs region is expanded to include room for up to 64 entries - this should cover a reasonable amount of inflight submissions without worrying about losing data. The target specific code inserts PM4 commands to sample the counters before and after submission and store them in the data region. The CPU can access the data after the submission retires to make sense of the statistics and communicate them to the user. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 20 +++++++++------- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 34 ++++++++++++++++++++------- drivers/gpu/drm/msm/msm_ringbuffer.h | 16 +++++++++++++ 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 0a0ceb76e2ba..e816947ac7d8 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -346,16 +346,20 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu) ret = gmu_poll_timeout(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val, !val, 100, 10000); - if (!ret) { - gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0); - - /* Re-enable the power counter */ - gmu_write(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 1); - return 0; + if (ret) { + DRM_DEV_ERROR(gmu->dev, "GPU RSC sequence stuck while waking up the GPU\n"); + return ret; } - DRM_DEV_ERROR(gmu->dev, "GPU RSC sequence stuck while waking up the GPU\n"); - return ret; + gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0); + + /* Set up CX GMU counter 0 to count busy ticks */ + gmu_write(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0xff000000); + gmu_rmw(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xff, 0x20); + + /* Enable the power counter */ + gmu_write(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 1); + return 0; } static void a6xx_rpmh_stop(struct a6xx_gmu *gmu) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 38b7a5a92bfb..cf66edfb5246 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -67,13 +67,34 @@ static void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) gpu_write(gpu, REG_A6XX_CP_RB_WPTR, wptr); } +static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter, + u64 iova) +{ + OUT_PKT7(ring, CP_REG_TO_MEM, 3); + OUT_RING(ring, counter | (1 << 30) | (2 << 18)); + OUT_RING(ring, lower_32_bits(iova)); + OUT_RING(ring, upper_32_bits(iova)); +} + static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, struct msm_file_private *ctx) { + unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT; struct msm_drm_private *priv = gpu->dev->dev_private; struct msm_ringbuffer *ring = submit->ring; unsigned int i; + get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO, + rbmemptr_stats(ring, index, cpcycles_start)); + + /* + * For PM4 the GMU register offsets are calculated from the base of the + * GPU registers so we need to add 0x1a800 to the register value on A630 + * to get the right value from PM4. + */ + get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800, + rbmemptr_stats(ring, index, alwayson_start)); + /* Invalidate CCU depth and color */ OUT_PKT7(ring, CP_EVENT_WRITE, 1); OUT_RING(ring, PC_CCU_INVALIDATE_DEPTH); @@ -98,6 +119,11 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, } } + get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO, + rbmemptr_stats(ring, index, cpcycles_end)); + get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800, + rbmemptr_stats(ring, index, alwayson_end)); + /* Write the fence to the scratch register */ OUT_PKT4(ring, REG_A6XX_CP_SCRATCH_REG(2), 1); OUT_RING(ring, submit->seqno); @@ -387,14 +413,6 @@ static int a6xx_hw_init(struct msm_gpu *gpu) /* Select CP0 to always count cycles */ gpu_write(gpu, REG_A6XX_CP_PERFCTR_CP_SEL_0, PERF_CP_ALWAYS_COUNT); - /* FIXME: not sure if this should live here or in a6xx_gmu.c */ - gmu_write(&a6xx_gpu->gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, - 0xff000000); - gmu_rmw(&a6xx_gpu->gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, - 0xff, 0x20); - gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, - 0x01); - gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL, 2 << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, 2 << 1); gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, 2 << 1); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h index cffce094aecb..6434ebb13136 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.h +++ b/drivers/gpu/drm/msm/msm_ringbuffer.h @@ -23,9 +23,25 @@ #define rbmemptr(ring, member) \ ((ring)->memptrs_iova + offsetof(struct msm_rbmemptrs, member)) +#define rbmemptr_stats(ring, index, member) \ + (rbmemptr((ring), stats) + \ + ((index) * sizeof(struct msm_gpu_submit_stats)) + \ + offsetof(struct msm_gpu_submit_stats, member)) + +struct msm_gpu_submit_stats { + u64 cpcycles_start; + u64 cpcycles_end; + u64 alwayson_start; + u64 alwayson_end; +}; + +#define MSM_GPU_SUBMIT_STATS_COUNT 64 + struct msm_rbmemptrs { volatile uint32_t rptr; volatile uint32_t fence; + + volatile struct msm_gpu_submit_stats stats[MSM_GPU_SUBMIT_STATS_COUNT]; }; struct msm_ringbuffer { From 4241db42e474ffc6d432e60eb5aaea98f12fda20 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:21 -0600 Subject: [PATCH 19/91] drm/msm/gpu: Add trace events for tracking GPU submissions Add trace events to track the progress of a GPU submission msm_gpu_submit occurs at the beginning of the submissions, msm_gpu_submit_flush happens when the submission is put on the ringbuffer and msm_submit_flush_retired is sent when the operation is retired. To make it easier to track the operations a unique sequence number is assigned to each submission and displayed in each event output so a human or a script can easily associate the events related to a specific submission. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 7 ++ drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 15 +++- drivers/gpu/drm/msm/msm_gpu.c | 23 +++++- drivers/gpu/drm/msm/msm_gpu_trace.h | 90 +++++++++++++++++++++++ drivers/gpu/drm/msm/msm_gpu_tracepoints.c | 6 ++ 7 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/msm/msm_gpu_trace.h create mode 100644 drivers/gpu/drm/msm/msm_gpu_tracepoints.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 19ab521d4c3a..5de2d8f0a7e5 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -90,7 +90,8 @@ msm-y := \ msm_perf.o \ msm_rd.o \ msm_ringbuffer.o \ - msm_submitqueue.o + msm_submitqueue.o \ + msm_gpu_tracepoints.o msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \ disp/dpu1/dpu_dbg.o diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index cf66edfb5246..e0a918e8e969 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -4,6 +4,7 @@ #include "msm_gem.h" #include "msm_mmu.h" +#include "msm_gpu_trace.h" #include "a6xx_gpu.h" #include "a6xx_gmu.xml.h" @@ -81,6 +82,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, { unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT; struct msm_drm_private *priv = gpu->dev->dev_private; + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); struct msm_ringbuffer *ring = submit->ring; unsigned int i; @@ -138,6 +141,10 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence))); OUT_RING(ring, submit->seqno); + trace_msm_gpu_submit_flush(submit, + gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L, + REG_A6XX_GMU_ALWAYS_ON_COUNTER_H)); + a6xx_flush(gpu, ring); } diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index c5d9bd3e47a8..ddaf8663dc95 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -150,6 +150,7 @@ struct msm_gem_submit { struct msm_ringbuffer *ring; unsigned int nr_cmds; unsigned int nr_bos; + u32 ident; /* A "identifier" for the submit for logging */ struct { uint32_t type; uint32_t size; /* in dwords */ diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index a90aedd6883a..e31be7417f94 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -20,6 +20,7 @@ #include "msm_drv.h" #include "msm_gpu.h" #include "msm_gem.h" +#include "msm_gpu_trace.h" /* * Cmdstream submission: @@ -48,7 +49,6 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev, submit->dev = dev; submit->gpu = gpu; submit->fence = NULL; - submit->pid = get_pid(task_pid(current)); submit->cmd = (void *)&submit->bos[nr_bos]; submit->queue = queue; submit->ring = gpu->rb[queue->prio]; @@ -406,6 +406,7 @@ static void submit_cleanup(struct msm_gem_submit *submit) int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file) { + static atomic_t ident = ATOMIC_INIT(0); struct msm_drm_private *priv = dev->dev_private; struct drm_msm_gem_submit *args = data; struct msm_file_private *ctx = file->driver_priv; @@ -416,9 +417,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct msm_gpu_submitqueue *queue; struct msm_ringbuffer *ring; int out_fence_fd = -1; + struct pid *pid = get_pid(task_pid(current)); unsigned i; - int ret; - + int ret, submitid; if (!gpu) return -ENXIO; @@ -441,7 +442,12 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, if (!queue) return -ENOENT; + /* Get a unique identifier for the submission for logging purposes */ + submitid = atomic_inc_return(&ident) - 1; + ring = gpu->rb[queue->prio]; + trace_msm_gpu_submit(pid_nr(pid), ring->id, submitid, + args->nr_bos, args->nr_cmds); if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { in_fence = sync_file_get_fence(args->fence_fd); @@ -478,6 +484,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, goto out_unlock; } + submit->pid = pid; + submit->ident = submitid; + if (args->flags & MSM_SUBMIT_SUDO) submit->in_rb = true; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index c3351ec880ef..d63fa2a36193 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -19,6 +19,7 @@ #include "msm_gem.h" #include "msm_mmu.h" #include "msm_fence.h" +#include "msm_gpu_trace.h" #include #include @@ -659,10 +660,28 @@ out: * Cmdstream submission/retirement: */ -static void retire_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) +static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, + struct msm_gem_submit *submit) { + int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT; + volatile struct msm_gpu_submit_stats *stats; + u64 elapsed, clock = 0; int i; + stats = &ring->memptrs->stats[index]; + /* Convert 19.2Mhz alwayson ticks to nanoseconds for elapsed time */ + elapsed = (stats->alwayson_end - stats->alwayson_start) * 10000; + do_div(elapsed, 192); + + /* Calculate the clock frequency from the number of CP cycles */ + if (elapsed) { + clock = (stats->cpcycles_end - stats->cpcycles_start) * 1000; + do_div(clock, elapsed); + } + + trace_msm_gpu_submit_retired(submit, elapsed, clock, + stats->alwayson_start, stats->alwayson_end); + for (i = 0; i < submit->nr_bos; i++) { struct msm_gem_object *msm_obj = submit->bos[i].obj; /* move to inactive: */ @@ -690,7 +709,7 @@ static void retire_submits(struct msm_gpu *gpu) list_for_each_entry_safe(submit, tmp, &ring->submits, node) { if (dma_fence_is_signaled(submit->fence)) - retire_submit(gpu, submit); + retire_submit(gpu, ring, submit); } } } diff --git a/drivers/gpu/drm/msm/msm_gpu_trace.h b/drivers/gpu/drm/msm/msm_gpu_trace.h new file mode 100644 index 000000000000..1155118a27a1 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_gpu_trace.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#if !defined(_MSM_GPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _MSM_GPU_TRACE_H_ + +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM drm_msm +#define TRACE_INCLUDE_FILE msm_gpu_trace + +TRACE_EVENT(msm_gpu_submit, + TP_PROTO(pid_t pid, u32 ringid, u32 id, u32 nr_bos, u32 nr_cmds), + TP_ARGS(pid, ringid, id, nr_bos, nr_cmds), + TP_STRUCT__entry( + __field(pid_t, pid) + __field(u32, id) + __field(u32, ringid) + __field(u32, nr_cmds) + __field(u32, nr_bos) + ), + TP_fast_assign( + __entry->pid = pid; + __entry->id = id; + __entry->ringid = ringid; + __entry->nr_bos = nr_bos; + __entry->nr_cmds = nr_cmds + ), + TP_printk("id=%d pid=%d ring=%d bos=%d cmds=%d", + __entry->id, __entry->pid, __entry->ringid, + __entry->nr_bos, __entry->nr_cmds) +); + +TRACE_EVENT(msm_gpu_submit_flush, + TP_PROTO(struct msm_gem_submit *submit, u64 ticks), + TP_ARGS(submit, ticks), + TP_STRUCT__entry( + __field(pid_t, pid) + __field(u32, id) + __field(u32, ringid) + __field(u32, seqno) + __field(u64, ticks) + ), + TP_fast_assign( + __entry->pid = pid_nr(submit->pid); + __entry->id = submit->ident; + __entry->ringid = submit->ring->id; + __entry->seqno = submit->seqno; + __entry->ticks = ticks; + ), + TP_printk("id=%d pid=%d ring=%d:%d ticks=%lld", + __entry->id, __entry->pid, __entry->ringid, __entry->seqno, + __entry->ticks) +); + + +TRACE_EVENT(msm_gpu_submit_retired, + TP_PROTO(struct msm_gem_submit *submit, u64 elapsed, u64 clock, + u64 start, u64 end), + TP_ARGS(submit, elapsed, clock, start, end), + TP_STRUCT__entry( + __field(pid_t, pid) + __field(u32, id) + __field(u32, ringid) + __field(u32, seqno) + __field(u64, elapsed) + __field(u64, clock) + __field(u64, start_ticks) + __field(u64, end_ticks) + ), + TP_fast_assign( + __entry->pid = pid_nr(submit->pid); + __entry->id = submit->ident; + __entry->ringid = submit->ring->id; + __entry->seqno = submit->seqno; + __entry->elapsed = elapsed; + __entry->clock = clock; + __entry->start_ticks = start; + __entry->end_ticks = end; + ), + TP_printk("id=%d pid=%d ring=%d:%d elapsed=%lld ns mhz=%lld start=%lld end=%lld", + __entry->id, __entry->pid, __entry->ringid, __entry->seqno, + __entry->elapsed, __entry->clock, + __entry->start_ticks, __entry->end_ticks) +); + +#endif + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/msm +#include diff --git a/drivers/gpu/drm/msm/msm_gpu_tracepoints.c b/drivers/gpu/drm/msm/msm_gpu_tracepoints.c new file mode 100644 index 000000000000..72c074f8c4f8 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_gpu_tracepoints.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "msm_gem.h" +#include "msm_ringbuffer.h" + +#define CREATE_TRACE_POINTS +#include "msm_gpu_trace.h" From 896a248a9034bf2226ec2cc1d314d94ea4266274 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:22 -0600 Subject: [PATCH 20/91] drm/msm/gpu: Only store local command buffers in the GPU state Instead of trying to store all the tagged buffers from a hanging submit only store the command buffers that were not imported. This cuts down on the amount of data stored in the GPU state to the base minimum of useful information. The downside is that this will make it more difficult to successfully replay a hang with just the GPU state but there isn't any reason why that functionality can't be added back in later once we've figured out how to better communicate such massive amounts of data. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index d63fa2a36193..f43e329146e5 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -316,28 +316,28 @@ static void msm_gpu_crashstate_get_bo(struct msm_gpu_state *state, struct msm_gpu_state_bo *state_bo = &state->bos[state->nr_bos]; /* Don't record write only objects */ - state_bo->size = obj->base.size; state_bo->iova = iova; - /* Only store the data for buffer objects marked for read */ - if ((flags & MSM_SUBMIT_BO_READ)) { + /* Only store data for non imported buffer objects marked for read */ + if ((flags & MSM_SUBMIT_BO_READ) && !obj->base.import_attach) { void *ptr; state_bo->data = kvmalloc(obj->base.size, GFP_KERNEL); if (!state_bo->data) - return; + goto out; ptr = msm_gem_get_vaddr_active(&obj->base); if (IS_ERR(ptr)) { kvfree(state_bo->data); - return; + state_bo->data = NULL; + goto out; } memcpy(state_bo->data, ptr, obj->base.size); msm_gem_put_vaddr(&obj->base); } - +out: state->nr_bos++; } @@ -361,12 +361,15 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, if (submit) { int i; - state->bos = kcalloc(submit->nr_bos, + state->bos = kcalloc(submit->nr_cmds, sizeof(struct msm_gpu_state_bo), GFP_KERNEL); - for (i = 0; state->bos && i < submit->nr_bos; i++) - msm_gpu_crashstate_get_bo(state, submit->bos[i].obj, - submit->bos[i].iova, submit->bos[i].flags); + for (i = 0; state->bos && i < submit->nr_cmds; i++) { + int idx = submit->cmd[i].idx; + + msm_gpu_crashstate_get_bo(state, submit->bos[idx].obj, + submit->bos[idx].iova, submit->bos[idx].flags); + } } /* Set the active crash state to be dumped on failure */ From 983674e24b4684045340b33dda1ecb81125d4cad Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:23 -0600 Subject: [PATCH 21/91] drm/msm/gpu: Move gpu_poll_timeout() to adreno_gpu.h The gpu_poll_timeout() function can be useful to multiple targets so mvoe it into adreno_gpu.h from the a5xx code. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 5 ----- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 1b9c724cbdfe..e64ab72f9681 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "msm_gem.h" #include "msm_mmu.h" @@ -1211,10 +1210,6 @@ struct a5xx_gpu_state { u32 *hlsqregs; }; -#define gpu_poll_timeout(gpu, addr, val, cond, interval, timeout) \ - readl_poll_timeout((gpu)->mmio + ((addr) << 2), val, cond, \ - interval, timeout) - static int a5xx_crashdumper_init(struct msm_gpu *gpu, struct a5xx_crashdumper *dumper) { diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index de6e6ee42fba..7e5f1120ce7a 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -21,6 +21,7 @@ #define __ADRENO_GPU_H__ #include +#include #include "msm_gpu.h" @@ -375,4 +376,9 @@ static inline uint32_t get_wptr(struct msm_ringbuffer *ring) ((1 << 29) \ ((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF)) + +#define gpu_poll_timeout(gpu, addr, val, cond, interval, timeout) \ + readl_poll_timeout((gpu)->mmio + ((addr) << 2), val, cond, \ + interval, timeout) + #endif /* __ADRENO_GPU_H__ */ From b9fc230252e7d0cbf109292bead71e50476f14c9 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:24 -0600 Subject: [PATCH 22/91] drm/msm/adreno: Don't capture register values if target doesn't define them If the GPU target doesn't define a list of registers then gracefully skip capturing and/or printing them. This is used by more complex targets like 6xx that have other means of capturing register values. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index cada3e634f92..789f7afe1851 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -414,6 +414,10 @@ int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state) } } + /* Some targets prefer to collect their own registers */ + if (!adreno_gpu->registers) + return 0; + /* Count the number of registers */ for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) count += adreno_gpu->registers[i + 1] - @@ -551,12 +555,14 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, } } - drm_puts(p, "registers:\n"); + if (state->nr_registers) { + drm_puts(p, "registers:\n"); - for (i = 0; i < state->nr_registers; i++) { - drm_printf(p, " - { offset: 0x%04x, value: 0x%08x }\n", - state->registers[i * 2] << 2, - state->registers[(i * 2) + 1]); + for (i = 0; i < state->nr_registers; i++) { + drm_printf(p, " - { offset: 0x%04x, value: 0x%08x }\n", + state->registers[i * 2] << 2, + state->registers[(i * 2) + 1]); + } } } #endif @@ -595,6 +601,9 @@ void adreno_dump(struct msm_gpu *gpu) struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); int i; + if (!adreno_gpu->registers) + return; + /* dump these out in a form that can be parsed by demsm: */ printk("IO:region %s 00000000 00020000\n", gpu->name); for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) { From 1707add815519da406c2d1444a1f10ef8bb4ad5b Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:25 -0600 Subject: [PATCH 23/91] drm/msm/a6xx: Add a6xx gpu state Add support for gathering and dumping the a6xx GPU state including registers, GMU registers, indexed registers, shader blocks, context clusters and debugbus. v2: Fix bugs discovered by Sharat Masetty Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 27 +- drivers/gpu/drm/msm/adreno/a6xx_gmu.h | 3 + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 39 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 8 + drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 1159 +++++++++++++++++++ drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 430 +++++++ 7 files changed, 1628 insertions(+), 39 deletions(-) create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c create mode 100644 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 5de2d8f0a7e5..fabc17bf1a58 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -14,6 +14,7 @@ msm-y := \ adreno/a6xx_gpu.o \ adreno/a6xx_gmu.o \ adreno/a6xx_hfi.o \ + adreno/a6xx_gpu_state.o \ hdmi/hdmi.o \ hdmi/hdmi_audio.o \ hdmi/hdmi_bridge.o \ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index e816947ac7d8..c58e953fefa3 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -51,10 +51,31 @@ static irqreturn_t a6xx_hfi_irq(int irq, void *data) return IRQ_HANDLED; } -/* Check to see if the GX rail is still powered */ -static bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) +bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu) { - u32 val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); + u32 val; + + /* This can be called from gpu state code so make sure GMU is valid */ + if (IS_ERR_OR_NULL(gmu->mmio)) + return false; + + val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); + + return !(val & + (A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SPTPRAC_GDSC_POWER_OFF | + A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SP_CLOCK_OFF)); +} + +/* Check to see if the GX rail is still powered */ +bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu) +{ + u32 val; + + /* This can be called from gpu state code so make sure GMU is valid */ + if (IS_ERR_OR_NULL(gmu->mmio)) + return false; + + val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS); return !(val & (A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF | diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h index 35f765afae45..c721d9165d8e 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h @@ -164,4 +164,7 @@ void a6xx_hfi_init(struct a6xx_gmu *gmu); int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state); void a6xx_hfi_stop(struct a6xx_gmu *gmu); +bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu); +bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu); + #endif diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index e0a918e8e969..11f0b99f94c8 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -670,33 +670,6 @@ static const u32 a6xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A6XX_CP_RB_CNTL), }; -static const u32 a6xx_registers[] = { - 0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0018, 0x001b, - 0x001e, 0x0032, 0x0038, 0x003c, 0x0042, 0x0042, 0x0044, 0x0044, - 0x0047, 0x0047, 0x0056, 0x0056, 0x00ad, 0x00ae, 0x00b0, 0x00fb, - 0x0100, 0x011d, 0x0200, 0x020d, 0x0210, 0x0213, 0x0218, 0x023d, - 0x0400, 0x04f9, 0x0500, 0x0500, 0x0505, 0x050b, 0x050e, 0x0511, - 0x0533, 0x0533, 0x0540, 0x0555, 0x0800, 0x0808, 0x0810, 0x0813, - 0x0820, 0x0821, 0x0823, 0x0827, 0x0830, 0x0833, 0x0840, 0x0843, - 0x084f, 0x086f, 0x0880, 0x088a, 0x08a0, 0x08ab, 0x08c0, 0x08c4, - 0x08d0, 0x08dd, 0x08f0, 0x08f3, 0x0900, 0x0903, 0x0908, 0x0911, - 0x0928, 0x093e, 0x0942, 0x094d, 0x0980, 0x0984, 0x098d, 0x0996, - 0x0998, 0x099e, 0x09a0, 0x09a6, 0x09a8, 0x09ae, 0x09b0, 0x09b1, - 0x09c2, 0x09c8, 0x0a00, 0x0a03, 0x0c00, 0x0c04, 0x0c06, 0x0c06, - 0x0c10, 0x0cd9, 0x0e00, 0x0e0e, 0x0e10, 0x0e13, 0x0e17, 0x0e19, - 0x0e1c, 0x0e2b, 0x0e30, 0x0e32, 0x0e38, 0x0e39, 0x8600, 0x8601, - 0x8610, 0x861b, 0x8620, 0x8620, 0x8628, 0x862b, 0x8630, 0x8637, - 0x8e01, 0x8e01, 0x8e04, 0x8e05, 0x8e07, 0x8e08, 0x8e0c, 0x8e0c, - 0x8e10, 0x8e1c, 0x8e20, 0x8e25, 0x8e28, 0x8e28, 0x8e2c, 0x8e2f, - 0x8e3b, 0x8e3e, 0x8e40, 0x8e43, 0x8e50, 0x8e5e, 0x8e70, 0x8e77, - 0x9600, 0x9604, 0x9624, 0x9637, 0x9e00, 0x9e01, 0x9e03, 0x9e0e, - 0x9e11, 0x9e16, 0x9e19, 0x9e19, 0x9e1c, 0x9e1c, 0x9e20, 0x9e23, - 0x9e30, 0x9e31, 0x9e34, 0x9e34, 0x9e70, 0x9e72, 0x9e78, 0x9e79, - 0x9e80, 0x9fff, 0xa600, 0xa601, 0xa603, 0xa603, 0xa60a, 0xa60a, - 0xa610, 0xa617, 0xa630, 0xa630, - ~0 -}; - static int a6xx_pm_resume(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -749,14 +722,6 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) return 0; } -#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) -static void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, - struct drm_printer *p) -{ - adreno_show(gpu, state, p); -} -#endif - static struct msm_ringbuffer *a6xx_active_ring(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -821,6 +786,8 @@ static const struct adreno_gpu_funcs funcs = { .gpu_busy = a6xx_gpu_busy, .gpu_get_freq = a6xx_gmu_get_freq, .gpu_set_freq = a6xx_gmu_set_freq, + .gpu_state_get = a6xx_gpu_state_get, + .gpu_state_put = a6xx_gpu_state_put, }, .get_timestamp = a6xx_get_timestamp, }; @@ -842,7 +809,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) adreno_gpu = &a6xx_gpu->base; gpu = &adreno_gpu->base; - adreno_gpu->registers = a6xx_registers; + adreno_gpu->registers = NULL; adreno_gpu->reg_offsets = a6xx_register_offsets; ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index 4127dcebc202..528a4cfe07cd 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -56,6 +56,14 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state); int a6xx_gmu_probe(struct a6xx_gpu *a6xx_gpu, struct device_node *node); void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu); + void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq); unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu); + +void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, + struct drm_printer *p); + +struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu); +int a6xx_gpu_state_put(struct msm_gpu_state *state); + #endif /* __A6XX_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c new file mode 100644 index 000000000000..20f5b914c6fb --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -0,0 +1,1159 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ + +#include +#include "msm_gem.h" +#include "a6xx_gpu.h" +#include "a6xx_gmu.h" +#include "a6xx_gpu_state.h" +#include "a6xx_gmu.xml.h" + +struct a6xx_gpu_state_obj { + const void *handle; + u32 *data; +}; + +struct a6xx_gpu_state { + struct msm_gpu_state base; + + struct a6xx_gpu_state_obj *gmu_registers; + int nr_gmu_registers; + + struct a6xx_gpu_state_obj *registers; + int nr_registers; + + struct a6xx_gpu_state_obj *shaders; + int nr_shaders; + + struct a6xx_gpu_state_obj *clusters; + int nr_clusters; + + struct a6xx_gpu_state_obj *dbgahb_clusters; + int nr_dbgahb_clusters; + + struct a6xx_gpu_state_obj *indexed_regs; + int nr_indexed_regs; + + struct a6xx_gpu_state_obj *debugbus; + int nr_debugbus; + + struct a6xx_gpu_state_obj *vbif_debugbus; + + struct a6xx_gpu_state_obj *cx_debugbus; + int nr_cx_debugbus; +}; + +static inline int CRASHDUMP_WRITE(u64 *in, u32 reg, u32 val) +{ + in[0] = val; + in[1] = (((u64) reg) << 44 | (1 << 21) | 1); + + return 2; +} + +static inline int CRASHDUMP_READ(u64 *in, u32 reg, u32 dwords, u64 target) +{ + in[0] = target; + in[1] = (((u64) reg) << 44 | dwords); + + return 2; +} + +static inline int CRASHDUMP_FINI(u64 *in) +{ + in[0] = 0; + in[1] = 0; + + return 2; +} + +struct a6xx_crashdumper { + void *ptr; + struct drm_gem_object *bo; + u64 iova; +}; + +/* + * Allocate 1MB for the crashdumper scratch region - 8k for the script and + * the rest for the data + */ +#define A6XX_CD_DATA_OFFSET 8192 +#define A6XX_CD_DATA_SIZE (SZ_1M - 8192) + +static int a6xx_crashdumper_init(struct msm_gpu *gpu, + struct a6xx_crashdumper *dumper) +{ + dumper->ptr = msm_gem_kernel_new_locked(gpu->dev, + SZ_1M, MSM_BO_UNCACHED, gpu->aspace, + &dumper->bo, &dumper->iova); + + return IS_ERR(dumper->ptr) ? PTR_ERR(dumper->ptr) : 0; +} + +static int a6xx_crashdumper_run(struct msm_gpu *gpu, + struct a6xx_crashdumper *dumper) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + u32 val; + int ret; + + if (IS_ERR_OR_NULL(dumper->ptr)) + return -EINVAL; + + if (!a6xx_gmu_sptprac_is_on(&a6xx_gpu->gmu)) + return -EINVAL; + + /* Make sure all pending memory writes are posted */ + wmb(); + + gpu_write64(gpu, REG_A6XX_CP_CRASH_SCRIPT_BASE_LO, + REG_A6XX_CP_CRASH_SCRIPT_BASE_HI, dumper->iova); + + gpu_write(gpu, REG_A6XX_CP_CRASH_DUMP_CNTL, 1); + + ret = gpu_poll_timeout(gpu, REG_A6XX_CP_CRASH_DUMP_STATUS, val, + val & 0x02, 100, 10000); + + gpu_write(gpu, REG_A6XX_CP_CRASH_DUMP_CNTL, 0); + + return ret; +} + +static void a6xx_crashdumper_free(struct msm_gpu *gpu, + struct a6xx_crashdumper *dumper) +{ + msm_gem_put_iova(dumper->bo, gpu->aspace); + msm_gem_put_vaddr(dumper->bo); + + drm_gem_object_unreference(dumper->bo); +} + +/* read a value from the GX debug bus */ +static int debugbus_read(struct msm_gpu *gpu, u32 block, u32 offset, + u32 *data) +{ + u32 reg = A6XX_DBGC_CFG_DBGBUS_SEL_D_PING_INDEX(offset) | + A6XX_DBGC_CFG_DBGBUS_SEL_D_PING_BLK_SEL(block); + + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_A, reg); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_B, reg); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_C, reg); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_D, reg); + + /* Wait 1 us to make sure the data is flowing */ + udelay(1); + + data[0] = gpu_read(gpu, REG_A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2); + data[1] = gpu_read(gpu, REG_A6XX_DBGC_CFG_DBGBUS_TRACE_BUF1); + + return 2; +} + +#define cxdbg_write(ptr, offset, val) \ + msm_writel((val), (ptr) + ((offset) << 2)) + +#define cxdbg_read(ptr, offset) \ + msm_readl((ptr) + ((offset) << 2)) + +/* read a value from the CX debug bus */ +static int cx_debugbus_read(void *__iomem cxdbg, u32 block, u32 offset, + u32 *data) +{ + u32 reg = A6XX_CX_DBGC_CFG_DBGBUS_SEL_A_PING_INDEX(offset) | + A6XX_CX_DBGC_CFG_DBGBUS_SEL_A_PING_BLK_SEL(block); + + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_A, reg); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_B, reg); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_C, reg); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_D, reg); + + /* Wait 1 us to make sure the data is flowing */ + udelay(1); + + data[0] = cxdbg_read(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2); + data[1] = cxdbg_read(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF1); + + return 2; +} + +/* Read a chunk of data from the VBIF debug bus */ +static int vbif_debugbus_read(struct msm_gpu *gpu, u32 ctrl0, u32 ctrl1, + u32 reg, int count, u32 *data) +{ + int i; + + gpu_write(gpu, ctrl0, reg); + + for (i = 0; i < count; i++) { + gpu_write(gpu, ctrl1, i); + data[i] = gpu_read(gpu, REG_A6XX_VBIF_TEST_BUS_OUT); + } + + return count; +} + +#define AXI_ARB_BLOCKS 2 +#define XIN_AXI_BLOCKS 5 +#define XIN_CORE_BLOCKS 4 + +#define VBIF_DEBUGBUS_BLOCK_SIZE \ + ((16 * AXI_ARB_BLOCKS) + \ + (18 * XIN_AXI_BLOCKS) + \ + (12 * XIN_CORE_BLOCKS)) + +static void a6xx_get_vbif_debugbus_block(struct msm_gpu *gpu, + struct a6xx_gpu_state_obj *obj) +{ + u32 clk, *ptr; + int i; + + obj->data = kcalloc(VBIF_DEBUGBUS_BLOCK_SIZE, sizeof(u32), GFP_KERNEL); + obj->handle = NULL; + + /* Get the current clock setting */ + clk = gpu_read(gpu, REG_A6XX_VBIF_CLKON); + + /* Force on the bus so we can read it */ + gpu_write(gpu, REG_A6XX_VBIF_CLKON, + clk | A6XX_VBIF_CLKON_FORCE_ON_TESTBUS); + + /* We will read from BUS2 first, so disable BUS1 */ + gpu_write(gpu, REG_A6XX_VBIF_TEST_BUS1_CTRL0, 0); + + /* Enable the VBIF bus for reading */ + gpu_write(gpu, REG_A6XX_VBIF_TEST_BUS_OUT_CTRL, 1); + + ptr = obj->data; + + for (i = 0; i < AXI_ARB_BLOCKS; i++) + ptr += vbif_debugbus_read(gpu, + REG_A6XX_VBIF_TEST_BUS2_CTRL0, + REG_A6XX_VBIF_TEST_BUS2_CTRL1, + 1 << (i + 16), 16, ptr); + + for (i = 0; i < XIN_AXI_BLOCKS; i++) + ptr += vbif_debugbus_read(gpu, + REG_A6XX_VBIF_TEST_BUS2_CTRL0, + REG_A6XX_VBIF_TEST_BUS2_CTRL1, + 1 << i, 18, ptr); + + /* Stop BUS2 so we can turn on BUS1 */ + gpu_write(gpu, REG_A6XX_VBIF_TEST_BUS2_CTRL0, 0); + + for (i = 0; i < XIN_CORE_BLOCKS; i++) + ptr += vbif_debugbus_read(gpu, + REG_A6XX_VBIF_TEST_BUS1_CTRL0, + REG_A6XX_VBIF_TEST_BUS1_CTRL1, + 1 << i, 12, ptr); + + /* Restore the VBIF clock setting */ + gpu_write(gpu, REG_A6XX_VBIF_CLKON, clk); +} + +static void a6xx_get_debugbus_block(struct msm_gpu *gpu, + const struct a6xx_debugbus_block *block, + struct a6xx_gpu_state_obj *obj) +{ + int i; + u32 *ptr; + + obj->data = kcalloc(block->count, sizeof(u64), GFP_KERNEL); + if (!obj->data) + return; + + obj->handle = block; + + for (ptr = obj->data, i = 0; i < block->count; i++) + ptr += debugbus_read(gpu, block->id, i, ptr); +} + +static void a6xx_get_cx_debugbus_block(void __iomem *cxdbg, + const struct a6xx_debugbus_block *block, + struct a6xx_gpu_state_obj *obj) +{ + int i; + u32 *ptr; + + obj->data = kcalloc(block->count, sizeof(u64), GFP_KERNEL); + if (!obj->data) + return; + + obj->handle = block; + + for (ptr = obj->data, i = 0; i < block->count; i++) + ptr += cx_debugbus_read(cxdbg, block->id, i, ptr); +} + +static void a6xx_get_debugbus(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state) +{ + struct resource *res; + void __iomem *cxdbg = NULL; + + /* Set up the GX debug bus */ + + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_CNTLT, + A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT(0xf)); + + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_CNTLM, + A6XX_DBGC_CFG_DBGBUS_CNTLM_ENABLE(0xf)); + + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0); + + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_0, 0x76543210); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_1, 0xFEDCBA98); + + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0); + gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0); + + /* Set up the CX debug bus - it lives elsewhere in the system so do a + * temporary ioremap for the registers + */ + res = platform_get_resource_byname(gpu->pdev, IORESOURCE_MEM, + "cx_dbgc"); + + if (res) + cxdbg = ioremap(res->start, resource_size(res)); + + if (cxdbg) { + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_CNTLT, + A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT(0xf)); + + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_CNTLM, + A6XX_DBGC_CFG_DBGBUS_CNTLM_ENABLE(0xf)); + + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0); + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0); + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0); + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0); + + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_0, + 0x76543210); + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_1, + 0xFEDCBA98); + + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0); + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0); + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0); + cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0); + } + + a6xx_state->debugbus = kcalloc(ARRAY_SIZE(a6xx_debugbus_blocks), + sizeof(*a6xx_state->debugbus), GFP_KERNEL); + + if (a6xx_state->debugbus) { + int i; + + for (i = 0; i < ARRAY_SIZE(a6xx_debugbus_blocks); i++) + a6xx_get_debugbus_block(gpu, + &a6xx_debugbus_blocks[i], + &a6xx_state->debugbus[i]); + + a6xx_state->nr_debugbus = ARRAY_SIZE(a6xx_debugbus_blocks); + } + + a6xx_state->vbif_debugbus = kzalloc(sizeof(*a6xx_state->vbif_debugbus), + GFP_KERNEL); + + if (a6xx_state->vbif_debugbus) + a6xx_get_vbif_debugbus_block(gpu, a6xx_state->vbif_debugbus); + + if (cxdbg) { + a6xx_state->cx_debugbus = + kcalloc(ARRAY_SIZE(a6xx_cx_debugbus_blocks), + sizeof(*a6xx_state->cx_debugbus), GFP_KERNEL); + + if (a6xx_state->cx_debugbus) { + int i; + + for (i = 0; i < ARRAY_SIZE(a6xx_cx_debugbus_blocks); i++) + a6xx_get_cx_debugbus_block(cxdbg, + &a6xx_cx_debugbus_blocks[i], + &a6xx_state->cx_debugbus[i]); + + a6xx_state->nr_cx_debugbus = + ARRAY_SIZE(a6xx_cx_debugbus_blocks); + } + + iounmap(cxdbg); + } +} + +#define RANGE(reg, a) ((reg)[(a) + 1] - (reg)[(a)] + 1) + +/* Read a data cluster from behind the AHB aperture */ +static void a6xx_get_dbgahb_cluster(struct msm_gpu *gpu, + const struct a6xx_dbgahb_cluster *dbgahb, + struct a6xx_gpu_state_obj *obj, + struct a6xx_crashdumper *dumper) +{ + u64 *in = dumper->ptr; + u64 out = dumper->iova + A6XX_CD_DATA_OFFSET; + size_t datasize; + int i, regcount = 0; + + for (i = 0; i < A6XX_NUM_CONTEXTS; i++) { + int j; + + in += CRASHDUMP_WRITE(in, REG_A6XX_HLSQ_DBG_READ_SEL, + (dbgahb->statetype + i * 2) << 8); + + for (j = 0; j < dbgahb->count; j += 2) { + int count = RANGE(dbgahb->registers, j); + u32 offset = REG_A6XX_HLSQ_DBG_AHB_READ_APERTURE + + dbgahb->registers[j] - (dbgahb->base >> 2); + + in += CRASHDUMP_READ(in, offset, count, out); + + out += count * sizeof(u32); + + if (i == 0) + regcount += count; + } + } + + CRASHDUMP_FINI(in); + + datasize = regcount * A6XX_NUM_CONTEXTS * sizeof(u32); + + if (WARN_ON(datasize > A6XX_CD_DATA_SIZE)) + return; + + if (a6xx_crashdumper_run(gpu, dumper)) + return; + + obj->handle = dbgahb; + obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, + datasize, GFP_KERNEL); +} + +static void a6xx_get_dbgahb_clusters(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, + struct a6xx_crashdumper *dumper) +{ + int i; + + a6xx_state->dbgahb_clusters = kcalloc(ARRAY_SIZE(a6xx_dbgahb_clusters), + sizeof(*a6xx_state->dbgahb_clusters), GFP_KERNEL); + + if (!a6xx_state->dbgahb_clusters) + return; + + a6xx_state->nr_dbgahb_clusters = ARRAY_SIZE(a6xx_dbgahb_clusters); + + for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_clusters); i++) + a6xx_get_dbgahb_cluster(gpu, &a6xx_dbgahb_clusters[i], + &a6xx_state->dbgahb_clusters[i], dumper); +} + +/* Read a data cluster from the CP aperture with the crashdumper */ +static void a6xx_get_cluster(struct msm_gpu *gpu, + const struct a6xx_cluster *cluster, + struct a6xx_gpu_state_obj *obj, + struct a6xx_crashdumper *dumper) +{ + u64 *in = dumper->ptr; + u64 out = dumper->iova + A6XX_CD_DATA_OFFSET; + size_t datasize; + int i, regcount = 0; + + /* Some clusters need a selector register to be programmed too */ + if (cluster->sel_reg) + in += CRASHDUMP_WRITE(in, cluster->sel_reg, cluster->sel_val); + + for (i = 0; i < A6XX_NUM_CONTEXTS; i++) { + int j; + + in += CRASHDUMP_WRITE(in, REG_A6XX_CP_APERTURE_CNTL_CD, + (cluster->id << 8) | (i << 4) | i); + + for (j = 0; j < cluster->count; j += 2) { + int count = RANGE(cluster->registers, j); + + in += CRASHDUMP_READ(in, cluster->registers[j], + count, out); + + out += count * sizeof(u32); + + if (i == 0) + regcount += count; + } + } + + CRASHDUMP_FINI(in); + + datasize = regcount * A6XX_NUM_CONTEXTS * sizeof(u32); + + if (WARN_ON(datasize > A6XX_CD_DATA_SIZE)) + return; + + if (a6xx_crashdumper_run(gpu, dumper)) + return; + + obj->handle = cluster; + obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, + datasize, GFP_KERNEL); +} + +static void a6xx_get_clusters(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, + struct a6xx_crashdumper *dumper) +{ + int i; + + a6xx_state->clusters = kcalloc(ARRAY_SIZE(a6xx_clusters), + sizeof(*a6xx_state->clusters), GFP_KERNEL); + + if (!a6xx_state->clusters) + return; + + a6xx_state->nr_clusters = ARRAY_SIZE(a6xx_clusters); + + for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) + a6xx_get_cluster(gpu, &a6xx_clusters[i], + &a6xx_state->clusters[i], dumper); +} + +/* Read a shader / debug block from the HLSQ aperture with the crashdumper */ +static void a6xx_get_shader_block(struct msm_gpu *gpu, + const struct a6xx_shader_block *block, + struct a6xx_gpu_state_obj *obj, + struct a6xx_crashdumper *dumper) +{ + u64 *in = dumper->ptr; + size_t datasize = block->size * A6XX_NUM_SHADER_BANKS * sizeof(u32); + int i; + + if (WARN_ON(datasize > A6XX_CD_DATA_SIZE)) + return; + + for (i = 0; i < A6XX_NUM_SHADER_BANKS; i++) { + in += CRASHDUMP_WRITE(in, REG_A6XX_HLSQ_DBG_READ_SEL, + (block->type << 8) | i); + + in += CRASHDUMP_READ(in, REG_A6XX_HLSQ_DBG_AHB_READ_APERTURE, + block->size, dumper->iova + A6XX_CD_DATA_OFFSET); + } + + CRASHDUMP_FINI(in); + + if (a6xx_crashdumper_run(gpu, dumper)) + return; + + obj->handle = block; + obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, + datasize, GFP_KERNEL); +} + +static void a6xx_get_shaders(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, + struct a6xx_crashdumper *dumper) +{ + int i; + + a6xx_state->shaders = kcalloc(ARRAY_SIZE(a6xx_shader_blocks), + sizeof(*a6xx_state->shaders), GFP_KERNEL); + + if (!a6xx_state->shaders) + return; + + a6xx_state->nr_shaders = ARRAY_SIZE(a6xx_shader_blocks); + + for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) + a6xx_get_shader_block(gpu, &a6xx_shader_blocks[i], + &a6xx_state->shaders[i], dumper); +} + +/* Read registers from behind the HLSQ aperture with the crashdumper */ +static void a6xx_get_crashdumper_hlsq_registers(struct msm_gpu *gpu, + const struct a6xx_registers *regs, + struct a6xx_gpu_state_obj *obj, + struct a6xx_crashdumper *dumper) + +{ + u64 *in = dumper->ptr; + u64 out = dumper->iova + A6XX_CD_DATA_OFFSET; + int i, regcount = 0; + + in += CRASHDUMP_WRITE(in, REG_A6XX_HLSQ_DBG_READ_SEL, regs->val1); + + for (i = 0; i < regs->count; i += 2) { + u32 count = RANGE(regs->registers, i); + u32 offset = REG_A6XX_HLSQ_DBG_AHB_READ_APERTURE + + regs->registers[i] - (regs->val0 >> 2); + + in += CRASHDUMP_READ(in, offset, count, out); + + out += count * sizeof(u32); + regcount += count; + } + + CRASHDUMP_FINI(in); + + if (WARN_ON((regcount * sizeof(u32)) > A6XX_CD_DATA_SIZE)) + return; + + if (a6xx_crashdumper_run(gpu, dumper)) + return; + + obj->handle = regs; + obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, + regcount * sizeof(u32), GFP_KERNEL); +} + +/* Read a block of registers using the crashdumper */ +static void a6xx_get_crashdumper_registers(struct msm_gpu *gpu, + const struct a6xx_registers *regs, + struct a6xx_gpu_state_obj *obj, + struct a6xx_crashdumper *dumper) + +{ + u64 *in = dumper->ptr; + u64 out = dumper->iova + A6XX_CD_DATA_OFFSET; + int i, regcount = 0; + + /* Some blocks might need to program a selector register first */ + if (regs->val0) + in += CRASHDUMP_WRITE(in, regs->val0, regs->val1); + + for (i = 0; i < regs->count; i += 2) { + u32 count = RANGE(regs->registers, i); + + in += CRASHDUMP_READ(in, regs->registers[i], count, out); + + out += count * sizeof(u32); + regcount += count; + } + + CRASHDUMP_FINI(in); + + if (WARN_ON((regcount * sizeof(u32)) > A6XX_CD_DATA_SIZE)) + return; + + if (a6xx_crashdumper_run(gpu, dumper)) + return; + + obj->handle = regs; + obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, + regcount * sizeof(u32), GFP_KERNEL); +} + +/* Read a block of registers via AHB */ +static void a6xx_get_ahb_gpu_registers(struct msm_gpu *gpu, + const struct a6xx_registers *regs, + struct a6xx_gpu_state_obj *obj) +{ + int i, regcount = 0, index = 0; + + for (i = 0; i < regs->count; i += 2) + regcount += RANGE(regs->registers, i); + + obj->handle = (const void *) regs; + obj->data = kcalloc(regcount, sizeof(u32), GFP_KERNEL); + if (!obj->data) + return; + + for (i = 0; i < regs->count; i += 2) { + u32 count = RANGE(regs->registers, i); + int j; + + for (j = 0; j < count; j++) + obj->data[index++] = gpu_read(gpu, + regs->registers[i] + j); + } +} + +/* Read a block of GMU registers */ +static void _a6xx_get_gmu_registers(struct msm_gpu *gpu, + const struct a6xx_registers *regs, + struct a6xx_gpu_state_obj *obj) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; + int i, regcount = 0, index = 0; + + for (i = 0; i < regs->count; i += 2) + regcount += RANGE(regs->registers, i); + + obj->handle = (const void *) regs; + obj->data = kcalloc(regcount, sizeof(u32), GFP_KERNEL); + if (!obj->data) + return; + + for (i = 0; i < regs->count; i += 2) { + u32 count = RANGE(regs->registers, i); + int j; + + for (j = 0; j < count; j++) + obj->data[index++] = gmu_read(gmu, + regs->registers[i] + j); + } +} + +static void a6xx_get_gmu_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + + a6xx_state->gmu_registers = kcalloc(2, + sizeof(*a6xx_state->gmu_registers), GFP_KERNEL); + + if (!a6xx_state->gmu_registers) + return; + + a6xx_state->nr_gmu_registers = 2; + + /* Get the CX GMU registers from AHB */ + _a6xx_get_gmu_registers(gpu, &a6xx_gmu_reglist[0], + &a6xx_state->gmu_registers[0]); + + if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) + return; + + /* Set the fence to ALLOW mode so we can access the registers */ + gpu_write(gpu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0); + + _a6xx_get_gmu_registers(gpu, &a6xx_gmu_reglist[1], + &a6xx_state->gmu_registers[1]); +} + +static void a6xx_get_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, + struct a6xx_crashdumper *dumper) +{ + int i, count = ARRAY_SIZE(a6xx_ahb_reglist) + + ARRAY_SIZE(a6xx_reglist) + + ARRAY_SIZE(a6xx_hlsq_reglist); + int index = 0; + + a6xx_state->registers = kcalloc(count, sizeof(*a6xx_state->registers), + GFP_KERNEL); + + if (!a6xx_state->registers) + return; + + a6xx_state->nr_registers = count; + + for (i = 0; i < ARRAY_SIZE(a6xx_ahb_reglist); i++) + a6xx_get_ahb_gpu_registers(gpu, + &a6xx_ahb_reglist[i], + &a6xx_state->registers[index++]); + + for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++) + a6xx_get_crashdumper_registers(gpu, + &a6xx_reglist[i], + &a6xx_state->registers[index++], + dumper); + + for (i = 0; i < ARRAY_SIZE(a6xx_hlsq_reglist); i++) + a6xx_get_crashdumper_hlsq_registers(gpu, + &a6xx_hlsq_reglist[i], + &a6xx_state->registers[index++], + dumper); +} + +/* Read a block of data from an indexed register pair */ +static void a6xx_get_indexed_regs(struct msm_gpu *gpu, + const struct a6xx_indexed_registers *indexed, + struct a6xx_gpu_state_obj *obj) +{ + int i; + + obj->handle = (const void *) indexed; + obj->data = kcalloc(indexed->count, sizeof(u32), GFP_KERNEL); + if (!obj->data) + return; + + /* All the indexed banks start at address 0 */ + gpu_write(gpu, indexed->addr, 0); + + /* Read the data - each read increments the internal address by 1 */ + for (i = 0; i < indexed->count; i++) + obj->data[i] = gpu_read(gpu, indexed->data); +} + +static void a6xx_get_indexed_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state) +{ + u32 mempool_size; + int count = ARRAY_SIZE(a6xx_indexed_reglist) + 1; + int i; + + a6xx_state->indexed_regs = kcalloc(count, + sizeof(a6xx_state->indexed_regs), GFP_KERNEL); + if (!a6xx_state->indexed_regs) + return; + + for (i = 0; i < ARRAY_SIZE(a6xx_indexed_reglist); i++) + a6xx_get_indexed_regs(gpu, &a6xx_indexed_reglist[i], + &a6xx_state->indexed_regs[i]); + + /* Set the CP mempool size to 0 to stabilize it while dumping */ + mempool_size = gpu_read(gpu, REG_A6XX_CP_MEM_POOL_SIZE); + gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 0); + + /* Get the contents of the CP mempool */ + a6xx_get_indexed_regs(gpu, &a6xx_cp_mempool_indexed, + &a6xx_state->indexed_regs[i]); + + /* + * Offset 0x2000 in the mempool is the size - copy the saved size over + * so the data is consistent + */ + a6xx_state->indexed_regs[i].data[0x2000] = mempool_size; + + /* Restore the size in the hardware */ + gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, mempool_size); + + a6xx_state->nr_indexed_regs = count; +} + +struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) +{ + struct a6xx_crashdumper dumper = { 0 }; + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_gpu_state *a6xx_state = kzalloc(sizeof(*a6xx_state), + GFP_KERNEL); + + if (!a6xx_state) + return ERR_PTR(-ENOMEM); + + /* Get the generic state from the adreno core */ + adreno_gpu_state_get(gpu, &a6xx_state->base); + + a6xx_get_gmu_registers(gpu, a6xx_state); + + /* If GX isn't on the rest of the data isn't going to be accessible */ + if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) + return &a6xx_state->base; + + /* Get the banks of indexed registers */ + a6xx_get_indexed_registers(gpu, a6xx_state); + + /* Try to initialize the crashdumper */ + if (!a6xx_crashdumper_init(gpu, &dumper)) { + a6xx_get_registers(gpu, a6xx_state, &dumper); + a6xx_get_shaders(gpu, a6xx_state, &dumper); + a6xx_get_clusters(gpu, a6xx_state, &dumper); + a6xx_get_dbgahb_clusters(gpu, a6xx_state, &dumper); + + a6xx_crashdumper_free(gpu, &dumper); + } + + a6xx_get_debugbus(gpu, a6xx_state); + + return &a6xx_state->base; +} + +void a6xx_gpu_state_destroy(struct kref *kref) +{ + struct msm_gpu_state *state = container_of(kref, + struct msm_gpu_state, ref); + struct a6xx_gpu_state *a6xx_state = container_of(state, + struct a6xx_gpu_state, base); + int i; + + for (i = 0; i < a6xx_state->nr_gmu_registers; i++) + kfree(a6xx_state->gmu_registers[i].data); + + kfree(a6xx_state->gmu_registers); + + for (i = 0; i < a6xx_state->nr_registers; i++) + kfree(a6xx_state->registers[i].data); + + kfree(a6xx_state->registers); + + for (i = 0; i < a6xx_state->nr_shaders; i++) + kfree(a6xx_state->shaders[i].data); + + kfree(a6xx_state->shaders); + + for (i = 0; i < a6xx_state->nr_clusters; i++) + kfree(a6xx_state->clusters[i].data); + + kfree(a6xx_state->clusters); + + for (i = 0; i < a6xx_state->nr_dbgahb_clusters; i++) + kfree(a6xx_state->dbgahb_clusters[i].data); + + kfree(a6xx_state->dbgahb_clusters); + + for (i = 0; i < a6xx_state->nr_indexed_regs; i++) + kfree(a6xx_state->indexed_regs[i].data); + + kfree(a6xx_state->indexed_regs); + + for (i = 0; i < a6xx_state->nr_debugbus; i++) + kfree(a6xx_state->debugbus[i].data); + + kfree(a6xx_state->debugbus); + + if (a6xx_state->vbif_debugbus) + kfree(a6xx_state->vbif_debugbus->data); + + kfree(a6xx_state->vbif_debugbus); + + for (i = 0; i < a6xx_state->nr_cx_debugbus; i++) + kfree(a6xx_state->cx_debugbus[i].data); + + kfree(a6xx_state->cx_debugbus); + + adreno_gpu_state_destroy(state); + kfree(a6xx_state); +} + +int a6xx_gpu_state_put(struct msm_gpu_state *state) +{ + if (IS_ERR_OR_NULL(state)) + return 1; + + return kref_put(&state->ref, a6xx_gpu_state_destroy); +} + +static void a6xx_show_registers(const u32 *registers, u32 *data, size_t count, + struct drm_printer *p) +{ + int i, index = 0; + + if (!data) + return; + + for (i = 0; i < count; i += 2) { + u32 count = RANGE(registers, i); + u32 offset = registers[i]; + int j; + + for (j = 0; j < count; index++, offset++, j++) { + if (data[index] == 0xdeafbead) + continue; + + drm_printf(p, " - { offset: 0x%06x, value: 0x%08x }\n", + offset << 2, data[index]); + } + } +} + +static void print_ascii85(struct drm_printer *p, size_t len, u32 *data) +{ + char out[ASCII85_BUFSZ]; + long i, l, datalen = 0; + + for (i = 0; i < len >> 2; i++) { + if (data[i]) + datalen = (i + 1) << 2; + } + + if (datalen == 0) + return; + + drm_puts(p, " data: !!ascii85 |\n"); + drm_puts(p, " "); + + + l = ascii85_encode_len(datalen); + + for (i = 0; i < l; i++) + drm_puts(p, ascii85_encode(data[i], out)); + + drm_puts(p, "\n"); +} + +static void print_name(struct drm_printer *p, const char *fmt, const char *name) +{ + drm_puts(p, fmt); + drm_puts(p, name); + drm_puts(p, "\n"); +} + +static void a6xx_show_shader(struct a6xx_gpu_state_obj *obj, + struct drm_printer *p) +{ + const struct a6xx_shader_block *block = obj->handle; + int i; + + if (!obj->handle) + return; + + print_name(p, " - type: ", block->name); + + for (i = 0; i < A6XX_NUM_SHADER_BANKS; i++) { + drm_printf(p, " - bank: %d\n", i); + drm_printf(p, " size: %d\n", block->size); + + if (!obj->data) + continue; + + print_ascii85(p, block->size << 2, + obj->data + (block->size * i)); + } +} + +static void a6xx_show_cluster_data(const u32 *registers, int size, u32 *data, + struct drm_printer *p) +{ + int ctx, index = 0; + + for (ctx = 0; ctx < A6XX_NUM_CONTEXTS; ctx++) { + int j; + + drm_printf(p, " - context: %d\n", ctx); + + for (j = 0; j < size; j += 2) { + u32 count = RANGE(registers, j); + u32 offset = registers[j]; + int k; + + for (k = 0; k < count; index++, offset++, k++) { + if (data[index] == 0xdeafbead) + continue; + + drm_printf(p, " - { offset: 0x%06x, value: 0x%08x }\n", + offset << 2, data[index]); + } + } + } +} + +static void a6xx_show_dbgahb_cluster(struct a6xx_gpu_state_obj *obj, + struct drm_printer *p) +{ + const struct a6xx_dbgahb_cluster *dbgahb = obj->handle; + + if (dbgahb) { + print_name(p, " - cluster-name: ", dbgahb->name); + a6xx_show_cluster_data(dbgahb->registers, dbgahb->count, + obj->data, p); + } +} + +static void a6xx_show_cluster(struct a6xx_gpu_state_obj *obj, + struct drm_printer *p) +{ + const struct a6xx_cluster *cluster = obj->handle; + + if (cluster) { + print_name(p, " - cluster-name: ", cluster->name); + a6xx_show_cluster_data(cluster->registers, cluster->count, + obj->data, p); + } +} + +static void a6xx_show_indexed_regs(struct a6xx_gpu_state_obj *obj, + struct drm_printer *p) +{ + const struct a6xx_indexed_registers *indexed = obj->handle; + + if (!indexed) + return; + + print_name(p, " - regs-name: ", indexed->name); + drm_printf(p, " dwords: %d\n", indexed->count); + + print_ascii85(p, indexed->count << 2, obj->data); +} + +static void a6xx_show_debugbus_block(const struct a6xx_debugbus_block *block, + u32 *data, struct drm_printer *p) +{ + if (block) { + print_name(p, " - debugbus-block: ", block->name); + + /* + * count for regular debugbus data is in quadwords, + * but print the size in dwords for consistency + */ + drm_printf(p, " count: %d\n", block->count << 1); + + print_ascii85(p, block->count << 3, data); + } +} + +static void a6xx_show_debugbus(struct a6xx_gpu_state *a6xx_state, + struct drm_printer *p) +{ + int i; + + for (i = 0; i < a6xx_state->nr_debugbus; i++) { + struct a6xx_gpu_state_obj *obj = &a6xx_state->debugbus[i]; + + a6xx_show_debugbus_block(obj->handle, obj->data, p); + } + + if (a6xx_state->vbif_debugbus) { + struct a6xx_gpu_state_obj *obj = a6xx_state->vbif_debugbus; + + drm_puts(p, " - debugbus-block: A6XX_DBGBUS_VBIF\n"); + drm_printf(p, " count: %d\n", VBIF_DEBUGBUS_BLOCK_SIZE); + + /* vbif debugbus data is in dwords. Confusing, huh? */ + print_ascii85(p, VBIF_DEBUGBUS_BLOCK_SIZE << 2, obj->data); + } + + for (i = 0; i < a6xx_state->nr_cx_debugbus; i++) { + struct a6xx_gpu_state_obj *obj = &a6xx_state->cx_debugbus[i]; + + a6xx_show_debugbus_block(obj->handle, obj->data, p); + } +} + +void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, + struct drm_printer *p) +{ + struct a6xx_gpu_state *a6xx_state = container_of(state, + struct a6xx_gpu_state, base); + int i; + + if (IS_ERR_OR_NULL(state)) + return; + + adreno_show(gpu, state, p); + + drm_puts(p, "registers:\n"); + for (i = 0; i < a6xx_state->nr_registers; i++) { + struct a6xx_gpu_state_obj *obj = &a6xx_state->registers[i]; + const struct a6xx_registers *regs = obj->handle; + + if (!obj->handle) + continue; + + a6xx_show_registers(regs->registers, obj->data, regs->count, p); + } + + drm_puts(p, "registers-gmu:\n"); + for (i = 0; i < a6xx_state->nr_gmu_registers; i++) { + struct a6xx_gpu_state_obj *obj = &a6xx_state->gmu_registers[i]; + const struct a6xx_registers *regs = obj->handle; + + if (!obj->handle) + continue; + + a6xx_show_registers(regs->registers, obj->data, regs->count, p); + } + + drm_puts(p, "indexed-registers:\n"); + for (i = 0; i < a6xx_state->nr_indexed_regs; i++) + a6xx_show_indexed_regs(&a6xx_state->indexed_regs[i], p); + + drm_puts(p, "shader-blocks:\n"); + for (i = 0; i < a6xx_state->nr_shaders; i++) + a6xx_show_shader(&a6xx_state->shaders[i], p); + + drm_puts(p, "clusters:\n"); + for (i = 0; i < a6xx_state->nr_clusters; i++) + a6xx_show_cluster(&a6xx_state->clusters[i], p); + + for (i = 0; i < a6xx_state->nr_dbgahb_clusters; i++) + a6xx_show_dbgahb_cluster(&a6xx_state->dbgahb_clusters[i], p); + + drm_puts(p, "debugbus:\n"); + a6xx_show_debugbus(a6xx_state, p); +} diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h new file mode 100644 index 000000000000..68cccfa2870a --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h @@ -0,0 +1,430 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ + +#ifndef _A6XX_CRASH_DUMP_H_ +#define _A6XX_CRASH_DUMP_H_ + +#include "a6xx.xml.h" + +#define A6XX_NUM_CONTEXTS 2 +#define A6XX_NUM_SHADER_BANKS 3 + +static const u32 a6xx_gras_cluster[] = { + 0x8000, 0x8006, 0x8010, 0x8092, 0x8094, 0x809d, 0x80a0, 0x80a6, + 0x80af, 0x80f1, 0x8100, 0x8107, 0x8109, 0x8109, 0x8110, 0x8110, + 0x8400, 0x840b, +}; + +static const u32 a6xx_ps_cluster_rac[] = { + 0x8800, 0x8806, 0x8809, 0x8811, 0x8818, 0x881e, 0x8820, 0x8865, + 0x8870, 0x8879, 0x8880, 0x8889, 0x8890, 0x8891, 0x8898, 0x8898, + 0x88c0, 0x88c1, 0x88d0, 0x88e3, 0x8900, 0x890c, 0x890f, 0x891a, + 0x8c00, 0x8c01, 0x8c08, 0x8c10, 0x8c17, 0x8c1f, 0x8c26, 0x8c33, +}; + +static const u32 a6xx_ps_cluster_rbp[] = { + 0x88f0, 0x88f3, 0x890d, 0x890e, 0x8927, 0x8928, 0x8bf0, 0x8bf1, + 0x8c02, 0x8c07, 0x8c11, 0x8c16, 0x8c20, 0x8c25, +}; + +static const u32 a6xx_ps_cluster[] = { + 0x9200, 0x9216, 0x9218, 0x9236, 0x9300, 0x9306, +}; + +static const u32 a6xx_fe_cluster[] = { + 0x9300, 0x9306, 0x9800, 0x9806, 0x9b00, 0x9b07, 0xa000, 0xa009, + 0xa00e, 0xa0ef, 0xa0f8, 0xa0f8, +}; + +static const u32 a6xx_pc_vs_cluster[] = { + 0x9100, 0x9108, 0x9300, 0x9306, 0x9980, 0x9981, 0x9b00, 0x9b07, +}; + +#define CLUSTER_FE 0 +#define CLUSTER_SP_VS 1 +#define CLUSTER_PC_VS 2 +#define CLUSTER_GRAS 3 +#define CLUSTER_SP_PS 4 +#define CLUSTER_PS 5 + +#define CLUSTER(_id, _reg, _sel_reg, _sel_val) \ + { .id = _id, .name = #_id,\ + .registers = _reg, \ + .count = ARRAY_SIZE(_reg), \ + .sel_reg = _sel_reg, .sel_val = _sel_val } + +static const struct a6xx_cluster { + u32 id; + const char *name; + const u32 *registers; + size_t count; + u32 sel_reg; + u32 sel_val; +} a6xx_clusters[] = { + CLUSTER(CLUSTER_GRAS, a6xx_gras_cluster, 0, 0), + CLUSTER(CLUSTER_PS, a6xx_ps_cluster_rac, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 0x0), + CLUSTER(CLUSTER_PS, a6xx_ps_cluster_rbp, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 0x9), + CLUSTER(CLUSTER_PS, a6xx_ps_cluster, 0, 0), + CLUSTER(CLUSTER_FE, a6xx_fe_cluster, 0, 0), + CLUSTER(CLUSTER_PC_VS, a6xx_pc_vs_cluster, 0, 0), +}; + +static const u32 a6xx_sp_vs_hlsq_cluster[] = { + 0xb800, 0xb803, 0xb820, 0xb822, +}; + +static const u32 a6xx_sp_vs_sp_cluster[] = { + 0xa800, 0xa824, 0xa830, 0xa83c, 0xa840, 0xa864, 0xa870, 0xa895, + 0xa8a0, 0xa8af, 0xa8c0, 0xa8c3, +}; + +static const u32 a6xx_hlsq_duplicate_cluster[] = { + 0xbb10, 0xbb11, 0xbb20, 0xbb29, +}; + +static const u32 a6xx_hlsq_2d_duplicate_cluster[] = { + 0xbd80, 0xbd80, +}; + +static const u32 a6xx_sp_duplicate_cluster[] = { + 0xab00, 0xab00, 0xab04, 0xab05, 0xab10, 0xab1b, 0xab20, 0xab20, +}; + +static const u32 a6xx_tp_duplicate_cluster[] = { + 0xb300, 0xb307, 0xb309, 0xb309, 0xb380, 0xb382, +}; + +static const u32 a6xx_sp_ps_hlsq_cluster[] = { + 0xb980, 0xb980, 0xb982, 0xb987, 0xb990, 0xb99b, 0xb9a0, 0xb9a2, + 0xb9c0, 0xb9c9, +}; + +static const u32 a6xx_sp_ps_hlsq_2d_cluster[] = { + 0xbd80, 0xbd80, +}; + +static const u32 a6xx_sp_ps_sp_cluster[] = { + 0xa980, 0xa9a8, 0xa9b0, 0xa9bc, 0xa9d0, 0xa9d3, 0xa9e0, 0xa9f3, + 0xaa00, 0xaa00, 0xaa30, 0xaa31, +}; + +static const u32 a6xx_sp_ps_sp_2d_cluster[] = { + 0xacc0, 0xacc0, +}; + +static const u32 a6xx_sp_ps_tp_cluster[] = { + 0xb180, 0xb183, 0xb190, 0xb191, +}; + +static const u32 a6xx_sp_ps_tp_2d_cluster[] = { + 0xb4c0, 0xb4d1, +}; + +#define CLUSTER_DBGAHB(_id, _base, _type, _reg) \ + { .name = #_id, .statetype = _type, .base = _base, \ + .registers = _reg, .count = ARRAY_SIZE(_reg) } + +static const struct a6xx_dbgahb_cluster { + const char *name; + u32 statetype; + u32 base; + const u32 *registers; + size_t count; +} a6xx_dbgahb_clusters[] = { + CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002e000, 0x41, a6xx_sp_vs_hlsq_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002a000, 0x21, a6xx_sp_vs_sp_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002e000, 0x41, a6xx_hlsq_duplicate_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002f000, 0x45, a6xx_hlsq_2d_duplicate_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002a000, 0x21, a6xx_sp_duplicate_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002c000, 0x1, a6xx_tp_duplicate_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002e000, 0x42, a6xx_sp_ps_hlsq_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002f000, 0x46, a6xx_sp_ps_hlsq_2d_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002a000, 0x22, a6xx_sp_ps_sp_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002b000, 0x26, a6xx_sp_ps_sp_2d_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002c000, 0x2, a6xx_sp_ps_tp_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002d000, 0x6, a6xx_sp_ps_tp_2d_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002e000, 0x42, a6xx_hlsq_duplicate_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002a000, 0x22, a6xx_sp_duplicate_cluster), + CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002c000, 0x2, a6xx_tp_duplicate_cluster), +}; + +static const u32 a6xx_hlsq_registers[] = { + 0xbe00, 0xbe01, 0xbe04, 0xbe05, 0xbe08, 0xbe09, 0xbe10, 0xbe15, + 0xbe20, 0xbe23, +}; + +static const u32 a6xx_sp_registers[] = { + 0xae00, 0xae04, 0xae0c, 0xae0c, 0xae0f, 0xae2b, 0xae30, 0xae32, + 0xae35, 0xae35, 0xae3a, 0xae3f, 0xae50, 0xae52, +}; + +static const u32 a6xx_tp_registers[] = { + 0xb600, 0xb601, 0xb604, 0xb605, 0xb610, 0xb61b, 0xb620, 0xb623, +}; + +struct a6xx_registers { + const u32 *registers; + size_t count; + u32 val0; + u32 val1; +}; + +#define HLSQ_DBG_REGS(_base, _type, _array) \ + { .val0 = _base, .val1 = _type, .registers = _array, \ + .count = ARRAY_SIZE(_array), } + +static const struct a6xx_registers a6xx_hlsq_reglist[] = { + HLSQ_DBG_REGS(0x0002F800, 0x40, a6xx_hlsq_registers), + HLSQ_DBG_REGS(0x0002B800, 0x20, a6xx_sp_registers), + HLSQ_DBG_REGS(0x0002D800, 0x0, a6xx_tp_registers), +}; + +#define SHADER(_type, _size) \ + { .type = _type, .name = #_type, .size = _size } + +static const struct a6xx_shader_block { + const char *name; + u32 type; + u32 size; +} a6xx_shader_blocks[] = { + SHADER(A6XX_TP0_TMO_DATA, 0x200), + SHADER(A6XX_TP0_SMO_DATA, 0x80), + SHADER(A6XX_TP0_MIPMAP_BASE_DATA, 0x3c0), + SHADER(A6XX_TP1_TMO_DATA, 0x200), + SHADER(A6XX_TP1_SMO_DATA, 0x80), + SHADER(A6XX_TP1_MIPMAP_BASE_DATA, 0x3c0), + SHADER(A6XX_SP_INST_DATA, 0x800), + SHADER(A6XX_SP_LB_0_DATA, 0x800), + SHADER(A6XX_SP_LB_1_DATA, 0x800), + SHADER(A6XX_SP_LB_2_DATA, 0x800), + SHADER(A6XX_SP_LB_3_DATA, 0x800), + SHADER(A6XX_SP_LB_4_DATA, 0x800), + SHADER(A6XX_SP_LB_5_DATA, 0x200), + SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000), + SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280), + SHADER(A6XX_SP_UAV_DATA, 0x80), + SHADER(A6XX_SP_INST_TAG, 0x80), + SHADER(A6XX_SP_CB_BINDLESS_TAG, 0x80), + SHADER(A6XX_SP_TMO_UMO_TAG, 0x80), + SHADER(A6XX_SP_SMO_TAG, 0x80), + SHADER(A6XX_SP_STATE_DATA, 0x3f), + SHADER(A6XX_HLSQ_CHUNK_CVS_RAM, 0x1c0), + SHADER(A6XX_HLSQ_CHUNK_CPS_RAM, 0x280), + SHADER(A6XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x40), + SHADER(A6XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x40), + SHADER(A6XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x4), + SHADER(A6XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x4), + SHADER(A6XX_HLSQ_CVS_MISC_RAM, 0x1c0), + SHADER(A6XX_HLSQ_CPS_MISC_RAM, 0x580), + SHADER(A6XX_HLSQ_INST_RAM, 0x800), + SHADER(A6XX_HLSQ_GFX_CVS_CONST_RAM, 0x800), + SHADER(A6XX_HLSQ_GFX_CPS_CONST_RAM, 0x800), + SHADER(A6XX_HLSQ_CVS_MISC_RAM_TAG, 0x8), + SHADER(A6XX_HLSQ_CPS_MISC_RAM_TAG, 0x4), + SHADER(A6XX_HLSQ_INST_RAM_TAG, 0x80), + SHADER(A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0xc), + SHADER(A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x10), + SHADER(A6XX_HLSQ_PWR_REST_RAM, 0x28), + SHADER(A6XX_HLSQ_PWR_REST_TAG, 0x14), + SHADER(A6XX_HLSQ_DATAPATH_META, 0x40), + SHADER(A6XX_HLSQ_FRONTEND_META, 0x40), + SHADER(A6XX_HLSQ_INDIRECT_META, 0x40), +}; + +static const u32 a6xx_rb_rac_registers[] = { + 0x8e04, 0x8e05, 0x8e07, 0x8e08, 0x8e10, 0x8e1c, 0x8e20, 0x8e25, + 0x8e28, 0x8e28, 0x8e2c, 0x8e2f, 0x8e50, 0x8e52, +}; + +static const u32 a6xx_rb_rbp_registers[] = { + 0x8e01, 0x8e01, 0x8e0c, 0x8e0c, 0x8e3b, 0x8e3e, 0x8e40, 0x8e43, + 0x8e53, 0x8e5f, 0x8e70, 0x8e77, +}; + +static const u32 a6xx_registers[] = { + /* RBBM */ + 0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0018, 0x001b, + 0x001e, 0x0032, 0x0038, 0x003c, 0x0042, 0x0042, 0x0044, 0x0044, + 0x0047, 0x0047, 0x0056, 0x0056, 0x00ad, 0x00ae, 0x00b0, 0x00fb, + 0x0100, 0x011d, 0x0200, 0x020d, 0x0218, 0x023d, 0x0400, 0x04f9, + 0x0500, 0x0500, 0x0505, 0x050b, 0x050e, 0x0511, 0x0533, 0x0533, + 0x0540, 0x0555, + /* CP */ + 0x0800, 0x0808, 0x0810, 0x0813, 0x0820, 0x0821, 0x0823, 0x0824, + 0x0826, 0x0827, 0x0830, 0x0833, 0x0840, 0x0843, 0x084f, 0x086f, + 0x0880, 0x088a, 0x08a0, 0x08ab, 0x08c0, 0x08c4, 0x08d0, 0x08dd, + 0x08f0, 0x08f3, 0x0900, 0x0903, 0x0908, 0x0911, 0x0928, 0x093e, + 0x0942, 0x094d, 0x0980, 0x0984, 0x098d, 0x0996, 0x0998, 0x099e, + 0x09a0, 0x09a6, 0x09a8, 0x09ae, 0x09b0, 0x09b1, 0x09c2, 0x09c8, + 0x0a00, 0x0a03, + /* VSC */ + 0x0c00, 0x0c04, 0x0c06, 0x0c06, 0x0c10, 0x0cd9, 0x0e00, 0x0e0e, + /* UCHE */ + 0x0e10, 0x0e13, 0x0e17, 0x0e19, 0x0e1c, 0x0e2b, 0x0e30, 0x0e32, + 0x0e38, 0x0e39, + /* GRAS */ + 0x8600, 0x8601, 0x8610, 0x861b, 0x8620, 0x8620, 0x8628, 0x862b, + 0x8630, 0x8637, + /* VPC */ + 0x9600, 0x9604, 0x9624, 0x9637, + /* PC */ + 0x9e00, 0x9e01, 0x9e03, 0x9e0e, 0x9e11, 0x9e16, 0x9e19, 0x9e19, + 0x9e1c, 0x9e1c, 0x9e20, 0x9e23, 0x9e30, 0x9e31, 0x9e34, 0x9e34, + 0x9e70, 0x9e72, 0x9e78, 0x9e79, 0x9e80, 0x9fff, + /* VFD */ + 0xa600, 0xa601, 0xa603, 0xa603, 0xa60a, 0xa60a, 0xa610, 0xa617, + 0xa630, 0xa630, +}; + +#define REGS(_array, _sel_reg, _sel_val) \ + { .registers = _array, .count = ARRAY_SIZE(_array), \ + .val0 = _sel_reg, .val1 = _sel_val } + +static const struct a6xx_registers a6xx_reglist[] = { + REGS(a6xx_registers, 0, 0), + REGS(a6xx_rb_rac_registers, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 0), + REGS(a6xx_rb_rbp_registers, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 9), +}; + +static const u32 a6xx_ahb_registers[] = { + /* RBBM_STATUS - RBBM_STATUS3 */ + 0x210, 0x213, + /* CP_STATUS_1 */ + 0x825, 0x825, +}; + +static const u32 a6xx_vbif_registers[] = { + 0x3000, 0x3007, 0x300c, 0x3014, 0x3018, 0x302d, 0x3030, 0x3031, + 0x3034, 0x3036, 0x303c, 0x303d, 0x3040, 0x3040, 0x3042, 0x3042, + 0x3049, 0x3049, 0x3058, 0x3058, 0x305a, 0x3061, 0x3064, 0x3068, + 0x306c, 0x306d, 0x3080, 0x3088, 0x308b, 0x308c, 0x3090, 0x3094, + 0x3098, 0x3098, 0x309c, 0x309c, 0x30c0, 0x30c0, 0x30c8, 0x30c8, + 0x30d0, 0x30d0, 0x30d8, 0x30d8, 0x30e0, 0x30e0, 0x3100, 0x3100, + 0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120, + 0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x3154, 0x3154, + 0x3156, 0x3156, 0x3158, 0x3158, 0x315a, 0x315a, 0x315c, 0x315c, + 0x315e, 0x315e, 0x3160, 0x3160, 0x3162, 0x3162, 0x340c, 0x340c, + 0x3410, 0x3410, 0x3800, 0x3801, +}; + +static const struct a6xx_registers a6xx_ahb_reglist[] = { + REGS(a6xx_ahb_registers, 0, 0), + REGS(a6xx_vbif_registers, 0, 0), +}; + +static const u32 a6xx_gmu_gx_registers[] = { + /* GMU GX */ + 0x0000, 0x0000, 0x0010, 0x0013, 0x0016, 0x0016, 0x0018, 0x001b, + 0x001e, 0x001e, 0x0020, 0x0023, 0x0026, 0x0026, 0x0028, 0x002b, + 0x002e, 0x002e, 0x0030, 0x0033, 0x0036, 0x0036, 0x0038, 0x003b, + 0x003e, 0x003e, 0x0040, 0x0043, 0x0046, 0x0046, 0x0080, 0x0084, + 0x0100, 0x012b, 0x0140, 0x0140, +}; + +static const u32 a6xx_gmu_cx_registers[] = { + /* GMU CX */ + 0x4c00, 0x4c07, 0x4c10, 0x4c12, 0x4d00, 0x4d00, 0x4d07, 0x4d0a, + 0x5000, 0x5004, 0x5007, 0x5008, 0x500b, 0x500c, 0x500f, 0x501c, + 0x5024, 0x502a, 0x502d, 0x5030, 0x5040, 0x5053, 0x5087, 0x5089, + 0x50a0, 0x50a2, 0x50a4, 0x50af, 0x50c0, 0x50c3, 0x50d0, 0x50d0, + 0x50e4, 0x50e4, 0x50e8, 0x50ec, 0x5100, 0x5103, 0x5140, 0x5140, + 0x5142, 0x5144, 0x514c, 0x514d, 0x514f, 0x5151, 0x5154, 0x5154, + 0x5157, 0x5158, 0x515d, 0x515d, 0x5162, 0x5162, 0x5164, 0x5165, + 0x5180, 0x5186, 0x5190, 0x519e, 0x51c0, 0x51c0, 0x51c5, 0x51cc, + 0x51e0, 0x51e2, 0x51f0, 0x51f0, 0x5200, 0x5201, + /* GPU RSCC */ + 0x8c8c, 0x8c8c, 0x8d01, 0x8d02, 0x8f40, 0x8f42, 0x8f44, 0x8f47, + 0x8f4c, 0x8f87, 0x8fec, 0x8fef, 0x8ff4, 0x902f, 0x9094, 0x9097, + 0x909c, 0x90d7, 0x913c, 0x913f, 0x9144, 0x917f, + /* GMU AO */ + 0x9300, 0x9316, 0x9400, 0x9400, + /* GPU CC */ + 0x9800, 0x9812, 0x9840, 0x9852, 0x9c00, 0x9c04, 0x9c07, 0x9c0b, + 0x9c15, 0x9c1c, 0x9c1e, 0x9c2d, 0x9c3c, 0x9c3d, 0x9c3f, 0x9c40, + 0x9c42, 0x9c49, 0x9c58, 0x9c5a, 0x9d40, 0x9d5e, 0xa000, 0xa002, + 0xa400, 0xa402, 0xac00, 0xac02, 0xb000, 0xb002, 0xb400, 0xb402, + 0xb800, 0xb802, + /* GPU CC ACD */ + 0xbc00, 0xbc16, 0xbc20, 0xbc27, +}; + +static const struct a6xx_registers a6xx_gmu_reglist[] = { + REGS(a6xx_gmu_cx_registers, 0, 0), + REGS(a6xx_gmu_gx_registers, 0, 0), +}; + +static const struct a6xx_indexed_registers { + const char *name; + u32 addr; + u32 data; + u32 count; +} a6xx_indexed_reglist[] = { + { "CP_SEQ_STAT", REG_A6XX_CP_SQE_STAT_ADDR, + REG_A6XX_CP_SQE_STAT_DATA, 0x33 }, + { "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR, + REG_A6XX_CP_DRAW_STATE_DATA, 0x100 }, + { "CP_UCODE_DBG_DATA", REG_A6XX_CP_SQE_UCODE_DBG_ADDR, + REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x6000 }, + { "CP_ROQ", REG_A6XX_CP_ROQ_DBG_ADDR, + REG_A6XX_CP_ROQ_DBG_DATA, 0x400 }, +}; + +static const struct a6xx_indexed_registers a6xx_cp_mempool_indexed = { + "CP_MEMPOOOL", REG_A6XX_CP_MEM_POOL_DBG_ADDR, + REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2060, +}; + +#define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count } + +static const struct a6xx_debugbus_block { + const char *name; + u32 id; + u32 count; +} a6xx_debugbus_blocks[] = { + DEBUGBUS(A6XX_DBGBUS_CP, 0x100), + DEBUGBUS(A6XX_DBGBUS_RBBM, 0x100), + DEBUGBUS(A6XX_DBGBUS_HLSQ, 0x100), + DEBUGBUS(A6XX_DBGBUS_UCHE, 0x100), + DEBUGBUS(A6XX_DBGBUS_DPM, 0x100), + DEBUGBUS(A6XX_DBGBUS_TESS, 0x100), + DEBUGBUS(A6XX_DBGBUS_PC, 0x100), + DEBUGBUS(A6XX_DBGBUS_VFDP, 0x100), + DEBUGBUS(A6XX_DBGBUS_VPC, 0x100), + DEBUGBUS(A6XX_DBGBUS_TSE, 0x100), + DEBUGBUS(A6XX_DBGBUS_RAS, 0x100), + DEBUGBUS(A6XX_DBGBUS_VSC, 0x100), + DEBUGBUS(A6XX_DBGBUS_COM, 0x100), + DEBUGBUS(A6XX_DBGBUS_LRZ, 0x100), + DEBUGBUS(A6XX_DBGBUS_A2D, 0x100), + DEBUGBUS(A6XX_DBGBUS_CCUFCHE, 0x100), + DEBUGBUS(A6XX_DBGBUS_RBP, 0x100), + DEBUGBUS(A6XX_DBGBUS_DCS, 0x100), + DEBUGBUS(A6XX_DBGBUS_DBGC, 0x100), + DEBUGBUS(A6XX_DBGBUS_GMU_GX, 0x100), + DEBUGBUS(A6XX_DBGBUS_TPFCHE, 0x100), + DEBUGBUS(A6XX_DBGBUS_GPC, 0x100), + DEBUGBUS(A6XX_DBGBUS_LARC, 0x100), + DEBUGBUS(A6XX_DBGBUS_HLSQ_SPTP, 0x100), + DEBUGBUS(A6XX_DBGBUS_RB_0, 0x100), + DEBUGBUS(A6XX_DBGBUS_RB_1, 0x100), + DEBUGBUS(A6XX_DBGBUS_UCHE_WRAPPER, 0x100), + DEBUGBUS(A6XX_DBGBUS_CCU_0, 0x100), + DEBUGBUS(A6XX_DBGBUS_CCU_1, 0x100), + DEBUGBUS(A6XX_DBGBUS_VFD_0, 0x100), + DEBUGBUS(A6XX_DBGBUS_VFD_1, 0x100), + DEBUGBUS(A6XX_DBGBUS_VFD_2, 0x100), + DEBUGBUS(A6XX_DBGBUS_VFD_3, 0x100), + DEBUGBUS(A6XX_DBGBUS_SP_0, 0x100), + DEBUGBUS(A6XX_DBGBUS_SP_1, 0x100), + DEBUGBUS(A6XX_DBGBUS_TPL1_0, 0x100), + DEBUGBUS(A6XX_DBGBUS_TPL1_1, 0x100), + DEBUGBUS(A6XX_DBGBUS_TPL1_2, 0x100), + DEBUGBUS(A6XX_DBGBUS_TPL1_3, 0x100), +}; + +static const struct a6xx_debugbus_block a6xx_cx_debugbus_blocks[] = { + DEBUGBUS(A6XX_DBGBUS_GMU_CX, 0x100), + DEBUGBUS(A6XX_DBGBUS_CX, 0x100), +}; + +#endif From d6852b4b2d0140b0fbfe112edf4fe66c1857b561 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Fri, 2 Nov 2018 09:25:26 -0600 Subject: [PATCH 24/91] drm/msm/a6xx: Track and manage a6xx state memory The a6xx GPU state allocates a LOT of memory. Add a bit of infrastructure to track the memory allocations in the GPU structure and delete them when the state is destroyed much the same way that devm works with the device model as a whole. This protects against the developer accidentally forgetting to add a kfree() to an ever growing list. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 192 +++++++++++--------- 1 file changed, 102 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 20f5b914c6fb..ec57ddeb8c77 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -41,6 +41,8 @@ struct a6xx_gpu_state { struct a6xx_gpu_state_obj *cx_debugbus; int nr_cx_debugbus; + + struct list_head objs; }; static inline int CRASHDUMP_WRITE(u64 *in, u32 reg, u32 val) @@ -73,6 +75,33 @@ struct a6xx_crashdumper { u64 iova; }; +struct a6xx_state_memobj { + struct list_head node; + unsigned long long data[]; +}; + +void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize) +{ + struct a6xx_state_memobj *obj = + kzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL); + + if (!obj) + return NULL; + + list_add_tail(&obj->node, &a6xx_state->objs); + return &obj->data; +} + +void *state_kmemdup(struct a6xx_gpu_state *a6xx_state, void *src, + size_t size) +{ + void *dst = state_kcalloc(a6xx_state, 1, size); + + if (dst) + memcpy(dst, src, size); + return dst; +} + /* * Allocate 1MB for the crashdumper scratch region - 8k for the script and * the rest for the data @@ -203,12 +232,17 @@ static int vbif_debugbus_read(struct msm_gpu *gpu, u32 ctrl0, u32 ctrl1, (12 * XIN_CORE_BLOCKS)) static void a6xx_get_vbif_debugbus_block(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, struct a6xx_gpu_state_obj *obj) { u32 clk, *ptr; int i; - obj->data = kcalloc(VBIF_DEBUGBUS_BLOCK_SIZE, sizeof(u32), GFP_KERNEL); + obj->data = state_kcalloc(a6xx_state, VBIF_DEBUGBUS_BLOCK_SIZE, + sizeof(u32)); + if (!obj->data) + return; + obj->handle = NULL; /* Get the current clock setting */ @@ -252,13 +286,14 @@ static void a6xx_get_vbif_debugbus_block(struct msm_gpu *gpu, } static void a6xx_get_debugbus_block(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_debugbus_block *block, struct a6xx_gpu_state_obj *obj) { int i; u32 *ptr; - obj->data = kcalloc(block->count, sizeof(u64), GFP_KERNEL); + obj->data = state_kcalloc(a6xx_state, block->count, sizeof(u64)); if (!obj->data) return; @@ -269,13 +304,14 @@ static void a6xx_get_debugbus_block(struct msm_gpu *gpu, } static void a6xx_get_cx_debugbus_block(void __iomem *cxdbg, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_debugbus_block *block, struct a6xx_gpu_state_obj *obj) { int i; u32 *ptr; - obj->data = kcalloc(block->count, sizeof(u64), GFP_KERNEL); + obj->data = state_kcalloc(a6xx_state, block->count, sizeof(u64)); if (!obj->data) return; @@ -344,36 +380,42 @@ static void a6xx_get_debugbus(struct msm_gpu *gpu, cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0); } - a6xx_state->debugbus = kcalloc(ARRAY_SIZE(a6xx_debugbus_blocks), - sizeof(*a6xx_state->debugbus), GFP_KERNEL); + a6xx_state->debugbus = state_kcalloc(a6xx_state, + ARRAY_SIZE(a6xx_debugbus_blocks), + sizeof(*a6xx_state->debugbus)); if (a6xx_state->debugbus) { int i; for (i = 0; i < ARRAY_SIZE(a6xx_debugbus_blocks); i++) a6xx_get_debugbus_block(gpu, + a6xx_state, &a6xx_debugbus_blocks[i], &a6xx_state->debugbus[i]); a6xx_state->nr_debugbus = ARRAY_SIZE(a6xx_debugbus_blocks); } - a6xx_state->vbif_debugbus = kzalloc(sizeof(*a6xx_state->vbif_debugbus), - GFP_KERNEL); + a6xx_state->vbif_debugbus = + state_kcalloc(a6xx_state, 1, + sizeof(*a6xx_state->vbif_debugbus)); if (a6xx_state->vbif_debugbus) - a6xx_get_vbif_debugbus_block(gpu, a6xx_state->vbif_debugbus); + a6xx_get_vbif_debugbus_block(gpu, a6xx_state, + a6xx_state->vbif_debugbus); if (cxdbg) { a6xx_state->cx_debugbus = - kcalloc(ARRAY_SIZE(a6xx_cx_debugbus_blocks), - sizeof(*a6xx_state->cx_debugbus), GFP_KERNEL); + state_kcalloc(a6xx_state, + ARRAY_SIZE(a6xx_cx_debugbus_blocks), + sizeof(*a6xx_state->cx_debugbus)); if (a6xx_state->cx_debugbus) { int i; for (i = 0; i < ARRAY_SIZE(a6xx_cx_debugbus_blocks); i++) a6xx_get_cx_debugbus_block(cxdbg, + a6xx_state, &a6xx_cx_debugbus_blocks[i], &a6xx_state->cx_debugbus[i]); @@ -389,6 +431,7 @@ static void a6xx_get_debugbus(struct msm_gpu *gpu, /* Read a data cluster from behind the AHB aperture */ static void a6xx_get_dbgahb_cluster(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_dbgahb_cluster *dbgahb, struct a6xx_gpu_state_obj *obj, struct a6xx_crashdumper *dumper) @@ -429,8 +472,8 @@ static void a6xx_get_dbgahb_cluster(struct msm_gpu *gpu, return; obj->handle = dbgahb; - obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, - datasize, GFP_KERNEL); + obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET, + datasize); } static void a6xx_get_dbgahb_clusters(struct msm_gpu *gpu, @@ -439,8 +482,9 @@ static void a6xx_get_dbgahb_clusters(struct msm_gpu *gpu, { int i; - a6xx_state->dbgahb_clusters = kcalloc(ARRAY_SIZE(a6xx_dbgahb_clusters), - sizeof(*a6xx_state->dbgahb_clusters), GFP_KERNEL); + a6xx_state->dbgahb_clusters = state_kcalloc(a6xx_state, + ARRAY_SIZE(a6xx_dbgahb_clusters), + sizeof(*a6xx_state->dbgahb_clusters)); if (!a6xx_state->dbgahb_clusters) return; @@ -448,12 +492,14 @@ static void a6xx_get_dbgahb_clusters(struct msm_gpu *gpu, a6xx_state->nr_dbgahb_clusters = ARRAY_SIZE(a6xx_dbgahb_clusters); for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_clusters); i++) - a6xx_get_dbgahb_cluster(gpu, &a6xx_dbgahb_clusters[i], + a6xx_get_dbgahb_cluster(gpu, a6xx_state, + &a6xx_dbgahb_clusters[i], &a6xx_state->dbgahb_clusters[i], dumper); } /* Read a data cluster from the CP aperture with the crashdumper */ static void a6xx_get_cluster(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_cluster *cluster, struct a6xx_gpu_state_obj *obj, struct a6xx_crashdumper *dumper) @@ -497,8 +543,8 @@ static void a6xx_get_cluster(struct msm_gpu *gpu, return; obj->handle = cluster; - obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, - datasize, GFP_KERNEL); + obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET, + datasize); } static void a6xx_get_clusters(struct msm_gpu *gpu, @@ -507,8 +553,8 @@ static void a6xx_get_clusters(struct msm_gpu *gpu, { int i; - a6xx_state->clusters = kcalloc(ARRAY_SIZE(a6xx_clusters), - sizeof(*a6xx_state->clusters), GFP_KERNEL); + a6xx_state->clusters = state_kcalloc(a6xx_state, + ARRAY_SIZE(a6xx_clusters), sizeof(*a6xx_state->clusters)); if (!a6xx_state->clusters) return; @@ -516,12 +562,13 @@ static void a6xx_get_clusters(struct msm_gpu *gpu, a6xx_state->nr_clusters = ARRAY_SIZE(a6xx_clusters); for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) - a6xx_get_cluster(gpu, &a6xx_clusters[i], + a6xx_get_cluster(gpu, a6xx_state, &a6xx_clusters[i], &a6xx_state->clusters[i], dumper); } /* Read a shader / debug block from the HLSQ aperture with the crashdumper */ static void a6xx_get_shader_block(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_shader_block *block, struct a6xx_gpu_state_obj *obj, struct a6xx_crashdumper *dumper) @@ -547,8 +594,8 @@ static void a6xx_get_shader_block(struct msm_gpu *gpu, return; obj->handle = block; - obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, - datasize, GFP_KERNEL); + obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET, + datasize); } static void a6xx_get_shaders(struct msm_gpu *gpu, @@ -557,8 +604,8 @@ static void a6xx_get_shaders(struct msm_gpu *gpu, { int i; - a6xx_state->shaders = kcalloc(ARRAY_SIZE(a6xx_shader_blocks), - sizeof(*a6xx_state->shaders), GFP_KERNEL); + a6xx_state->shaders = state_kcalloc(a6xx_state, + ARRAY_SIZE(a6xx_shader_blocks), sizeof(*a6xx_state->shaders)); if (!a6xx_state->shaders) return; @@ -566,12 +613,13 @@ static void a6xx_get_shaders(struct msm_gpu *gpu, a6xx_state->nr_shaders = ARRAY_SIZE(a6xx_shader_blocks); for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) - a6xx_get_shader_block(gpu, &a6xx_shader_blocks[i], + a6xx_get_shader_block(gpu, a6xx_state, &a6xx_shader_blocks[i], &a6xx_state->shaders[i], dumper); } /* Read registers from behind the HLSQ aperture with the crashdumper */ static void a6xx_get_crashdumper_hlsq_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_registers *regs, struct a6xx_gpu_state_obj *obj, struct a6xx_crashdumper *dumper) @@ -603,12 +651,13 @@ static void a6xx_get_crashdumper_hlsq_registers(struct msm_gpu *gpu, return; obj->handle = regs; - obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, - regcount * sizeof(u32), GFP_KERNEL); + obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET, + regcount * sizeof(u32)); } /* Read a block of registers using the crashdumper */ static void a6xx_get_crashdumper_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_registers *regs, struct a6xx_gpu_state_obj *obj, struct a6xx_crashdumper *dumper) @@ -640,12 +689,13 @@ static void a6xx_get_crashdumper_registers(struct msm_gpu *gpu, return; obj->handle = regs; - obj->data = kmemdup(dumper->ptr + A6XX_CD_DATA_OFFSET, - regcount * sizeof(u32), GFP_KERNEL); + obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET, + regcount * sizeof(u32)); } /* Read a block of registers via AHB */ static void a6xx_get_ahb_gpu_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_registers *regs, struct a6xx_gpu_state_obj *obj) { @@ -655,7 +705,7 @@ static void a6xx_get_ahb_gpu_registers(struct msm_gpu *gpu, regcount += RANGE(regs->registers, i); obj->handle = (const void *) regs; - obj->data = kcalloc(regcount, sizeof(u32), GFP_KERNEL); + obj->data = state_kcalloc(a6xx_state, regcount, sizeof(u32)); if (!obj->data) return; @@ -671,6 +721,7 @@ static void a6xx_get_ahb_gpu_registers(struct msm_gpu *gpu, /* Read a block of GMU registers */ static void _a6xx_get_gmu_registers(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_registers *regs, struct a6xx_gpu_state_obj *obj) { @@ -683,7 +734,7 @@ static void _a6xx_get_gmu_registers(struct msm_gpu *gpu, regcount += RANGE(regs->registers, i); obj->handle = (const void *) regs; - obj->data = kcalloc(regcount, sizeof(u32), GFP_KERNEL); + obj->data = state_kcalloc(a6xx_state, regcount, sizeof(u32)); if (!obj->data) return; @@ -703,8 +754,8 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); - a6xx_state->gmu_registers = kcalloc(2, - sizeof(*a6xx_state->gmu_registers), GFP_KERNEL); + a6xx_state->gmu_registers = state_kcalloc(a6xx_state, + 2, sizeof(*a6xx_state->gmu_registers)); if (!a6xx_state->gmu_registers) return; @@ -712,7 +763,7 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, a6xx_state->nr_gmu_registers = 2; /* Get the CX GMU registers from AHB */ - _a6xx_get_gmu_registers(gpu, &a6xx_gmu_reglist[0], + _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0], &a6xx_state->gmu_registers[0]); if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) @@ -721,7 +772,7 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, /* Set the fence to ALLOW mode so we can access the registers */ gpu_write(gpu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0); - _a6xx_get_gmu_registers(gpu, &a6xx_gmu_reglist[1], + _a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[1], &a6xx_state->gmu_registers[1]); } @@ -734,8 +785,8 @@ static void a6xx_get_registers(struct msm_gpu *gpu, ARRAY_SIZE(a6xx_hlsq_reglist); int index = 0; - a6xx_state->registers = kcalloc(count, sizeof(*a6xx_state->registers), - GFP_KERNEL); + a6xx_state->registers = state_kcalloc(a6xx_state, + count, sizeof(*a6xx_state->registers)); if (!a6xx_state->registers) return; @@ -744,31 +795,32 @@ static void a6xx_get_registers(struct msm_gpu *gpu, for (i = 0; i < ARRAY_SIZE(a6xx_ahb_reglist); i++) a6xx_get_ahb_gpu_registers(gpu, - &a6xx_ahb_reglist[i], + a6xx_state, &a6xx_ahb_reglist[i], &a6xx_state->registers[index++]); for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++) a6xx_get_crashdumper_registers(gpu, - &a6xx_reglist[i], + a6xx_state, &a6xx_reglist[i], &a6xx_state->registers[index++], dumper); for (i = 0; i < ARRAY_SIZE(a6xx_hlsq_reglist); i++) a6xx_get_crashdumper_hlsq_registers(gpu, - &a6xx_hlsq_reglist[i], + a6xx_state, &a6xx_hlsq_reglist[i], &a6xx_state->registers[index++], dumper); } /* Read a block of data from an indexed register pair */ static void a6xx_get_indexed_regs(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state, const struct a6xx_indexed_registers *indexed, struct a6xx_gpu_state_obj *obj) { int i; obj->handle = (const void *) indexed; - obj->data = kcalloc(indexed->count, sizeof(u32), GFP_KERNEL); + obj->data = state_kcalloc(a6xx_state, indexed->count, sizeof(u32)); if (!obj->data) return; @@ -787,13 +839,13 @@ static void a6xx_get_indexed_registers(struct msm_gpu *gpu, int count = ARRAY_SIZE(a6xx_indexed_reglist) + 1; int i; - a6xx_state->indexed_regs = kcalloc(count, - sizeof(a6xx_state->indexed_regs), GFP_KERNEL); + a6xx_state->indexed_regs = state_kcalloc(a6xx_state, count, + sizeof(a6xx_state->indexed_regs)); if (!a6xx_state->indexed_regs) return; for (i = 0; i < ARRAY_SIZE(a6xx_indexed_reglist); i++) - a6xx_get_indexed_regs(gpu, &a6xx_indexed_reglist[i], + a6xx_get_indexed_regs(gpu, a6xx_state, &a6xx_indexed_reglist[i], &a6xx_state->indexed_regs[i]); /* Set the CP mempool size to 0 to stabilize it while dumping */ @@ -801,7 +853,7 @@ static void a6xx_get_indexed_registers(struct msm_gpu *gpu, gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 0); /* Get the contents of the CP mempool */ - a6xx_get_indexed_regs(gpu, &a6xx_cp_mempool_indexed, + a6xx_get_indexed_regs(gpu, a6xx_state, &a6xx_cp_mempool_indexed, &a6xx_state->indexed_regs[i]); /* @@ -827,6 +879,8 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) if (!a6xx_state) return ERR_PTR(-ENOMEM); + INIT_LIST_HEAD(&a6xx_state->objs); + /* Get the generic state from the adreno core */ adreno_gpu_state_get(gpu, &a6xx_state->base); @@ -856,56 +910,14 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) void a6xx_gpu_state_destroy(struct kref *kref) { + struct a6xx_state_memobj *obj, *tmp; struct msm_gpu_state *state = container_of(kref, struct msm_gpu_state, ref); struct a6xx_gpu_state *a6xx_state = container_of(state, struct a6xx_gpu_state, base); - int i; - for (i = 0; i < a6xx_state->nr_gmu_registers; i++) - kfree(a6xx_state->gmu_registers[i].data); - - kfree(a6xx_state->gmu_registers); - - for (i = 0; i < a6xx_state->nr_registers; i++) - kfree(a6xx_state->registers[i].data); - - kfree(a6xx_state->registers); - - for (i = 0; i < a6xx_state->nr_shaders; i++) - kfree(a6xx_state->shaders[i].data); - - kfree(a6xx_state->shaders); - - for (i = 0; i < a6xx_state->nr_clusters; i++) - kfree(a6xx_state->clusters[i].data); - - kfree(a6xx_state->clusters); - - for (i = 0; i < a6xx_state->nr_dbgahb_clusters; i++) - kfree(a6xx_state->dbgahb_clusters[i].data); - - kfree(a6xx_state->dbgahb_clusters); - - for (i = 0; i < a6xx_state->nr_indexed_regs; i++) - kfree(a6xx_state->indexed_regs[i].data); - - kfree(a6xx_state->indexed_regs); - - for (i = 0; i < a6xx_state->nr_debugbus; i++) - kfree(a6xx_state->debugbus[i].data); - - kfree(a6xx_state->debugbus); - - if (a6xx_state->vbif_debugbus) - kfree(a6xx_state->vbif_debugbus->data); - - kfree(a6xx_state->vbif_debugbus); - - for (i = 0; i < a6xx_state->nr_cx_debugbus; i++) - kfree(a6xx_state->cx_debugbus[i].data); - - kfree(a6xx_state->cx_debugbus); + list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) + kfree(obj); adreno_gpu_state_destroy(state); kfree(a6xx_state); From 1e29dff00400d40fdd3d52f2a76c188f5126f033 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:46 -0700 Subject: [PATCH 25/91] drm/msm: Add a common function to free kernel buffer objects Buffer objects allocated with msm_gem_kernel_new() are mostly freed the same way so we can save a few lines of code with a common function. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 13 ++----------- drivers/gpu/drm/msm/adreno/a5xx_power.c | 13 +------------ drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 14 ++------------ drivers/gpu/drm/msm/msm_drv.h | 2 ++ drivers/gpu/drm/msm/msm_gem.c | 15 +++++++++++++++ drivers/gpu/drm/msm/msm_gpu.c | 12 ++---------- drivers/gpu/drm/msm/msm_ringbuffer.c | 7 ++----- 7 files changed, 26 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index e64ab72f9681..0d3f61abbf37 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1220,15 +1220,6 @@ static int a5xx_crashdumper_init(struct msm_gpu *gpu, return PTR_ERR_OR_ZERO(dumper->ptr); } -static void a5xx_crashdumper_free(struct msm_gpu *gpu, - struct a5xx_crashdumper *dumper) -{ - msm_gem_put_iova(dumper->bo, gpu->aspace); - msm_gem_put_vaddr(dumper->bo); - - drm_gem_object_put(dumper->bo); -} - static int a5xx_crashdumper_run(struct msm_gpu *gpu, struct a5xx_crashdumper *dumper) { @@ -1321,7 +1312,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu, if (a5xx_crashdumper_run(gpu, &dumper)) { kfree(a5xx_state->hlsqregs); - a5xx_crashdumper_free(gpu, &dumper); + msm_gem_kernel_put(dumper.bo, gpu->aspace, true); return; } @@ -1329,7 +1320,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu, memcpy(a5xx_state->hlsqregs, dumper.ptr + (256 * SZ_1K), count * sizeof(u32)); - a5xx_crashdumper_free(gpu, &dumper); + msm_gem_kernel_put(dumper.bo, gpu->aspace, true); } static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index 7a41e1c147e4..66bcd88dd8c0 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -298,7 +298,7 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) MSM_BO_UNCACHED | MSM_BO_GPU_READONLY, gpu->aspace, &a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova); if (IS_ERR(ptr)) - goto err; + return; while (cmds_size > 0) { int i; @@ -317,15 +317,4 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) msm_gem_put_vaddr(a5xx_gpu->gpmu_bo); a5xx_gpu->gpmu_dwords = dwords; - - return; -err: - if (a5xx_gpu->gpmu_iova) - msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace); - if (a5xx_gpu->gpmu_bo) - drm_gem_object_put(a5xx_gpu->gpmu_bo); - - a5xx_gpu->gpmu_bo = NULL; - a5xx_gpu->gpmu_iova = 0; - a5xx_gpu->gpmu_dwords = 0; } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c index fdb08fc68c2c..48481e663685 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -267,18 +267,8 @@ void a5xx_preempt_fini(struct msm_gpu *gpu) struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu); int i; - for (i = 0; i < gpu->nr_rings; i++) { - if (!a5xx_gpu->preempt_bo[i]) - continue; - - msm_gem_put_vaddr(a5xx_gpu->preempt_bo[i]); - - if (a5xx_gpu->preempt_iova[i]) - msm_gem_put_iova(a5xx_gpu->preempt_bo[i], gpu->aspace); - - drm_gem_object_put(a5xx_gpu->preempt_bo[i]); - a5xx_gpu->preempt_bo[i] = NULL; - } + for (i = 0; i < gpu->nr_rings; i++) + msm_gem_kernel_put(a5xx_gpu->preempt_bo[i], gpu->aspace, true); } void a5xx_preempt_init(struct msm_gpu *gpu) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 9d11f321f5a9..3225f8fbd8c9 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -312,6 +312,8 @@ void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size, void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size, uint32_t flags, struct msm_gem_address_space *aspace, struct drm_gem_object **bo, uint64_t *iova); +void msm_gem_kernel_put(struct drm_gem_object *bo, + struct msm_gem_address_space *aspace, bool locked); struct drm_gem_object *msm_gem_import(struct drm_device *dev, struct dma_buf *dmabuf, struct sg_table *sgt); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 4646e9e45fc2..f32cf75e1b3f 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1079,3 +1079,18 @@ void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size, { return _msm_gem_kernel_new(dev, size, flags, aspace, bo, iova, true); } + +void msm_gem_kernel_put(struct drm_gem_object *bo, + struct msm_gem_address_space *aspace, bool locked) +{ + if (IS_ERR_OR_NULL(bo)) + return; + + msm_gem_put_vaddr(bo); + msm_gem_put_iova(bo, aspace); + + if (locked) + drm_gem_object_put(bo); + else + drm_gem_object_put_unlocked(bo); +} diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index f43e329146e5..3e2b3568d932 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -981,11 +981,7 @@ fail: gpu->rb[i] = NULL; } - if (gpu->memptrs_bo) { - msm_gem_put_vaddr(gpu->memptrs_bo); - msm_gem_put_iova(gpu->memptrs_bo, gpu->aspace); - drm_gem_object_put_unlocked(gpu->memptrs_bo); - } + msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace, false); platform_set_drvdata(pdev, NULL); return ret; @@ -1004,11 +1000,7 @@ void msm_gpu_cleanup(struct msm_gpu *gpu) gpu->rb[i] = NULL; } - if (gpu->memptrs_bo) { - msm_gem_put_vaddr(gpu->memptrs_bo); - msm_gem_put_iova(gpu->memptrs_bo, gpu->aspace); - drm_gem_object_put_unlocked(gpu->memptrs_bo); - } + msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace, false); if (!IS_ERR_OR_NULL(gpu->aspace)) { gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu, diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 6f5295b3f2f6..9fa9525c5293 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -73,10 +73,7 @@ void msm_ringbuffer_destroy(struct msm_ringbuffer *ring) msm_fence_context_free(ring->fctx); - if (ring->bo) { - msm_gem_put_iova(ring->bo, ring->gpu->aspace); - msm_gem_put_vaddr(ring->bo); - drm_gem_object_put_unlocked(ring->bo); - } + msm_gem_kernel_put(ring->bo, ring->gpu->aspace, false); + kfree(ring); } From 70dc51b447f570ba3881e289b8134d364977a6f0 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:47 -0700 Subject: [PATCH 26/91] drm/msm: Remove sgt from the mmu unmap function The scatter gather table doesn't need to be passed in for the MMU unmap function. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 2 +- drivers/gpu/drm/msm/msm_gem.c | 2 +- drivers/gpu/drm/msm/msm_gem_vma.c | 4 ++-- drivers/gpu/drm/msm/msm_iommu.c | 3 +-- drivers/gpu/drm/msm/msm_mmu.h | 3 +-- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 3225f8fbd8c9..3a0f2119127b 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -242,7 +242,7 @@ void msm_atomic_state_clear(struct drm_atomic_state *state); void msm_atomic_state_free(struct drm_atomic_state *state); void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, - struct msm_gem_vma *vma, struct sg_table *sgt); + struct msm_gem_vma *vma); int msm_gem_map_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, struct sg_table *sgt, int npages); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index f32cf75e1b3f..0b9b8a21dfbb 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -352,7 +352,7 @@ put_iova(struct drm_gem_object *obj) WARN_ON(!mutex_is_locked(&msm_obj->lock)); list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) { - msm_gem_unmap_vma(vma->aspace, vma, msm_obj->sgt); + msm_gem_unmap_vma(vma->aspace, vma); del_vma(vma); } } diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index ffbec224551b..704ae7e69500 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -40,14 +40,14 @@ void msm_gem_address_space_put(struct msm_gem_address_space *aspace) void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, - struct msm_gem_vma *vma, struct sg_table *sgt) + struct msm_gem_vma *vma) { if (!aspace || !vma->iova) return; if (aspace->mmu) { unsigned size = vma->node.size << PAGE_SHIFT; - aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt, size); + aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, size); } spin_lock(&aspace->lock); diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index b23d33622f37..9c313cb129ee 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -71,8 +71,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, return (ret == len) ? 0 : -EINVAL; } -static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, - struct sg_table *sgt, unsigned len) +static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len) { struct msm_iommu *iommu = to_msm_iommu(mmu); diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index aa2c5d4580c8..94c0b83d8026 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -25,8 +25,7 @@ struct msm_mmu_funcs { void (*detach)(struct msm_mmu *mmu, const char * const *names, int cnt); int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt, unsigned len, int prot); - int (*unmap)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt, - unsigned len); + int (*unmap)(struct msm_mmu *mmu, uint64_t iova, unsigned len); void (*destroy)(struct msm_mmu *mmu); }; From c0ee9794693c1ff5bf540fc642fac954e39234a0 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:48 -0700 Subject: [PATCH 27/91] drm/msm: Split msm_gem_get_iova into two steps Split the operation of msm_gem_get_iova into two operations: 1) allocate an iova and 2) map (pin) the backing memory int the iommu. This is the first step toward allowing memory pinning to occur independently of the iova management. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.h | 2 + drivers/gpu/drm/msm/msm_gem.c | 80 ++++++++++++++++++++----------- drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_vma.c | 44 ++++++++++++----- 4 files changed, 86 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 3a0f2119127b..63b28b69b2ab 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -241,6 +241,8 @@ struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev); void msm_atomic_state_clear(struct drm_atomic_state *state); void msm_atomic_state_free(struct drm_atomic_state *state); +int msm_gem_init_vma(struct msm_gem_address_space *aspace, + struct msm_gem_vma *vma, int npages); void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma); int msm_gem_map_vma(struct msm_gem_address_space *aspace, diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 0b9b8a21dfbb..013b023528b8 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -357,52 +357,76 @@ put_iova(struct drm_gem_object *obj) } } -/* get iova, taking a reference. Should have a matching put */ -int msm_gem_get_iova(struct drm_gem_object *obj, +static int msm_gem_get_iova_locked(struct drm_gem_object *obj, struct msm_gem_address_space *aspace, uint64_t *iova) { struct msm_gem_object *msm_obj = to_msm_bo(obj); struct msm_gem_vma *vma; int ret = 0; - mutex_lock(&msm_obj->lock); - - if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) { - mutex_unlock(&msm_obj->lock); - return -EBUSY; - } + WARN_ON(!mutex_is_locked(&msm_obj->lock)); vma = lookup_vma(obj, aspace); if (!vma) { - struct page **pages; - vma = add_vma(obj, aspace); - if (IS_ERR(vma)) { - ret = PTR_ERR(vma); - goto unlock; - } + if (IS_ERR(vma)) + return PTR_ERR(vma); - pages = get_pages(obj); - if (IS_ERR(pages)) { - ret = PTR_ERR(pages); - goto fail; + ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT); + if (ret) { + del_vma(vma); + return ret; } - - ret = msm_gem_map_vma(aspace, vma, msm_obj->sgt, - obj->size >> PAGE_SHIFT); - if (ret) - goto fail; } *iova = vma->iova; - - mutex_unlock(&msm_obj->lock); return 0; +} + +static int msm_gem_pin_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *vma; + struct page **pages; + + WARN_ON(!mutex_is_locked(&msm_obj->lock)); + + if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) + return -EBUSY; + + vma = lookup_vma(obj, aspace); + if (WARN_ON(!vma)) + return -EINVAL; + + pages = get_pages(obj); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + return msm_gem_map_vma(aspace, vma, msm_obj->sgt, + obj->size >> PAGE_SHIFT); +} + + +/* get iova, taking a reference. Should have a matching put */ +int msm_gem_get_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint64_t *iova) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + u64 local; + int ret; + + mutex_lock(&msm_obj->lock); + + ret = msm_gem_get_iova_locked(obj, aspace, &local); + + if (!ret) + ret = msm_gem_pin_iova(obj, aspace); + + if (!ret) + *iova = local; -fail: - del_vma(vma); -unlock: mutex_unlock(&msm_obj->lock); return ret; } diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index ddaf8663dc95..a44847364504 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -41,6 +41,7 @@ struct msm_gem_vma { uint64_t iova; struct msm_gem_address_space *aspace; struct list_head list; /* node in msm_gem_object::vmas */ + bool mapped; }; struct msm_gem_object { diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 704ae7e69500..c4c42bf0db0e 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -55,6 +55,7 @@ msm_gem_unmap_vma(struct msm_gem_address_space *aspace, spin_unlock(&aspace->lock); vma->iova = 0; + vma->mapped = false; msm_gem_address_space_put(aspace); } @@ -62,15 +63,38 @@ msm_gem_unmap_vma(struct msm_gem_address_space *aspace, int msm_gem_map_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, struct sg_table *sgt, int npages) +{ + unsigned size = npages << PAGE_SHIFT; + int ret = 0; + + if (WARN_ON(!vma->iova)) + return -EINVAL; + + if (vma->mapped) + return 0; + + vma->mapped = true; + + if (aspace->mmu) + ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, + size, IOMMU_READ | IOMMU_WRITE); + + if (ret) + vma->mapped = false; + + return ret; +} + +/* Initialize a new vma and allocate an iova for it */ +int msm_gem_init_vma(struct msm_gem_address_space *aspace, + struct msm_gem_vma *vma, int npages) { int ret; - spin_lock(&aspace->lock); - if (WARN_ON(drm_mm_node_allocated(&vma->node))) { - spin_unlock(&aspace->lock); - return 0; - } + if (WARN_ON(vma->iova)) + return -EBUSY; + spin_lock(&aspace->lock); ret = drm_mm_insert_node(&aspace->mm, &vma->node, npages); spin_unlock(&aspace->lock); @@ -78,17 +102,11 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, return ret; vma->iova = vma->node.start << PAGE_SHIFT; + vma->mapped = false; - if (aspace->mmu) { - unsigned size = npages << PAGE_SHIFT; - ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, - size, IOMMU_READ | IOMMU_WRITE); - } - - /* Get a reference to the aspace to keep it around */ kref_get(&aspace->kref); - return ret; + return 0; } struct msm_gem_address_space * From 575f0485508bb210914d8b45bdd8481d0ecd4a72 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:49 -0700 Subject: [PATCH 28/91] drm/msm: Clean up and enhance the output of the 'gem' debugfs node Add headers for the 'gem' debugfs file to make it easier to remember what all the values mean and move the list of virtual address regions to the next line and add the name and map status to make it clearer what we are looking at. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 013b023528b8..f24c9fe37aaa 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -763,16 +763,23 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) break; } - seq_printf(m, "%08x: %c %2d (%2d) %08llx %p\t", + seq_printf(m, "%08x: %c %2d (%2d) %08llx %p", msm_obj->flags, is_active(msm_obj) ? 'A' : 'I', obj->name, kref_read(&obj->refcount), off, msm_obj->vaddr); - /* FIXME: we need to print the address space here too */ - list_for_each_entry(vma, &msm_obj->vmas, list) - seq_printf(m, " %08llx", vma->iova); + seq_printf(m, " %08zu%9s\n", obj->size, madv); - seq_printf(m, " %zu%s\n", obj->size, madv); + if (!list_empty(&msm_obj->vmas)) { + + seq_puts(m, " vmas:"); + + list_for_each_entry(vma, &msm_obj->vmas, list) + seq_printf(m, " [%s: %08llx,%s]", vma->aspace->name, + vma->iova, vma->mapped ? "mapped" : "unmapped"); + + seq_puts(m, "\n"); + } rcu_read_lock(); fobj = rcu_dereference(robj->fence); @@ -799,9 +806,10 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m) int count = 0; size_t size = 0; + seq_puts(m, " flags id ref offset kaddr size madv\n"); list_for_each_entry(msm_obj, list, mm_list) { struct drm_gem_object *obj = &msm_obj->base; - seq_printf(m, " "); + seq_puts(m, " "); msm_gem_describe(obj, m); count++; size += obj->size; From 9fe041f6fdfedd92e15dd81d96475ff04bdf879e Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:50 -0700 Subject: [PATCH 29/91] drm/msm: Add msm_gem_get_and_pin_iova() Add a new function to get and pin the iova memory in one step (basically renaming the old msm_gem_get_iova function) and switch msm_gem_get_iova() to only allocate an iova but not map it in the IOMMU. This is only currently used by msm_ioctl_gem_info() since all other users of of the iova expect that the memory be immediately available. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 ++- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 4 ++-- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 2 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- drivers/gpu/drm/msm/msm_drv.c | 4 ++++ drivers/gpu/drm/msm/msm_drv.h | 2 ++ drivers/gpu/drm/msm/msm_fb.c | 2 +- drivers/gpu/drm/msm/msm_fbdev.c | 2 +- drivers/gpu/drm/msm/msm_gem.c | 24 ++++++++++++++++++----- drivers/gpu/drm/msm/msm_gem_submit.c | 2 +- drivers/gpu/drm/msm/msm_gpu.c | 2 +- 12 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 789f7afe1851..7ab2788e33b6 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -209,7 +209,8 @@ int adreno_hw_init(struct msm_gpu *gpu) if (!ring) continue; - ret = msm_gem_get_iova(ring->bo, gpu->aspace, &ring->iova); + ret = msm_gem_get_and_pin_iova(ring->bo, gpu->aspace, + &ring->iova); if (ret) { ring->iova = 0; DRM_DEV_ERROR(gpu->dev->dev, diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c index b91706cee2b8..ef6884f1fc34 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -384,7 +384,7 @@ static void update_cursor(struct drm_crtc *crtc) if (next_bo) { /* take a obj ref + iova ref when we start scanning out: */ drm_gem_object_get(next_bo); - msm_gem_get_iova(next_bo, kms->aspace, &iova); + msm_gem_get_and_pin_iova(next_bo, kms->aspace, &iova); /* enable cursor: */ mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma), @@ -442,7 +442,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, } if (cursor_bo) { - ret = msm_gem_get_iova(cursor_bo, kms->aspace, &iova); + ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, &iova); if (ret) goto fail; } else { diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 481c0d231149..9fd6b9b2dbcb 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -538,7 +538,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) goto fail; } - ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, kms->aspace, + ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->aspace, &mdp4_kms->blank_cursor_iova); if (ret) { DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 413b52211017..c7cc276575fb 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -903,7 +903,7 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, if (!cursor_bo) return -ENOENT; - ret = msm_gem_get_iova(cursor_bo, kms->aspace, + ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, &mdp5_crtc->cursor.iova); if (ret) return -EINVAL; diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index eba901584035..99122767abf4 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1248,7 +1248,7 @@ int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *dma_base) if (!dma_base) return -EINVAL; - return msm_gem_get_iova(msm_host->tx_gem_obj, + return msm_gem_get_and_pin_iova(msm_host->tx_gem_obj, priv->kms->aspace, dma_base); } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index cf960dc78982..3f8ed21dfffb 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -868,6 +868,10 @@ static int msm_ioctl_gem_info_iova(struct drm_device *dev, if (!priv->gpu) return -EINVAL; + /* + * Don't pin the memory here - just get an address so that userspace can + * be productive + */ return msm_gem_get_iova(obj, priv->gpu->aspace, iova); } diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 63b28b69b2ab..4372505a0bda 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -271,6 +271,8 @@ vm_fault_t msm_gem_fault(struct vm_fault *vmf); uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj); int msm_gem_get_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace, uint64_t *iova); +int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint64_t *iova); uint64_t msm_gem_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace); struct page **msm_gem_get_pages(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 475191fcf412..4e1e435db5a6 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -66,7 +66,7 @@ int msm_framebuffer_prepare(struct drm_framebuffer *fb, uint64_t iova; for (i = 0; i < n; i++) { - ret = msm_gem_get_iova(fb->obj[i], aspace, &iova); + ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &iova); DBG("FB[%u]: iova[%d]: %08llx (%d)", fb->base.id, i, iova, ret); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index f94cbbbf3834..c03e860ba737 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -104,7 +104,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, * in panic (ie. lock-safe, etc) we could avoid pinning the * buffer now: */ - ret = msm_gem_get_iova(bo, priv->kms->aspace, &paddr); + ret = msm_gem_get_and_pin_iova(bo, priv->kms->aspace, &paddr); if (ret) { DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret); goto fail_unlock; diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index f24c9fe37aaa..75a1f50f8f57 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -408,9 +408,8 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj, obj->size >> PAGE_SHIFT); } - -/* get iova, taking a reference. Should have a matching put */ -int msm_gem_get_iova(struct drm_gem_object *obj, +/* get iova and pin it. Should have a matching put */ +int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace, uint64_t *iova) { struct msm_gem_object *msm_obj = to_msm_bo(obj); @@ -431,8 +430,23 @@ int msm_gem_get_iova(struct drm_gem_object *obj, return ret; } +/* Get an iova but don't pin the memory behind it */ +int msm_gem_get_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint64_t *iova) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + int ret; + + mutex_lock(&msm_obj->lock); + ret = msm_gem_get_iova_locked(obj, aspace, iova); + mutex_unlock(&msm_obj->lock); + + return ret; +} + + /* get iova without taking a reference, used in places where you have - * already done a 'msm_gem_get_iova()'. + * already done a 'msm_gem_get_and_pin_iova' or 'msm_gem_get_iova' */ uint64_t msm_gem_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace) @@ -1072,7 +1086,7 @@ static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size, return ERR_CAST(obj); if (iova) { - ret = msm_gem_get_iova(obj, aspace, iova); + ret = msm_gem_get_and_pin_iova(obj, aspace, iova); if (ret) goto err; } diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index e31be7417f94..1322179386f6 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -270,7 +270,7 @@ static int submit_pin_objects(struct msm_gem_submit *submit) uint64_t iova; /* if locking succeeded, pin bo: */ - ret = msm_gem_get_iova(&msm_obj->base, + ret = msm_gem_get_and_pin_iova(&msm_obj->base, submit->gpu->aspace, &iova); if (ret) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 3e2b3568d932..fcfff333ed96 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -773,7 +773,7 @@ void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, /* submit takes a reference to the bo and iova until retired: */ drm_gem_object_get(&msm_obj->base); - msm_gem_get_iova(&msm_obj->base, + msm_gem_get_and_pin_iova(&msm_obj->base, submit->gpu->aspace, &iova); if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE) From 7ad0e8cf6317825d2b7fc52a9000fb16461c2857 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:51 -0700 Subject: [PATCH 30/91] drm/msm: Count how many times iova memory is pinned Add a reference count to track how many times a particular chunk of iova memory is pinned (mapped) in the iomu and add msm_gem_unpin_iova to give up references. It is important to note that msm_gem_unpin_iova replaces msm_gem_put_iova because the new implicit behavior that an assigned iova in a given vma is now valid for the life of the buffer and what we are really focusing on is the use of that iova. For now the unmappings are lazy; once the reference counts go to zero they *COULD* be unmapped dynamically but that will require an outside force such as a shrinker or mm_notifiers. For now, we're just focusing on getting the counting right and setting ourselves up to be ready for the future. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_debugfs.c | 6 +-- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 9 ++-- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 +- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 2 +- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 2 +- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 2 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- drivers/gpu/drm/msm/msm_drv.h | 8 +++- drivers/gpu/drm/msm/msm_fb.c | 2 +- drivers/gpu/drm/msm/msm_gem.c | 43 +++++++++++------ drivers/gpu/drm/msm/msm_gem.h | 1 + drivers/gpu/drm/msm/msm_gem_submit.c | 2 +- drivers/gpu/drm/msm/msm_gem_vma.c | 51 ++++++++++++++++----- drivers/gpu/drm/msm/msm_gpu.c | 2 +- 15 files changed, 88 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c index 6983cd9102bd..d9af3aff690f 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c @@ -130,15 +130,13 @@ reset_set(void *data, u64 val) adreno_gpu->fw[ADRENO_FW_PFP] = NULL; if (a5xx_gpu->pm4_bo) { - if (a5xx_gpu->pm4_iova) - msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace); + msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace); drm_gem_object_put(a5xx_gpu->pm4_bo); a5xx_gpu->pm4_bo = NULL; } if (a5xx_gpu->pfp_bo) { - if (a5xx_gpu->pfp_iova) - msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace); + msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace); drm_gem_object_put(a5xx_gpu->pfp_bo); a5xx_gpu->pfp_bo = NULL; } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 0d3f61abbf37..c514590ef593 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -840,20 +840,17 @@ static void a5xx_destroy(struct msm_gpu *gpu) a5xx_preempt_fini(gpu); if (a5xx_gpu->pm4_bo) { - if (a5xx_gpu->pm4_iova) - msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->aspace); + msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace); drm_gem_object_put_unlocked(a5xx_gpu->pm4_bo); } if (a5xx_gpu->pfp_bo) { - if (a5xx_gpu->pfp_iova) - msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->aspace); + msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace); drm_gem_object_put_unlocked(a5xx_gpu->pfp_bo); } if (a5xx_gpu->gpmu_bo) { - if (a5xx_gpu->gpmu_iova) - msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->aspace); + msm_gem_unpin_iova(a5xx_gpu->gpmu_bo, gpu->aspace); drm_gem_object_put_unlocked(a5xx_gpu->gpmu_bo); } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 11f0b99f94c8..34d6087e5209 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -736,8 +736,7 @@ static void a6xx_destroy(struct msm_gpu *gpu) struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); if (a6xx_gpu->sqe_bo) { - if (a6xx_gpu->sqe_iova) - msm_gem_put_iova(a6xx_gpu->sqe_bo, gpu->aspace); + msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace); drm_gem_object_put_unlocked(a6xx_gpu->sqe_bo); } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index ec57ddeb8c77..df6308e7ea67 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -152,7 +152,7 @@ static int a6xx_crashdumper_run(struct msm_gpu *gpu, static void a6xx_crashdumper_free(struct msm_gpu *gpu, struct a6xx_crashdumper *dumper) { - msm_gem_put_iova(dumper->bo, gpu->aspace); + msm_gem_unpin_iova(dumper->bo, gpu->aspace); msm_gem_put_vaddr(dumper->bo); drm_gem_object_unreference(dumper->bo); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c index ef6884f1fc34..8f2359dc87b4 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -128,7 +128,7 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base); struct msm_kms *kms = &mdp4_kms->base.base; - msm_gem_put_iova(val, kms->aspace); + msm_gem_unpin_iova(val, kms->aspace); drm_gem_object_put_unlocked(val); } diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 9fd6b9b2dbcb..934a49818ea4 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -165,7 +165,7 @@ static void mdp4_destroy(struct msm_kms *kms) struct msm_gem_address_space *aspace = kms->aspace; if (mdp4_kms->blank_cursor_iova) - msm_gem_put_iova(mdp4_kms->blank_cursor_bo, kms->aspace); + msm_gem_unpin_iova(mdp4_kms->blank_cursor_bo, kms->aspace); drm_gem_object_put_unlocked(mdp4_kms->blank_cursor_bo); if (aspace) { diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index c7cc276575fb..c5fde1a4191a 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -173,7 +173,7 @@ static void unref_cursor_worker(struct drm_flip_work *work, void *val) struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base); struct msm_kms *kms = &mdp5_kms->base.base; - msm_gem_put_iova(val, kms->aspace); + msm_gem_unpin_iova(val, kms->aspace); drm_gem_object_put_unlocked(val); } diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 99122767abf4..3b7092e1dcc7 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1118,7 +1118,7 @@ static void dsi_tx_buf_free(struct msm_dsi_host *msm_host) priv = dev->dev_private; if (msm_host->tx_gem_obj) { - msm_gem_put_iova(msm_host->tx_gem_obj, priv->kms->aspace); + msm_gem_unpin_iova(msm_host->tx_gem_obj, priv->kms->aspace); drm_gem_object_put_unlocked(msm_host->tx_gem_obj); msm_host->tx_gem_obj = NULL; } diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 4372505a0bda..955c2f522db6 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -243,10 +243,14 @@ void msm_atomic_state_free(struct drm_atomic_state *state); int msm_gem_init_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, int npages); +void msm_gem_purge_vma(struct msm_gem_address_space *aspace, + struct msm_gem_vma *vma); void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma); int msm_gem_map_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, struct sg_table *sgt, int npages); +void msm_gem_close_vma(struct msm_gem_address_space *aspace, + struct msm_gem_vma *vma); void msm_gem_address_space_put(struct msm_gem_address_space *aspace); @@ -275,10 +279,10 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace, uint64_t *iova); uint64_t msm_gem_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace); +void msm_gem_unpin_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace); struct page **msm_gem_get_pages(struct drm_gem_object *obj); void msm_gem_put_pages(struct drm_gem_object *obj); -void msm_gem_put_iova(struct drm_gem_object *obj, - struct msm_gem_address_space *aspace); int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 4e1e435db5a6..1224739094f2 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -81,7 +81,7 @@ void msm_framebuffer_cleanup(struct drm_framebuffer *fb, int i, n = fb->format->num_planes; for (i = 0; i < n; i++) - msm_gem_put_iova(fb->obj[i], aspace); + msm_gem_unpin_iova(fb->obj[i], aspace); } uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 75a1f50f8f57..3d46d931ba67 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -352,7 +352,8 @@ put_iova(struct drm_gem_object *obj) WARN_ON(!mutex_is_locked(&msm_obj->lock)); list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) { - msm_gem_unmap_vma(vma->aspace, vma); + msm_gem_purge_vma(vma->aspace, vma); + msm_gem_close_vma(vma->aspace, vma); del_vma(vma); } } @@ -430,7 +431,10 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, return ret; } -/* Get an iova but don't pin the memory behind it */ +/* + * Get an iova but don't pin it. Doesn't need a put because iovas are currently + * valid for the life of the object + */ int msm_gem_get_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace, uint64_t *iova) { @@ -444,7 +448,6 @@ int msm_gem_get_iova(struct drm_gem_object *obj, return ret; } - /* get iova without taking a reference, used in places where you have * already done a 'msm_gem_get_and_pin_iova' or 'msm_gem_get_iova' */ @@ -462,15 +465,24 @@ uint64_t msm_gem_iova(struct drm_gem_object *obj, return vma ? vma->iova : 0; } -void msm_gem_put_iova(struct drm_gem_object *obj, +/* + * Unpin a iova by updating the reference counts. The memory isn't actually + * purged until something else (shrinker, mm_notifier, destroy, etc) decides + * to get rid of it + */ +void msm_gem_unpin_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace) { - // XXX TODO .. - // NOTE: probably don't need a _locked() version.. we wouldn't - // normally unmap here, but instead just mark that it could be - // unmapped (if the iova refcnt drops to zero), but then later - // if another _get_iova_locked() fails we can start unmapping - // things that are no longer needed.. + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *vma; + + mutex_lock(&msm_obj->lock); + vma = lookup_vma(obj, aspace); + + if (!WARN_ON(!vma)) + msm_gem_unmap_vma(aspace, vma); + + mutex_unlock(&msm_obj->lock); } int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, @@ -786,11 +798,12 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) if (!list_empty(&msm_obj->vmas)) { - seq_puts(m, " vmas:"); + seq_puts(m, " vmas:"); list_for_each_entry(vma, &msm_obj->vmas, list) - seq_printf(m, " [%s: %08llx,%s]", vma->aspace->name, - vma->iova, vma->mapped ? "mapped" : "unmapped"); + seq_printf(m, " [%s: %08llx,%s,inuse=%d]", vma->aspace->name, + vma->iova, vma->mapped ? "mapped" : "unmapped", + vma->inuse); seq_puts(m, "\n"); } @@ -1093,7 +1106,7 @@ static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size, vaddr = msm_gem_get_vaddr(obj); if (IS_ERR(vaddr)) { - msm_gem_put_iova(obj, aspace); + msm_gem_unpin_iova(obj, aspace); ret = PTR_ERR(vaddr); goto err; } @@ -1133,7 +1146,7 @@ void msm_gem_kernel_put(struct drm_gem_object *bo, return; msm_gem_put_vaddr(bo); - msm_gem_put_iova(bo, aspace); + msm_gem_unpin_iova(bo, aspace); if (locked) drm_gem_object_put(bo); diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index a44847364504..b318fe278e52 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -42,6 +42,7 @@ struct msm_gem_vma { struct msm_gem_address_space *aspace; struct list_head list; /* node in msm_gem_object::vmas */ bool mapped; + int inuse; }; struct msm_gem_object { diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 1322179386f6..a43e91e70bd9 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -167,7 +167,7 @@ static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, struct msm_gem_object *msm_obj = submit->bos[i].obj; if (submit->bos[i].flags & BO_PINNED) - msm_gem_put_iova(&msm_obj->base, submit->gpu->aspace); + msm_gem_unpin_iova(&msm_obj->base, submit->gpu->aspace); if (submit->bos[i].flags & BO_LOCKED) ww_mutex_unlock(&msm_obj->resv->lock); diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index c4c42bf0db0e..ee46d8321b05 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -38,26 +38,32 @@ void msm_gem_address_space_put(struct msm_gem_address_space *aspace) kref_put(&aspace->kref, msm_gem_address_space_destroy); } -void -msm_gem_unmap_vma(struct msm_gem_address_space *aspace, +/* Actually unmap memory for the vma */ +void msm_gem_purge_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma) { - if (!aspace || !vma->iova) + unsigned size = vma->node.size << PAGE_SHIFT; + + /* Print a message if we try to purge a vma in use */ + if (WARN_ON(vma->inuse > 0)) return; - if (aspace->mmu) { - unsigned size = vma->node.size << PAGE_SHIFT; + /* Don't do anything if the memory isn't mapped */ + if (!vma->mapped) + return; + + if (aspace->mmu) aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, size); - } - spin_lock(&aspace->lock); - drm_mm_remove_node(&vma->node); - spin_unlock(&aspace->lock); - - vma->iova = 0; vma->mapped = false; +} - msm_gem_address_space_put(aspace); +/* Remove reference counts for the mapping */ +void msm_gem_unmap_vma(struct msm_gem_address_space *aspace, + struct msm_gem_vma *vma) +{ + if (!WARN_ON(!vma->iova)) + vma->inuse--; } int @@ -70,6 +76,9 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, if (WARN_ON(!vma->iova)) return -EINVAL; + /* Increase the usage counter */ + vma->inuse++; + if (vma->mapped) return 0; @@ -85,6 +94,23 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, return ret; } +/* Close an iova. Warn if it is still in use */ +void msm_gem_close_vma(struct msm_gem_address_space *aspace, + struct msm_gem_vma *vma) +{ + if (WARN_ON(vma->inuse > 0 || vma->mapped)) + return; + + spin_lock(&aspace->lock); + if (vma->iova) + drm_mm_remove_node(&vma->node); + spin_unlock(&aspace->lock); + + vma->iova = 0; + + msm_gem_address_space_put(aspace); +} + /* Initialize a new vma and allocate an iova for it */ int msm_gem_init_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, int npages) @@ -109,6 +135,7 @@ int msm_gem_init_vma(struct msm_gem_address_space *aspace, return 0; } + struct msm_gem_address_space * msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, const char *name) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index fcfff333ed96..86bb1ed8ddbb 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -689,7 +689,7 @@ static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring, struct msm_gem_object *msm_obj = submit->bos[i].obj; /* move to inactive: */ msm_gem_move_to_inactive(&msm_obj->base); - msm_gem_put_iova(&msm_obj->base, gpu->aspace); + msm_gem_unpin_iova(&msm_obj->base, gpu->aspace); drm_gem_object_put(&msm_obj->base); } From 0815d7749a68527adabe2ac40d49f6fc0800eae5 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:52 -0700 Subject: [PATCH 31/91] drm/msm: Add a name field for gem objects For debugging purposes it is useful to assign descriptions to buffers so that we know what they are used for. Add a field to the buffer object and use that to name the various kernel side allocations which ends up looking like like this in /d/dri/X/gem: flags id ref offset kaddr size madv name 00040000: I 0 ( 1) 00000000 0000000070b79eca 00004096 memptrs vmas: [gpu: 01000000,mapped,inuse=1] 00020000: I 0 ( 1) 00000000 0000000031ed4074 00032768 ring0 Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 8 ++++++++ drivers/gpu/drm/msm/adreno/a5xx_power.c | 2 ++ drivers/gpu/drm/msm/adreno/a5xx_preempt.c | 2 ++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 ++ drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++ drivers/gpu/drm/msm/msm_drv.c | 2 +- drivers/gpu/drm/msm/msm_drv.h | 4 +++- drivers/gpu/drm/msm/msm_fb.c | 2 ++ drivers/gpu/drm/msm/msm_gem.c | 25 +++++++++++++++++++---- drivers/gpu/drm/msm/msm_gem.h | 2 ++ drivers/gpu/drm/msm/msm_gpu.c | 2 ++ drivers/gpu/drm/msm/msm_ringbuffer.c | 3 +++ 12 files changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index c514590ef593..d5f5e56422f5 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -510,6 +510,7 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) a5xx_gpu->pm4_bo = adreno_fw_create_bo(gpu, adreno_gpu->fw[ADRENO_FW_PM4], &a5xx_gpu->pm4_iova); + if (IS_ERR(a5xx_gpu->pm4_bo)) { ret = PTR_ERR(a5xx_gpu->pm4_bo); a5xx_gpu->pm4_bo = NULL; @@ -517,6 +518,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) ret); return ret; } + + msm_gem_object_set_name(a5xx_gpu->pm4_bo, "pm4fw"); } if (!a5xx_gpu->pfp_bo) { @@ -530,6 +533,8 @@ static int a5xx_ucode_init(struct msm_gpu *gpu) ret); return ret; } + + msm_gem_object_set_name(a5xx_gpu->pfp_bo, "pfpfw"); } gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO, @@ -1214,6 +1219,9 @@ static int a5xx_crashdumper_init(struct msm_gpu *gpu, SZ_1M, MSM_BO_UNCACHED, gpu->aspace, &dumper->bo, &dumper->iova); + if (!IS_ERR(dumper->ptr)) + msm_gem_object_set_name(dumper->bo, "crashdump"); + return PTR_ERR_OR_ZERO(dumper->ptr); } diff --git a/drivers/gpu/drm/msm/adreno/a5xx_power.c b/drivers/gpu/drm/msm/adreno/a5xx_power.c index 66bcd88dd8c0..70e65c94e525 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -300,6 +300,8 @@ void a5xx_gpmu_ucode_init(struct msm_gpu *gpu) if (IS_ERR(ptr)) return; + msm_gem_object_set_name(a5xx_gpu->gpmu_bo, "gpmufw"); + while (cmds_size > 0) { int i; uint32_t _size = cmds_size > TYPE4_MAX_PAYLOAD ? diff --git a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c index 48481e663685..3d62310a535f 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -245,6 +245,8 @@ static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu, if (IS_ERR(ptr)) return PTR_ERR(ptr); + msm_gem_object_set_name(bo, "preempt"); + a5xx_gpu->preempt_bo[ring->id] = bo; a5xx_gpu->preempt_iova[ring->id] = iova; a5xx_gpu->preempt[ring->id] = ptr; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 34d6087e5209..fefe773c989e 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -333,6 +333,8 @@ static int a6xx_ucode_init(struct msm_gpu *gpu) return ret; } + + msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw"); } gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE_LO, diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 3b7092e1dcc7..38e481d2d606 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1083,6 +1083,8 @@ int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size) return PTR_ERR(data); } + msm_gem_object_set_name(msm_host->tx_gem_obj, "tx_gem"); + msm_host->tx_size = msm_host->tx_gem_obj->size; return 0; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 3f8ed21dfffb..a73187274b62 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -810,7 +810,7 @@ static int msm_ioctl_gem_new(struct drm_device *dev, void *data, } return msm_gem_new_handle(dev, file, args->size, - args->flags, &args->handle); + args->flags, &args->handle, NULL); } static inline ktime_t to_ktime(struct drm_msm_timespec timeout) diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 955c2f522db6..71a03ce21da5 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -309,7 +309,7 @@ int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout); int msm_gem_cpu_fini(struct drm_gem_object *obj); void msm_gem_free_object(struct drm_gem_object *obj); int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, - uint32_t size, uint32_t flags, uint32_t *handle); + uint32_t size, uint32_t flags, uint32_t *handle, char *name); struct drm_gem_object *msm_gem_new(struct drm_device *dev, uint32_t size, uint32_t flags); struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev, @@ -325,6 +325,8 @@ void msm_gem_kernel_put(struct drm_gem_object *bo, struct drm_gem_object *msm_gem_import(struct drm_device *dev, struct dma_buf *dmabuf, struct sg_table *sgt); +void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...); + int msm_framebuffer_prepare(struct drm_framebuffer *fb, struct msm_gem_address_space *aspace); void msm_framebuffer_cleanup(struct drm_framebuffer *fb, diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 1224739094f2..67dfd8d3dc12 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -237,6 +237,8 @@ msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format return ERR_CAST(bo); } + msm_gem_object_set_name(bo, "stolenfb"); + fb = msm_framebuffer_init(dev, &mode_cmd, &bo); if (IS_ERR(fb)) { DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n"); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 3d46d931ba67..ee44b0f01e90 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -491,7 +491,7 @@ int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, args->pitch = align_pitch(args->width, args->bpp); args->size = PAGE_ALIGN(args->pitch * args->height); return msm_gem_new_handle(dev, file, args->size, - MSM_BO_SCANOUT | MSM_BO_WC, &args->handle); + MSM_BO_SCANOUT | MSM_BO_WC, &args->handle, "dumb"); } int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, @@ -794,7 +794,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m) obj->name, kref_read(&obj->refcount), off, msm_obj->vaddr); - seq_printf(m, " %08zu%9s\n", obj->size, madv); + seq_printf(m, " %08zu %9s %-32s\n", obj->size, madv, msm_obj->name); if (!list_empty(&msm_obj->vmas)) { @@ -833,7 +833,7 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m) int count = 0; size_t size = 0; - seq_puts(m, " flags id ref offset kaddr size madv\n"); + seq_puts(m, " flags id ref offset kaddr size madv name\n"); list_for_each_entry(msm_obj, list, mm_list) { struct drm_gem_object *obj = &msm_obj->base; seq_puts(m, " "); @@ -890,7 +890,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) /* convenience method to construct a GEM buffer object, and userspace handle */ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, - uint32_t size, uint32_t flags, uint32_t *handle) + uint32_t size, uint32_t flags, uint32_t *handle, + char *name) { struct drm_gem_object *obj; int ret; @@ -900,6 +901,9 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, if (IS_ERR(obj)) return PTR_ERR(obj); + if (name) + msm_gem_object_set_name(obj, "%s", name); + ret = drm_gem_handle_create(file, obj, handle); /* drop reference from allocate - handle holds it now */ @@ -1153,3 +1157,16 @@ void msm_gem_kernel_put(struct drm_gem_object *bo, else drm_gem_object_put_unlocked(bo); } + +void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...) +{ + struct msm_gem_object *msm_obj = to_msm_bo(bo); + va_list ap; + + if (!fmt) + return; + + va_start(ap, fmt); + vsnprintf(msm_obj->name, sizeof(msm_obj->name), fmt, ap); + va_end(ap); +} diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index b318fe278e52..2064fac871b8 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -93,6 +93,8 @@ struct msm_gem_object { */ struct drm_mm_node *vram_node; struct mutex lock; /* Protects resources associated with bo */ + + char name[32]; /* Identifier to print for the debugfs files */ }; #define to_msm_bo(x) container_of(x, struct msm_gem_object, base) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 86bb1ed8ddbb..c3909ba75b12 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -950,6 +950,8 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev, goto fail; } + msm_gem_object_set_name(gpu->memptrs_bo, "memptrs"); + if (nr_rings > ARRAY_SIZE(gpu->rb)) { DRM_DEV_INFO_ONCE(drm->dev, "Only creating %zu ringbuffers\n", ARRAY_SIZE(gpu->rb)); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 9fa9525c5293..6169bd6ca153 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -45,6 +45,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, ring->start = 0; goto fail; } + + msm_gem_object_set_name(ring->bo, "ring%d", id); + ring->end = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2); ring->next = ring->start; ring->cur = ring->start; From 84c6127580c1cee58d57d5f97ce22f1131ecdfc9 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 7 Nov 2018 15:35:54 -0700 Subject: [PATCH 32/91] drm/msm/gpu: Map the ringbuffer in the iova at create time For reasons that I'm sure made perfect sense at the time we were opting to defer the iova alloc / pin on the ringbuffer until HW init time so when we moved to iova reference counting we ended up adding a reference count every time the hardware started. Not that it mattered (because the ring is always around) but it did make the debug output look odd. Allocate and pin the iova at create time instead. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 9 --------- drivers/gpu/drm/msm/msm_ringbuffer.c | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 7ab2788e33b6..20c86e2369f3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -209,15 +209,6 @@ int adreno_hw_init(struct msm_gpu *gpu) if (!ring) continue; - ret = msm_gem_get_and_pin_iova(ring->bo, gpu->aspace, - &ring->iova); - if (ret) { - ring->iova = 0; - DRM_DEV_ERROR(gpu->dev->dev, - "could not map ringbuffer %d: %d\n", i, ret); - return ret; - } - ring->cur = ring->start; ring->next = ring->start; diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index 6169bd6ca153..20a96fe69dcd 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -36,9 +36,9 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, ring->gpu = gpu; ring->id = id; - /* Pass NULL for the iova pointer - we will map it later */ + ring->start = msm_gem_kernel_new(gpu->dev, MSM_GPU_RINGBUFFER_SZ, - MSM_BO_WC, gpu->aspace, &ring->bo, NULL); + MSM_BO_WC, gpu->aspace, &ring->bo, &ring->iova); if (IS_ERR(ring->start)) { ret = PTR_ERR(ring->start); From 1df4289d5b23178a8a2c38ca766feb3d9c40d9fb Mon Sep 17 00:00:00 2001 From: Sharat Masetty Date: Thu, 1 Nov 2018 20:16:45 +0530 Subject: [PATCH 33/91] drm/msm: Optimize adreno_show_object() When the userspace tries to read the crashstate dump, the read side implementation in the driver currently ascii85 encodes all the binary buffers and it does this each time the read system call is called. A userspace tool like cat typically does a page by page read and the number of read calls depends on the size of the data captured by the driver. This is certainly not desirable and does not scale well with large captures. This patch encodes the buffer only once in the read path. With this there is an immediate >10X speed improvement in crashstate save time. Signed-off-by: Sharat Masetty Reviewed-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 82 ++++++++++++++++++------- drivers/gpu/drm/msm/msm_gpu.h | 2 + 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 20c86e2369f3..bbd7350a7f39 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -398,7 +398,7 @@ int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state) size = j + 1; if (size) { - state->ring[i].data = kmalloc(size << 2, GFP_KERNEL); + state->ring[i].data = kvmalloc(size << 2, GFP_KERNEL); if (state->ring[i].data) { memcpy(state->ring[i].data, gpu->rb[i]->start, size << 2); state->ring[i].data_size = size << 2; @@ -441,7 +441,7 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state) int i; for (i = 0; i < ARRAY_SIZE(state->ring); i++) - kfree(state->ring[i].data); + kvfree(state->ring[i].data); for (i = 0; state->bos && i < state->nr_bos; i++) kvfree(state->bos[i].data); @@ -471,34 +471,74 @@ int adreno_gpu_state_put(struct msm_gpu_state *state) #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) -static void adreno_show_object(struct drm_printer *p, u32 *ptr, int len) +static char *adreno_gpu_ascii85_encode(u32 *src, size_t len) { + void *buf; + size_t buf_itr = 0, buffer_size; char out[ASCII85_BUFSZ]; - long l, datalen, i; + long l; + int i; - if (!ptr || !len) - return; + if (!src || !len) + return NULL; + + l = ascii85_encode_len(len); /* - * Only dump the non-zero part of the buffer - rarely will any data - * completely fill the entire allocated size of the buffer + * Ascii85 outputs either a 5 byte string or a 1 byte string. So we + * account for the worst case of 5 bytes per dword plus the 1 for '\0' */ - for (datalen = 0, i = 0; i < len >> 2; i++) { - if (ptr[i]) - datalen = (i << 2) + 1; - } + buffer_size = (l * 5) + 1; - /* Skip printing the object if it is empty */ - if (datalen == 0) + buf = kvmalloc(buffer_size, GFP_KERNEL); + if (!buf) + return NULL; + + for (i = 0; i < l; i++) + buf_itr += snprintf(buf + buf_itr, buffer_size - buf_itr, "%s", + ascii85_encode(src[i], out)); + + return buf; +} + +/* len is expected to be in bytes */ +static void adreno_show_object(struct drm_printer *p, void **ptr, int len, + bool *encoded) +{ + if (!*ptr || !len) return; - l = ascii85_encode_len(datalen); + if (!*encoded) { + long datalen, i; + u32 *buf = *ptr; + + /* + * Only dump the non-zero part of the buffer - rarely will + * any data completely fill the entire allocated size of + * the buffer. + */ + for (datalen = 0, i = 0; i < len >> 2; i++) + if (buf[i]) + datalen = ((i + 1) << 2); + + /* + * If we reach here, then the originally captured binary buffer + * will be replaced with the ascii85 encoded string + */ + *ptr = adreno_gpu_ascii85_encode(buf, datalen); + + kvfree(buf); + + *encoded = true; + } + + if (!*ptr) + return; drm_puts(p, " data: !!ascii85 |\n"); drm_puts(p, " "); - for (i = 0; i < l; i++) - drm_puts(p, ascii85_encode(ptr[i], out)); + drm_puts(p, *ptr); drm_puts(p, "\n"); } @@ -530,8 +570,8 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, drm_printf(p, " wptr: %d\n", state->ring[i].wptr); drm_printf(p, " size: %d\n", MSM_GPU_RINGBUFFER_SZ); - adreno_show_object(p, state->ring[i].data, - state->ring[i].data_size); + adreno_show_object(p, &state->ring[i].data, + state->ring[i].data_size, &state->ring[i].encoded); } if (state->bos) { @@ -542,8 +582,8 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state, state->bos[i].iova); drm_printf(p, " size: %zd\n", state->bos[i].size); - adreno_show_object(p, state->bos[i].data, - state->bos[i].size); + adreno_show_object(p, &state->bos[i].data, + state->bos[i].size, &state->bos[i].encoded); } } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index f82bac086666..efb49bb64191 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -187,6 +187,7 @@ struct msm_gpu_state_bo { u64 iova; size_t size; void *data; + bool encoded; }; struct msm_gpu_state { @@ -201,6 +202,7 @@ struct msm_gpu_state { u32 wptr; void *data; int data_size; + bool encoded; } ring[MSM_GPU_MAX_RINGS]; int nr_registers; From 7a93d5c38e5ee68376ca88d9e3f9841451b9efb1 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 23 Oct 2018 14:42:37 -0400 Subject: [PATCH 34/91] drm/msm/gpu: add submit flag to hint which buffers should be dumped To lower CPU overhead, future userspace will be switching to pinning iova and avoiding the use of relocs, and only include cmds table entries for IB1 level cmdstream (but not IB2 or state-groups). This leaves the kernel unsure what to dump for rd/hangrd cmdstream dumping. So add a MSM_SUBMIT_BO_DUMP flag so userspace can indicate buffers that contain cmdstream (or are otherwise important to dump). Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem_submit.c | 5 ++++- drivers/gpu/drm/msm/msm_rd.c | 13 ++++++++++--- include/uapi/drm/msm_drm.h | 5 ++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index a43e91e70bd9..3cbed4acb0f4 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -114,8 +114,11 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, pagefault_disable(); } +/* at least one of READ and/or WRITE flags should be set: */ +#define MANDATORY_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE) + if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) || - !(submit_bo.flags & MSM_SUBMIT_BO_FLAGS)) { + !(submit_bo.flags & MANDATORY_FLAGS)) { DRM_ERROR("invalid flags: %x\n", submit_bo.flags); ret = -EINVAL; goto out_unlock; diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index cca933458439..b5672061ae08 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -345,6 +345,12 @@ static void snapshot_buf(struct msm_rd_state *rd, msm_gem_put_vaddr(&obj->base); } +static bool +should_dump(struct msm_gem_submit *submit, int idx) +{ + return rd_full || (submit->bos[idx].flags & MSM_SUBMIT_BO_DUMP); +} + /* called under struct_mutex */ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, const char *fmt, ...) @@ -386,15 +392,16 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4)); - for (i = 0; rd_full && i < submit->nr_bos; i++) - snapshot_buf(rd, submit, i, 0, 0); + for (i = 0; i < submit->nr_bos; i++) + if (should_dump(submit, i)) + snapshot_buf(rd, submit, i, 0, 0); for (i = 0; i < submit->nr_cmds; i++) { uint64_t iova = submit->cmd[i].iova; uint32_t szd = submit->cmd[i].size; /* in dwords */ /* snapshot cmdstream bo's (if we haven't already): */ - if (!rd_full) { + if (!should_dump(submit, i)) { snapshot_buf(rd, submit, submit->cmd[i].idx, submit->cmd[i].iova, szd * 4); } diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index c06d0a5bdd80..3c3af92c4b3e 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -188,8 +188,11 @@ struct drm_msm_gem_submit_cmd { */ #define MSM_SUBMIT_BO_READ 0x0001 #define MSM_SUBMIT_BO_WRITE 0x0002 +#define MSM_SUBMIT_BO_DUMP 0x0004 -#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE) +#define MSM_SUBMIT_BO_FLAGS (MSM_SUBMIT_BO_READ | \ + MSM_SUBMIT_BO_WRITE | \ + MSM_SUBMIT_BO_DUMP) struct drm_msm_gem_submit_bo { __u32 flags; /* in, mask of MSM_SUBMIT_BO_x */ From 789d2e5a772ce312a7a2b81ffaf304946195beb5 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 29 Nov 2018 09:54:42 -0500 Subject: [PATCH 35/91] drm/msm: rework GEM_INFO ioctl Prep work to add a way to get/set the GEM objects debug name. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 28 +++++++++++++++++++--------- include/uapi/drm/msm_drm.h | 18 +++++++++++++----- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index a73187274b62..fe86c675d5b7 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -882,21 +882,31 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, struct drm_gem_object *obj; int ret = 0; - if (args->flags & ~MSM_INFO_FLAGS) + if (args->pad) return -EINVAL; + switch (args->info) { + case MSM_INFO_GET_OFFSET: + case MSM_INFO_GET_IOVA: + /* value returned as immediate, not pointer, so len==0: */ + if (args->len) + return -EINVAL; + break; + default: + return -EINVAL; + } + obj = drm_gem_object_lookup(file, args->handle); if (!obj) return -ENOENT; - if (args->flags & MSM_INFO_IOVA) { - uint64_t iova; - - ret = msm_ioctl_gem_info_iova(dev, obj, &iova); - if (!ret) - args->offset = iova; - } else { - args->offset = msm_gem_mmap_offset(obj); + switch (args->info) { + case MSM_INFO_GET_OFFSET: + args->value = msm_gem_mmap_offset(obj); + break; + case MSM_INFO_GET_IOVA: + ret = msm_ioctl_gem_info_iova(dev, obj, &args->value); + break; } drm_gem_object_put_unlocked(obj); diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 3c3af92c4b3e..7b372c1bcc7d 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -105,14 +105,22 @@ struct drm_msm_gem_new { __u32 handle; /* out */ }; -#define MSM_INFO_IOVA 0x01 - -#define MSM_INFO_FLAGS (MSM_INFO_IOVA) +/* Get or set GEM buffer info. The requested value can be passed + * directly in 'value', or for data larger than 64b 'value' is a + * pointer to userspace buffer, with 'len' specifying the number of + * bytes copied into that buffer. For info returned by pointer, + * calling the GEM_INFO ioctl with null 'value' will return the + * required buffer size in 'len' + */ +#define MSM_INFO_GET_OFFSET 0x00 /* get mmap() offset, returned by value */ +#define MSM_INFO_GET_IOVA 0x01 /* get iova, returned by value */ struct drm_msm_gem_info { __u32 handle; /* in */ - __u32 flags; /* in - combination of MSM_INFO_* flags */ - __u64 offset; /* out, mmap() offset or iova */ + __u32 info; /* in - one of MSM_INFO_* */ + __u64 value; /* in or out */ + __u32 len; /* in or out */ + __u32 pad; }; #define MSM_PREP_READ 0x01 From f05c83e7746088e6ada6ce83fd7840b4b7b52ffe Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 29 Nov 2018 10:27:22 -0500 Subject: [PATCH 36/91] drm/msm: add uapi to get/set debug name Add UAPI to get/set GEM objects' debug name. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 36 ++++++++++++++++++++++++++++++++++- include/uapi/drm/msm_drm.h | 2 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index fe86c675d5b7..c08f83c7ca57 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -23,6 +23,7 @@ #include "msm_drv.h" #include "msm_debugfs.h" #include "msm_fence.h" +#include "msm_gem.h" #include "msm_gpu.h" #include "msm_kms.h" @@ -880,7 +881,8 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, { struct drm_msm_gem_info *args = data; struct drm_gem_object *obj; - int ret = 0; + struct msm_gem_object *msm_obj; + int i, ret = 0; if (args->pad) return -EINVAL; @@ -892,6 +894,9 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, if (args->len) return -EINVAL; break; + case MSM_INFO_SET_NAME: + case MSM_INFO_GET_NAME: + break; default: return -EINVAL; } @@ -900,6 +905,8 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, if (!obj) return -ENOENT; + msm_obj = to_msm_bo(obj); + switch (args->info) { case MSM_INFO_GET_OFFSET: args->value = msm_gem_mmap_offset(obj); @@ -907,6 +914,33 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, case MSM_INFO_GET_IOVA: ret = msm_ioctl_gem_info_iova(dev, obj, &args->value); break; + case MSM_INFO_SET_NAME: + /* length check should leave room for terminating null: */ + if (args->len >= sizeof(msm_obj->name)) { + ret = -EINVAL; + break; + } + ret = copy_from_user(msm_obj->name, + u64_to_user_ptr(args->value), args->len); + msm_obj->name[args->len] = '\0'; + for (i = 0; i < args->len; i++) { + if (!isprint(msm_obj->name[i])) { + msm_obj->name[i] = '\0'; + break; + } + } + break; + case MSM_INFO_GET_NAME: + if (args->value && (args->len < strlen(msm_obj->name))) { + ret = -EINVAL; + break; + } + args->len = strlen(msm_obj->name); + if (args->value) { + ret = copy_to_user(u64_to_user_ptr(args->value), + msm_obj->name, args->len); + } + break; } drm_gem_object_put_unlocked(obj); diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 7b372c1bcc7d..91a16b333c69 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -114,6 +114,8 @@ struct drm_msm_gem_new { */ #define MSM_INFO_GET_OFFSET 0x00 /* get mmap() offset, returned by value */ #define MSM_INFO_GET_IOVA 0x01 /* get iova, returned by value */ +#define MSM_INFO_SET_NAME 0x02 /* set the debug name (by pointer) */ +#define MSM_INFO_GET_NAME 0x03 /* get debug name, returned by pointer */ struct drm_msm_gem_info { __u32 handle; /* in */ From 1fed8df301336d904ba45b1bda0c7ce5bd7e6932 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 29 Nov 2018 10:30:04 -0500 Subject: [PATCH 37/91] drm/msm: bump UAPI version Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c08f83c7ca57..cce5bc97b863 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -36,9 +36,11 @@ * - 1.3.0 - adds GMEM_BASE + NR_RINGS params, SUBMITQUEUE_NEW + * SUBMITQUEUE_CLOSE ioctls, and MSM_INFO_IOVA flag for * MSM_GEM_INFO ioctl. + * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get + * GEM object's debug name */ #define MSM_VERSION_MAJOR 1 -#define MSM_VERSION_MINOR 3 +#define MSM_VERSION_MINOR 4 #define MSM_VERSION_PATCHLEVEL 0 static const struct drm_mode_config_funcs mode_config_funcs = { From eb2b47bb9a03206a645af40a3128a00264b0207e Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 21 Nov 2018 20:52:27 -0500 Subject: [PATCH 38/91] drm/msm/mdp4: only use lut_clk on mdp4.2+ Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index 934a49818ea4..ab3938f24522 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -206,7 +206,8 @@ int mdp4_disable(struct mdp4_kms *mdp4_kms) clk_disable_unprepare(mdp4_kms->clk); if (mdp4_kms->pclk) clk_disable_unprepare(mdp4_kms->pclk); - clk_disable_unprepare(mdp4_kms->lut_clk); + if (mdp4_kms->lut_clk) + clk_disable_unprepare(mdp4_kms->lut_clk); if (mdp4_kms->axi_clk) clk_disable_unprepare(mdp4_kms->axi_clk); @@ -220,7 +221,8 @@ int mdp4_enable(struct mdp4_kms *mdp4_kms) clk_prepare_enable(mdp4_kms->clk); if (mdp4_kms->pclk) clk_prepare_enable(mdp4_kms->pclk); - clk_prepare_enable(mdp4_kms->lut_clk); + if (mdp4_kms->lut_clk) + clk_prepare_enable(mdp4_kms->lut_clk); if (mdp4_kms->axi_clk) clk_prepare_enable(mdp4_kms->axi_clk); @@ -472,12 +474,13 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) if (IS_ERR(mdp4_kms->pclk)) mdp4_kms->pclk = NULL; - // XXX if (rev >= MDP_REV_42) { ??? - mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk"); - if (IS_ERR(mdp4_kms->lut_clk)) { - DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n"); - ret = PTR_ERR(mdp4_kms->lut_clk); - goto fail; + if (mdp4_kms->rev >= 2) { + mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk"); + if (IS_ERR(mdp4_kms->lut_clk)) { + DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n"); + ret = PTR_ERR(mdp4_kms->lut_clk); + goto fail; + } } mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "bus_clk"); @@ -488,7 +491,8 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) } clk_set_rate(mdp4_kms->clk, config->max_clk); - clk_set_rate(mdp4_kms->lut_clk, config->max_clk); + if (mdp4_kms->lut_clk) + clk_set_rate(mdp4_kms->lut_clk, config->max_clk); pm_runtime_enable(dev->dev); mdp4_kms->rpm_enabled = true; From 373931d2d7cd37d627c0713940c4c5abfdda043d Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 21 Nov 2018 20:52:28 -0500 Subject: [PATCH 39/91] drm/msm/mdp4: allocate blank_cursor_no with MSM_BO_SCANOUT flag For allocation in contiguous memory when the GPU has MMU but not mdp4. Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index ab3938f24522..e437aa806f7b 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -534,7 +534,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) goto fail; } - mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC); + mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | MSM_BO_SCANOUT); if (IS_ERR(mdp4_kms->blank_cursor_bo)) { ret = PTR_ERR(mdp4_kms->blank_cursor_bo); DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); From 86f46f25d8ff8dc32e1c8cd9b5ab0d285d5c3523 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 21 Nov 2018 20:52:30 -0500 Subject: [PATCH 40/91] drm/msm: use contiguous vram for MSM_BO_SCANOUT when possible Makes it possible to have MMU for GPU but not display. Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index ee44b0f01e90..38b7f4e9e7ff 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -977,7 +977,7 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, if (!iommu_present(&platform_bus_type)) use_vram = true; - else if ((flags & MSM_BO_STOLEN) && priv->vram.size) + else if ((flags & (MSM_BO_STOLEN | MSM_BO_SCANOUT)) && priv->vram.size) use_vram = true; if (WARN_ON(use_vram && !priv->vram.size)) From 21af872cd8c695060dd1d045293bf21ea9156a51 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 21 Nov 2018 20:52:32 -0500 Subject: [PATCH 41/91] drm/msm/adreno: add a2xx derived from the a3xx driver and tested on the following hardware: imx51-zii-rdu1 (a200 with 128kb gmem) imx53-qsrb (a200) msm8060-tenderloin (a220) Signed-off-by: Jonathan Marek Reviewed-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 450 +++++++++++++++++++++ drivers/gpu/drm/msm/adreno/a2xx_gpu.h | 21 + drivers/gpu/drm/msm/adreno/adreno_device.c | 33 ++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 27 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 15 + 6 files changed, 539 insertions(+), 8 deletions(-) create mode 100644 drivers/gpu/drm/msm/adreno/a2xx_gpu.c create mode 100644 drivers/gpu/drm/msm/adreno/a2xx_gpu.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index fabc17bf1a58..61e76f87a5a1 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -6,6 +6,7 @@ ccflags-$(CONFIG_DRM_MSM_DSI) += -Idrivers/gpu/drm/msm/dsi msm-y := \ adreno/adreno_device.o \ adreno/adreno_gpu.o \ + adreno/a2xx_gpu.o \ adreno/a3xx_gpu.o \ adreno/a4xx_gpu.o \ adreno/a5xx_gpu.o \ diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c new file mode 100644 index 000000000000..5eddcf14eeb9 --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -0,0 +1,450 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ + +#include "a2xx_gpu.h" + +extern bool hang_debug; + +static void a2xx_dump(struct msm_gpu *gpu); +static bool a2xx_idle(struct msm_gpu *gpu); + +static bool a2xx_me_init(struct msm_gpu *gpu) +{ + struct msm_ringbuffer *ring = gpu->rb[0]; + + OUT_PKT3(ring, CP_ME_INIT, 18); + + /* All fields present (bits 9:0) */ + OUT_RING(ring, 0x000003ff); + /* Disable/Enable Real-Time Stream processing (present but ignored) */ + OUT_RING(ring, 0x00000000); + /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */ + OUT_RING(ring, 0x00000000); + + OUT_RING(ring, REG_A2XX_RB_SURFACE_INFO - 0x2000); + OUT_RING(ring, REG_A2XX_PA_SC_WINDOW_OFFSET - 0x2000); + OUT_RING(ring, REG_A2XX_VGT_MAX_VTX_INDX - 0x2000); + OUT_RING(ring, REG_A2XX_SQ_PROGRAM_CNTL - 0x2000); + OUT_RING(ring, REG_A2XX_RB_DEPTHCONTROL - 0x2000); + OUT_RING(ring, REG_A2XX_PA_SU_POINT_SIZE - 0x2000); + OUT_RING(ring, REG_A2XX_PA_SC_LINE_CNTL - 0x2000); + OUT_RING(ring, REG_A2XX_PA_SU_POLY_OFFSET_FRONT_SCALE - 0x2000); + + /* Vertex and Pixel Shader Start Addresses in instructions + * (3 DWORDS per instruction) */ + OUT_RING(ring, 0x80000180); + /* Maximum Contexts */ + OUT_RING(ring, 0x00000001); + /* Write Confirm Interval and The CP will wait the + * wait_interval * 16 clocks between polling */ + OUT_RING(ring, 0x00000000); + /* NQ and External Memory Swap */ + OUT_RING(ring, 0x00000000); + /* protected mode error checking (0x1f2 is REG_AXXX_CP_INT_CNTL) */ + OUT_RING(ring, 0x200001f2); + /* Disable header dumping and Header dump address */ + OUT_RING(ring, 0x00000000); + /* Header dump size */ + OUT_RING(ring, 0x00000000); + + /* enable protected mode */ + OUT_PKT3(ring, CP_SET_PROTECTED_MODE, 1); + OUT_RING(ring, 1); + + gpu->funcs->flush(gpu, ring); + return a2xx_idle(gpu); +} + +static int a2xx_hw_init(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + uint32_t *ptr, len; + int i, ret; + + DBG("%s", gpu->name); + + /* halt ME to avoid ucode upload issues on a20x */ + gpu_write(gpu, REG_AXXX_CP_ME_CNTL, AXXX_CP_ME_CNTL_HALT); + + gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE1, 0xfffffffe); + gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE2, 0xffffffff); + + /* note: kgsl uses 0x00000001 after first reset on a22x */ + gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0xffffffff); + msleep(30); + gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0x00000000); + + if (adreno_is_a225(adreno_gpu)) + gpu_write(gpu, REG_A2XX_SQ_FLOW_CONTROL, 0x18000000); + + /* note: kgsl uses 0x0000ffff for a20x */ + gpu_write(gpu, REG_A2XX_RBBM_CNTL, 0x00004442); + + gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, 0); + gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0); + gpu_write(gpu, REG_A2XX_MH_MMU_MPU_END, 0xfffff000); + gpu_write(gpu, REG_A2XX_MH_ARBITER_CONFIG, + A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT(16) | + A2XX_MH_ARBITER_CONFIG_L1_ARB_ENABLE | + A2XX_MH_ARBITER_CONFIG_L1_ARB_HOLD_ENABLE | + A2XX_MH_ARBITER_CONFIG_PAGE_SIZE(1) | + A2XX_MH_ARBITER_CONFIG_TC_REORDER_ENABLE | + A2XX_MH_ARBITER_CONFIG_TC_ARB_HOLD_ENABLE | + A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT_ENABLE | + A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT(8) | + A2XX_MH_ARBITER_CONFIG_CP_CLNT_ENABLE | + A2XX_MH_ARBITER_CONFIG_VGT_CLNT_ENABLE | + A2XX_MH_ARBITER_CONFIG_TC_CLNT_ENABLE | + A2XX_MH_ARBITER_CONFIG_RB_CLNT_ENABLE | + A2XX_MH_ARBITER_CONFIG_PA_CLNT_ENABLE); + if (!adreno_is_a20x(adreno_gpu)) + gpu_write(gpu, REG_A2XX_MH_CLNT_INTF_CTRL_CONFIG1, 0x00032f07); + + gpu_write(gpu, REG_A2XX_SQ_VS_PROGRAM, 0x00000000); + gpu_write(gpu, REG_A2XX_SQ_PS_PROGRAM, 0x00000000); + + gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE1, 0); /* 0x200 for msm8960? */ + gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE2, 0); /* 0x80/0x1a0 for a22x? */ + + /* note: gsl doesn't set this */ + gpu_write(gpu, REG_A2XX_RBBM_DEBUG, 0x00080000); + + gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL, 0); + gpu_write(gpu, REG_AXXX_CP_INT_CNTL, 0x80000000); /* RB INT */ + gpu_write(gpu, REG_A2XX_SQ_INT_CNTL, 0); + + for (i = 3; i <= 5; i++) + if ((SZ_16K << i) == adreno_gpu->gmem) + break; + gpu_write(gpu, REG_A2XX_RB_EDRAM_INFO, i); + + ret = adreno_hw_init(gpu); + if (ret) + return ret; + + /* NOTE: PM4/micro-engine firmware registers look to be the same + * for a2xx and a3xx.. we could possibly push that part down to + * adreno_gpu base class. Or push both PM4 and PFP but + * parameterize the pfp ucode addr/data registers.. + */ + + /* Load PM4: */ + ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data); + len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4; + DBG("loading PM4 ucode version: %x", ptr[1]); + + gpu_write(gpu, REG_AXXX_CP_DEBUG, + AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE); + gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]); + + /* Load PFP: */ + ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data); + len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4; + DBG("loading PFP ucode version: %x", ptr[5]); + + gpu_write(gpu, REG_A2XX_CP_PFP_UCODE_ADDR, 0); + for (i = 1; i < len; i++) + gpu_write(gpu, REG_A2XX_CP_PFP_UCODE_DATA, ptr[i]); + + gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS, 0x000C0804); + + /* clear ME_HALT to start micro engine */ + gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0); + + return a2xx_me_init(gpu) ? 0 : -EINVAL; +} + +static void a2xx_recover(struct msm_gpu *gpu) +{ + int i; + + adreno_dump_info(gpu); + + for (i = 0; i < 8; i++) { + printk("CP_SCRATCH_REG%d: %u\n", i, + gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i)); + } + + /* dump registers before resetting gpu, if enabled: */ + if (hang_debug) + a2xx_dump(gpu); + + gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 1); + gpu_read(gpu, REG_A2XX_RBBM_SOFT_RESET); + gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0); + adreno_recover(gpu); +} + +static void a2xx_destroy(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a2xx_gpu *a2xx_gpu = to_a2xx_gpu(adreno_gpu); + + DBG("%s", gpu->name); + + adreno_gpu_cleanup(adreno_gpu); + + kfree(a2xx_gpu); +} + +static bool a2xx_idle(struct msm_gpu *gpu) +{ + /* wait for ringbuffer to drain: */ + if (!adreno_idle(gpu, gpu->rb[0])) + return false; + + /* then wait for GPU to finish: */ + if (spin_until(!(gpu_read(gpu, REG_A2XX_RBBM_STATUS) & + A2XX_RBBM_STATUS_GUI_ACTIVE))) { + DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name); + + /* TODO maybe we need to reset GPU here to recover from hang? */ + return false; + } + + return true; +} + +static irqreturn_t a2xx_irq(struct msm_gpu *gpu) +{ + uint32_t mstatus, status; + + mstatus = gpu_read(gpu, REG_A2XX_MASTER_INT_SIGNAL); + + if (mstatus & A2XX_MASTER_INT_SIGNAL_MH_INT_STAT) { + status = gpu_read(gpu, REG_A2XX_MH_INTERRUPT_STATUS); + + dev_warn(gpu->dev->dev, "MH_INT: %08X\n", status); + dev_warn(gpu->dev->dev, "MMU_PAGE_FAULT: %08X\n", + gpu_read(gpu, REG_A2XX_MH_MMU_PAGE_FAULT)); + + gpu_write(gpu, REG_A2XX_MH_INTERRUPT_CLEAR, status); + } + + if (mstatus & A2XX_MASTER_INT_SIGNAL_CP_INT_STAT) { + status = gpu_read(gpu, REG_AXXX_CP_INT_STATUS); + + /* only RB_INT is expected */ + if (status & ~AXXX_CP_INT_CNTL_RB_INT_MASK) + dev_warn(gpu->dev->dev, "CP_INT: %08X\n", status); + + gpu_write(gpu, REG_AXXX_CP_INT_ACK, status); + } + + if (mstatus & A2XX_MASTER_INT_SIGNAL_RBBM_INT_STAT) { + status = gpu_read(gpu, REG_A2XX_RBBM_INT_STATUS); + + dev_warn(gpu->dev->dev, "RBBM_INT: %08X\n", status); + + gpu_write(gpu, REG_A2XX_RBBM_INT_ACK, status); + } + + msm_gpu_retire(gpu); + + return IRQ_HANDLED; +} + +static const unsigned int a200_registers[] = { + 0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044, + 0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9, + 0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7, + 0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5, + 0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444, + 0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B, + 0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0, + 0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614, + 0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A43, 0x0A45, 0x0A45, + 0x0A4E, 0x0A4F, 0x0C2C, 0x0C2C, 0x0C30, 0x0C30, 0x0C38, 0x0C3C, + 0x0C40, 0x0C40, 0x0C44, 0x0C44, 0x0C80, 0x0C86, 0x0C88, 0x0C94, + 0x0C99, 0x0C9A, 0x0CA4, 0x0CA5, 0x0D00, 0x0D03, 0x0D06, 0x0D06, + 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4, + 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E, + 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7, + 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x0F0C, 0x0F0C, 0x0F0E, 0x0F12, + 0x0F26, 0x0F2A, 0x0F2C, 0x0F2C, 0x2000, 0x2002, 0x2006, 0x200F, + 0x2080, 0x2082, 0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184, + 0x21F5, 0x21F7, 0x2200, 0x2208, 0x2280, 0x2283, 0x2293, 0x2294, + 0x2300, 0x2308, 0x2312, 0x2312, 0x2316, 0x231D, 0x2324, 0x2326, + 0x2380, 0x2383, 0x2400, 0x2402, 0x2406, 0x240F, 0x2480, 0x2482, + 0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7, + 0x2600, 0x2608, 0x2680, 0x2683, 0x2693, 0x2694, 0x2700, 0x2708, + 0x2712, 0x2712, 0x2716, 0x271D, 0x2724, 0x2726, 0x2780, 0x2783, + 0x4000, 0x4003, 0x4800, 0x4805, 0x4900, 0x4900, 0x4908, 0x4908, + ~0 /* sentinel */ +}; + +static const unsigned int a220_registers[] = { + 0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044, + 0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9, + 0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7, + 0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5, + 0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444, + 0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B, + 0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0, + 0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614, + 0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A40, 0x0A42, 0x0A43, + 0x0A45, 0x0A45, 0x0A4E, 0x0A4F, 0x0C30, 0x0C30, 0x0C38, 0x0C39, + 0x0C3C, 0x0C3C, 0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03, + 0x0D05, 0x0D06, 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, + 0x0DC8, 0x0DD4, 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, + 0x0E17, 0x0E1E, 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, + 0x0ED4, 0x0ED7, 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x2002, + 0x2006, 0x200F, 0x2080, 0x2082, 0x2100, 0x2102, 0x2104, 0x2109, + 0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7, 0x2200, 0x2202, + 0x2204, 0x2204, 0x2208, 0x2208, 0x2280, 0x2282, 0x2294, 0x2294, + 0x2300, 0x2308, 0x2309, 0x230A, 0x2312, 0x2312, 0x2316, 0x2316, + 0x2318, 0x231D, 0x2324, 0x2326, 0x2380, 0x2383, 0x2400, 0x2402, + 0x2406, 0x240F, 0x2480, 0x2482, 0x2500, 0x2502, 0x2504, 0x2509, + 0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7, 0x2600, 0x2602, + 0x2604, 0x2606, 0x2608, 0x2608, 0x2680, 0x2682, 0x2694, 0x2694, + 0x2700, 0x2708, 0x2712, 0x2712, 0x2716, 0x2716, 0x2718, 0x271D, + 0x2724, 0x2726, 0x2780, 0x2783, 0x4000, 0x4003, 0x4800, 0x4805, + 0x4900, 0x4900, 0x4908, 0x4908, + ~0 /* sentinel */ +}; + +static const unsigned int a225_registers[] = { + 0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044, + 0x0046, 0x0047, 0x013C, 0x013C, 0x0140, 0x014F, 0x01C0, 0x01C1, + 0x01C3, 0x01C8, 0x01D5, 0x01D9, 0x01DC, 0x01DD, 0x01EA, 0x01EA, + 0x01EE, 0x01F3, 0x01F6, 0x01F7, 0x01FC, 0x01FF, 0x0391, 0x0392, + 0x039B, 0x039E, 0x03B2, 0x03B5, 0x03B7, 0x03B7, 0x03F8, 0x03FB, + 0x0440, 0x0440, 0x0443, 0x0444, 0x044B, 0x044B, 0x044D, 0x044F, + 0x0452, 0x0452, 0x0454, 0x045B, 0x047F, 0x047F, 0x0578, 0x0587, + 0x05C9, 0x05C9, 0x05D0, 0x05D0, 0x0601, 0x0604, 0x0606, 0x0609, + 0x060B, 0x060E, 0x0613, 0x0614, 0x0A29, 0x0A2B, 0x0A2F, 0x0A31, + 0x0A40, 0x0A40, 0x0A42, 0x0A43, 0x0A45, 0x0A45, 0x0A4E, 0x0A4F, + 0x0C01, 0x0C1D, 0x0C30, 0x0C30, 0x0C38, 0x0C39, 0x0C3C, 0x0C3C, + 0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03, 0x0D05, 0x0D06, + 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4, + 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E, + 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7, + 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x200F, 0x2080, 0x2082, + 0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7, + 0x2200, 0x2202, 0x2204, 0x2206, 0x2208, 0x2210, 0x2220, 0x2222, + 0x2280, 0x2282, 0x2294, 0x2294, 0x2297, 0x2297, 0x2300, 0x230A, + 0x2312, 0x2312, 0x2315, 0x2316, 0x2318, 0x231D, 0x2324, 0x2326, + 0x2340, 0x2357, 0x2360, 0x2360, 0x2380, 0x2383, 0x2400, 0x240F, + 0x2480, 0x2482, 0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584, + 0x25F5, 0x25F7, 0x2600, 0x2602, 0x2604, 0x2606, 0x2608, 0x2610, + 0x2620, 0x2622, 0x2680, 0x2682, 0x2694, 0x2694, 0x2697, 0x2697, + 0x2700, 0x270A, 0x2712, 0x2712, 0x2715, 0x2716, 0x2718, 0x271D, + 0x2724, 0x2726, 0x2740, 0x2757, 0x2760, 0x2760, 0x2780, 0x2783, + 0x4000, 0x4003, 0x4800, 0x4806, 0x4808, 0x4808, 0x4900, 0x4900, + 0x4908, 0x4908, + ~0 /* sentinel */ +}; + +/* would be nice to not have to duplicate the _show() stuff with printk(): */ +static void a2xx_dump(struct msm_gpu *gpu) +{ + printk("status: %08x\n", + gpu_read(gpu, REG_A2XX_RBBM_STATUS)); + adreno_dump(gpu); +} + +static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu) +{ + struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + + if (!state) + return ERR_PTR(-ENOMEM); + + adreno_gpu_state_get(gpu, state); + + state->rbbm_status = gpu_read(gpu, REG_A2XX_RBBM_STATUS); + + return state; +} + +/* Register offset defines for A2XX - copy of A3XX */ +static const unsigned int a2xx_register_offsets[REG_ADRENO_REGISTER_MAX] = { + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_AXXX_CP_RB_BASE), + REG_ADRENO_SKIP(REG_ADRENO_CP_RB_BASE_HI), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_AXXX_CP_RB_RPTR_ADDR), + REG_ADRENO_SKIP(REG_ADRENO_CP_RB_RPTR_ADDR_HI), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_AXXX_CP_RB_RPTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_AXXX_CP_RB_WPTR), + REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_AXXX_CP_RB_CNTL), +}; + +static const struct adreno_gpu_funcs funcs = { + .base = { + .get_param = adreno_get_param, + .hw_init = a2xx_hw_init, + .pm_suspend = msm_gpu_pm_suspend, + .pm_resume = msm_gpu_pm_resume, + .recover = a2xx_recover, + .submit = adreno_submit, + .flush = adreno_flush, + .active_ring = adreno_active_ring, + .irq = a2xx_irq, + .destroy = a2xx_destroy, +#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP) + .show = adreno_show, +#endif + .gpu_state_get = a2xx_gpu_state_get, + .gpu_state_put = adreno_gpu_state_put, + }, +}; + +static const struct msm_gpu_perfcntr perfcntrs[] = { +/* TODO */ +}; + +struct msm_gpu *a2xx_gpu_init(struct drm_device *dev) +{ + struct a2xx_gpu *a2xx_gpu = NULL; + struct adreno_gpu *adreno_gpu; + struct msm_gpu *gpu; + struct msm_drm_private *priv = dev->dev_private; + struct platform_device *pdev = priv->gpu_pdev; + int ret; + + if (!pdev) { + dev_err(dev->dev, "no a2xx device\n"); + ret = -ENXIO; + goto fail; + } + + a2xx_gpu = kzalloc(sizeof(*a2xx_gpu), GFP_KERNEL); + if (!a2xx_gpu) { + ret = -ENOMEM; + goto fail; + } + + adreno_gpu = &a2xx_gpu->base; + gpu = &adreno_gpu->base; + + gpu->perfcntrs = perfcntrs; + gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs); + + if (adreno_is_a20x(adreno_gpu)) + adreno_gpu->registers = a200_registers; + else if (adreno_is_a225(adreno_gpu)) + adreno_gpu->registers = a225_registers; + else + adreno_gpu->registers = a220_registers; + + adreno_gpu->reg_offsets = a2xx_register_offsets; + + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); + if (ret) + goto fail; + + if (!gpu->aspace) { + dev_err(dev->dev, "No memory protection without MMU\n"); + ret = -ENXIO; + goto fail; + } + + return gpu; + +fail: + if (a2xx_gpu) + a2xx_destroy(&a2xx_gpu->base.base); + + return ERR_PTR(ret); +} diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.h b/drivers/gpu/drm/msm/adreno/a2xx_gpu.h new file mode 100644 index 000000000000..02fba2cb8932 --- /dev/null +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ + +#ifndef __A2XX_GPU_H__ +#define __A2XX_GPU_H__ + +#include "adreno_gpu.h" + +/* arrg, somehow fb.h is getting pulled in: */ +#undef ROP_COPY +#undef ROP_XOR + +#include "a2xx.xml.h" + +struct a2xx_gpu { + struct adreno_gpu base; + bool pm_enabled; +}; +#define to_a2xx_gpu(x) container_of(x, struct a2xx_gpu, base) + +#endif /* __A2XX_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index fb77c87da690..adc442f736a2 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -27,6 +27,39 @@ module_param_named(hang_debug, hang_debug, bool, 0600); static const struct adreno_info gpulist[] = { { + .rev = ADRENO_REV(2, 0, 0, 0), + .revn = 200, + .name = "A200", + .fw = { + [ADRENO_FW_PM4] = "yamato_pm4.fw", + [ADRENO_FW_PFP] = "yamato_pfp.fw", + }, + .gmem = SZ_256K, + .inactive_period = DRM_MSM_INACTIVE_PERIOD, + .init = a2xx_gpu_init, + }, { /* a200 on i.mx51 has only 128kib gmem */ + .rev = ADRENO_REV(2, 0, 0, 1), + .revn = 201, + .name = "A200", + .fw = { + [ADRENO_FW_PM4] = "yamato_pm4.fw", + [ADRENO_FW_PFP] = "yamato_pfp.fw", + }, + .gmem = SZ_128K, + .inactive_period = DRM_MSM_INACTIVE_PERIOD, + .init = a2xx_gpu_init, + }, { + .rev = ADRENO_REV(2, 2, 0, ANY_ID), + .revn = 220, + .name = "A220", + .fw = { + [ADRENO_FW_PM4] = "leia_pm4_470.fw", + [ADRENO_FW_PFP] = "leia_pfp_470.fw", + }, + .gmem = SZ_512K, + .inactive_period = DRM_MSM_INACTIVE_PERIOD, + .init = a2xx_gpu_init, + }, { .rev = ADRENO_REV(3, 0, 5, ANY_ID), .revn = 305, .name = "A305", diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index bbd7350a7f39..9ab67dd1bcd3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -311,16 +311,27 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, */ OUT_PKT3(ring, CP_EVENT_WRITE, 1); OUT_RING(ring, HLSQ_FLUSH); - - OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1); - OUT_RING(ring, 0x00000000); } - /* BIT(31) of CACHE_FLUSH_TS triggers CACHE_FLUSH_TS IRQ from GPU */ - OUT_PKT3(ring, CP_EVENT_WRITE, 3); - OUT_RING(ring, CACHE_FLUSH_TS | BIT(31)); - OUT_RING(ring, rbmemptr(ring, fence)); - OUT_RING(ring, submit->seqno); + /* wait for idle before cache flush/interrupt */ + OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1); + OUT_RING(ring, 0x00000000); + + if (!adreno_is_a2xx(adreno_gpu)) { + /* BIT(31) of CACHE_FLUSH_TS triggers CACHE_FLUSH_TS IRQ from GPU */ + OUT_PKT3(ring, CP_EVENT_WRITE, 3); + OUT_RING(ring, CACHE_FLUSH_TS | BIT(31)); + OUT_RING(ring, rbmemptr(ring, fence)); + OUT_RING(ring, submit->seqno); + } else { + /* BIT(31) means something else on a2xx */ + OUT_PKT3(ring, CP_EVENT_WRITE, 3); + OUT_RING(ring, CACHE_FLUSH_TS); + OUT_RING(ring, rbmemptr(ring, fence)); + OUT_RING(ring, submit->seqno); + OUT_PKT3(ring, CP_INTERRUPT, 1); + OUT_RING(ring, 0x80000000); + } #if 0 if (adreno_is_a3xx(adreno_gpu)) { diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 7e5f1120ce7a..5db459bc28a7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -155,6 +155,20 @@ struct adreno_platform_config { __ret; \ }) +static inline bool adreno_is_a2xx(struct adreno_gpu *gpu) +{ + return (gpu->revn < 300); +} + +static inline bool adreno_is_a20x(struct adreno_gpu *gpu) +{ + return (gpu->revn < 210); +} + +static inline bool adreno_is_a225(struct adreno_gpu *gpu) +{ + return gpu->revn == 225; +} static inline bool adreno_is_a3xx(struct adreno_gpu *gpu) { @@ -335,6 +349,7 @@ static inline void adreno_gpu_write(struct adreno_gpu *gpu, gpu_write(&gpu->base, reg - 1, data); } +struct msm_gpu *a2xx_gpu_init(struct drm_device *dev); struct msm_gpu *a3xx_gpu_init(struct drm_device *dev); struct msm_gpu *a4xx_gpu_init(struct drm_device *dev); struct msm_gpu *a5xx_gpu_init(struct drm_device *dev); From a5cd7b55dfac41a45432de0bf261f8b92c43c3fa Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 21 Nov 2018 20:52:34 -0500 Subject: [PATCH 42/91] drm/msm/mdp5: add config for msm8917 Add the mdp5_cfg_hw entry for MDP5 version v1.15 found on msm8917. Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 86 ++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c index 42f9e4b3da9c..ea8f7d7daf7f 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c @@ -553,6 +553,91 @@ const struct mdp5_cfg_hw msm8x96_config = { .max_clk = 412500000, }; +const struct mdp5_cfg_hw msm8917_config = { + .name = "msm8917", + .mdp = { + .count = 1, + .caps = MDP_CAP_CDM, + }, + .ctl = { + .count = 3, + .base = { 0x01000, 0x01200, 0x01400 }, + .flush_hw_mask = 0xffffffff, + }, + .pipe_vig = { + .count = 1, + .base = { 0x04000 }, + .caps = MDP_PIPE_CAP_HFLIP | + MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SCALE | + MDP_PIPE_CAP_CSC | + MDP_PIPE_CAP_DECIMATION | + MDP_PIPE_CAP_SW_PIX_EXT | + 0, + }, + .pipe_rgb = { + .count = 2, + .base = { 0x14000, 0x16000 }, + .caps = MDP_PIPE_CAP_HFLIP | + MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_DECIMATION | + MDP_PIPE_CAP_SW_PIX_EXT | + 0, + }, + .pipe_dma = { + .count = 1, + .base = { 0x24000 }, + .caps = MDP_PIPE_CAP_HFLIP | + MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SW_PIX_EXT | + 0, + }, + .pipe_cursor = { + .count = 1, + .base = { 0x34000 }, + .caps = MDP_PIPE_CAP_HFLIP | + MDP_PIPE_CAP_VFLIP | + MDP_PIPE_CAP_SW_PIX_EXT | + MDP_PIPE_CAP_CURSOR | + 0, + }, + + .lm = { + .count = 2, + .base = { 0x44000, 0x45000 }, + .instances = { + { .id = 0, .pp = 0, .dspp = 0, + .caps = MDP_LM_CAP_DISPLAY, }, + { .id = 1, .pp = -1, .dspp = -1, + .caps = MDP_LM_CAP_WB }, + }, + .nb_stages = 8, + .max_width = 2048, + .max_height = 0xFFFF, + }, + .dspp = { + .count = 1, + .base = { 0x54000 }, + + }, + .pp = { + .count = 1, + .base = { 0x70000 }, + }, + .cdm = { + .count = 1, + .base = { 0x79200 }, + }, + .intf = { + .base = { 0x6a000, 0x6a800 }, + .connect = { + [0] = INTF_DISABLED, + [1] = INTF_DSI, + }, + }, + .max_clk = 320000000, +}; + static const struct mdp5_cfg_handler cfg_handlers[] = { { .revision = 0, .config = { .hw = &msm8x74v1_config } }, { .revision = 2, .config = { .hw = &msm8x74v2_config } }, @@ -560,6 +645,7 @@ static const struct mdp5_cfg_handler cfg_handlers[] = { { .revision = 6, .config = { .hw = &msm8x16_config } }, { .revision = 9, .config = { .hw = &msm8x94_config } }, { .revision = 7, .config = { .hw = &msm8x96_config } }, + { .revision = 15, .config = { .hw = &msm8917_config } }, }; static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev); From b2ccfdf1dde588d0e90d6d235b9ae557cbea5d4d Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 21 Nov 2018 20:52:35 -0500 Subject: [PATCH 43/91] drm/msm: set priv->kms to NULL before uninit otherwise, priv->kms is non-NULL and msm_drm_uninit will cause a panic. Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index cce5bc97b863..1a3b80d31726 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -524,6 +524,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) */ DRM_DEV_ERROR(dev, "failed to load kms\n"); ret = PTR_ERR(kms); + priv->kms = NULL; goto err_msm_uninit; } From c1866d44d149a1ea5c303632114fb6aa08cfd263 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Thu, 11 Oct 2018 10:18:57 -0700 Subject: [PATCH 44/91] drm/msm/dsi: fix dsi clock names in DSI 10nm PLL driver Fix the dsi clock names in the DSI 10nm PLL driver to match the names in the dispcc driver as those are according to the clock plan of the chipset. Changes in v2: - Update the clock diagram with the new clock name Reviewed-by: Sean Paul Signed-off-by: Abhinav Kumar Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c index f8819ccdc25c..e41f278e4e62 100644 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +++ b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c @@ -17,7 +17,7 @@ * | | * | | * +---------+ | +----------+ | +----+ - * dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0pllbyte + * dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk * +---------+ | +----------+ | +----+ * | | * | | dsi0_pll_by_2_bit_clk @@ -25,7 +25,7 @@ * | | +----+ | |\ dsi0_pclk_mux * | |--| /2 |--o--| \ | * | | +----+ | \ | +---------+ - * | --------------| |--o--| div_7_4 |-- dsi0pll + * | --------------| |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk * |------------------------------| / +---------+ * | +-----+ | / * -----------| /4? |--o----------|/ @@ -688,7 +688,7 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) hws[num++] = hw; - snprintf(clk_name, 32, "dsi%dpllbyte", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id); snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ @@ -737,7 +737,7 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) hws[num++] = hw; - snprintf(clk_name, 32, "dsi%dpll", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id); snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id); /* PIX CLK DIV : DIV_CTRL_7_4*/ From d4e98855d170dc808e7f52c478f1beb18b700139 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Fri, 2 Nov 2018 18:19:17 +0530 Subject: [PATCH 45/91] drm/msm/dpu: Correct dpu destroy and disable order In case of msm drm bind failure, dpu_mdss_destroy is triggered. In this function, resources are freed and pm runtime disable is called, which triggers dpu_mdss_disable. Now in dpu_mdss_disable, driver tries to access a memory which is already freed. This results in kernel panic. Fix this by ensuring proper sequence of dpu destroy and disable calls. Changes in v2: - Removed double spacings [Jeykumar] Tested-by: Douglas Anderson Signed-off-by: Jayant Shekhar Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index 2235ef8129f4..38576f8b90b6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -156,18 +156,15 @@ static void dpu_mdss_destroy(struct drm_device *dev) struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss); struct dss_module_power *mp = &dpu_mdss->mp; + pm_runtime_disable(dev->dev); _dpu_mdss_irq_domain_fini(dpu_mdss); - free_irq(platform_get_irq(pdev, 0), dpu_mdss); - msm_dss_put_clk(mp->clk_config, mp->num_clk); devm_kfree(&pdev->dev, mp->clk_config); if (dpu_mdss->mmio) devm_iounmap(&pdev->dev, dpu_mdss->mmio); dpu_mdss->mmio = NULL; - - pm_runtime_disable(dev->dev); priv->mdss = NULL; } From 5f79e03b1f7c1b2cf0019ce6365fe5d52629813d Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Tue, 30 Oct 2018 12:00:08 -0400 Subject: [PATCH 46/91] drm/msm: dpu: Only check flush register against pending flushes There exists a case where a flush of a plane/dma may have been triggered & started from an async commit. If that plane/dma is subsequently disabled by the next commit, the flush register will continue to hold the flush bit for the disabled plane. Since the bit remains active, pending_kickoff_cnt will never decrement and we'll miss frame_done events. This patch limits the check of flush_register to include only those bits which have been updated with the latest commit. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index b3c68c4fcc8e..667f304c92ea 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -331,7 +331,7 @@ static void dpu_encoder_phys_vid_vblank_irq(void *arg, int irq_idx) if (hw_ctl && hw_ctl->ops.get_flush_register) flush_register = hw_ctl->ops.get_flush_register(hw_ctl); - if (flush_register == 0) + if (!(flush_register & hw_ctl->ops.get_pending_flush(hw_ctl))) new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); From 50bcc689b1f1c5eb00eda0db76e00783b97c02c2 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Tue, 30 Oct 2018 12:00:09 -0400 Subject: [PATCH 47/91] drm/msm: dpu: Make legacy cursor updates asynchronous This patch sprinkles a few async/legacy_cursor_update checks through commit to ensure that cursor updates aren't blocked on vsync. There are 2 main components to this, the first is that we don't want to wait_for_commit_done in msm_atomic before returning from atomic_complete. The second is that in dpu we don't want to wait for frame_done events when updating the cursor. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 46 +++++++++++---------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 22 ++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 6 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 5 ++- drivers/gpu/drm/msm/msm_atomic.c | 3 +- 6 files changed, 50 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ae63590ad2d3..cb62ef092c20 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -702,7 +702,7 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) return rc; } -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) { struct drm_encoder *encoder; struct drm_device *dev = crtc->dev; @@ -731,39 +731,43 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) * Encoder will flush/start now, unless it has a tx pending. * If so, it may delay and flush at an irq event (e.g. ppdone) */ - dpu_encoder_prepare_for_kickoff(encoder, ¶ms); + dpu_encoder_prepare_for_kickoff(encoder, ¶ms, async); } - /* wait for frame_event_done completion */ - DPU_ATRACE_BEGIN("wait_for_frame_done_event"); - ret = _dpu_crtc_wait_for_frame_done(crtc); - DPU_ATRACE_END("wait_for_frame_done_event"); - if (ret) { - DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n", - crtc->base.id, - atomic_read(&dpu_crtc->frame_pending)); - goto end; + + if (!async) { + /* wait for frame_event_done completion */ + DPU_ATRACE_BEGIN("wait_for_frame_done_event"); + ret = _dpu_crtc_wait_for_frame_done(crtc); + DPU_ATRACE_END("wait_for_frame_done_event"); + if (ret) { + DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n", + crtc->base.id, + atomic_read(&dpu_crtc->frame_pending)); + goto end; + } + + if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { + /* acquire bandwidth and other resources */ + DPU_DEBUG("crtc%d first commit\n", crtc->base.id); + } else + DPU_DEBUG("crtc%d commit\n", crtc->base.id); + + dpu_crtc->play_count++; } - if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { - /* acquire bandwidth and other resources */ - DPU_DEBUG("crtc%d first commit\n", crtc->base.id); - } else - DPU_DEBUG("crtc%d commit\n", crtc->base.id); - - dpu_crtc->play_count++; - dpu_vbif_clear_errors(dpu_kms); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc != crtc) continue; - dpu_encoder_kickoff(encoder); + dpu_encoder_kickoff(encoder, async); } end: - reinit_completion(&dpu_crtc->frame_done_comp); + if (!async) + reinit_completion(&dpu_crtc->frame_done_comp); DPU_ATRACE_END("crtc_commit"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 4822602402f9..ec633ce3ee6c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -277,8 +277,9 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en); /** * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc * @crtc: Pointer to drm crtc object + * @async: true if the commit is asynchronous, false otherwise */ -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc); +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async); /** * dpu_crtc_complete_commit - callback signalling completion of current commit diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 82c55efb500f..a8ba10ceaacf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1375,7 +1375,8 @@ static void dpu_encoder_off_work(struct kthread_work *work) * extra_flush_bits: Additional bit mask to include in flush trigger */ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, - struct dpu_encoder_phys *phys, uint32_t extra_flush_bits) + struct dpu_encoder_phys *phys, uint32_t extra_flush_bits, + bool async) { struct dpu_hw_ctl *ctl; int pending_kickoff_cnt; @@ -1398,7 +1399,10 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, return; } - pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys); + if (!async) + pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys); + else + pending_kickoff_cnt = atomic_read(&phys->pending_kickoff_cnt); if (extra_flush_bits && ctl->ops.update_pending_flush) ctl->ops.update_pending_flush(ctl, extra_flush_bits); @@ -1511,7 +1515,8 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc) * a time. * dpu_enc: Pointer to virtual encoder structure */ -static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc) +static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc, + bool async) { struct dpu_hw_ctl *ctl; uint32_t i, pending_flush; @@ -1542,7 +1547,8 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc) set_bit(i, dpu_enc->frame_busy_mask); if (!phys->ops.needs_single_flush || !phys->ops.needs_single_flush(phys)) - _dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0); + _dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0, + async); else if (ctl->ops.get_pending_flush) pending_flush |= ctl->ops.get_pending_flush(ctl); } @@ -1552,7 +1558,7 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc) _dpu_encoder_trigger_flush( &dpu_enc->base, dpu_enc->cur_master, - pending_flush); + pending_flush, async); } _dpu_encoder_trigger_start(dpu_enc->cur_master); @@ -1736,7 +1742,7 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work) } void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, - struct dpu_encoder_kickoff_params *params) + struct dpu_encoder_kickoff_params *params, bool async) { struct dpu_encoder_virt *dpu_enc; struct dpu_encoder_phys *phys; @@ -1775,7 +1781,7 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, } } -void dpu_encoder_kickoff(struct drm_encoder *drm_enc) +void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) { struct dpu_encoder_virt *dpu_enc; struct dpu_encoder_phys *phys; @@ -1798,7 +1804,7 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc) ((atomic_read(&dpu_enc->frame_done_timeout) * HZ) / 1000)); /* All phys encs are ready to go, trigger the kickoff */ - _dpu_encoder_kickoff_phys(dpu_enc); + _dpu_encoder_kickoff_phys(dpu_enc, async); /* allow phys encs to handle any post-kickoff business */ for (i = 0; i < dpu_enc->num_phys_encs; i++) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 9dbf38f446d9..c2044122d609 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -81,9 +81,10 @@ void dpu_encoder_register_frame_event_callback(struct drm_encoder *encoder, * Delayed: Block until next trigger can be issued. * @encoder: encoder pointer * @params: kickoff time parameters + * @async: true if this is an asynchronous commit */ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *encoder, - struct dpu_encoder_kickoff_params *params); + struct dpu_encoder_kickoff_params *params, bool async); /** * dpu_encoder_trigger_kickoff_pending - Clear the flush bits from previous @@ -96,8 +97,9 @@ void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *encoder); * dpu_encoder_kickoff - trigger a double buffer flip of the ctl path * (i.e. ctl flush and start) immediately. * @encoder: encoder pointer + * @async: true if this is an asynchronous commit */ -void dpu_encoder_kickoff(struct drm_encoder *encoder); +void dpu_encoder_kickoff(struct drm_encoder *encoder, bool async); /** * dpu_encoder_wait_for_event - Waits for encoder events diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index b57977f30274..1969f0d07d86 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -352,7 +352,7 @@ void dpu_kms_encoder_enable(struct drm_encoder *encoder) if (crtc && crtc->state->active) { trace_dpu_kms_enc_enable(DRMID(crtc)); - dpu_crtc_commit_kickoff(crtc); + dpu_crtc_commit_kickoff(crtc, false); } } @@ -369,7 +369,8 @@ static void dpu_kms_commit(struct msm_kms *kms, struct drm_atomic_state *state) if (crtc->state->active) { trace_dpu_kms_commit(DRMID(crtc)); - dpu_crtc_commit_kickoff(crtc); + dpu_crtc_commit_kickoff(crtc, + state->legacy_cursor_update); } } } diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 4bcdeca7479d..ff291dd0744b 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -78,7 +78,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) kms->funcs->commit(kms, state); } - msm_atomic_wait_for_commit_done(dev, state); + if (!state->legacy_cursor_update) + msm_atomic_wait_for_commit_done(dev, state); kms->funcs->complete_commit(kms, state); From d135c7ebb7bd13af8e09ff03fba73de113a6b501 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 12:39:45 -0700 Subject: [PATCH 48/91] drm/msm/a6xx: Use new kernel API free function for gpu state dadb36b7ec42 ("drm/msm: Add a common function to free kernel buffer objects") missed freeing the crashdumper state for a6xx. Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index df6308e7ea67..716595b664dd 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -149,15 +149,6 @@ static int a6xx_crashdumper_run(struct msm_gpu *gpu, return ret; } -static void a6xx_crashdumper_free(struct msm_gpu *gpu, - struct a6xx_crashdumper *dumper) -{ - msm_gem_unpin_iova(dumper->bo, gpu->aspace); - msm_gem_put_vaddr(dumper->bo); - - drm_gem_object_unreference(dumper->bo); -} - /* read a value from the GX debug bus */ static int debugbus_read(struct msm_gpu *gpu, u32 block, u32 offset, u32 *data) @@ -900,7 +891,7 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) a6xx_get_clusters(gpu, a6xx_state, &dumper); a6xx_get_dbgahb_clusters(gpu, a6xx_state, &dumper); - a6xx_crashdumper_free(gpu, &dumper); + msm_gem_kernel_put(dumper.bo, gpu->aspace, true); } a6xx_get_debugbus(gpu, a6xx_state); From e400b9edb078ba1c72a7017aab52c4a4a5c1fae8 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 12:40:31 -0700 Subject: [PATCH 49/91] drm/msm/a6xx: Add a name for the crashdumper buffer Add a buffer object name for the a6xx crashdumper so it can be seen with the changes introduced by 7799a98edd ("drm/msm: Add a name field for gem objects"). Signed-off-by: Jordan Crouse Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 716595b664dd..e686331fa089 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -116,7 +116,10 @@ static int a6xx_crashdumper_init(struct msm_gpu *gpu, SZ_1M, MSM_BO_UNCACHED, gpu->aspace, &dumper->bo, &dumper->iova); - return IS_ERR(dumper->ptr) ? PTR_ERR(dumper->ptr) : 0; + if (!IS_ERR(dumper->ptr)) + msm_gem_object_set_name(dumper->bo, "crashdump"); + + return PTR_ERR_OR_ZERO(dumper->ptr); } static int a6xx_crashdumper_run(struct msm_gpu *gpu, From d1d9d0e1724d6a7123b4280fdf6630ae70f96c9c Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 4 Dec 2018 10:04:41 -0800 Subject: [PATCH 50/91] drm/msm: Only add available components When trying to get the display up on my sdm845 board I noticed that the display wouldn't probe if I had the dsi1 node marked as "disabled" even though my board doesn't use dsi1. It looks like the msm code adds all nodes to its list of components even if they are disabled. I believe this doesn't work because all registered components need to come up before we finish probing. Let's do like other DRM code and only add available components. Signed-off-by: Douglas Anderson Reviewed-by: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 1a3b80d31726..7661ca71fca6 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1256,8 +1256,10 @@ static int add_components_mdp(struct device *mdp_dev, if (!intf) continue; - drm_of_component_match_add(master_dev, matchptr, compare_of, - intf); + if (of_device_is_available(intf)) + drm_of_component_match_add(master_dev, matchptr, + compare_of, intf); + of_node_put(intf); } From c2052a4e5c99f7edcb0283e6e12b2fb6975b7353 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 14 Nov 2018 17:08:04 -0500 Subject: [PATCH 51/91] drm/msm: implement a2xx mmu A2XX has its own very simple MMU. Added a msm_use_mmu() function because we can't rely on iommu_present to decide to use MMU or not. Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 50 ++++++++- drivers/gpu/drm/msm/adreno/adreno_device.c | 3 + drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 + drivers/gpu/drm/msm/msm_drv.c | 11 +- drivers/gpu/drm/msm/msm_drv.h | 8 ++ drivers/gpu/drm/msm/msm_gem.c | 4 +- drivers/gpu/drm/msm/msm_gem_vma.c | 23 ++++ drivers/gpu/drm/msm/msm_gpu.c | 27 +++-- drivers/gpu/drm/msm/msm_gpummu.c | 123 +++++++++++++++++++++ drivers/gpu/drm/msm/msm_mmu.h | 3 + 11 files changed, 240 insertions(+), 18 deletions(-) create mode 100644 drivers/gpu/drm/msm/msm_gpummu.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 61e76f87a5a1..1b26c410599d 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -93,7 +93,8 @@ msm-y := \ msm_rd.o \ msm_ringbuffer.o \ msm_submitqueue.o \ - msm_gpu_tracepoints.o + msm_gpu_tracepoints.o \ + msm_gpummu.o msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \ disp/dpu1/dpu_dbg.o diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index 5eddcf14eeb9..1f83bc18d500 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -2,6 +2,8 @@ /* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ #include "a2xx_gpu.h" +#include "msm_gem.h" +#include "msm_mmu.h" extern bool hang_debug; @@ -58,9 +60,12 @@ static bool a2xx_me_init(struct msm_gpu *gpu) static int a2xx_hw_init(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + dma_addr_t pt_base, tran_error; uint32_t *ptr, len; int i, ret; + msm_gpummu_params(gpu->aspace->mmu, &pt_base, &tran_error); + DBG("%s", gpu->name); /* halt ME to avoid ucode upload issues on a20x */ @@ -80,9 +85,34 @@ static int a2xx_hw_init(struct msm_gpu *gpu) /* note: kgsl uses 0x0000ffff for a20x */ gpu_write(gpu, REG_A2XX_RBBM_CNTL, 0x00004442); - gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, 0); - gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0); + /* MPU: physical range */ + gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0x00000000); gpu_write(gpu, REG_A2XX_MH_MMU_MPU_END, 0xfffff000); + + gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, A2XX_MH_MMU_CONFIG_MMU_ENABLE | + A2XX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR(BEH_TRAN_RNG) | + A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(BEH_TRAN_RNG)); + + /* same as parameters in adreno_gpu */ + gpu_write(gpu, REG_A2XX_MH_MMU_VA_RANGE, SZ_16M | + A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS(0xfff)); + + gpu_write(gpu, REG_A2XX_MH_MMU_PT_BASE, pt_base); + gpu_write(gpu, REG_A2XX_MH_MMU_TRAN_ERROR, tran_error); + + gpu_write(gpu, REG_A2XX_MH_MMU_INVALIDATE, + A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL | + A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC); + gpu_write(gpu, REG_A2XX_MH_ARBITER_CONFIG, A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT(16) | A2XX_MH_ARBITER_CONFIG_L1_ARB_ENABLE | @@ -109,9 +139,21 @@ static int a2xx_hw_init(struct msm_gpu *gpu) /* note: gsl doesn't set this */ gpu_write(gpu, REG_A2XX_RBBM_DEBUG, 0x00080000); - gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL, 0); - gpu_write(gpu, REG_AXXX_CP_INT_CNTL, 0x80000000); /* RB INT */ + gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL, + A2XX_RBBM_INT_CNTL_RDERR_INT_MASK); + gpu_write(gpu, REG_AXXX_CP_INT_CNTL, + AXXX_CP_INT_CNTL_T0_PACKET_IN_IB_MASK | + AXXX_CP_INT_CNTL_OPCODE_ERROR_MASK | + AXXX_CP_INT_CNTL_PROTECTED_MODE_ERROR_MASK | + AXXX_CP_INT_CNTL_RESERVED_BIT_ERROR_MASK | + AXXX_CP_INT_CNTL_IB_ERROR_MASK | + AXXX_CP_INT_CNTL_IB1_INT_MASK | + AXXX_CP_INT_CNTL_RB_INT_MASK); gpu_write(gpu, REG_A2XX_SQ_INT_CNTL, 0); + gpu_write(gpu, REG_A2XX_MH_INTERRUPT_MASK, + A2XX_MH_INTERRUPT_MASK_AXI_READ_ERROR | + A2XX_MH_INTERRUPT_MASK_AXI_WRITE_ERROR | + A2XX_MH_INTERRUPT_MASK_MMU_PAGE_FAULT); for (i = 3; i <= 5; i++) if ((SZ_16K << i) == adreno_gpu->gmem) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index adc442f736a2..473433f574f9 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -307,6 +307,7 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) static struct adreno_platform_config config = {}; const struct adreno_info *info; struct drm_device *drm = dev_get_drvdata(master); + struct msm_drm_private *priv = drm->dev_private; struct msm_gpu *gpu; int ret; @@ -329,6 +330,8 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) DBG("Found GPU: %u.%u.%u.%u", config.rev.core, config.rev.major, config.rev.minor, config.rev.patchid); + priv->is_a2xx = config.rev.core == 2; + gpu = info->init(drm); if (IS_ERR(gpu)) { dev_warn(drm->dev, "failed to load adreno gpu\n"); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 9ab67dd1bcd3..2e4372ef17a3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -769,6 +769,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, adreno_gpu_config.va_start = SZ_16M; adreno_gpu_config.va_end = 0xffffffff; + /* maximum range of a2xx mmu */ + if (adreno_is_a2xx(adreno_gpu)) + adreno_gpu_config.va_end = SZ_16M + 0xfff * SZ_64K; adreno_gpu_config.nr_rings = nr_rings; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 7661ca71fca6..ae3d6b440bcc 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -26,6 +26,7 @@ #include "msm_gem.h" #include "msm_gpu.h" #include "msm_kms.h" +#include "adreno/adreno_gpu.h" /* @@ -361,6 +362,14 @@ static int get_mdp_ver(struct platform_device *pdev) #include +bool msm_use_mmu(struct drm_device *dev) +{ + struct msm_drm_private *priv = dev->dev_private; + + /* a2xx comes with its own MMU */ + return priv->is_a2xx || iommu_present(&platform_bus_type); +} + static int msm_init_vram(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; @@ -399,7 +408,7 @@ static int msm_init_vram(struct drm_device *dev) * Grab the entire CMA chunk carved out in early startup in * mach-msm: */ - } else if (!iommu_present(&platform_bus_type)) { + } else if (!msm_use_mmu(dev)) { DRM_INFO("using %s VRAM carveout\n", vram); size = memparse(vram, NULL); } diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 71a03ce21da5..9cd6a96c6bf2 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -179,6 +179,8 @@ struct msm_drm_private { /* when we have more than one 'msm_gpu' these need to be an array: */ struct msm_gpu *gpu; struct msm_file_private *lastctx; + /* gpu is only set on open(), but we need this info earlier */ + bool is_a2xx; struct drm_fb_helper *fbdev; @@ -258,9 +260,15 @@ struct msm_gem_address_space * msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, const char *name); +struct msm_gem_address_space * +msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu, + const char *name, uint64_t va_start, uint64_t va_end); + int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu); void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu); +bool msm_use_mmu(struct drm_device *dev); + void msm_gem_submit_free(struct msm_gem_submit *submit); int msm_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 38b7f4e9e7ff..51a95da694d8 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -975,7 +975,7 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, size = PAGE_ALIGN(size); - if (!iommu_present(&platform_bus_type)) + if (!msm_use_mmu(dev)) use_vram = true; else if ((flags & (MSM_BO_STOLEN | MSM_BO_SCANOUT)) && priv->vram.size) use_vram = true; @@ -1052,7 +1052,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, int ret, npages; /* if we don't have IOMMU, don't bother pretending we can import: */ - if (!iommu_present(&platform_bus_type)) { + if (!msm_use_mmu(dev)) { DRM_DEV_ERROR(dev->dev, "cannot import without IOMMU\n"); return ERR_PTR(-EINVAL); } diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index ee46d8321b05..557360788084 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -159,3 +159,26 @@ msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain, return aspace; } + +struct msm_gem_address_space * +msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu, + const char *name, uint64_t va_start, uint64_t va_end) +{ + struct msm_gem_address_space *aspace; + u64 size = va_end - va_start; + + aspace = kzalloc(sizeof(*aspace), GFP_KERNEL); + if (!aspace) + return ERR_PTR(-ENOMEM); + + spin_lock_init(&aspace->lock); + aspace->name = name; + aspace->mmu = msm_gpummu_new(dev, gpu); + + drm_mm_init(&aspace->mm, (va_start >> PAGE_SHIFT), + size >> PAGE_SHIFT); + + kref_init(&aspace->kref); + + return aspace; +} diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index c3909ba75b12..6e079a83bd36 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -20,6 +20,7 @@ #include "msm_mmu.h" #include "msm_fence.h" #include "msm_gpu_trace.h" +#include "adreno/adreno_gpu.h" #include #include @@ -822,7 +823,6 @@ static struct msm_gem_address_space * msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev, uint64_t va_start, uint64_t va_end) { - struct iommu_domain *iommu; struct msm_gem_address_space *aspace; int ret; @@ -831,20 +831,27 @@ msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev, * and have separate page tables per context. For now, to keep things * simple and to get something working, just use a single address space: */ - iommu = iommu_domain_alloc(&platform_bus_type); - if (!iommu) - return NULL; + if (!adreno_is_a2xx(to_adreno_gpu(gpu))) { + struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type); + if (!iommu) + return NULL; - iommu->geometry.aperture_start = va_start; - iommu->geometry.aperture_end = va_end; + iommu->geometry.aperture_start = va_start; + iommu->geometry.aperture_end = va_end; - DRM_DEV_INFO(gpu->dev->dev, "%s: using IOMMU\n", gpu->name); + DRM_DEV_INFO(gpu->dev->dev, "%s: using IOMMU\n", gpu->name); + + aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu"); + if (IS_ERR(aspace)) + iommu_domain_free(iommu); + } else { + aspace = msm_gem_address_space_create_a2xx(&pdev->dev, gpu, "gpu", + va_start, va_end); + } - aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu"); if (IS_ERR(aspace)) { - DRM_DEV_ERROR(gpu->dev->dev, "failed to init iommu: %ld\n", + DRM_DEV_ERROR(gpu->dev->dev, "failed to init mmu: %ld\n", PTR_ERR(aspace)); - iommu_domain_free(iommu); return ERR_CAST(aspace); } diff --git a/drivers/gpu/drm/msm/msm_gpummu.c b/drivers/gpu/drm/msm/msm_gpummu.c new file mode 100644 index 000000000000..27312b553dd8 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_gpummu.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */ + +#include "msm_drv.h" +#include "msm_mmu.h" +#include "adreno/adreno_gpu.h" +#include "adreno/a2xx.xml.h" + +struct msm_gpummu { + struct msm_mmu base; + struct msm_gpu *gpu; + dma_addr_t pt_base; + uint32_t *table; +}; +#define to_msm_gpummu(x) container_of(x, struct msm_gpummu, base) + +#define GPUMMU_VA_START SZ_16M +#define GPUMMU_VA_RANGE (0xfff * SZ_64K) +#define GPUMMU_PAGE_SIZE SZ_4K +#define TABLE_SIZE (sizeof(uint32_t) * GPUMMU_VA_RANGE / GPUMMU_PAGE_SIZE) + +static int msm_gpummu_attach(struct msm_mmu *mmu, const char * const *names, + int cnt) +{ + return 0; +} + +static void msm_gpummu_detach(struct msm_mmu *mmu, const char * const *names, + int cnt) +{ +} + +static int msm_gpummu_map(struct msm_mmu *mmu, uint64_t iova, + struct sg_table *sgt, unsigned len, int prot) +{ + struct msm_gpummu *gpummu = to_msm_gpummu(mmu); + unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE; + struct scatterlist *sg; + unsigned prot_bits = 0; + unsigned i, j; + + if (prot & IOMMU_WRITE) + prot_bits |= 1; + if (prot & IOMMU_READ) + prot_bits |= 2; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) { + dma_addr_t addr = sg->dma_address; + for (j = 0; j < sg->length / GPUMMU_PAGE_SIZE; j++, idx++) { + gpummu->table[idx] = addr | prot_bits; + addr += GPUMMU_PAGE_SIZE; + } + } + + /* we can improve by deferring flush for multiple map() */ + gpu_write(gpummu->gpu, REG_A2XX_MH_MMU_INVALIDATE, + A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL | + A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC); + return 0; +} + +static int msm_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, unsigned len) +{ + struct msm_gpummu *gpummu = to_msm_gpummu(mmu); + unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE; + unsigned i; + + for (i = 0; i < len / GPUMMU_PAGE_SIZE; i++, idx++) + gpummu->table[idx] = 0; + + gpu_write(gpummu->gpu, REG_A2XX_MH_MMU_INVALIDATE, + A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL | + A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC); + return 0; +} + +static void msm_gpummu_destroy(struct msm_mmu *mmu) +{ + struct msm_gpummu *gpummu = to_msm_gpummu(mmu); + + dma_free_attrs(mmu->dev, TABLE_SIZE, gpummu->table, gpummu->pt_base, + DMA_ATTR_FORCE_CONTIGUOUS); + + kfree(gpummu); +} + +static const struct msm_mmu_funcs funcs = { + .attach = msm_gpummu_attach, + .detach = msm_gpummu_detach, + .map = msm_gpummu_map, + .unmap = msm_gpummu_unmap, + .destroy = msm_gpummu_destroy, +}; + +struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu) +{ + struct msm_gpummu *gpummu; + + gpummu = kzalloc(sizeof(*gpummu), GFP_KERNEL); + if (!gpummu) + return ERR_PTR(-ENOMEM); + + gpummu->table = dma_alloc_attrs(dev, TABLE_SIZE + 32, &gpummu->pt_base, + GFP_KERNEL | __GFP_ZERO, DMA_ATTR_FORCE_CONTIGUOUS); + if (!gpummu->table) { + kfree(gpummu); + return ERR_PTR(-ENOMEM); + } + + gpummu->gpu = gpu; + msm_mmu_init(&gpummu->base, dev, &funcs); + + return &gpummu->base; +} + +void msm_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base, + dma_addr_t *tran_error) +{ + dma_addr_t base = to_msm_gpummu(mmu)->pt_base; + + *pt_base = base; + *tran_error = base + TABLE_SIZE; /* 32-byte aligned */ +} diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h index 94c0b83d8026..d21b26604d0b 100644 --- a/drivers/gpu/drm/msm/msm_mmu.h +++ b/drivers/gpu/drm/msm/msm_mmu.h @@ -53,4 +53,7 @@ static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg, mmu->handler = handler; } +void msm_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base, + dma_addr_t *tran_error); + #endif /* __MSM_MMU_H__ */ From f72f4f1ae498a3c93c23c3d0e600df92977e86b1 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Tue, 4 Dec 2018 10:16:57 -0500 Subject: [PATCH 52/91] drm/msm/mdp4: add lcdc-align-lsb flag to control lane alignment This allows controlling which of the 8 lanes are used for 6 bit color. Signed-off-by: Jonathan Marek Reviewed-by: Rob Herring Signed-off-by: Rob Clark --- .../devicetree/bindings/display/msm/mdp4.txt | 2 ++ .../gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 21 ++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/display/msm/mdp4.txt b/Documentation/devicetree/bindings/display/msm/mdp4.txt index 3c341a15ccdc..b07eeb38f709 100644 --- a/Documentation/devicetree/bindings/display/msm/mdp4.txt +++ b/Documentation/devicetree/bindings/display/msm/mdp4.txt @@ -38,6 +38,8 @@ Required properties: Optional properties: - clock-names: the following clocks are optional: * "lut_clk" +- qcom,lcdc-align-lsb: Boolean value indicating that LSB alignment should be + used for LCDC. This is only valid for 18bpp panels. Example: diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c index 9e08c2efac24..c9e34501a89e 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c @@ -377,20 +377,25 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) unsigned long pc = mdp4_lcdc_encoder->pixclock; struct mdp4_kms *mdp4_kms = get_kms(encoder); struct drm_panel *panel; + uint32_t config; int i, ret; if (WARN_ON(mdp4_lcdc_encoder->enabled)) return; /* TODO: hard-coded for 18bpp: */ - mdp4_crtc_set_config(encoder->crtc, - MDP4_DMA_CONFIG_R_BPC(BPC6) | - MDP4_DMA_CONFIG_G_BPC(BPC6) | - MDP4_DMA_CONFIG_B_BPC(BPC6) | - MDP4_DMA_CONFIG_PACK_ALIGN_MSB | - MDP4_DMA_CONFIG_PACK(0x21) | - MDP4_DMA_CONFIG_DEFLKR_EN | - MDP4_DMA_CONFIG_DITHER_EN); + config = + MDP4_DMA_CONFIG_R_BPC(BPC6) | + MDP4_DMA_CONFIG_G_BPC(BPC6) | + MDP4_DMA_CONFIG_B_BPC(BPC6) | + MDP4_DMA_CONFIG_PACK(0x21) | + MDP4_DMA_CONFIG_DEFLKR_EN | + MDP4_DMA_CONFIG_DITHER_EN; + + if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb")) + config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB; + + mdp4_crtc_set_config(encoder->crtc, config); mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); bs_set(mdp4_lcdc_encoder, 1); From e888c279579e9c2409899eb3a5e9ad5b9f91260e Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Tue, 4 Dec 2018 10:17:01 -0500 Subject: [PATCH 53/91] dt-bindings: display: msm/gpu: document amd,imageon compatible Document the new amd,imageon compatible, used for non-qcom hardware that uses the drm/msm driver (iMX5). Signed-off-by: Jonathan Marek Reviewed-by: Rob Herring Signed-off-by: Rob Clark --- Documentation/devicetree/bindings/display/msm/gpu.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/msm/gpu.txt b/Documentation/devicetree/bindings/display/msm/gpu.txt index 43fac0fe09bb..ac8df3b871f9 100644 --- a/Documentation/devicetree/bindings/display/msm/gpu.txt +++ b/Documentation/devicetree/bindings/display/msm/gpu.txt @@ -1,11 +1,13 @@ Qualcomm adreno/snapdragon GPU Required properties: -- compatible: "qcom,adreno-XYZ.W", "qcom,adreno" +- compatible: "qcom,adreno-XYZ.W", "qcom,adreno" or + "amd,imageon-XYZ.W", "amd,imageon" for example: "qcom,adreno-306.0", "qcom,adreno" Note that you need to list the less specific "qcom,adreno" (since this is what the device is matched on), in addition to the more specific with the chip-id. + If "amd,imageon" is used, there should be no top level msm device. - reg: Physical base address and length of the controller's registers. - interrupts: The interrupt signal from the gpu. - clocks: device clocks From fb42b5354d71b09d3dcfcf4e38b1e98b277a0fc8 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Tue, 4 Dec 2018 14:42:27 -0800 Subject: [PATCH 54/91] dt-bindings: msm/dsi: Add ref clock for PHYs Allow the PHY drivers to get the ref clock from the DT. Signed-off-by: Matthias Kaehlcke Reviewed-by: Stephen Boyd Reviewed-by: Douglas Anderson Reviewed-by: Rob Herring Signed-off-by: Rob Clark --- Documentation/devicetree/bindings/display/msm/dsi.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/msm/dsi.txt b/Documentation/devicetree/bindings/display/msm/dsi.txt index dfc743219bd8..9ae946942720 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi.txt +++ b/Documentation/devicetree/bindings/display/msm/dsi.txt @@ -106,6 +106,7 @@ Required properties: - clocks: Phandles to device clocks. See [1] for details on clock bindings. - clock-names: the following clocks are required: * "iface" + * "ref" (only required for new DTS files/entries) For 28nm HPM/LP, 28nm 8960 PHYs: - vddio-supply: phandle to vdd-io regulator device node For 20nm PHY: From e6f6d63ed14c20528aa6df05a8f0707c183c6ba3 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Tue, 4 Dec 2018 10:16:58 -0500 Subject: [PATCH 55/91] drm/msm: add headless gpu device for imx5 This patch allows using drm/msm without qcom display hardware. It adds a amd,imageon compatible, which is used instead of qcom,adreno, but does not require a top level msm node. Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Kconfig | 4 +-- drivers/gpu/drm/msm/adreno/adreno_device.c | 35 ++++++++++++++++++++-- drivers/gpu/drm/msm/msm_debugfs.c | 2 +- drivers/gpu/drm/msm/msm_drv.c | 21 +++++++------ 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 843a9d40c05e..cf549f1ed403 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -2,7 +2,7 @@ config DRM_MSM tristate "MSM DRM" depends on DRM - depends on ARCH_QCOM || (ARM && COMPILE_TEST) + depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST) depends on OF && COMMON_CLK depends on MMU select QCOM_MDT_LOADER if ARCH_QCOM @@ -11,7 +11,7 @@ config DRM_MSM select DRM_PANEL select SHMEM select TMPFS - select QCOM_SCM + select QCOM_SCM if ARCH_QCOM select WANT_DEV_COREDUMP select SND_SOC_HDMI_CODEC if SND_SOC select SYNC_FILE diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 473433f574f9..714ed6505e47 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -271,7 +271,8 @@ static int find_chipid(struct device *dev, struct adreno_rev *rev) if (ret == 0) { unsigned int r, patch; - if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2) { + if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2 || + sscanf(compat, "amd,imageon-%u.%u", &r, &patch) == 2) { rev->core = r / 100; r %= 100; rev->major = r / 10; @@ -359,9 +360,37 @@ static const struct component_ops a3xx_ops = { .unbind = adreno_unbind, }; +static void adreno_device_register_headless(void) +{ + /* on imx5, we don't have a top-level mdp/dpu node + * this creates a dummy node for the driver for that case + */ + struct platform_device_info dummy_info = { + .parent = NULL, + .name = "msm", + .id = -1, + .res = NULL, + .num_res = 0, + .data = NULL, + .size_data = 0, + .dma_mask = ~0, + }; + platform_device_register_full(&dummy_info); +} + static int adreno_probe(struct platform_device *pdev) { - return component_add(&pdev->dev, &a3xx_ops); + + int ret; + + ret = component_add(&pdev->dev, &a3xx_ops); + if (ret) + return ret; + + if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon")) + adreno_device_register_headless(); + + return 0; } static int adreno_remove(struct platform_device *pdev) @@ -373,6 +402,8 @@ static int adreno_remove(struct platform_device *pdev) static const struct of_device_id dt_match[] = { { .compatible = "qcom,adreno" }, { .compatible = "qcom,adreno-3xx" }, + /* for compatibility with imx5 gpu: */ + { .compatible = "amd,imageon" }, /* for backwards compat w/ downstream kgsl DT files: */ { .compatible = "qcom,kgsl-3d0" }, {} diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 03210f45bf87..42a2cba78998 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -235,7 +235,7 @@ int msm_debugfs_init(struct drm_minor *minor) debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, dev, &msm_gpu_fops); - if (priv->kms->funcs->debugfs_init) { + if (priv->kms && priv->kms->funcs->debugfs_init) { ret = priv->kms->funcs->debugfs_init(priv->kms, minor); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index ae3d6b440bcc..79d1847f1c28 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -520,17 +520,13 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) priv->kms = kms; break; default: - kms = ERR_PTR(-ENODEV); + /* valid only for the dummy headless case, where of_node=NULL */ + WARN_ON(dev->of_node); + kms = NULL; break; } if (IS_ERR(kms)) { - /* - * NOTE: once we have GPU support, having no kms should not - * be considered fatal.. ideally we would still support gpu - * and (for example) use dmabuf/prime to share buffers with - * imx drm driver on iMX5 - */ DRM_DEV_ERROR(dev, "failed to load kms\n"); ret = PTR_ERR(kms); priv->kms = NULL; @@ -648,7 +644,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) drm_mode_config_reset(ddev); #ifdef CONFIG_DRM_FBDEV_EMULATION - if (fbdev) + if (kms && fbdev) priv->fbdev = msm_fbdev_init(ddev); #endif @@ -1332,6 +1328,7 @@ static int add_display_components(struct device *dev, static const struct of_device_id msm_gpu_match[] = { { .compatible = "qcom,adreno" }, { .compatible = "qcom,adreno-3xx" }, + { .compatible = "amd,imageon" }, { .compatible = "qcom,kgsl-3d0" }, { }, }; @@ -1376,9 +1373,11 @@ static int msm_pdev_probe(struct platform_device *pdev) struct component_match *match = NULL; int ret; - ret = add_display_components(&pdev->dev, &match); - if (ret) - return ret; + if (get_mdp_ver(pdev)) { + ret = add_display_components(&pdev->dev, &match); + if (ret) + return ret; + } ret = add_gpu_components(&pdev->dev, &match); if (ret) From ff5952a72cb4d04c976eeffd8443e4eef22e1bfb Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Mon, 3 Dec 2018 14:55:56 -0500 Subject: [PATCH 56/91] drm/msm: dpu: Allocate proper amount for dpu_crtc_state Since dpu_crtc subclasses crtc_state, we need a custom .reset hook in order to allocate the right amount of memory to accommodate the additional struct members in dpu_crtc_state. So bring it [partially] back. Relevant KASAN splat: [ 10.333382] ================================================================== [ 10.344288] BUG: KASAN: slab-out-of-bounds in kmemdup+0x50/0x80 [ 10.350390] Read of size 736 at addr ffffffc0d9f06080 by task frecon/394 [ 10.358861] CPU: 6 PID: 394 Comm: frecon Tainted: G W 4.19.4 #121 [ 10.366476] Hardware name: Google Cheza (rev2) (DT) [ 10.371514] Call trace: [ 10.374087] dump_backtrace+0x0/0x194 [ 10.377878] show_stack+0x20/0x28 [ 10.381330] dump_stack+0xa0/0xc8 [ 10.384783] print_address_description+0x78/0x2e0 [ 10.389639] kasan_report+0x290/0x2d0 [ 10.393428] check_memory_region+0x20/0x14c [ 10.397740] __asan_loadN+0x14/0x1c [ 10.401345] kmemdup+0x50/0x80 [ 10.404524] dpu_crtc_duplicate_state+0x58/0xa0 [ 10.409228] drm_atomic_get_crtc_state+0xac/0x178 [ 10.414095] __drm_atomic_helper_set_config+0x54/0x4a4 [ 10.419393] drm_atomic_helper_set_config+0x60/0xb4 [ 10.424435] drm_mode_setcrtc+0x720/0x760 [ 10.428570] drm_ioctl_kernel+0xd8/0x13c [ 10.432617] drm_ioctl+0x380/0x4f4 [ 10.436150] drm_compat_ioctl+0x54/0x13c [ 10.440219] __arm64_compat_sys_ioctl+0x1d8/0xef4 [ 10.445086] el0_svc_common+0xd8/0x138 [ 10.448961] el0_svc_compat_handler+0x58/0x68 [ 10.453463] el0_svc_compat+0x8/0x18 [ 10.458712] Allocated by task 56: [ 10.462148] kasan_kmalloc.part.4+0x48/0xf4 [ 10.466465] kasan_kmalloc+0x8c/0xa0 [ 10.470165] kmem_cache_alloc_trace+0x25c/0x27c [ 10.474848] drm_atomic_helper_crtc_reset+0x68/0x98 [ 10.479877] drm_mode_config_reset+0xc4/0x19c [ 10.484383] msm_drm_bind+0x814/0x8dc [ 10.488169] try_to_bring_up_master.part.7+0x48/0xac [ 10.493282] component_master_add_with_match+0x158/0x198 [ 10.498758] msm_pdev_probe+0x328/0x348 [ 10.502736] platform_drv_probe+0x74/0xc8 [ 10.506877] really_probe+0x1ac/0x35c [ 10.510659] driver_probe_device+0xd4/0x118 [ 10.514975] __device_attach_driver+0xc8/0xf4 [ 10.519477] bus_for_each_drv+0xb4/0xe4 [ 10.523439] __device_attach+0xd0/0x158 [ 10.527394] device_initial_probe+0x24/0x30 [ 10.531715] bus_probe_device+0x50/0xe4 [ 10.535681] deferred_probe_work_func+0xac/0xdc [ 10.540376] process_one_work+0x3f0/0x6d4 [ 10.544521] worker_thread+0x3f4/0x520 [ 10.548399] kthread+0x1b4/0x1c8 [ 10.551740] ret_from_fork+0x10/0x18 [ 10.556986] Freed by task 0: [ 10.559967] (stack is not available) [ 10.565216] The buggy address belongs to the object at ffffffc0d9f06080 which belongs to the cache kmalloc-1024 of size 1024 [ 10.578268] The buggy address is located 0 bytes inside of 1024-byte region [ffffffc0d9f06080, ffffffc0d9f06480) [ 10.590248] The buggy address belongs to the page: [ 10.595195] page:ffffffbf0367c000 count:1 mapcount:0 mapping:ffffffc0de40f680 index:0x0 compound_mapcount: 0 [ 10.605321] flags: 0x4000000000008100(slab|head) [ 10.610100] raw: 4000000000008100 ffffffbf0369fa08 ffffffbf0367f008 ffffffc0de40f680 [ 10.618077] raw: 0000000000000000 0000000000150015 00000001ffffffff 0000000000000000 [ 10.626049] page dumped because: kasan: bad access detected [ 10.633341] Memory state around the buggy address: [ 10.638282] ffffffc0d9f06180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 10.645710] ffffffc0d9f06200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 10.653139] >ffffffc0d9f06280: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc [ 10.660571] ^ [ 10.665774] ffffffc0d9f06300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 10.673210] ffffffc0d9f06380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 10.680639] ================================================================== Fixes: a6ba45afda41 (drm/msm/dpu: Replace dpu_crtc_reset by atomic helper) Cc: Sean Paul Cc: Bruce Wang Cc: Rob Clark Reviewed-by: Bruce Wang Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index cb62ef092c20..d8ca312fc30c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -819,6 +819,18 @@ static void _dpu_crtc_vblank_enable_no_lock( } } +static void dpu_crtc_reset(struct drm_crtc *crtc) +{ + struct dpu_crtc_state *cstate; + + if (crtc->state) + dpu_crtc_destroy_state(crtc, crtc->state); + + crtc->state = kzalloc(sizeof(*cstate), GFP_KERNEL); + if (crtc->state) + crtc->state->crtc = crtc; +} + /** * dpu_crtc_duplicate_state - state duplicate hook * @crtc: Pointer to drm crtc structure @@ -1466,7 +1478,7 @@ static const struct drm_crtc_funcs dpu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = dpu_crtc_destroy, .page_flip = drm_atomic_helper_page_flip, - .reset = drm_atomic_helper_crtc_reset, + .reset = dpu_crtc_reset, .atomic_duplicate_state = dpu_crtc_duplicate_state, .atomic_destroy_state = dpu_crtc_destroy_state, .late_register = dpu_crtc_late_register, From 5e1228d7fdedfbb1227e53706264bc7631c8e49c Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:11 -0500 Subject: [PATCH 57/91] drm/msm: dpu: Remove dpu_power_handle_get_dbus_name() It's only used for debugfs, so just output the enum value instead. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ++---- drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 14 -------------- drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 7 ------- 3 files changed, 2 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index d8ca312fc30c..17ab68feba49 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1397,11 +1397,9 @@ static int dpu_crtc_debugfs_state_show(struct seq_file *s, void *v) dpu_crtc->cur_perf.core_clk_rate); for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { - seq_printf(s, "bw_ctl[%s]: %llu\n", - dpu_power_handle_get_dbus_name(i), + seq_printf(s, "bw_ctl[%d]: %llu\n", i, dpu_crtc->cur_perf.bw_ctl[i]); - seq_printf(s, "max_per_pipe_ib[%s]: %llu\n", - dpu_power_handle_get_dbus_name(i), + seq_printf(s, "max_per_pipe_ib[%d]: %llu\n", i, dpu_crtc->cur_perf.max_per_pipe_ib[i]); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c index fc14116789f2..8c6f92aaaf87 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c @@ -24,20 +24,6 @@ #include "dpu_power_handle.h" #include "dpu_trace.h" -static const char *data_bus_name[DPU_POWER_HANDLE_DBUS_ID_MAX] = { - [DPU_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,dpu-data-bus", - [DPU_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,dpu-llcc-bus", - [DPU_POWER_HANDLE_DBUS_ID_EBI] = "qcom,dpu-ebi-bus", -}; - -const char *dpu_power_handle_get_dbus_name(u32 bus_id) -{ - if (bus_id < DPU_POWER_HANDLE_DBUS_ID_MAX) - return data_bus_name[bus_id]; - - return NULL; -} - static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle, u32 event_type) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h index a65b7a297f21..f627ae28ec68 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h @@ -207,11 +207,4 @@ struct dpu_power_event *dpu_power_handle_register_event( void dpu_power_handle_unregister_event(struct dpu_power_handle *phandle, struct dpu_power_event *event); -/** - * dpu_power_handle_get_dbus_name - get name of given data bus identifier - * @bus_id: data bus identifier - * Return: Pointer to name string if success; NULL otherwise - */ -const char *dpu_power_handle_get_dbus_name(u32 bus_id); - #endif /* _DPU_POWER_HANDLE_H_ */ From d05994dfa9509ccc88a4f687817410328902c5de Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:12 -0500 Subject: [PATCH 58/91] drm/msm: dpu: Remove unused trace_dpu_perf_update_bus() Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index 0c122e173892..7ab0ba8224f6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -99,27 +99,6 @@ TRACE_EVENT(dpu_perf_set_ot, __entry->vbif_idx) ) -TRACE_EVENT(dpu_perf_update_bus, - TP_PROTO(int client, unsigned long long ab_quota, - unsigned long long ib_quota), - TP_ARGS(client, ab_quota, ib_quota), - TP_STRUCT__entry( - __field(int, client) - __field(u64, ab_quota) - __field(u64, ib_quota) - ), - TP_fast_assign( - __entry->client = client; - __entry->ab_quota = ab_quota; - __entry->ib_quota = ib_quota; - ), - TP_printk("Request client:%d ab=%llu ib=%llu", - __entry->client, - __entry->ab_quota, - __entry->ib_quota) -) - - TRACE_EVENT(dpu_cmd_release_bw, TP_PROTO(u32 crtc_id), TP_ARGS(crtc_id), From 88447b9b58fab9aedb9fdb090e17694dd4933639 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:13 -0500 Subject: [PATCH 59/91] drm/msm: dpu: Remove dpu_power_client There's only one client -- core, and it's only used for runtime pm which is already refcounted. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 22 +---- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 96 +------------------ .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 86 +---------------- 4 files changed, 6 insertions(+), 199 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 1969f0d07d86..62a3a46715e3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -677,11 +677,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) dpu_hw_catalog_deinit(dpu_kms->catalog); dpu_kms->catalog = NULL; - if (dpu_kms->core_client) - dpu_power_client_destroy(&dpu_kms->phandle, - dpu_kms->core_client); - dpu_kms->core_client = NULL; - if (dpu_kms->vbif[VBIF_NRT]) devm_iounmap(&dpu_kms->pdev->dev, dpu_kms->vbif[VBIF_NRT]); dpu_kms->vbif[VBIF_NRT] = NULL; @@ -917,17 +912,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) dpu_kms->reg_dma_len = dpu_iomap_size(dpu_kms->pdev, "regdma"); } - dpu_kms->core_client = dpu_power_client_create(&dpu_kms->phandle, - "core"); - if (IS_ERR_OR_NULL(dpu_kms->core_client)) { - rc = PTR_ERR(dpu_kms->core_client); - if (!dpu_kms->core_client) - rc = -EINVAL; - DPU_ERROR("dpu power client create failed: %d\n", rc); - dpu_kms->core_client = NULL; - goto error; - } - pm_runtime_get_sync(&dpu_kms->pdev->dev); _dpu_kms_core_hw_rev_init(dpu_kms); @@ -1161,8 +1145,7 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev) return rc; } - rc = dpu_power_resource_enable(&dpu_kms->phandle, - dpu_kms->core_client, false); + rc = dpu_power_resource_enable(&dpu_kms->phandle, false); if (rc) DPU_ERROR("resource disable failed: %d\n", rc); @@ -1193,8 +1176,7 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) return rc; } - rc = dpu_power_resource_enable(&dpu_kms->phandle, - dpu_kms->core_client, true); + rc = dpu_power_resource_enable(&dpu_kms->phandle, true); if (rc) DPU_ERROR("resource enable failed: %d\n", rc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 2a3625eef6d3..f2c78deb0854 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -114,7 +114,6 @@ struct dpu_kms { struct dpu_mdss_cfg *catalog; struct dpu_power_handle phandle; - struct dpu_power_client *core_client; struct dpu_power_event *power_event; /* directory entry for debugfs */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c index 8c6f92aaaf87..8e64f0a52147 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c @@ -35,59 +35,11 @@ static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle, } } -struct dpu_power_client *dpu_power_client_create( - struct dpu_power_handle *phandle, char *client_name) -{ - struct dpu_power_client *client; - static u32 id; - - if (!client_name || !phandle) { - pr_err("client name is null or invalid power data\n"); - return ERR_PTR(-EINVAL); - } - - client = kzalloc(sizeof(struct dpu_power_client), GFP_KERNEL); - if (!client) - return ERR_PTR(-ENOMEM); - - mutex_lock(&phandle->phandle_lock); - strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN); - client->usecase_ndx = VOTE_INDEX_DISABLE; - client->id = id; - client->active = true; - pr_debug("client %s created:%pK id :%d\n", client_name, - client, id); - id++; - list_add(&client->list, &phandle->power_client_clist); - mutex_unlock(&phandle->phandle_lock); - - return client; -} - -void dpu_power_client_destroy(struct dpu_power_handle *phandle, - struct dpu_power_client *client) -{ - if (!client || !phandle) { - pr_err("reg bus vote: invalid client handle\n"); - } else if (!client->active) { - pr_err("dpu power deinit already done\n"); - kfree(client); - } else { - pr_debug("bus vote client %s destroyed:%pK id:%u\n", - client->name, client, client->id); - mutex_lock(&phandle->phandle_lock); - list_del_init(&client->list); - mutex_unlock(&phandle->phandle_lock); - kfree(client); - } -} - void dpu_power_resource_init(struct platform_device *pdev, struct dpu_power_handle *phandle) { phandle->dev = &pdev->dev; - INIT_LIST_HEAD(&phandle->power_client_clist); INIT_LIST_HEAD(&phandle->event_list); mutex_init(&phandle->phandle_lock); @@ -96,7 +48,6 @@ void dpu_power_resource_init(struct platform_device *pdev, void dpu_power_resource_deinit(struct platform_device *pdev, struct dpu_power_handle *phandle) { - struct dpu_power_client *curr_client, *next_client; struct dpu_power_event *curr_event, *next_event; if (!phandle || !pdev) { @@ -105,15 +56,6 @@ void dpu_power_resource_deinit(struct platform_device *pdev, } mutex_lock(&phandle->phandle_lock); - list_for_each_entry_safe(curr_client, next_client, - &phandle->power_client_clist, list) { - pr_err("client:%s-%d still registered with refcount:%d\n", - curr_client->name, curr_client->id, - curr_client->refcount); - curr_client->active = false; - list_del(&curr_client->list); - } - list_for_each_entry_safe(curr_event, next_event, &phandle->event_list, list) { pr_err("event:%d, client:%s still registered\n", @@ -125,53 +67,21 @@ void dpu_power_resource_deinit(struct platform_device *pdev, mutex_unlock(&phandle->phandle_lock); } -int dpu_power_resource_enable(struct dpu_power_handle *phandle, - struct dpu_power_client *pclient, bool enable) +int dpu_power_resource_enable(struct dpu_power_handle *phandle, bool enable) { - bool changed = false; - u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx; - struct dpu_power_client *client; u32 event_type; - if (!phandle || !pclient) { + if (!phandle) { pr_err("invalid input argument\n"); return -EINVAL; } mutex_lock(&phandle->phandle_lock); - if (enable) - pclient->refcount++; - else if (pclient->refcount) - pclient->refcount--; - - if (pclient->refcount) - pclient->usecase_ndx = VOTE_INDEX_LOW; - else - pclient->usecase_ndx = VOTE_INDEX_DISABLE; - - list_for_each_entry(client, &phandle->power_client_clist, list) { - if (client->usecase_ndx < VOTE_INDEX_MAX && - client->usecase_ndx > max_usecase_ndx) - max_usecase_ndx = client->usecase_ndx; - } - - if (phandle->current_usecase_ndx != max_usecase_ndx) { - changed = true; - prev_usecase_ndx = phandle->current_usecase_ndx; - phandle->current_usecase_ndx = max_usecase_ndx; - } - - pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n", - __builtin_return_address(0), changed, max_usecase_ndx, - pclient->name, pclient->id, enable, pclient->refcount); - - if (!changed) - goto end; event_type = enable ? DPU_POWER_EVENT_ENABLE : DPU_POWER_EVENT_DISABLE; dpu_power_event_trigger_locked(phandle, event_type); -end: + mutex_unlock(&phandle->phandle_lock); return 0; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h index f627ae28ec68..124ebc93c877 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h @@ -27,30 +27,6 @@ #define DPU_POWER_EVENT_DISABLE BIT(0) #define DPU_POWER_EVENT_ENABLE BIT(1) -/** - * mdss_bus_vote_type: register bus vote type - * VOTE_INDEX_DISABLE: removes the client vote - * VOTE_INDEX_LOW: keeps the lowest vote for register bus - * VOTE_INDEX_MAX: invalid - */ -enum mdss_bus_vote_type { - VOTE_INDEX_DISABLE, - VOTE_INDEX_LOW, - VOTE_INDEX_MAX, -}; - -/** - * enum dpu_power_handle_data_bus_client - type of axi bus clients - * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT: core real-time bus client - * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT: core non-real-time bus client - * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX: maximum number of bus client type - */ -enum dpu_power_handle_data_bus_client { - DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT, - DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT, - DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX -}; - /** * enum DPU_POWER_HANDLE_DBUS_ID - data bus identifier * @DPU_POWER_HANDLE_DBUS_ID_MNOC: DPU/MNOC data bus @@ -64,31 +40,6 @@ enum DPU_POWER_HANDLE_DBUS_ID { DPU_POWER_HANDLE_DBUS_ID_MAX, }; -/** - * struct dpu_power_client: stores the power client for dpu driver - * @name: name of the client - * @usecase_ndx: current regs bus vote type - * @refcount: current refcount if multiple modules are using same - * same client for enable/disable. Power module will - * aggregate the refcount and vote accordingly for this - * client. - * @id: assigned during create. helps for debugging. - * @list: list to attach power handle master list - * @ab: arbitrated bandwidth for each bus client - * @ib: instantaneous bandwidth for each bus client - * @active: inidcates the state of dpu power handle - */ -struct dpu_power_client { - char name[MAX_CLIENT_NAME_LEN]; - short usecase_ndx; - short refcount; - u32 id; - struct list_head list; - u64 ab[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX]; - u64 ib[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX]; - bool active; -}; - /* * struct dpu_power_event - local event registration structure * @client_name: name of the client registering @@ -109,14 +60,12 @@ struct dpu_power_event { /** * struct dpu_power_handle: power handle main struct - * @client_clist: master list to store all clients * @phandle_lock: lock to synchronize the enable/disable * @dev: pointer to device structure * @usecase_ndx: current usecase index * @event_list: current power handle event list */ struct dpu_power_handle { - struct list_head power_client_clist; struct mutex phandle_lock; struct device *dev; u32 current_usecase_ndx; @@ -141,47 +90,14 @@ void dpu_power_resource_init(struct platform_device *pdev, void dpu_power_resource_deinit(struct platform_device *pdev, struct dpu_power_handle *pdata); -/** - * dpu_power_client_create() - create the client on power handle - * @pdata: power handle containing the resources - * @client_name: new client name for registration - * - * Return: error code. - */ -struct dpu_power_client *dpu_power_client_create(struct dpu_power_handle *pdata, - char *client_name); - -/** - * dpu_power_client_destroy() - destroy the client on power handle - * @pdata: power handle containing the resources - * @client_name: new client name for registration - * - * Return: none - */ -void dpu_power_client_destroy(struct dpu_power_handle *phandle, - struct dpu_power_client *client); - /** * dpu_power_resource_enable() - enable/disable the power resources * @pdata: power handle containing the resources - * @client: client information to enable/disable its vote * @enable: boolean request for enable/disable * * Return: error code. */ -int dpu_power_resource_enable(struct dpu_power_handle *pdata, - struct dpu_power_client *pclient, bool enable); - -/** - * dpu_power_data_bus_bandwidth_ctrl() - control data bus bandwidth enable - * @phandle: power handle containing the resources - * @client: client information to bandwidth control - * @enable: true to enable bandwidth for data base - * - * Return: none - */ -void dpu_power_data_bus_bandwidth_ctrl(struct dpu_power_handle *phandle, - struct dpu_power_client *pclient, int enable); +int dpu_power_resource_enable(struct dpu_power_handle *pdata, bool enable); /** * dpu_power_handle_register_event - register a callback function for an event. From c24b6330035acd992bc1bd682bbc955f21153294 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:14 -0500 Subject: [PATCH 60/91] drm/msm: dpu: Don't use power_event for vbif_init_memtypes power_events are only used for pm_runtime, and that's all handled in dpu_kms. So just call vbif_init_memtypes at the correct times. Changes in v2: - Removed obsolete comment (Jeykumar) Cc: Jeykumar Sankaran Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 24 +++--------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 62a3a46715e3..62bba492d81c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -652,10 +652,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) dpu_hw_intr_destroy(dpu_kms->hw_intr); dpu_kms->hw_intr = NULL; - if (dpu_kms->power_event) - dpu_power_handle_unregister_event( - &dpu_kms->phandle, dpu_kms->power_event); - /* safe to call these more than once during shutdown */ _dpu_debugfs_destroy(dpu_kms); _dpu_kms_mmu_destroy(dpu_kms); @@ -836,16 +832,6 @@ u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name) return clk_get_rate(clk->clk); } -static void dpu_kms_handle_power_event(u32 event_type, void *usr) -{ - struct dpu_kms *dpu_kms = usr; - - if (!dpu_kms) - return; - - dpu_vbif_init_memtypes(dpu_kms); -} - static int dpu_kms_hw_init(struct msm_kms *kms) { struct dpu_kms *dpu_kms; @@ -1016,13 +1002,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) */ dev->mode_config.allow_fb_modifiers = true; - /* - * Handle (re)initializations during power enable - */ - dpu_kms_handle_power_event(DPU_POWER_EVENT_ENABLE, dpu_kms); - dpu_kms->power_event = dpu_power_handle_register_event( - &dpu_kms->phandle, DPU_POWER_EVENT_ENABLE, - dpu_kms_handle_power_event, dpu_kms, "kms"); + dpu_vbif_init_memtypes(dpu_kms); pm_runtime_put_sync(&dpu_kms->pdev->dev); @@ -1176,6 +1156,8 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) return rc; } + dpu_vbif_init_memtypes(dpu_kms); + rc = dpu_power_resource_enable(&dpu_kms->phandle, true); if (rc) DPU_ERROR("resource enable failed: %d\n", rc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index f2c78deb0854..5f08be187c86 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -114,7 +114,6 @@ struct dpu_kms { struct dpu_mdss_cfg *catalog; struct dpu_power_handle phandle; - struct dpu_power_event *power_event; /* directory entry for debugfs */ struct dentry *debugfs_root; From 3cf63cd5f880988fd0a223f36c08cdd1b628c78d Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:15 -0500 Subject: [PATCH 61/91] drm/msm: dpu: Handle crtc pm_runtime_resume() directly Instead of registering through dpu_power_handle just to get a call on runtime_resume, call the crtc function directly. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 23 ++++++----------------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 10 ++++++---- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 ++++ drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 8 ++++---- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 17ab68feba49..e0f55259aa6d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -33,7 +33,6 @@ #include "dpu_plane.h" #include "dpu_encoder.h" #include "dpu_vbif.h" -#include "dpu_power_handle.h" #include "dpu_core_perf.h" #include "dpu_trace.h" @@ -69,8 +68,6 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc) if (!crtc) return; - dpu_crtc->phandle = NULL; - drm_crtc_cleanup(crtc); mutex_destroy(&dpu_crtc->crtc_lock); kfree(dpu_crtc); @@ -860,15 +857,17 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc) return &cstate->base; } -static void dpu_crtc_handle_power_event(u32 event_type, void *arg) +void dpu_crtc_runtime_resume(struct drm_crtc *crtc) { - struct drm_crtc *crtc = arg; struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct drm_encoder *encoder; mutex_lock(&dpu_crtc->crtc_lock); - trace_dpu_crtc_handle_power_event(DRMID(crtc), event_type); + if (!dpu_crtc->enabled) + goto end; + + trace_dpu_crtc_runtime_resume(DRMID(crtc)); /* restore encoder; crtc will be programmed during commit */ drm_for_each_encoder(encoder, crtc->dev) { @@ -878,6 +877,7 @@ static void dpu_crtc_handle_power_event(u32 event_type, void *arg) dpu_encoder_virt_restore(encoder); } +end: mutex_unlock(&dpu_crtc->crtc_lock); } @@ -933,10 +933,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) dpu_encoder_register_frame_event_callback(encoder, NULL, NULL); } - if (dpu_crtc->power_event) - dpu_power_handle_unregister_event(dpu_crtc->phandle, - dpu_crtc->power_event); - memset(cstate->mixers, 0, sizeof(cstate->mixers)); cstate->num_mixers = 0; @@ -988,11 +984,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, /* Enable/restore vblank irq handling */ drm_crtc_vblank_on(crtc); - - dpu_crtc->power_event = dpu_power_handle_register_event( - dpu_crtc->phandle, DPU_POWER_EVENT_ENABLE, - dpu_crtc_handle_power_event, crtc, dpu_crtc->name); - } struct plane_state { @@ -1539,8 +1530,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, /* initialize event handling */ spin_lock_init(&dpu_crtc->event_lock); - dpu_crtc->phandle = &kms->phandle; - DPU_DEBUG("%s: successfully initialized crtc\n", dpu_crtc->name); return crtc; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index ec633ce3ee6c..d5cd7a0b302f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -151,7 +151,6 @@ struct dpu_crtc_frame_event { * @event_worker : Event worker queue * @event_lock : Spinlock around event handling code * @phandle: Pointer to power handler - * @power_event : registered power event handle * @cur_perf : current performance committed to clock/bandwidth driver */ struct dpu_crtc { @@ -187,9 +186,6 @@ struct dpu_crtc { /* for handling internal event thread */ spinlock_t event_lock; - struct dpu_power_handle *phandle; - struct dpu_power_event *power_event; - struct dpu_core_perf_params cur_perf; struct dpu_crtc_smmu_state_data smmu_state; @@ -334,4 +330,10 @@ static inline bool dpu_crtc_is_enabled(struct drm_crtc *crtc) return crtc ? crtc->enabled : false; } +/** + * dpu_crtc_runtime_resume - called by the top-level on pm_runtime_resume + * @crtc: CRTC to resume + */ +void dpu_crtc_runtime_resume(struct drm_crtc *crtc); + #endif /* _DPU_CRTC_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 62bba492d81c..85247a9a80f2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1141,6 +1141,7 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) int rc = -1; struct platform_device *pdev = to_platform_device(dev); struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); + struct drm_crtc *crtc; struct drm_device *ddev; struct dss_module_power *mp = &dpu_kms->mp; @@ -1158,6 +1159,9 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) dpu_vbif_init_memtypes(dpu_kms); + drm_for_each_crtc(crtc, ddev) + dpu_crtc_runtime_resume(crtc); + rc = dpu_power_resource_enable(&dpu_kms->phandle, true); if (rc) DPU_ERROR("resource enable failed: %d\n", rc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index 7ab0ba8224f6..328df37d7580 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -298,6 +298,10 @@ DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_wait_for_commit_done, TP_PROTO(uint32_t drm_id), TP_ARGS(drm_id) ); +DEFINE_EVENT(dpu_drm_obj_template, dpu_crtc_runtime_resume, + TP_PROTO(uint32_t drm_id), + TP_ARGS(drm_id) +); TRACE_EVENT(dpu_enc_enable, TP_PROTO(uint32_t drm_id, int hdisplay, int vdisplay), @@ -518,10 +522,6 @@ DEFINE_EVENT(dpu_id_event_template, dpu_crtc_frame_event_cb, TP_PROTO(uint32_t drm_id, u32 event), TP_ARGS(drm_id, event) ); -DEFINE_EVENT(dpu_id_event_template, dpu_crtc_handle_power_event, - TP_PROTO(uint32_t drm_id, u32 event), - TP_ARGS(drm_id, event) -); DEFINE_EVENT(dpu_id_event_template, dpu_crtc_frame_event_done, TP_PROTO(uint32_t drm_id, u32 event), TP_ARGS(drm_id, event) From b2bb51e83539c9bebd58c3d809c862ea52410969 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:16 -0500 Subject: [PATCH 62/91] drm/msm: dpu: Remove power_handle from core_perf It's unused Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 3 --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 5 ----- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1 - 3 files changed, 9 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 22e84b3d7f98..ef6dd43f8bec 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -605,7 +605,6 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf) dpu_core_perf_debugfs_destroy(perf); perf->max_core_clk_rate = 0; perf->core_clk = NULL; - perf->phandle = NULL; perf->catalog = NULL; perf->dev = NULL; } @@ -613,12 +612,10 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf) int dpu_core_perf_init(struct dpu_core_perf *perf, struct drm_device *dev, struct dpu_mdss_cfg *catalog, - struct dpu_power_handle *phandle, struct dss_clk *core_clk) { perf->dev = dev; perf->catalog = catalog; - perf->phandle = phandle; perf->core_clk = core_clk; perf->max_core_clk_rate = core_clk->max_rate; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h index fbcbe0c7527a..68b84d85eb8f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -19,7 +19,6 @@ #include #include "dpu_hw_catalog.h" -#include "dpu_power_handle.h" #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 @@ -52,7 +51,6 @@ struct dpu_core_perf_tune { * @dev: Pointer to drm device * @debugfs_root: top level debug folder * @catalog: Pointer to catalog configuration - * @phandle: Pointer to power handler * @core_clk: Pointer to core clock structure * @core_clk_rate: current core clock rate * @max_core_clk_rate: maximum allowable core clock rate @@ -66,7 +64,6 @@ struct dpu_core_perf { struct drm_device *dev; struct dentry *debugfs_root; struct dpu_mdss_cfg *catalog; - struct dpu_power_handle *phandle; struct dss_clk *core_clk; u64 core_clk_rate; u64 max_core_clk_rate; @@ -113,13 +110,11 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf); * @perf: Pointer to core performance context * @dev: Pointer to drm device * @catalog: Pointer to catalog - * @phandle: Pointer to power handle * @core_clk: pointer to core clock */ int dpu_core_perf_init(struct dpu_core_perf *perf, struct drm_device *dev, struct dpu_mdss_cfg *catalog, - struct dpu_power_handle *phandle, struct dss_clk *core_clk); /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 85247a9a80f2..7ea24d989d10 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -961,7 +961,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) } rc = dpu_core_perf_init(&dpu_kms->perf, dev, dpu_kms->catalog, - &dpu_kms->phandle, _dpu_kms_get_clk(dpu_kms, "core")); if (rc) { DPU_ERROR("failed to init perf %d\n", rc); From d53a61e1c055de1174cd227ecc07dbcdfe1f2530 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:17 -0500 Subject: [PATCH 63/91] drm/msm: dpu: Include dpu_io_util.h directly in dpu_kms.h It's needed for struct dss_module_power, and is currently being pulled in by dpu_power_handle.h Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 5f08be187c86..4e5acacb3065 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -29,6 +29,7 @@ #include "dpu_hw_lm.h" #include "dpu_hw_interrupts.h" #include "dpu_hw_top.h" +#include "dpu_io_util.h" #include "dpu_rm.h" #include "dpu_power_handle.h" #include "dpu_irq.h" From aeb7b49a1b0fc2c8d8de6bb890ccbf40015ecb2c Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:18 -0500 Subject: [PATCH 64/91] drm/msm: dpu: Move DPU_POWER_HANDLE_DBUS_ID to core_perf It's only used in core_perf, so stick it there (and change the name to reflect that). Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 34 +++++++++---------- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 17 ++++++++-- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 +-- .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 13 ------- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index ef6dd43f8bec..bffc51e496e7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -95,20 +95,20 @@ static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms, memset(perf, 0, sizeof(struct dpu_core_perf_params)); if (!dpu_cstate->bw_control) { - for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { perf->bw_ctl[i] = kms->catalog->perf.max_bw_high * 1000ULL; perf->max_per_pipe_ib[i] = perf->bw_ctl[i]; } perf->core_clk_rate = kms->perf.max_core_clk_rate; } else if (kms->perf.perf_tune.mode == DPU_PERF_MODE_MINIMUM) { - for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { perf->bw_ctl[i] = 0; perf->max_per_pipe_ib[i] = 0; } perf->core_clk_rate = 0; } else if (kms->perf.perf_tune.mode == DPU_PERF_MODE_FIXED) { - for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { perf->bw_ctl[i] = kms->perf.fix_core_ab_vote; perf->max_per_pipe_ib[i] = kms->perf.fix_core_ib_vote; } @@ -118,12 +118,12 @@ static void _dpu_core_perf_calc_crtc(struct dpu_kms *kms, DPU_DEBUG( "crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu llcc_ib=%llu llcc_ab=%llu mem_ib=%llu mem_ab=%llu\n", crtc->base.id, perf->core_clk_rate, - perf->max_per_pipe_ib[DPU_POWER_HANDLE_DBUS_ID_MNOC], - perf->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_MNOC], - perf->max_per_pipe_ib[DPU_POWER_HANDLE_DBUS_ID_LLCC], - perf->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_LLCC], - perf->max_per_pipe_ib[DPU_POWER_HANDLE_DBUS_ID_EBI], - perf->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_EBI]); + perf->max_per_pipe_ib[DPU_CORE_PERF_DATA_BUS_ID_MNOC], + perf->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_MNOC], + perf->max_per_pipe_ib[DPU_CORE_PERF_DATA_BUS_ID_LLCC], + perf->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_LLCC], + perf->max_per_pipe_ib[DPU_CORE_PERF_DATA_BUS_ID_EBI], + perf->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_EBI]); } int dpu_core_perf_crtc_check(struct drm_crtc *crtc, @@ -158,8 +158,8 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, /* obtain new values */ _dpu_core_perf_calc_crtc(kms, crtc, state, &dpu_cstate->new_perf); - for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC; - i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = DPU_CORE_PERF_DATA_BUS_ID_MNOC; + i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { bw_sum_of_intfs = dpu_cstate->new_perf.bw_ctl[i]; curr_client_type = dpu_crtc_get_client_type(crtc); @@ -290,7 +290,7 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc) if (kms->perf.enable_bw_release) { trace_dpu_cmd_release_bw(crtc->base.id); DPU_DEBUG("Release BW crtc=%d\n", crtc->base.id); - for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { dpu_crtc->cur_perf.bw_ctl[i] = 0; _dpu_core_perf_crtc_update_bus(kms, crtc, i); } @@ -367,7 +367,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, new = &dpu_cstate->new_perf; if (_dpu_core_perf_crtc_is_power_on(crtc) && !stop_req) { - for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { /* * cases for bus bandwidth update. * 1. new bandwidth vote - "ab or ib vote" is higher @@ -409,13 +409,13 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, update_clk = 1; } trace_dpu_perf_crtc_update(crtc->base.id, - new->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_MNOC], - new->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_LLCC], - new->bw_ctl[DPU_POWER_HANDLE_DBUS_ID_EBI], + new->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_MNOC], + new->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_LLCC], + new->bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_EBI], new->core_clk_rate, stop_req, update_bus, update_clk); - for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { if (update_bus & BIT(i)) { ret = _dpu_core_perf_crtc_update_bus(kms, crtc, i); if (ret) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h index 68b84d85eb8f..c708451a94a1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -22,6 +22,19 @@ #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 +/** + * enum dpu_core_perf_data_bus_id - data bus identifier + * @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus + * @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus + * @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus + */ +enum dpu_core_perf_data_bus_id { + DPU_CORE_PERF_DATA_BUS_ID_MNOC, + DPU_CORE_PERF_DATA_BUS_ID_LLCC, + DPU_CORE_PERF_DATA_BUS_ID_EBI, + DPU_CORE_PERF_DATA_BUS_ID_MAX, +}; + /** * struct dpu_core_perf_params - definition of performance parameters * @max_per_pipe_ib: maximum instantaneous bandwidth request @@ -29,8 +42,8 @@ * @core_clk_rate: core clock rate request */ struct dpu_core_perf_params { - u64 max_per_pipe_ib[DPU_POWER_HANDLE_DBUS_ID_MAX]; - u64 bw_ctl[DPU_POWER_HANDLE_DBUS_ID_MAX]; + u64 max_per_pipe_ib[DPU_CORE_PERF_DATA_BUS_ID_MAX]; + u64 bw_ctl[DPU_CORE_PERF_DATA_BUS_ID_MAX]; u64 core_clk_rate; }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index e0f55259aa6d..61449e311819 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1386,8 +1386,8 @@ static int dpu_crtc_debugfs_state_show(struct seq_file *s, void *v) seq_printf(s, "intf_mode: %d\n", dpu_crtc_get_intf_mode(crtc)); seq_printf(s, "core_clk_rate: %llu\n", dpu_crtc->cur_perf.core_clk_rate); - for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC; - i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) { + for (i = DPU_CORE_PERF_DATA_BUS_ID_MNOC; + i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { seq_printf(s, "bw_ctl[%d]: %llu\n", i, dpu_crtc->cur_perf.bw_ctl[i]); seq_printf(s, "max_per_pipe_ib[%d]: %llu\n", i, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h index 124ebc93c877..7536624c8b20 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h @@ -27,19 +27,6 @@ #define DPU_POWER_EVENT_DISABLE BIT(0) #define DPU_POWER_EVENT_ENABLE BIT(1) -/** - * enum DPU_POWER_HANDLE_DBUS_ID - data bus identifier - * @DPU_POWER_HANDLE_DBUS_ID_MNOC: DPU/MNOC data bus - * @DPU_POWER_HANDLE_DBUS_ID_LLCC: MNOC/LLCC data bus - * @DPU_POWER_HANDLE_DBUS_ID_EBI: LLCC/EBI data bus - */ -enum DPU_POWER_HANDLE_DBUS_ID { - DPU_POWER_HANDLE_DBUS_ID_MNOC, - DPU_POWER_HANDLE_DBUS_ID_LLCC, - DPU_POWER_HANDLE_DBUS_ID_EBI, - DPU_POWER_HANDLE_DBUS_ID_MAX, -}; - /* * struct dpu_power_event - local event registration structure * @client_name: name of the client registering From 09a2e645b0f7a5af061b0bf66dd1e04a7a78caf5 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:19 -0500 Subject: [PATCH 65/91] drm/msm: dpu: Remove dpu_power_handle Now that we don't have any event handlers, remove dpu_power_handle! Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 11 -- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 3 - .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 136 ------------------ .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 113 --------------- 5 files changed, 264 deletions(-) delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 1b26c410599d..f45ac4c19258 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -74,7 +74,6 @@ msm-y := \ disp/dpu1/dpu_kms.o \ disp/dpu1/dpu_mdss.o \ disp/dpu1/dpu_plane.o \ - disp/dpu1/dpu_power_handle.o \ disp/dpu1/dpu_rm.o \ disp/dpu1/dpu_vbif.o \ msm_atomic.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 7ea24d989d10..610845bb72e0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1064,8 +1064,6 @@ static int dpu_bind(struct device *dev, struct device *master, void *data) return ret; } - dpu_power_resource_init(pdev, &dpu_kms->phandle); - platform_set_drvdata(pdev, dpu_kms); msm_kms_init(&dpu_kms->base, &kms_funcs); @@ -1085,7 +1083,6 @@ static void dpu_unbind(struct device *dev, struct device *master, void *data) struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); struct dss_module_power *mp = &dpu_kms->mp; - dpu_power_resource_deinit(pdev, &dpu_kms->phandle); msm_dss_put_clk(mp->clk_config, mp->num_clk); devm_kfree(&pdev->dev, mp->clk_config); mp->num_clk = 0; @@ -1124,10 +1121,6 @@ static int __maybe_unused dpu_runtime_suspend(struct device *dev) return rc; } - rc = dpu_power_resource_enable(&dpu_kms->phandle, false); - if (rc) - DPU_ERROR("resource disable failed: %d\n", rc); - rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); if (rc) DPU_ERROR("clock disable failed rc:%d\n", rc); @@ -1161,10 +1154,6 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) drm_for_each_crtc(crtc, ddev) dpu_crtc_runtime_resume(crtc); - rc = dpu_power_resource_enable(&dpu_kms->phandle, true); - if (rc) - DPU_ERROR("resource enable failed: %d\n", rc); - return rc; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 4e5acacb3065..59e18e2d3c59 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -31,7 +31,6 @@ #include "dpu_hw_top.h" #include "dpu_io_util.h" #include "dpu_rm.h" -#include "dpu_power_handle.h" #include "dpu_irq.h" #include "dpu_core_perf.h" @@ -114,8 +113,6 @@ struct dpu_kms { int core_rev; struct dpu_mdss_cfg *catalog; - struct dpu_power_handle phandle; - /* directory entry for debugfs */ struct dentry *debugfs_root; struct dentry *debugfs_danger; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c deleted file mode 100644 index 8e64f0a52147..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#define pr_fmt(fmt) "[drm:%s:%d]: " fmt, __func__, __LINE__ - -#include -#include -#include -#include -#include -#include -#include - -#include "dpu_power_handle.h" -#include "dpu_trace.h" - -static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle, - u32 event_type) -{ - struct dpu_power_event *event; - - list_for_each_entry(event, &phandle->event_list, list) { - if (event->event_type & event_type) - event->cb_fnc(event_type, event->usr); - } -} - -void dpu_power_resource_init(struct platform_device *pdev, - struct dpu_power_handle *phandle) -{ - phandle->dev = &pdev->dev; - - INIT_LIST_HEAD(&phandle->event_list); - - mutex_init(&phandle->phandle_lock); -} - -void dpu_power_resource_deinit(struct platform_device *pdev, - struct dpu_power_handle *phandle) -{ - struct dpu_power_event *curr_event, *next_event; - - if (!phandle || !pdev) { - pr_err("invalid input param\n"); - return; - } - - mutex_lock(&phandle->phandle_lock); - list_for_each_entry_safe(curr_event, next_event, - &phandle->event_list, list) { - pr_err("event:%d, client:%s still registered\n", - curr_event->event_type, - curr_event->client_name); - curr_event->active = false; - list_del(&curr_event->list); - } - mutex_unlock(&phandle->phandle_lock); -} - -int dpu_power_resource_enable(struct dpu_power_handle *phandle, bool enable) -{ - u32 event_type; - - if (!phandle) { - pr_err("invalid input argument\n"); - return -EINVAL; - } - - mutex_lock(&phandle->phandle_lock); - - event_type = enable ? DPU_POWER_EVENT_ENABLE : DPU_POWER_EVENT_DISABLE; - - dpu_power_event_trigger_locked(phandle, event_type); - - mutex_unlock(&phandle->phandle_lock); - return 0; -} - -struct dpu_power_event *dpu_power_handle_register_event( - struct dpu_power_handle *phandle, - u32 event_type, void (*cb_fnc)(u32 event_type, void *usr), - void *usr, char *client_name) -{ - struct dpu_power_event *event; - - if (!phandle) { - pr_err("invalid power handle\n"); - return ERR_PTR(-EINVAL); - } else if (!cb_fnc || !event_type) { - pr_err("no callback fnc or event type\n"); - return ERR_PTR(-EINVAL); - } - - event = kzalloc(sizeof(struct dpu_power_event), GFP_KERNEL); - if (!event) - return ERR_PTR(-ENOMEM); - - event->event_type = event_type; - event->cb_fnc = cb_fnc; - event->usr = usr; - strlcpy(event->client_name, client_name, MAX_CLIENT_NAME_LEN); - event->active = true; - - mutex_lock(&phandle->phandle_lock); - list_add(&event->list, &phandle->event_list); - mutex_unlock(&phandle->phandle_lock); - - return event; -} - -void dpu_power_handle_unregister_event( - struct dpu_power_handle *phandle, - struct dpu_power_event *event) -{ - if (!phandle || !event) { - pr_err("invalid phandle or event\n"); - } else if (!event->active) { - pr_err("power handle deinit already done\n"); - kfree(event); - } else { - mutex_lock(&phandle->phandle_lock); - list_del_init(&event->list); - mutex_unlock(&phandle->phandle_lock); - kfree(event); - } -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h deleted file mode 100644 index 7536624c8b20..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef _DPU_POWER_HANDLE_H_ -#define _DPU_POWER_HANDLE_H_ - -#define MAX_CLIENT_NAME_LEN 128 - -#define DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA 0 -#define DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA 0 -#define DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA 1600000000 -#define DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA 0 - -#include "dpu_io_util.h" - -/* events will be triggered on power handler enable/disable */ -#define DPU_POWER_EVENT_DISABLE BIT(0) -#define DPU_POWER_EVENT_ENABLE BIT(1) - -/* - * struct dpu_power_event - local event registration structure - * @client_name: name of the client registering - * @cb_fnc: pointer to desired callback function - * @usr: user pointer to pass to callback event trigger - * @event: refer to DPU_POWER_HANDLE_EVENT_* - * @list: list to attach event master list - * @active: indicates the state of dpu power handle - */ -struct dpu_power_event { - char client_name[MAX_CLIENT_NAME_LEN]; - void (*cb_fnc)(u32 event_type, void *usr); - void *usr; - u32 event_type; - struct list_head list; - bool active; -}; - -/** - * struct dpu_power_handle: power handle main struct - * @phandle_lock: lock to synchronize the enable/disable - * @dev: pointer to device structure - * @usecase_ndx: current usecase index - * @event_list: current power handle event list - */ -struct dpu_power_handle { - struct mutex phandle_lock; - struct device *dev; - u32 current_usecase_ndx; - struct list_head event_list; -}; - -/** - * dpu_power_resource_init() - initializes the dpu power handle - * @pdev: platform device to search the power resources - * @pdata: power handle to store the power resources - */ -void dpu_power_resource_init(struct platform_device *pdev, - struct dpu_power_handle *pdata); - -/** - * dpu_power_resource_deinit() - release the dpu power handle - * @pdev: platform device for power resources - * @pdata: power handle containing the resources - * - * Return: error code. - */ -void dpu_power_resource_deinit(struct platform_device *pdev, - struct dpu_power_handle *pdata); - -/** - * dpu_power_resource_enable() - enable/disable the power resources - * @pdata: power handle containing the resources - * @enable: boolean request for enable/disable - * - * Return: error code. - */ -int dpu_power_resource_enable(struct dpu_power_handle *pdata, bool enable); - -/** - * dpu_power_handle_register_event - register a callback function for an event. - * Clients can register for multiple events with a single register. - * Any block with access to phandle can register for the event - * notification. - * @phandle: power handle containing the resources - * @event_type: event type to register; refer DPU_POWER_HANDLE_EVENT_* - * @cb_fnc: pointer to desired callback function - * @usr: user pointer to pass to callback on event trigger - * - * Return: event pointer if success, or error code otherwise - */ -struct dpu_power_event *dpu_power_handle_register_event( - struct dpu_power_handle *phandle, - u32 event_type, void (*cb_fnc)(u32 event_type, void *usr), - void *usr, char *client_name); -/** - * dpu_power_handle_unregister_event - unregister callback for event(s) - * @phandle: power handle containing the resources - * @event: event pointer returned after power handle register - */ -void dpu_power_handle_unregister_event(struct dpu_power_handle *phandle, - struct dpu_power_event *event); - -#endif /* _DPU_POWER_HANDLE_H_ */ From 585b3f9472eea88b82f9cde6a3129fd0c36e7e67 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:20 -0500 Subject: [PATCH 66/91] drm/msm: dpu: Fix typo in dpu_encoder enc_spinlock instead of enc_spin_lock. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index a8ba10ceaacf..64ff0fa2c36d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -130,7 +130,7 @@ enum dpu_enc_rc_states { * Virtual encoder defers as much as possible to the physical encoders. * Virtual encoder registers itself with the DRM Framework as the encoder. * @base: drm_encoder base class for registration with DRM - * @enc_spin_lock: Virtual-Encoder-Wide Spin Lock for IRQ purposes + * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes * @bus_scaling_client: Client handle to the bus scaling interface * @num_phys_encs: Actual number of physical encoders contained. * @phys_encs: Container of physical encoders managed. From fba7427eb594964726ab92bde7b9c20c995b4685 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:21 -0500 Subject: [PATCH 67/91] drm/msm: dpu: Add ->enabled to dpu_encoder_virt Add a bool to dpu_encoder_virt to track whether the encoder is enabled or not. Repurpose the enc_lock mutex to ensure that it is consistent with the hw state. Changes in v2: - None Cc: Jeykumar Sankaran Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 27 +++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 64ff0fa2c36d..c1b32ef1fc46 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -132,6 +132,7 @@ enum dpu_enc_rc_states { * @base: drm_encoder base class for registration with DRM * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes * @bus_scaling_client: Client handle to the bus scaling interface + * @enabled: True if the encoder is active, protected by enc_lock * @num_phys_encs: Actual number of physical encoders contained. * @phys_encs: Container of physical encoders managed. * @cur_master: Pointer to the current master in this mode. Optimization @@ -148,8 +149,8 @@ enum dpu_enc_rc_states { * all CTL paths * @crtc_kickoff_cb_data: Opaque user data given to crtc_kickoff_cb * @debugfs_root: Debug file system root file node - * @enc_lock: Lock around physical encoder create/destroy and - access. + * @enc_lock: Lock around physical encoder + * create/destroy/enable/disable * @frame_busy_mask: Bitmask tracking which phys_enc we are still * busy processing current command. * Bit0 = phys_encs[0] etc. @@ -175,6 +176,8 @@ struct dpu_encoder_virt { spinlock_t enc_spinlock; uint32_t bus_scaling_client; + bool enabled; + unsigned int num_phys_encs; struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL]; struct dpu_encoder_phys *cur_master; @@ -1121,6 +1124,8 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) return; } dpu_enc = to_dpu_encoder_virt(drm_enc); + + mutex_lock(&dpu_enc->enc_lock); cur_mode = &dpu_enc->base.crtc->state->adjusted_mode; trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay, @@ -1137,10 +1142,15 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) if (ret) { DPU_ERROR_ENC(dpu_enc, "dpu resource control failed: %d\n", ret); - return; + goto out; } _dpu_encoder_virt_enable_helper(drm_enc); + + dpu_enc->enabled = true; + +out: + mutex_unlock(&dpu_enc->enc_lock); } static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) @@ -1162,11 +1172,14 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) return; } - mode = &drm_enc->crtc->state->adjusted_mode; - dpu_enc = to_dpu_encoder_virt(drm_enc); DPU_DEBUG_ENC(dpu_enc, "\n"); + mutex_lock(&dpu_enc->enc_lock); + dpu_enc->enabled = false; + + mode = &drm_enc->crtc->state->adjusted_mode; + priv = drm_enc->dev->dev_private; dpu_kms = to_dpu_kms(priv->kms); @@ -1200,6 +1213,8 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); dpu_rm_release(&dpu_kms->rm, drm_enc); + + mutex_unlock(&dpu_enc->enc_lock); } static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg *catalog, @@ -2239,6 +2254,8 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs); + dpu_enc->enabled = false; + return &dpu_enc->base; } From 18a63b3c6f0b6247f93f5eb05353b0486512017e Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:22 -0500 Subject: [PATCH 68/91] drm/msm: dpu: Move crtc runtime resume to encoder The crtc runtime resume doesn't actually operate on the crtc, but rather its encoders. The problem with this is that we need to inspect the crtc state to get the currently connected encoders. Since runtime resume isn't guaranteed to be called while holding the modeset locks (although it sometimes is), this presents a race condition. Now that we have ->enabled on the virtual encoders, and a lock to protect it, just call resume on each encoder and only restore the ones that are enabled. Changes in v2: - None Cc: Jeykumar Sankaran Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 24 --------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 ------ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 +++++++++------------ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 6 +++--- 5 files changed, 15 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 61449e311819..44bd3b853b2c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -857,30 +857,6 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc) return &cstate->base; } -void dpu_crtc_runtime_resume(struct drm_crtc *crtc) -{ - struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); - struct drm_encoder *encoder; - - mutex_lock(&dpu_crtc->crtc_lock); - - if (!dpu_crtc->enabled) - goto end; - - trace_dpu_crtc_runtime_resume(DRMID(crtc)); - - /* restore encoder; crtc will be programmed during commit */ - drm_for_each_encoder(encoder, crtc->dev) { - if (encoder->crtc != crtc) - continue; - - dpu_encoder_virt_restore(encoder); - } - -end: - mutex_unlock(&dpu_crtc->crtc_lock); -} - static void dpu_crtc_disable(struct drm_crtc *crtc) { struct dpu_crtc *dpu_crtc; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index d5cd7a0b302f..7617132b8fb7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -330,10 +330,4 @@ static inline bool dpu_crtc_is_enabled(struct drm_crtc *crtc) return crtc ? crtc->enabled : false; } -/** - * dpu_crtc_runtime_resume - called by the top-level on pm_runtime_resume - * @crtc: CRTC to resume - */ -void dpu_crtc_runtime_resume(struct drm_crtc *crtc); - #endif /* _DPU_CRTC_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index c1b32ef1fc46..83b25a1f65d6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1089,28 +1089,24 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) _dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info); } -void dpu_encoder_virt_restore(struct drm_encoder *drm_enc) +void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc) { - struct dpu_encoder_virt *dpu_enc = NULL; - int i; + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - dpu_enc = to_dpu_encoder_virt(drm_enc); + mutex_lock(&dpu_enc->enc_lock); - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - - if (phys && (phys != dpu_enc->cur_master) && phys->ops.restore) - phys->ops.restore(phys); - } + if (!dpu_enc->enabled) + goto out; + if (dpu_enc->cur_slave && dpu_enc->cur_slave->ops.restore) + dpu_enc->cur_slave->ops.restore(dpu_enc->cur_slave); if (dpu_enc->cur_master && dpu_enc->cur_master->ops.restore) dpu_enc->cur_master->ops.restore(dpu_enc->cur_master); _dpu_encoder_virt_enable_helper(drm_enc); + +out: + mutex_unlock(&dpu_enc->enc_lock); } static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index c2044122d609..c9ebdf60a4ba 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -128,10 +128,10 @@ int dpu_encoder_wait_for_event(struct drm_encoder *drm_encoder, enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder); /** - * dpu_encoder_virt_restore - restore the encoder configs + * dpu_encoder_virt_runtime_resume - pm runtime resume the encoder configs * @encoder: encoder pointer */ -void dpu_encoder_virt_restore(struct drm_encoder *encoder); +void dpu_encoder_virt_runtime_resume(struct drm_encoder *encoder); /** * dpu_encoder_init - initialize virtual encoder object diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 610845bb72e0..606b284064a6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1133,7 +1133,7 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) int rc = -1; struct platform_device *pdev = to_platform_device(dev); struct dpu_kms *dpu_kms = platform_get_drvdata(pdev); - struct drm_crtc *crtc; + struct drm_encoder *encoder; struct drm_device *ddev; struct dss_module_power *mp = &dpu_kms->mp; @@ -1151,8 +1151,8 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) dpu_vbif_init_memtypes(dpu_kms); - drm_for_each_crtc(crtc, ddev) - dpu_crtc_runtime_resume(crtc); + drm_for_each_encoder(encoder, ddev) + dpu_encoder_virt_runtime_resume(encoder); return rc; } From b01c2399226c294fe9b22d26ce0ebf1707acb8d9 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:23 -0500 Subject: [PATCH 69/91] drm/msm: dpu: Don't drop locks in crtc_vblank_enable Now that runtime resume is handled in encoder, we don't need to worry about crtc_lock recursion when calling pm_runtime_(get|put). So drop the lock drops in _dpu_crtc_vblank_enable_no_lock(). Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 44bd3b853b2c..6da2492e6511 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -781,10 +781,7 @@ static void _dpu_crtc_vblank_enable_no_lock( struct drm_encoder *enc; if (enable) { - /* drop lock since power crtc cb may try to re-acquire lock */ - mutex_unlock(&dpu_crtc->crtc_lock); pm_runtime_get_sync(dev->dev); - mutex_lock(&dpu_crtc->crtc_lock); list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { if (enc->crtc != crtc) @@ -809,10 +806,7 @@ static void _dpu_crtc_vblank_enable_no_lock( dpu_encoder_register_vblank_callback(enc, NULL, NULL); } - /* drop lock since power crtc cb may try to re-acquire lock */ - mutex_unlock(&dpu_crtc->crtc_lock); pm_runtime_put_sync(dev->dev); - mutex_lock(&dpu_crtc->crtc_lock); } } From f449aa6e447c321585dbb97178fedac7183bc2f3 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 30 Nov 2018 17:00:02 -0500 Subject: [PATCH 70/91] drm/msm: dpu: Grab the modeset locks in frame_event This patch wraps dpu_core_perf_crtc_release_bw() with modeset locks since it digs into the state objects. Changes in v2: - None Changes in v3: - Use those nifty new DRM_MODESET_LOCK_ALL_* helpers (Daniel) Cc: Daniel Vetter Cc: Jeykumar Sankaran Acked-by: Daniel Vetter Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 6da2492e6511..8881f88391b0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -306,6 +306,19 @@ static void dpu_crtc_vblank_cb(void *data) trace_dpu_crtc_vblank_cb(DRMID(crtc)); } +static void dpu_crtc_release_bw_unlocked(struct drm_crtc *crtc) +{ + int ret = 0; + struct drm_modeset_acquire_ctx ctx; + + DRM_MODESET_LOCK_ALL_BEGIN(crtc->dev, ctx, 0, ret); + dpu_core_perf_crtc_release_bw(crtc); + DRM_MODESET_LOCK_ALL_END(ctx, ret); + if (ret) + DRM_ERROR("Failed to acquire modeset locks to release bw, %d\n", + ret); +} + static void dpu_crtc_frame_event_work(struct kthread_work *work) { struct dpu_crtc_frame_event *fevent = container_of(work, @@ -335,7 +348,7 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work) /* release bandwidth and other resources */ trace_dpu_crtc_frame_event_done(DRMID(crtc), fevent->event); - dpu_core_perf_crtc_release_bw(crtc); + dpu_crtc_release_bw_unlocked(crtc); } else { trace_dpu_crtc_frame_event_more_pending(DRMID(crtc), fevent->event); From 4b8c6279593aa6b412d42bc77fbf73b497e1f4ec Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:25 -0500 Subject: [PATCH 71/91] drm/msm: dpu: Stop using encoder->crtc pointer It's for legacy drivers, for atomic drivers crtc->state->encoder_mask should be used to map encoder to crtc. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul [seanpaul resolved conflict with async param of dpu_encoder_kickoff] Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 46 ++++++++---------------- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 19 +++++++--- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 8881f88391b0..5745d46a7858 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -284,9 +284,9 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) return INTF_MODE_NONE; } - drm_for_each_encoder(encoder, crtc->dev) - if (encoder->crtc == crtc) - return dpu_encoder_get_intf_mode(encoder); + /* TODO: Returns the first INTF_MODE, could there be multiple values? */ + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) + return dpu_encoder_get_intf_mode(encoder); return INTF_MODE_NONE; } @@ -562,13 +562,9 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, spin_unlock_irqrestore(&dev->event_lock, flags); } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc != crtc) - continue; - - /* encoder will trigger pending mask now */ + /* encoder will trigger pending mask now */ + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) dpu_encoder_trigger_kickoff_pending(encoder); - } /* * If no mixers have been allocated in dpu_crtc_atomic_check(), @@ -715,7 +711,6 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) { struct drm_encoder *encoder; - struct drm_device *dev = crtc->dev; struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); @@ -731,16 +726,13 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) DPU_ATRACE_BEGIN("crtc_commit"); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + /* + * Encoder will flush/start now, unless it has a tx pending. If so, it + * may delay and flush at an irq event (e.g. ppdone) + */ + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc->state->encoder_mask) { struct dpu_encoder_kickoff_params params = { 0 }; - - if (encoder->crtc != crtc) - continue; - - /* - * Encoder will flush/start now, unless it has a tx pending. - * If so, it may delay and flush at an irq event (e.g. ppdone) - */ dpu_encoder_prepare_for_kickoff(encoder, ¶ms, async); } @@ -768,12 +760,8 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) dpu_vbif_clear_errors(dpu_kms); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc != crtc) - continue; - + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) dpu_encoder_kickoff(encoder, async); - } end: if (!async) @@ -910,11 +898,8 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) dpu_core_perf_crtc_update(crtc, 0, true); - drm_for_each_encoder(encoder, crtc->dev) { - if (encoder->crtc != crtc) - continue; + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) dpu_encoder_register_frame_event_callback(encoder, NULL, NULL); - } memset(cstate->mixers, 0, sizeof(cstate->mixers)); cstate->num_mixers = 0; @@ -949,12 +934,9 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, DRM_DEBUG_KMS("crtc%d\n", crtc->base.id); dpu_crtc = to_dpu_crtc(crtc); - drm_for_each_encoder(encoder, crtc->dev) { - if (encoder->crtc != crtc) - continue; + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) dpu_encoder_register_frame_event_callback(encoder, dpu_crtc_frame_event_cb, (void *)crtc); - } mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 606b284064a6..7085cde868be 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -320,7 +320,10 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms, struct dpu_kms *dpu_kms; struct msm_drm_private *priv; struct drm_device *dev; + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; struct drm_encoder *encoder; + int i; if (!kms) return; @@ -332,9 +335,13 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms, priv = dev->dev_private; pm_runtime_get_sync(&dpu_kms->pdev->dev); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->crtc != NULL) + /* Call prepare_commit for all affected encoders */ + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc_state->encoder_mask) { dpu_encoder_prepare_commit(encoder); + } + } } /* @@ -344,13 +351,17 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms, void dpu_kms_encoder_enable(struct drm_encoder *encoder) { const struct drm_encoder_helper_funcs *funcs = encoder->helper_private; - struct drm_crtc *crtc = encoder->crtc; + struct drm_device *dev = encoder->dev; + struct drm_crtc *crtc; /* Forward this enable call to the commit hook */ if (funcs && funcs->commit) funcs->commit(encoder); - if (crtc && crtc->state->active) { + drm_for_each_crtc(crtc, dev) { + if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder))) + continue; + trace_dpu_kms_enc_enable(DRMID(crtc)); dpu_crtc_commit_kickoff(crtc, false); } From 1dfdb0e107dbe6ebff3f6bbbe4aad0b5aa87bba4 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:26 -0500 Subject: [PATCH 72/91] drm/msm: dpu: Add modeset lock checks where applicable Add modeset lock checks to functions that could be called outside the core atomic stack. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 5745d46a7858..28465063e345 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -284,6 +284,8 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) return INTF_MODE_NONE; } + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + /* TODO: Returns the first INTF_MODE, could there be multiple values? */ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) return dpu_encoder_get_intf_mode(encoder); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 7085cde868be..fe98a39eaae5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -358,6 +358,7 @@ void dpu_kms_encoder_enable(struct drm_encoder *encoder) if (funcs && funcs->commit) funcs->commit(encoder); + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); drm_for_each_crtc(crtc, dev) { if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder))) continue; From b77d0f0d4ee757e0a27a269a8b679108162f9bd2 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:27 -0500 Subject: [PATCH 73/91] drm/msm: dpu: Move pm_runtime_(get|put) from vblank_enable There are 4 times that _dpu_crtc_vblank_enable_no_lock() is called: 1- crtc enable 2- crtc disable 3- crtc vblank enable 4- crtc vblank disable When we enable or disable the crtc, we call drm_crtc_vblank_on and drm_crtc_vblank_off respectively. That will gate vblank enables and disables to only being called when the crtc is active. That means that we can just enable/disable pm runtime in crtc enable/disable. This will be beneficial in trying to eliminate blocking calls from the vblank call chain. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 28465063e345..f359994ab596 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -784,8 +784,6 @@ static void _dpu_crtc_vblank_enable_no_lock( struct drm_encoder *enc; if (enable) { - pm_runtime_get_sync(dev->dev); - list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { if (enc->crtc != crtc) continue; @@ -808,8 +806,6 @@ static void _dpu_crtc_vblank_enable_no_lock( dpu_encoder_register_vblank_callback(enc, NULL, NULL); } - - pm_runtime_put_sync(dev->dev); } } @@ -918,6 +914,8 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) crtc->state->event = NULL; spin_unlock_irqrestore(&crtc->dev->event_lock, flags); } + + pm_runtime_put_sync(crtc->dev->dev); } static void dpu_crtc_enable(struct drm_crtc *crtc, @@ -933,6 +931,8 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, } priv = crtc->dev->dev_private; + pm_runtime_get_sync(crtc->dev->dev); + DRM_DEBUG_KMS("crtc%d\n", crtc->base.id); dpu_crtc = to_dpu_crtc(crtc); From a9d629d71dc7f8d93538f783a7a9ee15e9f1a328 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:28 -0500 Subject: [PATCH 74/91] drm/msm: dpu: Remove crtc_lock from setup_mixers I think the intention here was to protect the enc->crtc access, but that's insufficient to avoid enc->crtc changing. Fortunately we're already holding the modeset lock when this is called (from atomic_check), so remove the crtc_lock and add a modeset lock check. While we're at it, use the encoder mask from crtc state instead of legacy pointer. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index f359994ab596..83f9f945d12c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -485,19 +485,13 @@ static void _dpu_crtc_setup_mixer_for_encoder( static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc) { - struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct drm_encoder *enc; - mutex_lock(&dpu_crtc->crtc_lock); + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + /* Check for mixers on all encoders attached to this crtc */ - list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) { - if (enc->crtc != crtc) - continue; - + drm_for_each_encoder_mask(enc, crtc->dev, crtc->state->encoder_mask) _dpu_crtc_setup_mixer_for_encoder(crtc, enc); - } - - mutex_unlock(&dpu_crtc->crtc_lock); } static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, From e4914867ac99caee9a239c227a07791098ab5e53 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:29 -0500 Subject: [PATCH 75/91] drm/msm: dpu: Remove vblank_callback from encoder The indirection of registering a callback and opaque pointer isn't reall useful when there's only one callsite. So instead of having the vblank_cb registration, just give encoder a crtc and let it directly call the vblank handler. In a later patch, we'll make use of this further. Changes in v2: - None Cc: Jeykumar Sankaran Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 8 +++---- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 +++++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 25 +++++++++++---------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 ++++----- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 83f9f945d12c..576708aed5c2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -293,9 +293,8 @@ enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc) return INTF_MODE_NONE; } -static void dpu_crtc_vblank_cb(void *data) +void dpu_crtc_vblank_callback(struct drm_crtc *crtc) { - struct drm_crtc *crtc = (struct drm_crtc *)data; struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); /* keep statistics on vblank callback - with auto reset via debugfs */ @@ -786,8 +785,7 @@ static void _dpu_crtc_vblank_enable_no_lock( DRMID(enc), enable, dpu_crtc); - dpu_encoder_register_vblank_callback(enc, - dpu_crtc_vblank_cb, (void *)crtc); + dpu_encoder_assign_crtc(enc, crtc); } } else { list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { @@ -798,7 +796,7 @@ static void _dpu_crtc_vblank_enable_no_lock( DRMID(enc), enable, dpu_crtc); - dpu_encoder_register_vblank_callback(enc, NULL, NULL); + dpu_encoder_assign_crtc(enc, NULL); } } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 7617132b8fb7..fee29d1a84f6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -270,6 +270,12 @@ static inline int dpu_crtc_frame_pending(struct drm_crtc *crtc) */ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en); +/** + * dpu_crtc_vblank_callback - called on vblank irq, issues completion events + * @crtc: Pointer to drm crtc object + */ +void dpu_crtc_vblank_callback(struct drm_crtc *crtc); + /** * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc * @crtc: Pointer to drm crtc object diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 83b25a1f65d6..340e7360152c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -142,9 +142,11 @@ enum dpu_enc_rc_states { * @intfs_swapped Whether or not the phys_enc interfaces have been swapped * for partial update right-only cases, such as pingpong * split where virtual pingpong does not generate IRQs - * @crtc_vblank_cb: Callback into the upper layer / CRTC for - * notification of the VBLANK - * @crtc_vblank_cb_data: Data from upper layer for VBLANK notification + * @crtc: Pointer to the currently assigned crtc. Normally you + * would use crtc->state->encoder_mask to determine the + * link between encoder/crtc. However in this case we need + * to track crtc in the disable() hook which is called + * _after_ encoder_mask is cleared. * @crtc_kickoff_cb: Callback into CRTC that will flush & start * all CTL paths * @crtc_kickoff_cb_data: Opaque user data given to crtc_kickoff_cb @@ -186,8 +188,7 @@ struct dpu_encoder_virt { bool intfs_swapped; - void (*crtc_vblank_cb)(void *); - void *crtc_vblank_cb_data; + struct drm_crtc *crtc; struct dentry *debugfs_root; struct mutex enc_lock; @@ -1241,8 +1242,8 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, dpu_enc = to_dpu_encoder_virt(drm_enc); spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags); - if (dpu_enc->crtc_vblank_cb) - dpu_enc->crtc_vblank_cb(dpu_enc->crtc_vblank_cb_data); + if (dpu_enc->crtc) + dpu_crtc_vblank_callback(dpu_enc->crtc); spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); atomic_inc(&phy_enc->vsync_cnt); @@ -1262,15 +1263,14 @@ static void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc, DPU_ATRACE_END("encoder_underrun_callback"); } -void dpu_encoder_register_vblank_callback(struct drm_encoder *drm_enc, - void (*vbl_cb)(void *), void *vbl_data) +void dpu_encoder_assign_crtc(struct drm_encoder *drm_enc, struct drm_crtc *crtc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); unsigned long lock_flags; bool enable; int i; - enable = vbl_cb ? true : false; + enable = crtc ? true : false; if (!drm_enc) { DPU_ERROR("invalid encoder\n"); @@ -1279,8 +1279,9 @@ void dpu_encoder_register_vblank_callback(struct drm_encoder *drm_enc, trace_dpu_enc_vblank_cb(DRMID(drm_enc), enable); spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags); - dpu_enc->crtc_vblank_cb = vbl_cb; - dpu_enc->crtc_vblank_cb_data = vbl_data; + /* crtc should always be cleared before re-assigning */ + WARN_ON(crtc && dpu_enc->crtc); + dpu_enc->crtc = crtc; spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); for (i = 0; i < dpu_enc->num_phys_encs; i++) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index c9ebdf60a4ba..9790bd1a31e0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -55,14 +55,12 @@ void dpu_encoder_get_hw_resources(struct drm_encoder *encoder, struct dpu_encoder_hw_resources *hw_res); /** - * dpu_encoder_register_vblank_callback - provide callback to encoder that - * will be called on the next vblank. + * dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to * @encoder: encoder pointer - * @cb: callback pointer, provide NULL to deregister and disable IRQs - * @data: user data provided to callback + * @crtc: crtc pointer */ -void dpu_encoder_register_vblank_callback(struct drm_encoder *encoder, - void (*cb)(void *), void *data); +void dpu_encoder_assign_crtc(struct drm_encoder *encoder, + struct drm_crtc *crtc); /** * dpu_encoder_register_frame_event_callback - provide callback to encoder that From f7aafc8d53482be6c0e6faf6746bff21b772a1a5 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:30 -0500 Subject: [PATCH 76/91] drm/msm: dpu: Use atomic_disable for dpu_crtc_disable Matches dpu_crtc_enable and we'll need the old state in a future patch Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 576708aed5c2..a403002d5e8e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -842,7 +842,8 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc) return &cstate->base; } -static void dpu_crtc_disable(struct drm_crtc *crtc) +static void dpu_crtc_disable(struct drm_crtc *crtc, + struct drm_crtc_state *old_crtc_state) { struct dpu_crtc *dpu_crtc; struct dpu_crtc_state *cstate; @@ -1434,7 +1435,7 @@ static const struct drm_crtc_funcs dpu_crtc_funcs = { }; static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = { - .disable = dpu_crtc_disable, + .atomic_disable = dpu_crtc_disable, .atomic_enable = dpu_crtc_enable, .atomic_check = dpu_crtc_atomic_check, .atomic_begin = dpu_crtc_atomic_begin, From 5c6277c1d25b5fbb1555f7962ce0d72f78fea266 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:31 -0500 Subject: [PATCH 77/91] drm/msm: dpu: Don't bother checking ->enabled in dpu_crtc_vblank The drm_crtc_vblank_on/off calls in enable/disable guarantee that we won't call this function when crtc is not enabled. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index a403002d5e8e..558f9abb1a99 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1189,9 +1189,7 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en) mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_vblank(DRMID(&dpu_crtc->base), en, dpu_crtc); - if (dpu_crtc->enabled) { - _dpu_crtc_vblank_enable_no_lock(dpu_crtc, en); - } + _dpu_crtc_vblank_enable_no_lock(dpu_crtc, en); dpu_crtc->vblank_requested = en; mutex_unlock(&dpu_crtc->crtc_lock); From a796ba2cb3dde3d155401e91e8341879de1248ec Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:32 -0500 Subject: [PATCH 78/91] drm/msm: dpu: Separate crtc assignment from vblank enable Instead of assigning/clearing the crtc on vblank enable/disable, we can just assign and clear the crtc on modeset. That allows us to just toggle the encoder's vblank interrupts on vblank_enable. So why is this important? Previously the driver was using the legacy pointers to assign/clear the crtc. Legacy pointers are cleared _after_ disabling the hardware, so the legacy pointer was valid during vblank_disable, but that's not something we should rely on. Instead of relying on the core ordering the legacy pointer assignments just so, we'll assign the crtc in dpu_crtc enable/disable. This is the only place that mapping can change, so we're covered there. We're also taking advantage of drm_crtc_vblank_on/off. By using this, we ensure that vblank_enable/disable can never be called while the crtc is off (which means the assigned crtc will always be valid). As such, we don't need to use modeset locks or the crtc_lock in the vblank_enable/disable routine to be sure state is consistent. ...I think. Changes in v2: - Changed crtc check in toggle_vblank to != (Jeykumar) Cc: Jeykumar Sankaran Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul [dpu_crtc.c change needed to be manually applied b/c of the dpu_crtc_reset change] Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 77 +++++++++------------ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 27 +++++--- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 +++ 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 558f9abb1a99..995d11e69365 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -764,43 +764,6 @@ end: DPU_ATRACE_END("crtc_commit"); } -/** - * _dpu_crtc_vblank_enable_no_lock - update power resource and vblank request - * @dpu_crtc: Pointer to dpu crtc structure - * @enable: Whether to enable/disable vblanks - */ -static void _dpu_crtc_vblank_enable_no_lock( - struct dpu_crtc *dpu_crtc, bool enable) -{ - struct drm_crtc *crtc = &dpu_crtc->base; - struct drm_device *dev = crtc->dev; - struct drm_encoder *enc; - - if (enable) { - list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { - if (enc->crtc != crtc) - continue; - - trace_dpu_crtc_vblank_enable(DRMID(&dpu_crtc->base), - DRMID(enc), enable, - dpu_crtc); - - dpu_encoder_assign_crtc(enc, crtc); - } - } else { - list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { - if (enc->crtc != crtc) - continue; - - trace_dpu_crtc_vblank_enable(DRMID(&dpu_crtc->base), - DRMID(enc), enable, - dpu_crtc); - - dpu_encoder_assign_crtc(enc, NULL); - } - } -} - static void dpu_crtc_reset(struct drm_crtc *crtc) { struct dpu_crtc_state *cstate; @@ -866,6 +829,10 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, /* Disable/save vblank irq handling */ drm_crtc_vblank_off(crtc); + drm_for_each_encoder_mask(encoder, crtc->dev, + old_crtc_state->encoder_mask) + dpu_encoder_assign_crtc(encoder, NULL); + mutex_lock(&dpu_crtc->crtc_lock); /* wait for frame_event_done completion */ @@ -875,9 +842,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, atomic_read(&dpu_crtc->frame_pending)); trace_dpu_crtc_disable(DRMID(crtc), false, dpu_crtc); - if (dpu_crtc->enabled && dpu_crtc->vblank_requested) { - _dpu_crtc_vblank_enable_no_lock(dpu_crtc, false); - } dpu_crtc->enabled = false; if (atomic_read(&dpu_crtc->frame_pending)) { @@ -935,13 +899,13 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc); - if (!dpu_crtc->enabled && dpu_crtc->vblank_requested) { - _dpu_crtc_vblank_enable_no_lock(dpu_crtc, true); - } dpu_crtc->enabled = true; mutex_unlock(&dpu_crtc->crtc_lock); + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) + dpu_encoder_assign_crtc(encoder, crtc); + /* Enable/restore vblank irq handling */ drm_crtc_vblank_on(crtc); } @@ -1186,10 +1150,33 @@ end: int dpu_crtc_vblank(struct drm_crtc *crtc, bool en) { struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); + struct drm_encoder *enc; + + trace_dpu_crtc_vblank(DRMID(&dpu_crtc->base), en, dpu_crtc); + + /* + * Normally we would iterate through encoder_mask in crtc state to find + * attached encoders. In this case, we might be disabling vblank _after_ + * encoder_mask has been cleared. + * + * Instead, we "assign" a crtc to the encoder in enable and clear it in + * disable (which is also after encoder_mask is cleared). So instead of + * using encoder mask, we'll ask the encoder to toggle itself iff it's + * currently assigned to our crtc. + * + * Note also that this function cannot be called while crtc is disabled + * since we use drm_crtc_vblank_on/off. So we don't need to worry + * about the assigned crtcs being inconsistent with the current state + * (which means no need to worry about modeset locks). + */ + list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) { + trace_dpu_crtc_vblank_enable(DRMID(crtc), DRMID(enc), en, + dpu_crtc); + + dpu_encoder_toggle_vblank_for_crtc(enc, crtc, en); + } mutex_lock(&dpu_crtc->crtc_lock); - trace_dpu_crtc_vblank(DRMID(&dpu_crtc->base), en, dpu_crtc); - _dpu_crtc_vblank_enable_no_lock(dpu_crtc, en); dpu_crtc->vblank_requested = en; mutex_unlock(&dpu_crtc->crtc_lock); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 340e7360152c..f60dcf217755 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1267,22 +1267,29 @@ void dpu_encoder_assign_crtc(struct drm_encoder *drm_enc, struct drm_crtc *crtc) { struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); unsigned long lock_flags; - bool enable; - int i; - - enable = crtc ? true : false; - - if (!drm_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - trace_dpu_enc_vblank_cb(DRMID(drm_enc), enable); spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags); /* crtc should always be cleared before re-assigning */ WARN_ON(crtc && dpu_enc->crtc); dpu_enc->crtc = crtc; spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); +} + +void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *drm_enc, + struct drm_crtc *crtc, bool enable) +{ + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); + unsigned long lock_flags; + int i; + + trace_dpu_enc_vblank_cb(DRMID(drm_enc), enable); + + spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags); + if (dpu_enc->crtc != crtc) { + spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); + return; + } + spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); for (i = 0; i < dpu_enc->num_phys_encs; i++) { struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 9790bd1a31e0..3f5dafe00580 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -62,6 +62,16 @@ void dpu_encoder_get_hw_resources(struct drm_encoder *encoder, void dpu_encoder_assign_crtc(struct drm_encoder *encoder, struct drm_crtc *crtc); +/** + * dpu_encoder_toggle_vblank_for_crtc - Toggles vblank interrupts on or off if + * the encoder is assigned to the given crtc + * @encoder: encoder pointer + * @crtc: crtc pointer + * @enable: true if vblank should be enabled + */ +void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *encoder, + struct drm_crtc *crtc, bool enable); + /** * dpu_encoder_register_frame_event_callback - provide callback to encoder that * will be called after the request is complete, or other events. From 3e46c5df667b361627a57861877c5881a22ef071 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:33 -0500 Subject: [PATCH 79/91] drm/msm: dpu: Remove vblank_requested flag from dpu_crtc It's just for debugfs output, we don't need it Changes in v2: - None Cc: Jeykumar Sankaran Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 6 ------ drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 -- drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 14 ++++---------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 995d11e69365..7c6262136aa3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1176,10 +1176,6 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en) dpu_encoder_toggle_vblank_for_crtc(enc, crtc, en); } - mutex_lock(&dpu_crtc->crtc_lock); - dpu_crtc->vblank_requested = en; - mutex_unlock(&dpu_crtc->crtc_lock); - return 0; } @@ -1295,8 +1291,6 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) dpu_crtc->vblank_cb_time = ktime_set(0, 0); } - seq_printf(s, "vblank_enable:%d\n", dpu_crtc->vblank_requested); - mutex_unlock(&dpu_crtc->crtc_lock); drm_modeset_unlock_all(crtc->dev); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index fee29d1a84f6..0b58a2f161e0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -132,7 +132,6 @@ struct dpu_crtc_frame_event { * @vblank_cb_count : count of vblank callback since last reset * @play_count : frame count between crtc enable and disable * @vblank_cb_time : ktime at vblank count reset - * @vblank_requested : whether the user has requested vblank events * @enabled : whether the DPU CRTC is currently enabled. updated in the * commit-thread, not state-swap time which is earlier, so * safe to make decisions on during VBLANK on/off work @@ -166,7 +165,6 @@ struct dpu_crtc { u32 vblank_cb_count; u64 play_count; ktime_t vblank_cb_time; - bool vblank_requested; bool enabled; struct list_head feature_list; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index 328df37d7580..c78b521ceda1 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -728,20 +728,17 @@ TRACE_EVENT(dpu_crtc_vblank_enable, __field( uint32_t, enc_id ) __field( bool, enable ) __field( bool, enabled ) - __field( bool, vblank_requested ) ), TP_fast_assign( __entry->drm_id = drm_id; __entry->enc_id = enc_id; __entry->enable = enable; __entry->enabled = crtc->enabled; - __entry->vblank_requested = crtc->vblank_requested; ), - TP_printk("id:%u encoder:%u enable:%s state{enabled:%s vblank_req:%s}", + TP_printk("id:%u encoder:%u enable:%s state{enabled:%s}", __entry->drm_id, __entry->enc_id, __entry->enable ? "true" : "false", - __entry->enabled ? "true" : "false", - __entry->vblank_requested ? "true" : "false") + __entry->enabled ? "true" : "false") ); DECLARE_EVENT_CLASS(dpu_crtc_enable_template, @@ -751,18 +748,15 @@ DECLARE_EVENT_CLASS(dpu_crtc_enable_template, __field( uint32_t, drm_id ) __field( bool, enable ) __field( bool, enabled ) - __field( bool, vblank_requested ) ), TP_fast_assign( __entry->drm_id = drm_id; __entry->enable = enable; __entry->enabled = crtc->enabled; - __entry->vblank_requested = crtc->vblank_requested; ), - TP_printk("id:%u enable:%s state{enabled:%s vblank_req:%s}", + TP_printk("id:%u enable:%s state{enabled:%s}", __entry->drm_id, __entry->enable ? "true" : "false", - __entry->enabled ? "true" : "false", - __entry->vblank_requested ? "true" : "false") + __entry->enabled ? "true" : "false") ); DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_enable, TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc), From f9e81b8da34d79978ae4effa18b16cb71cc5cb4a Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Fri, 16 Nov 2018 13:42:34 -0500 Subject: [PATCH 80/91] drm/msm: dpu: Remove crtc_lock Each time it's called we're holding the crtc modeset lock, so it's redundant. Changes in v2: - None Reviewed-by: Jeykumar Sankaran Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 11 ----------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 3 --- 2 files changed, 14 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 7c6262136aa3..5404c330d258 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -69,7 +69,6 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc) return; drm_crtc_cleanup(crtc); - mutex_destroy(&dpu_crtc->crtc_lock); kfree(dpu_crtc); } @@ -833,8 +832,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, old_crtc_state->encoder_mask) dpu_encoder_assign_crtc(encoder, NULL); - mutex_lock(&dpu_crtc->crtc_lock); - /* wait for frame_event_done completion */ if (_dpu_crtc_wait_for_frame_done(crtc)) DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n", @@ -863,8 +860,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, cstate->bw_control = false; cstate->bw_split_vote = false; - mutex_unlock(&dpu_crtc->crtc_lock); - if (crtc->state->event && !crtc->state->active) { spin_lock_irqsave(&crtc->dev->event_lock, flags); drm_crtc_send_vblank_event(crtc, crtc->state->event); @@ -897,12 +892,9 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, dpu_encoder_register_frame_event_callback(encoder, dpu_crtc_frame_event_cb, (void *)crtc); - mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc); dpu_crtc->enabled = true; - mutex_unlock(&dpu_crtc->crtc_lock); - drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) dpu_encoder_assign_crtc(encoder, crtc); @@ -1204,7 +1196,6 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) drm_modeset_lock_all(crtc->dev); cstate = to_dpu_crtc_state(crtc->state); - mutex_lock(&dpu_crtc->crtc_lock); mode = &crtc->state->adjusted_mode; out_width = _dpu_crtc_get_mixer_width(cstate, mode); @@ -1291,7 +1282,6 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) dpu_crtc->vblank_cb_time = ktime_set(0, 0); } - mutex_unlock(&dpu_crtc->crtc_lock); drm_modeset_unlock_all(crtc->dev); return 0; @@ -1441,7 +1431,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, crtc = &dpu_crtc->base; crtc->dev = dev; - mutex_init(&dpu_crtc->crtc_lock); spin_lock_init(&dpu_crtc->spin_lock); atomic_set(&dpu_crtc->frame_pending, 0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 0b58a2f161e0..fc7123573891 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -140,7 +140,6 @@ struct dpu_crtc_frame_event { * @dirty_list : list of color processing features are dirty * @ad_dirty: list containing ad properties that are dirty * @ad_active: list containing ad properties that are active - * @crtc_lock : crtc lock around create, destroy and access. * @frame_pending : Whether or not an update is pending * @frame_events : static allocation of in-flight frame events * @frame_event_list : available frame event list @@ -173,8 +172,6 @@ struct dpu_crtc { struct list_head ad_dirty; struct list_head ad_active; - struct mutex crtc_lock; - atomic_t frame_pending; struct dpu_crtc_frame_event frame_events[DPU_CRTC_FRAME_EVENT_SIZE]; struct list_head frame_event_list; From 27bc773aa69cf9aa03020a9d87abbcf06d4af1c2 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:14 -0700 Subject: [PATCH 81/91] drm/msm/dpu: Remove dpu_dbg The functions in dpu_dbg.c aren't used. The two main dump functions fail after a lookup from dpu_dbg_base.reg_base_list which turns out to never be populated and once those are removed the rest of the file doesn't make any sense. v3: No changes v2: Moved some unrelated changes to another patch Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c | 2393 ----------------- drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h | 103 - drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 +- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 1 - .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 1 - .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 3 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 20 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - 15 files changed, 4 insertions(+), 2531 deletions(-) delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index f45ac4c19258..125023068ca8 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -95,8 +95,7 @@ msm-y := \ msm_gpu_tracepoints.o \ msm_gpummu.o -msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \ - disp/dpu1/dpu_dbg.o +msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += disp/mdp4/mdp4_lvds_pll.o diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c deleted file mode 100644 index a85078123119..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.c +++ /dev/null @@ -1,2393 +0,0 @@ -/* Copyright (c) 2009-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dpu_dbg.h" -#include "disp/dpu1/dpu_hw_catalog.h" - - -#define DEFAULT_DBGBUS_DPU DPU_DBG_DUMP_IN_MEM -#define DEFAULT_DBGBUS_VBIFRT DPU_DBG_DUMP_IN_MEM -#define REG_BASE_NAME_LEN 80 - -#define DBGBUS_FLAGS_DSPP BIT(0) -#define DBGBUS_DSPP_STATUS 0x34C - -#define DBGBUS_NAME_DPU "dpu" -#define DBGBUS_NAME_VBIF_RT "vbif_rt" - -/* offsets from dpu top address for the debug buses */ -#define DBGBUS_SSPP0 0x188 -#define DBGBUS_AXI_INTF 0x194 -#define DBGBUS_SSPP1 0x298 -#define DBGBUS_DSPP 0x348 -#define DBGBUS_PERIPH 0x418 - -#define TEST_MASK(id, tp) ((id << 4) | (tp << 1) | BIT(0)) - -/* following offsets are with respect to MDP VBIF base for DBG BUS access */ -#define MMSS_VBIF_CLKON 0x4 -#define MMSS_VBIF_TEST_BUS_OUT_CTRL 0x210 -#define MMSS_VBIF_TEST_BUS_OUT 0x230 - -/* Vbif error info */ -#define MMSS_VBIF_PND_ERR 0x190 -#define MMSS_VBIF_SRC_ERR 0x194 -#define MMSS_VBIF_XIN_HALT_CTRL1 0x204 -#define MMSS_VBIF_ERR_INFO 0X1a0 -#define MMSS_VBIF_ERR_INFO_1 0x1a4 -#define MMSS_VBIF_CLIENT_NUM 14 - -/** - * struct dpu_dbg_reg_base - register region base. - * may sub-ranges: sub-ranges are used for dumping - * or may not have sub-ranges: dumping is base -> max_offset - * @reg_base_head: head of this node - * @name: register base name - * @base: base pointer - * @off: cached offset of region for manual register dumping - * @cnt: cached range of region for manual register dumping - * @max_offset: length of region - * @buf: buffer used for manual register dumping - * @buf_len: buffer length used for manual register dumping - * @cb: callback for external dump function, null if not defined - * @cb_ptr: private pointer to callback function - */ -struct dpu_dbg_reg_base { - struct list_head reg_base_head; - char name[REG_BASE_NAME_LEN]; - void __iomem *base; - size_t off; - size_t cnt; - size_t max_offset; - char *buf; - size_t buf_len; - void (*cb)(void *ptr); - void *cb_ptr; -}; - -struct dpu_debug_bus_entry { - u32 wr_addr; - u32 block_id; - u32 test_id; - void (*analyzer)(void __iomem *mem_base, - struct dpu_debug_bus_entry *entry, u32 val); -}; - -struct vbif_debug_bus_entry { - u32 disable_bus_addr; - u32 block_bus_addr; - u32 bit_offset; - u32 block_cnt; - u32 test_pnt_start; - u32 test_pnt_cnt; -}; - -struct dpu_dbg_debug_bus_common { - char *name; - u32 enable_mask; - bool include_in_deferred_work; - u32 flags; - u32 entries_size; - u32 *dumped_content; -}; - -struct dpu_dbg_dpu_debug_bus { - struct dpu_dbg_debug_bus_common cmn; - struct dpu_debug_bus_entry *entries; - u32 top_blk_off; -}; - -struct dpu_dbg_vbif_debug_bus { - struct dpu_dbg_debug_bus_common cmn; - struct vbif_debug_bus_entry *entries; -}; - -/** - * struct dpu_dbg_base - global dpu debug base structure - * @reg_base_list: list of register dumping regions - * @dev: device pointer - * @dump_work: work struct for deferring register dump work to separate thread - * @dbgbus_dpu: debug bus structure for the dpu - * @dbgbus_vbif_rt: debug bus structure for the realtime vbif - */ -static struct dpu_dbg_base { - struct list_head reg_base_list; - struct device *dev; - - struct work_struct dump_work; - - struct dpu_dbg_dpu_debug_bus dbgbus_dpu; - struct dpu_dbg_vbif_debug_bus dbgbus_vbif_rt; -} dpu_dbg_base; - -static void _dpu_debug_bus_xbar_dump(void __iomem *mem_base, - struct dpu_debug_bus_entry *entry, u32 val) -{ - DRM_DEV_ERROR(dpu_dbg_base.dev, "xbar 0x%x %d %d 0x%x\n", - entry->wr_addr, entry->block_id, entry->test_id, val); -} - -static void _dpu_debug_bus_lm_dump(void __iomem *mem_base, - struct dpu_debug_bus_entry *entry, u32 val) -{ - if (!(val & 0xFFF000)) - return; - - DRM_DEV_ERROR(dpu_dbg_base.dev, "lm 0x%x %d %d 0x%x\n", - entry->wr_addr, entry->block_id, entry->test_id, val); -} - -static void _dpu_debug_bus_ppb0_dump(void __iomem *mem_base, - struct dpu_debug_bus_entry *entry, u32 val) -{ - if (!(val & BIT(15))) - return; - - DRM_DEV_ERROR(dpu_dbg_base.dev, "ppb0 0x%x %d %d 0x%x\n", - entry->wr_addr, entry->block_id, entry->test_id, val); -} - -static void _dpu_debug_bus_ppb1_dump(void __iomem *mem_base, - struct dpu_debug_bus_entry *entry, u32 val) -{ - if (!(val & BIT(15))) - return; - - DRM_DEV_ERROR(dpu_dbg_base.dev, "ppb1 0x%x %d %d 0x%x\n", - entry->wr_addr, entry->block_id, entry->test_id, val); -} - -static struct dpu_debug_bus_entry dbg_bus_dpu_8998[] = { - - /* Unpack 0 sspp 0*/ - { DBGBUS_SSPP0, 50, 2 }, - { DBGBUS_SSPP0, 60, 2 }, - { DBGBUS_SSPP0, 70, 2 }, - { DBGBUS_SSPP0, 85, 2 }, - - /* Upack 0 sspp 1*/ - { DBGBUS_SSPP1, 50, 2 }, - { DBGBUS_SSPP1, 60, 2 }, - { DBGBUS_SSPP1, 70, 2 }, - { DBGBUS_SSPP1, 85, 2 }, - - /* scheduler */ - { DBGBUS_DSPP, 130, 0 }, - { DBGBUS_DSPP, 130, 1 }, - { DBGBUS_DSPP, 130, 2 }, - { DBGBUS_DSPP, 130, 3 }, - { DBGBUS_DSPP, 130, 4 }, - { DBGBUS_DSPP, 130, 5 }, - - /* qseed */ - { DBGBUS_SSPP0, 6, 0}, - { DBGBUS_SSPP0, 6, 1}, - { DBGBUS_SSPP0, 26, 0}, - { DBGBUS_SSPP0, 26, 1}, - { DBGBUS_SSPP1, 6, 0}, - { DBGBUS_SSPP1, 6, 1}, - { DBGBUS_SSPP1, 26, 0}, - { DBGBUS_SSPP1, 26, 1}, - - /* scale */ - { DBGBUS_SSPP0, 16, 0}, - { DBGBUS_SSPP0, 16, 1}, - { DBGBUS_SSPP0, 36, 0}, - { DBGBUS_SSPP0, 36, 1}, - { DBGBUS_SSPP1, 16, 0}, - { DBGBUS_SSPP1, 16, 1}, - { DBGBUS_SSPP1, 36, 0}, - { DBGBUS_SSPP1, 36, 1}, - - /* fetch sspp0 */ - - /* vig 0 */ - { DBGBUS_SSPP0, 0, 0 }, - { DBGBUS_SSPP0, 0, 1 }, - { DBGBUS_SSPP0, 0, 2 }, - { DBGBUS_SSPP0, 0, 3 }, - { DBGBUS_SSPP0, 0, 4 }, - { DBGBUS_SSPP0, 0, 5 }, - { DBGBUS_SSPP0, 0, 6 }, - { DBGBUS_SSPP0, 0, 7 }, - - { DBGBUS_SSPP0, 1, 0 }, - { DBGBUS_SSPP0, 1, 1 }, - { DBGBUS_SSPP0, 1, 2 }, - { DBGBUS_SSPP0, 1, 3 }, - { DBGBUS_SSPP0, 1, 4 }, - { DBGBUS_SSPP0, 1, 5 }, - { DBGBUS_SSPP0, 1, 6 }, - { DBGBUS_SSPP0, 1, 7 }, - - { DBGBUS_SSPP0, 2, 0 }, - { DBGBUS_SSPP0, 2, 1 }, - { DBGBUS_SSPP0, 2, 2 }, - { DBGBUS_SSPP0, 2, 3 }, - { DBGBUS_SSPP0, 2, 4 }, - { DBGBUS_SSPP0, 2, 5 }, - { DBGBUS_SSPP0, 2, 6 }, - { DBGBUS_SSPP0, 2, 7 }, - - { DBGBUS_SSPP0, 4, 0 }, - { DBGBUS_SSPP0, 4, 1 }, - { DBGBUS_SSPP0, 4, 2 }, - { DBGBUS_SSPP0, 4, 3 }, - { DBGBUS_SSPP0, 4, 4 }, - { DBGBUS_SSPP0, 4, 5 }, - { DBGBUS_SSPP0, 4, 6 }, - { DBGBUS_SSPP0, 4, 7 }, - - { DBGBUS_SSPP0, 5, 0 }, - { DBGBUS_SSPP0, 5, 1 }, - { DBGBUS_SSPP0, 5, 2 }, - { DBGBUS_SSPP0, 5, 3 }, - { DBGBUS_SSPP0, 5, 4 }, - { DBGBUS_SSPP0, 5, 5 }, - { DBGBUS_SSPP0, 5, 6 }, - { DBGBUS_SSPP0, 5, 7 }, - - /* vig 2 */ - { DBGBUS_SSPP0, 20, 0 }, - { DBGBUS_SSPP0, 20, 1 }, - { DBGBUS_SSPP0, 20, 2 }, - { DBGBUS_SSPP0, 20, 3 }, - { DBGBUS_SSPP0, 20, 4 }, - { DBGBUS_SSPP0, 20, 5 }, - { DBGBUS_SSPP0, 20, 6 }, - { DBGBUS_SSPP0, 20, 7 }, - - { DBGBUS_SSPP0, 21, 0 }, - { DBGBUS_SSPP0, 21, 1 }, - { DBGBUS_SSPP0, 21, 2 }, - { DBGBUS_SSPP0, 21, 3 }, - { DBGBUS_SSPP0, 21, 4 }, - { DBGBUS_SSPP0, 21, 5 }, - { DBGBUS_SSPP0, 21, 6 }, - { DBGBUS_SSPP0, 21, 7 }, - - { DBGBUS_SSPP0, 22, 0 }, - { DBGBUS_SSPP0, 22, 1 }, - { DBGBUS_SSPP0, 22, 2 }, - { DBGBUS_SSPP0, 22, 3 }, - { DBGBUS_SSPP0, 22, 4 }, - { DBGBUS_SSPP0, 22, 5 }, - { DBGBUS_SSPP0, 22, 6 }, - { DBGBUS_SSPP0, 22, 7 }, - - { DBGBUS_SSPP0, 24, 0 }, - { DBGBUS_SSPP0, 24, 1 }, - { DBGBUS_SSPP0, 24, 2 }, - { DBGBUS_SSPP0, 24, 3 }, - { DBGBUS_SSPP0, 24, 4 }, - { DBGBUS_SSPP0, 24, 5 }, - { DBGBUS_SSPP0, 24, 6 }, - { DBGBUS_SSPP0, 24, 7 }, - - { DBGBUS_SSPP0, 25, 0 }, - { DBGBUS_SSPP0, 25, 1 }, - { DBGBUS_SSPP0, 25, 2 }, - { DBGBUS_SSPP0, 25, 3 }, - { DBGBUS_SSPP0, 25, 4 }, - { DBGBUS_SSPP0, 25, 5 }, - { DBGBUS_SSPP0, 25, 6 }, - { DBGBUS_SSPP0, 25, 7 }, - - /* dma 2 */ - { DBGBUS_SSPP0, 30, 0 }, - { DBGBUS_SSPP0, 30, 1 }, - { DBGBUS_SSPP0, 30, 2 }, - { DBGBUS_SSPP0, 30, 3 }, - { DBGBUS_SSPP0, 30, 4 }, - { DBGBUS_SSPP0, 30, 5 }, - { DBGBUS_SSPP0, 30, 6 }, - { DBGBUS_SSPP0, 30, 7 }, - - { DBGBUS_SSPP0, 31, 0 }, - { DBGBUS_SSPP0, 31, 1 }, - { DBGBUS_SSPP0, 31, 2 }, - { DBGBUS_SSPP0, 31, 3 }, - { DBGBUS_SSPP0, 31, 4 }, - { DBGBUS_SSPP0, 31, 5 }, - { DBGBUS_SSPP0, 31, 6 }, - { DBGBUS_SSPP0, 31, 7 }, - - { DBGBUS_SSPP0, 32, 0 }, - { DBGBUS_SSPP0, 32, 1 }, - { DBGBUS_SSPP0, 32, 2 }, - { DBGBUS_SSPP0, 32, 3 }, - { DBGBUS_SSPP0, 32, 4 }, - { DBGBUS_SSPP0, 32, 5 }, - { DBGBUS_SSPP0, 32, 6 }, - { DBGBUS_SSPP0, 32, 7 }, - - { DBGBUS_SSPP0, 33, 0 }, - { DBGBUS_SSPP0, 33, 1 }, - { DBGBUS_SSPP0, 33, 2 }, - { DBGBUS_SSPP0, 33, 3 }, - { DBGBUS_SSPP0, 33, 4 }, - { DBGBUS_SSPP0, 33, 5 }, - { DBGBUS_SSPP0, 33, 6 }, - { DBGBUS_SSPP0, 33, 7 }, - - { DBGBUS_SSPP0, 34, 0 }, - { DBGBUS_SSPP0, 34, 1 }, - { DBGBUS_SSPP0, 34, 2 }, - { DBGBUS_SSPP0, 34, 3 }, - { DBGBUS_SSPP0, 34, 4 }, - { DBGBUS_SSPP0, 34, 5 }, - { DBGBUS_SSPP0, 34, 6 }, - { DBGBUS_SSPP0, 34, 7 }, - - { DBGBUS_SSPP0, 35, 0 }, - { DBGBUS_SSPP0, 35, 1 }, - { DBGBUS_SSPP0, 35, 2 }, - { DBGBUS_SSPP0, 35, 3 }, - - /* dma 0 */ - { DBGBUS_SSPP0, 40, 0 }, - { DBGBUS_SSPP0, 40, 1 }, - { DBGBUS_SSPP0, 40, 2 }, - { DBGBUS_SSPP0, 40, 3 }, - { DBGBUS_SSPP0, 40, 4 }, - { DBGBUS_SSPP0, 40, 5 }, - { DBGBUS_SSPP0, 40, 6 }, - { DBGBUS_SSPP0, 40, 7 }, - - { DBGBUS_SSPP0, 41, 0 }, - { DBGBUS_SSPP0, 41, 1 }, - { DBGBUS_SSPP0, 41, 2 }, - { DBGBUS_SSPP0, 41, 3 }, - { DBGBUS_SSPP0, 41, 4 }, - { DBGBUS_SSPP0, 41, 5 }, - { DBGBUS_SSPP0, 41, 6 }, - { DBGBUS_SSPP0, 41, 7 }, - - { DBGBUS_SSPP0, 42, 0 }, - { DBGBUS_SSPP0, 42, 1 }, - { DBGBUS_SSPP0, 42, 2 }, - { DBGBUS_SSPP0, 42, 3 }, - { DBGBUS_SSPP0, 42, 4 }, - { DBGBUS_SSPP0, 42, 5 }, - { DBGBUS_SSPP0, 42, 6 }, - { DBGBUS_SSPP0, 42, 7 }, - - { DBGBUS_SSPP0, 44, 0 }, - { DBGBUS_SSPP0, 44, 1 }, - { DBGBUS_SSPP0, 44, 2 }, - { DBGBUS_SSPP0, 44, 3 }, - { DBGBUS_SSPP0, 44, 4 }, - { DBGBUS_SSPP0, 44, 5 }, - { DBGBUS_SSPP0, 44, 6 }, - { DBGBUS_SSPP0, 44, 7 }, - - { DBGBUS_SSPP0, 45, 0 }, - { DBGBUS_SSPP0, 45, 1 }, - { DBGBUS_SSPP0, 45, 2 }, - { DBGBUS_SSPP0, 45, 3 }, - { DBGBUS_SSPP0, 45, 4 }, - { DBGBUS_SSPP0, 45, 5 }, - { DBGBUS_SSPP0, 45, 6 }, - { DBGBUS_SSPP0, 45, 7 }, - - /* fetch sspp1 */ - /* vig 1 */ - { DBGBUS_SSPP1, 0, 0 }, - { DBGBUS_SSPP1, 0, 1 }, - { DBGBUS_SSPP1, 0, 2 }, - { DBGBUS_SSPP1, 0, 3 }, - { DBGBUS_SSPP1, 0, 4 }, - { DBGBUS_SSPP1, 0, 5 }, - { DBGBUS_SSPP1, 0, 6 }, - { DBGBUS_SSPP1, 0, 7 }, - - { DBGBUS_SSPP1, 1, 0 }, - { DBGBUS_SSPP1, 1, 1 }, - { DBGBUS_SSPP1, 1, 2 }, - { DBGBUS_SSPP1, 1, 3 }, - { DBGBUS_SSPP1, 1, 4 }, - { DBGBUS_SSPP1, 1, 5 }, - { DBGBUS_SSPP1, 1, 6 }, - { DBGBUS_SSPP1, 1, 7 }, - - { DBGBUS_SSPP1, 2, 0 }, - { DBGBUS_SSPP1, 2, 1 }, - { DBGBUS_SSPP1, 2, 2 }, - { DBGBUS_SSPP1, 2, 3 }, - { DBGBUS_SSPP1, 2, 4 }, - { DBGBUS_SSPP1, 2, 5 }, - { DBGBUS_SSPP1, 2, 6 }, - { DBGBUS_SSPP1, 2, 7 }, - - { DBGBUS_SSPP1, 4, 0 }, - { DBGBUS_SSPP1, 4, 1 }, - { DBGBUS_SSPP1, 4, 2 }, - { DBGBUS_SSPP1, 4, 3 }, - { DBGBUS_SSPP1, 4, 4 }, - { DBGBUS_SSPP1, 4, 5 }, - { DBGBUS_SSPP1, 4, 6 }, - { DBGBUS_SSPP1, 4, 7 }, - - { DBGBUS_SSPP1, 5, 0 }, - { DBGBUS_SSPP1, 5, 1 }, - { DBGBUS_SSPP1, 5, 2 }, - { DBGBUS_SSPP1, 5, 3 }, - { DBGBUS_SSPP1, 5, 4 }, - { DBGBUS_SSPP1, 5, 5 }, - { DBGBUS_SSPP1, 5, 6 }, - { DBGBUS_SSPP1, 5, 7 }, - - /* vig 3 */ - { DBGBUS_SSPP1, 20, 0 }, - { DBGBUS_SSPP1, 20, 1 }, - { DBGBUS_SSPP1, 20, 2 }, - { DBGBUS_SSPP1, 20, 3 }, - { DBGBUS_SSPP1, 20, 4 }, - { DBGBUS_SSPP1, 20, 5 }, - { DBGBUS_SSPP1, 20, 6 }, - { DBGBUS_SSPP1, 20, 7 }, - - { DBGBUS_SSPP1, 21, 0 }, - { DBGBUS_SSPP1, 21, 1 }, - { DBGBUS_SSPP1, 21, 2 }, - { DBGBUS_SSPP1, 21, 3 }, - { DBGBUS_SSPP1, 21, 4 }, - { DBGBUS_SSPP1, 21, 5 }, - { DBGBUS_SSPP1, 21, 6 }, - { DBGBUS_SSPP1, 21, 7 }, - - { DBGBUS_SSPP1, 22, 0 }, - { DBGBUS_SSPP1, 22, 1 }, - { DBGBUS_SSPP1, 22, 2 }, - { DBGBUS_SSPP1, 22, 3 }, - { DBGBUS_SSPP1, 22, 4 }, - { DBGBUS_SSPP1, 22, 5 }, - { DBGBUS_SSPP1, 22, 6 }, - { DBGBUS_SSPP1, 22, 7 }, - - { DBGBUS_SSPP1, 24, 0 }, - { DBGBUS_SSPP1, 24, 1 }, - { DBGBUS_SSPP1, 24, 2 }, - { DBGBUS_SSPP1, 24, 3 }, - { DBGBUS_SSPP1, 24, 4 }, - { DBGBUS_SSPP1, 24, 5 }, - { DBGBUS_SSPP1, 24, 6 }, - { DBGBUS_SSPP1, 24, 7 }, - - { DBGBUS_SSPP1, 25, 0 }, - { DBGBUS_SSPP1, 25, 1 }, - { DBGBUS_SSPP1, 25, 2 }, - { DBGBUS_SSPP1, 25, 3 }, - { DBGBUS_SSPP1, 25, 4 }, - { DBGBUS_SSPP1, 25, 5 }, - { DBGBUS_SSPP1, 25, 6 }, - { DBGBUS_SSPP1, 25, 7 }, - - /* dma 3 */ - { DBGBUS_SSPP1, 30, 0 }, - { DBGBUS_SSPP1, 30, 1 }, - { DBGBUS_SSPP1, 30, 2 }, - { DBGBUS_SSPP1, 30, 3 }, - { DBGBUS_SSPP1, 30, 4 }, - { DBGBUS_SSPP1, 30, 5 }, - { DBGBUS_SSPP1, 30, 6 }, - { DBGBUS_SSPP1, 30, 7 }, - - { DBGBUS_SSPP1, 31, 0 }, - { DBGBUS_SSPP1, 31, 1 }, - { DBGBUS_SSPP1, 31, 2 }, - { DBGBUS_SSPP1, 31, 3 }, - { DBGBUS_SSPP1, 31, 4 }, - { DBGBUS_SSPP1, 31, 5 }, - { DBGBUS_SSPP1, 31, 6 }, - { DBGBUS_SSPP1, 31, 7 }, - - { DBGBUS_SSPP1, 32, 0 }, - { DBGBUS_SSPP1, 32, 1 }, - { DBGBUS_SSPP1, 32, 2 }, - { DBGBUS_SSPP1, 32, 3 }, - { DBGBUS_SSPP1, 32, 4 }, - { DBGBUS_SSPP1, 32, 5 }, - { DBGBUS_SSPP1, 32, 6 }, - { DBGBUS_SSPP1, 32, 7 }, - - { DBGBUS_SSPP1, 33, 0 }, - { DBGBUS_SSPP1, 33, 1 }, - { DBGBUS_SSPP1, 33, 2 }, - { DBGBUS_SSPP1, 33, 3 }, - { DBGBUS_SSPP1, 33, 4 }, - { DBGBUS_SSPP1, 33, 5 }, - { DBGBUS_SSPP1, 33, 6 }, - { DBGBUS_SSPP1, 33, 7 }, - - { DBGBUS_SSPP1, 34, 0 }, - { DBGBUS_SSPP1, 34, 1 }, - { DBGBUS_SSPP1, 34, 2 }, - { DBGBUS_SSPP1, 34, 3 }, - { DBGBUS_SSPP1, 34, 4 }, - { DBGBUS_SSPP1, 34, 5 }, - { DBGBUS_SSPP1, 34, 6 }, - { DBGBUS_SSPP1, 34, 7 }, - - { DBGBUS_SSPP1, 35, 0 }, - { DBGBUS_SSPP1, 35, 1 }, - { DBGBUS_SSPP1, 35, 2 }, - - /* dma 1 */ - { DBGBUS_SSPP1, 40, 0 }, - { DBGBUS_SSPP1, 40, 1 }, - { DBGBUS_SSPP1, 40, 2 }, - { DBGBUS_SSPP1, 40, 3 }, - { DBGBUS_SSPP1, 40, 4 }, - { DBGBUS_SSPP1, 40, 5 }, - { DBGBUS_SSPP1, 40, 6 }, - { DBGBUS_SSPP1, 40, 7 }, - - { DBGBUS_SSPP1, 41, 0 }, - { DBGBUS_SSPP1, 41, 1 }, - { DBGBUS_SSPP1, 41, 2 }, - { DBGBUS_SSPP1, 41, 3 }, - { DBGBUS_SSPP1, 41, 4 }, - { DBGBUS_SSPP1, 41, 5 }, - { DBGBUS_SSPP1, 41, 6 }, - { DBGBUS_SSPP1, 41, 7 }, - - { DBGBUS_SSPP1, 42, 0 }, - { DBGBUS_SSPP1, 42, 1 }, - { DBGBUS_SSPP1, 42, 2 }, - { DBGBUS_SSPP1, 42, 3 }, - { DBGBUS_SSPP1, 42, 4 }, - { DBGBUS_SSPP1, 42, 5 }, - { DBGBUS_SSPP1, 42, 6 }, - { DBGBUS_SSPP1, 42, 7 }, - - { DBGBUS_SSPP1, 44, 0 }, - { DBGBUS_SSPP1, 44, 1 }, - { DBGBUS_SSPP1, 44, 2 }, - { DBGBUS_SSPP1, 44, 3 }, - { DBGBUS_SSPP1, 44, 4 }, - { DBGBUS_SSPP1, 44, 5 }, - { DBGBUS_SSPP1, 44, 6 }, - { DBGBUS_SSPP1, 44, 7 }, - - { DBGBUS_SSPP1, 45, 0 }, - { DBGBUS_SSPP1, 45, 1 }, - { DBGBUS_SSPP1, 45, 2 }, - { DBGBUS_SSPP1, 45, 3 }, - { DBGBUS_SSPP1, 45, 4 }, - { DBGBUS_SSPP1, 45, 5 }, - { DBGBUS_SSPP1, 45, 6 }, - { DBGBUS_SSPP1, 45, 7 }, - - /* cursor 1 */ - { DBGBUS_SSPP1, 80, 0 }, - { DBGBUS_SSPP1, 80, 1 }, - { DBGBUS_SSPP1, 80, 2 }, - { DBGBUS_SSPP1, 80, 3 }, - { DBGBUS_SSPP1, 80, 4 }, - { DBGBUS_SSPP1, 80, 5 }, - { DBGBUS_SSPP1, 80, 6 }, - { DBGBUS_SSPP1, 80, 7 }, - - { DBGBUS_SSPP1, 81, 0 }, - { DBGBUS_SSPP1, 81, 1 }, - { DBGBUS_SSPP1, 81, 2 }, - { DBGBUS_SSPP1, 81, 3 }, - { DBGBUS_SSPP1, 81, 4 }, - { DBGBUS_SSPP1, 81, 5 }, - { DBGBUS_SSPP1, 81, 6 }, - { DBGBUS_SSPP1, 81, 7 }, - - { DBGBUS_SSPP1, 82, 0 }, - { DBGBUS_SSPP1, 82, 1 }, - { DBGBUS_SSPP1, 82, 2 }, - { DBGBUS_SSPP1, 82, 3 }, - { DBGBUS_SSPP1, 82, 4 }, - { DBGBUS_SSPP1, 82, 5 }, - { DBGBUS_SSPP1, 82, 6 }, - { DBGBUS_SSPP1, 82, 7 }, - - { DBGBUS_SSPP1, 83, 0 }, - { DBGBUS_SSPP1, 83, 1 }, - { DBGBUS_SSPP1, 83, 2 }, - { DBGBUS_SSPP1, 83, 3 }, - { DBGBUS_SSPP1, 83, 4 }, - { DBGBUS_SSPP1, 83, 5 }, - { DBGBUS_SSPP1, 83, 6 }, - { DBGBUS_SSPP1, 83, 7 }, - - { DBGBUS_SSPP1, 84, 0 }, - { DBGBUS_SSPP1, 84, 1 }, - { DBGBUS_SSPP1, 84, 2 }, - { DBGBUS_SSPP1, 84, 3 }, - { DBGBUS_SSPP1, 84, 4 }, - { DBGBUS_SSPP1, 84, 5 }, - { DBGBUS_SSPP1, 84, 6 }, - { DBGBUS_SSPP1, 84, 7 }, - - /* dspp */ - { DBGBUS_DSPP, 13, 0 }, - { DBGBUS_DSPP, 19, 0 }, - { DBGBUS_DSPP, 14, 0 }, - { DBGBUS_DSPP, 14, 1 }, - { DBGBUS_DSPP, 14, 3 }, - { DBGBUS_DSPP, 20, 0 }, - { DBGBUS_DSPP, 20, 1 }, - { DBGBUS_DSPP, 20, 3 }, - - /* ppb_0 */ - { DBGBUS_DSPP, 31, 0, _dpu_debug_bus_ppb0_dump }, - { DBGBUS_DSPP, 33, 0, _dpu_debug_bus_ppb0_dump }, - { DBGBUS_DSPP, 35, 0, _dpu_debug_bus_ppb0_dump }, - { DBGBUS_DSPP, 42, 0, _dpu_debug_bus_ppb0_dump }, - - /* ppb_1 */ - { DBGBUS_DSPP, 32, 0, _dpu_debug_bus_ppb1_dump }, - { DBGBUS_DSPP, 34, 0, _dpu_debug_bus_ppb1_dump }, - { DBGBUS_DSPP, 36, 0, _dpu_debug_bus_ppb1_dump }, - { DBGBUS_DSPP, 43, 0, _dpu_debug_bus_ppb1_dump }, - - /* lm_lut */ - { DBGBUS_DSPP, 109, 0 }, - { DBGBUS_DSPP, 105, 0 }, - { DBGBUS_DSPP, 103, 0 }, - - /* tear-check */ - { DBGBUS_PERIPH, 63, 0 }, - { DBGBUS_PERIPH, 64, 0 }, - { DBGBUS_PERIPH, 65, 0 }, - { DBGBUS_PERIPH, 73, 0 }, - { DBGBUS_PERIPH, 74, 0 }, - - /* crossbar */ - { DBGBUS_DSPP, 0, 0, _dpu_debug_bus_xbar_dump }, - - /* rotator */ - { DBGBUS_DSPP, 9, 0}, - - /* blend */ - /* LM0 */ - { DBGBUS_DSPP, 63, 0}, - { DBGBUS_DSPP, 63, 1}, - { DBGBUS_DSPP, 63, 2}, - { DBGBUS_DSPP, 63, 3}, - { DBGBUS_DSPP, 63, 4}, - { DBGBUS_DSPP, 63, 5}, - { DBGBUS_DSPP, 63, 6}, - { DBGBUS_DSPP, 63, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 64, 0}, - { DBGBUS_DSPP, 64, 1}, - { DBGBUS_DSPP, 64, 2}, - { DBGBUS_DSPP, 64, 3}, - { DBGBUS_DSPP, 64, 4}, - { DBGBUS_DSPP, 64, 5}, - { DBGBUS_DSPP, 64, 6}, - { DBGBUS_DSPP, 64, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 65, 0}, - { DBGBUS_DSPP, 65, 1}, - { DBGBUS_DSPP, 65, 2}, - { DBGBUS_DSPP, 65, 3}, - { DBGBUS_DSPP, 65, 4}, - { DBGBUS_DSPP, 65, 5}, - { DBGBUS_DSPP, 65, 6}, - { DBGBUS_DSPP, 65, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 66, 0}, - { DBGBUS_DSPP, 66, 1}, - { DBGBUS_DSPP, 66, 2}, - { DBGBUS_DSPP, 66, 3}, - { DBGBUS_DSPP, 66, 4}, - { DBGBUS_DSPP, 66, 5}, - { DBGBUS_DSPP, 66, 6}, - { DBGBUS_DSPP, 66, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 67, 0}, - { DBGBUS_DSPP, 67, 1}, - { DBGBUS_DSPP, 67, 2}, - { DBGBUS_DSPP, 67, 3}, - { DBGBUS_DSPP, 67, 4}, - { DBGBUS_DSPP, 67, 5}, - { DBGBUS_DSPP, 67, 6}, - { DBGBUS_DSPP, 67, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 68, 0}, - { DBGBUS_DSPP, 68, 1}, - { DBGBUS_DSPP, 68, 2}, - { DBGBUS_DSPP, 68, 3}, - { DBGBUS_DSPP, 68, 4}, - { DBGBUS_DSPP, 68, 5}, - { DBGBUS_DSPP, 68, 6}, - { DBGBUS_DSPP, 68, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 69, 0}, - { DBGBUS_DSPP, 69, 1}, - { DBGBUS_DSPP, 69, 2}, - { DBGBUS_DSPP, 69, 3}, - { DBGBUS_DSPP, 69, 4}, - { DBGBUS_DSPP, 69, 5}, - { DBGBUS_DSPP, 69, 6}, - { DBGBUS_DSPP, 69, 7, _dpu_debug_bus_lm_dump }, - - /* LM1 */ - { DBGBUS_DSPP, 70, 0}, - { DBGBUS_DSPP, 70, 1}, - { DBGBUS_DSPP, 70, 2}, - { DBGBUS_DSPP, 70, 3}, - { DBGBUS_DSPP, 70, 4}, - { DBGBUS_DSPP, 70, 5}, - { DBGBUS_DSPP, 70, 6}, - { DBGBUS_DSPP, 70, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 71, 0}, - { DBGBUS_DSPP, 71, 1}, - { DBGBUS_DSPP, 71, 2}, - { DBGBUS_DSPP, 71, 3}, - { DBGBUS_DSPP, 71, 4}, - { DBGBUS_DSPP, 71, 5}, - { DBGBUS_DSPP, 71, 6}, - { DBGBUS_DSPP, 71, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 72, 0}, - { DBGBUS_DSPP, 72, 1}, - { DBGBUS_DSPP, 72, 2}, - { DBGBUS_DSPP, 72, 3}, - { DBGBUS_DSPP, 72, 4}, - { DBGBUS_DSPP, 72, 5}, - { DBGBUS_DSPP, 72, 6}, - { DBGBUS_DSPP, 72, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 73, 0}, - { DBGBUS_DSPP, 73, 1}, - { DBGBUS_DSPP, 73, 2}, - { DBGBUS_DSPP, 73, 3}, - { DBGBUS_DSPP, 73, 4}, - { DBGBUS_DSPP, 73, 5}, - { DBGBUS_DSPP, 73, 6}, - { DBGBUS_DSPP, 73, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 74, 0}, - { DBGBUS_DSPP, 74, 1}, - { DBGBUS_DSPP, 74, 2}, - { DBGBUS_DSPP, 74, 3}, - { DBGBUS_DSPP, 74, 4}, - { DBGBUS_DSPP, 74, 5}, - { DBGBUS_DSPP, 74, 6}, - { DBGBUS_DSPP, 74, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 75, 0}, - { DBGBUS_DSPP, 75, 1}, - { DBGBUS_DSPP, 75, 2}, - { DBGBUS_DSPP, 75, 3}, - { DBGBUS_DSPP, 75, 4}, - { DBGBUS_DSPP, 75, 5}, - { DBGBUS_DSPP, 75, 6}, - { DBGBUS_DSPP, 75, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 76, 0}, - { DBGBUS_DSPP, 76, 1}, - { DBGBUS_DSPP, 76, 2}, - { DBGBUS_DSPP, 76, 3}, - { DBGBUS_DSPP, 76, 4}, - { DBGBUS_DSPP, 76, 5}, - { DBGBUS_DSPP, 76, 6}, - { DBGBUS_DSPP, 76, 7, _dpu_debug_bus_lm_dump }, - - /* LM2 */ - { DBGBUS_DSPP, 77, 0}, - { DBGBUS_DSPP, 77, 1}, - { DBGBUS_DSPP, 77, 2}, - { DBGBUS_DSPP, 77, 3}, - { DBGBUS_DSPP, 77, 4}, - { DBGBUS_DSPP, 77, 5}, - { DBGBUS_DSPP, 77, 6}, - { DBGBUS_DSPP, 77, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 78, 0}, - { DBGBUS_DSPP, 78, 1}, - { DBGBUS_DSPP, 78, 2}, - { DBGBUS_DSPP, 78, 3}, - { DBGBUS_DSPP, 78, 4}, - { DBGBUS_DSPP, 78, 5}, - { DBGBUS_DSPP, 78, 6}, - { DBGBUS_DSPP, 78, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 79, 0}, - { DBGBUS_DSPP, 79, 1}, - { DBGBUS_DSPP, 79, 2}, - { DBGBUS_DSPP, 79, 3}, - { DBGBUS_DSPP, 79, 4}, - { DBGBUS_DSPP, 79, 5}, - { DBGBUS_DSPP, 79, 6}, - { DBGBUS_DSPP, 79, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 80, 0}, - { DBGBUS_DSPP, 80, 1}, - { DBGBUS_DSPP, 80, 2}, - { DBGBUS_DSPP, 80, 3}, - { DBGBUS_DSPP, 80, 4}, - { DBGBUS_DSPP, 80, 5}, - { DBGBUS_DSPP, 80, 6}, - { DBGBUS_DSPP, 80, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 81, 0}, - { DBGBUS_DSPP, 81, 1}, - { DBGBUS_DSPP, 81, 2}, - { DBGBUS_DSPP, 81, 3}, - { DBGBUS_DSPP, 81, 4}, - { DBGBUS_DSPP, 81, 5}, - { DBGBUS_DSPP, 81, 6}, - { DBGBUS_DSPP, 81, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 82, 0}, - { DBGBUS_DSPP, 82, 1}, - { DBGBUS_DSPP, 82, 2}, - { DBGBUS_DSPP, 82, 3}, - { DBGBUS_DSPP, 82, 4}, - { DBGBUS_DSPP, 82, 5}, - { DBGBUS_DSPP, 82, 6}, - { DBGBUS_DSPP, 82, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 83, 0}, - { DBGBUS_DSPP, 83, 1}, - { DBGBUS_DSPP, 83, 2}, - { DBGBUS_DSPP, 83, 3}, - { DBGBUS_DSPP, 83, 4}, - { DBGBUS_DSPP, 83, 5}, - { DBGBUS_DSPP, 83, 6}, - { DBGBUS_DSPP, 83, 7, _dpu_debug_bus_lm_dump }, - - /* csc */ - { DBGBUS_SSPP0, 7, 0}, - { DBGBUS_SSPP0, 7, 1}, - { DBGBUS_SSPP0, 27, 0}, - { DBGBUS_SSPP0, 27, 1}, - { DBGBUS_SSPP1, 7, 0}, - { DBGBUS_SSPP1, 7, 1}, - { DBGBUS_SSPP1, 27, 0}, - { DBGBUS_SSPP1, 27, 1}, - - /* pcc */ - { DBGBUS_SSPP0, 3, 3}, - { DBGBUS_SSPP0, 23, 3}, - { DBGBUS_SSPP0, 33, 3}, - { DBGBUS_SSPP0, 43, 3}, - { DBGBUS_SSPP1, 3, 3}, - { DBGBUS_SSPP1, 23, 3}, - { DBGBUS_SSPP1, 33, 3}, - { DBGBUS_SSPP1, 43, 3}, - - /* spa */ - { DBGBUS_SSPP0, 8, 0}, - { DBGBUS_SSPP0, 28, 0}, - { DBGBUS_SSPP1, 8, 0}, - { DBGBUS_SSPP1, 28, 0}, - { DBGBUS_DSPP, 13, 0}, - { DBGBUS_DSPP, 19, 0}, - - /* igc */ - { DBGBUS_SSPP0, 9, 0}, - { DBGBUS_SSPP0, 9, 1}, - { DBGBUS_SSPP0, 9, 3}, - { DBGBUS_SSPP0, 29, 0}, - { DBGBUS_SSPP0, 29, 1}, - { DBGBUS_SSPP0, 29, 3}, - { DBGBUS_SSPP0, 17, 0}, - { DBGBUS_SSPP0, 17, 1}, - { DBGBUS_SSPP0, 17, 3}, - { DBGBUS_SSPP0, 37, 0}, - { DBGBUS_SSPP0, 37, 1}, - { DBGBUS_SSPP0, 37, 3}, - { DBGBUS_SSPP0, 46, 0}, - { DBGBUS_SSPP0, 46, 1}, - { DBGBUS_SSPP0, 46, 3}, - - { DBGBUS_SSPP1, 9, 0}, - { DBGBUS_SSPP1, 9, 1}, - { DBGBUS_SSPP1, 9, 3}, - { DBGBUS_SSPP1, 29, 0}, - { DBGBUS_SSPP1, 29, 1}, - { DBGBUS_SSPP1, 29, 3}, - { DBGBUS_SSPP1, 17, 0}, - { DBGBUS_SSPP1, 17, 1}, - { DBGBUS_SSPP1, 17, 3}, - { DBGBUS_SSPP1, 37, 0}, - { DBGBUS_SSPP1, 37, 1}, - { DBGBUS_SSPP1, 37, 3}, - { DBGBUS_SSPP1, 46, 0}, - { DBGBUS_SSPP1, 46, 1}, - { DBGBUS_SSPP1, 46, 3}, - - { DBGBUS_DSPP, 14, 0}, - { DBGBUS_DSPP, 14, 1}, - { DBGBUS_DSPP, 14, 3}, - { DBGBUS_DSPP, 20, 0}, - { DBGBUS_DSPP, 20, 1}, - { DBGBUS_DSPP, 20, 3}, - - { DBGBUS_PERIPH, 60, 0}, -}; - -static struct dpu_debug_bus_entry dbg_bus_dpu_sdm845[] = { - - /* Unpack 0 sspp 0*/ - { DBGBUS_SSPP0, 50, 2 }, - { DBGBUS_SSPP0, 60, 2 }, - { DBGBUS_SSPP0, 70, 2 }, - - /* Upack 0 sspp 1*/ - { DBGBUS_SSPP1, 50, 2 }, - { DBGBUS_SSPP1, 60, 2 }, - { DBGBUS_SSPP1, 70, 2 }, - - /* scheduler */ - { DBGBUS_DSPP, 130, 0 }, - { DBGBUS_DSPP, 130, 1 }, - { DBGBUS_DSPP, 130, 2 }, - { DBGBUS_DSPP, 130, 3 }, - { DBGBUS_DSPP, 130, 4 }, - { DBGBUS_DSPP, 130, 5 }, - - /* qseed */ - { DBGBUS_SSPP0, 6, 0}, - { DBGBUS_SSPP0, 6, 1}, - { DBGBUS_SSPP0, 26, 0}, - { DBGBUS_SSPP0, 26, 1}, - { DBGBUS_SSPP1, 6, 0}, - { DBGBUS_SSPP1, 6, 1}, - { DBGBUS_SSPP1, 26, 0}, - { DBGBUS_SSPP1, 26, 1}, - - /* scale */ - { DBGBUS_SSPP0, 16, 0}, - { DBGBUS_SSPP0, 16, 1}, - { DBGBUS_SSPP0, 36, 0}, - { DBGBUS_SSPP0, 36, 1}, - { DBGBUS_SSPP1, 16, 0}, - { DBGBUS_SSPP1, 16, 1}, - { DBGBUS_SSPP1, 36, 0}, - { DBGBUS_SSPP1, 36, 1}, - - /* fetch sspp0 */ - - /* vig 0 */ - { DBGBUS_SSPP0, 0, 0 }, - { DBGBUS_SSPP0, 0, 1 }, - { DBGBUS_SSPP0, 0, 2 }, - { DBGBUS_SSPP0, 0, 3 }, - { DBGBUS_SSPP0, 0, 4 }, - { DBGBUS_SSPP0, 0, 5 }, - { DBGBUS_SSPP0, 0, 6 }, - { DBGBUS_SSPP0, 0, 7 }, - - { DBGBUS_SSPP0, 1, 0 }, - { DBGBUS_SSPP0, 1, 1 }, - { DBGBUS_SSPP0, 1, 2 }, - { DBGBUS_SSPP0, 1, 3 }, - { DBGBUS_SSPP0, 1, 4 }, - { DBGBUS_SSPP0, 1, 5 }, - { DBGBUS_SSPP0, 1, 6 }, - { DBGBUS_SSPP0, 1, 7 }, - - { DBGBUS_SSPP0, 2, 0 }, - { DBGBUS_SSPP0, 2, 1 }, - { DBGBUS_SSPP0, 2, 2 }, - { DBGBUS_SSPP0, 2, 3 }, - { DBGBUS_SSPP0, 2, 4 }, - { DBGBUS_SSPP0, 2, 5 }, - { DBGBUS_SSPP0, 2, 6 }, - { DBGBUS_SSPP0, 2, 7 }, - - { DBGBUS_SSPP0, 4, 0 }, - { DBGBUS_SSPP0, 4, 1 }, - { DBGBUS_SSPP0, 4, 2 }, - { DBGBUS_SSPP0, 4, 3 }, - { DBGBUS_SSPP0, 4, 4 }, - { DBGBUS_SSPP0, 4, 5 }, - { DBGBUS_SSPP0, 4, 6 }, - { DBGBUS_SSPP0, 4, 7 }, - - { DBGBUS_SSPP0, 5, 0 }, - { DBGBUS_SSPP0, 5, 1 }, - { DBGBUS_SSPP0, 5, 2 }, - { DBGBUS_SSPP0, 5, 3 }, - { DBGBUS_SSPP0, 5, 4 }, - { DBGBUS_SSPP0, 5, 5 }, - { DBGBUS_SSPP0, 5, 6 }, - { DBGBUS_SSPP0, 5, 7 }, - - /* vig 2 */ - { DBGBUS_SSPP0, 20, 0 }, - { DBGBUS_SSPP0, 20, 1 }, - { DBGBUS_SSPP0, 20, 2 }, - { DBGBUS_SSPP0, 20, 3 }, - { DBGBUS_SSPP0, 20, 4 }, - { DBGBUS_SSPP0, 20, 5 }, - { DBGBUS_SSPP0, 20, 6 }, - { DBGBUS_SSPP0, 20, 7 }, - - { DBGBUS_SSPP0, 21, 0 }, - { DBGBUS_SSPP0, 21, 1 }, - { DBGBUS_SSPP0, 21, 2 }, - { DBGBUS_SSPP0, 21, 3 }, - { DBGBUS_SSPP0, 21, 4 }, - { DBGBUS_SSPP0, 21, 5 }, - { DBGBUS_SSPP0, 21, 6 }, - { DBGBUS_SSPP0, 21, 7 }, - - { DBGBUS_SSPP0, 22, 0 }, - { DBGBUS_SSPP0, 22, 1 }, - { DBGBUS_SSPP0, 22, 2 }, - { DBGBUS_SSPP0, 22, 3 }, - { DBGBUS_SSPP0, 22, 4 }, - { DBGBUS_SSPP0, 22, 5 }, - { DBGBUS_SSPP0, 22, 6 }, - { DBGBUS_SSPP0, 22, 7 }, - - { DBGBUS_SSPP0, 24, 0 }, - { DBGBUS_SSPP0, 24, 1 }, - { DBGBUS_SSPP0, 24, 2 }, - { DBGBUS_SSPP0, 24, 3 }, - { DBGBUS_SSPP0, 24, 4 }, - { DBGBUS_SSPP0, 24, 5 }, - { DBGBUS_SSPP0, 24, 6 }, - { DBGBUS_SSPP0, 24, 7 }, - - { DBGBUS_SSPP0, 25, 0 }, - { DBGBUS_SSPP0, 25, 1 }, - { DBGBUS_SSPP0, 25, 2 }, - { DBGBUS_SSPP0, 25, 3 }, - { DBGBUS_SSPP0, 25, 4 }, - { DBGBUS_SSPP0, 25, 5 }, - { DBGBUS_SSPP0, 25, 6 }, - { DBGBUS_SSPP0, 25, 7 }, - - /* dma 2 */ - { DBGBUS_SSPP0, 30, 0 }, - { DBGBUS_SSPP0, 30, 1 }, - { DBGBUS_SSPP0, 30, 2 }, - { DBGBUS_SSPP0, 30, 3 }, - { DBGBUS_SSPP0, 30, 4 }, - { DBGBUS_SSPP0, 30, 5 }, - { DBGBUS_SSPP0, 30, 6 }, - { DBGBUS_SSPP0, 30, 7 }, - - { DBGBUS_SSPP0, 31, 0 }, - { DBGBUS_SSPP0, 31, 1 }, - { DBGBUS_SSPP0, 31, 2 }, - { DBGBUS_SSPP0, 31, 3 }, - { DBGBUS_SSPP0, 31, 4 }, - { DBGBUS_SSPP0, 31, 5 }, - { DBGBUS_SSPP0, 31, 6 }, - { DBGBUS_SSPP0, 31, 7 }, - - { DBGBUS_SSPP0, 32, 0 }, - { DBGBUS_SSPP0, 32, 1 }, - { DBGBUS_SSPP0, 32, 2 }, - { DBGBUS_SSPP0, 32, 3 }, - { DBGBUS_SSPP0, 32, 4 }, - { DBGBUS_SSPP0, 32, 5 }, - { DBGBUS_SSPP0, 32, 6 }, - { DBGBUS_SSPP0, 32, 7 }, - - { DBGBUS_SSPP0, 33, 0 }, - { DBGBUS_SSPP0, 33, 1 }, - { DBGBUS_SSPP0, 33, 2 }, - { DBGBUS_SSPP0, 33, 3 }, - { DBGBUS_SSPP0, 33, 4 }, - { DBGBUS_SSPP0, 33, 5 }, - { DBGBUS_SSPP0, 33, 6 }, - { DBGBUS_SSPP0, 33, 7 }, - - { DBGBUS_SSPP0, 34, 0 }, - { DBGBUS_SSPP0, 34, 1 }, - { DBGBUS_SSPP0, 34, 2 }, - { DBGBUS_SSPP0, 34, 3 }, - { DBGBUS_SSPP0, 34, 4 }, - { DBGBUS_SSPP0, 34, 5 }, - { DBGBUS_SSPP0, 34, 6 }, - { DBGBUS_SSPP0, 34, 7 }, - - { DBGBUS_SSPP0, 35, 0 }, - { DBGBUS_SSPP0, 35, 1 }, - { DBGBUS_SSPP0, 35, 2 }, - { DBGBUS_SSPP0, 35, 3 }, - - /* dma 0 */ - { DBGBUS_SSPP0, 40, 0 }, - { DBGBUS_SSPP0, 40, 1 }, - { DBGBUS_SSPP0, 40, 2 }, - { DBGBUS_SSPP0, 40, 3 }, - { DBGBUS_SSPP0, 40, 4 }, - { DBGBUS_SSPP0, 40, 5 }, - { DBGBUS_SSPP0, 40, 6 }, - { DBGBUS_SSPP0, 40, 7 }, - - { DBGBUS_SSPP0, 41, 0 }, - { DBGBUS_SSPP0, 41, 1 }, - { DBGBUS_SSPP0, 41, 2 }, - { DBGBUS_SSPP0, 41, 3 }, - { DBGBUS_SSPP0, 41, 4 }, - { DBGBUS_SSPP0, 41, 5 }, - { DBGBUS_SSPP0, 41, 6 }, - { DBGBUS_SSPP0, 41, 7 }, - - { DBGBUS_SSPP0, 42, 0 }, - { DBGBUS_SSPP0, 42, 1 }, - { DBGBUS_SSPP0, 42, 2 }, - { DBGBUS_SSPP0, 42, 3 }, - { DBGBUS_SSPP0, 42, 4 }, - { DBGBUS_SSPP0, 42, 5 }, - { DBGBUS_SSPP0, 42, 6 }, - { DBGBUS_SSPP0, 42, 7 }, - - { DBGBUS_SSPP0, 44, 0 }, - { DBGBUS_SSPP0, 44, 1 }, - { DBGBUS_SSPP0, 44, 2 }, - { DBGBUS_SSPP0, 44, 3 }, - { DBGBUS_SSPP0, 44, 4 }, - { DBGBUS_SSPP0, 44, 5 }, - { DBGBUS_SSPP0, 44, 6 }, - { DBGBUS_SSPP0, 44, 7 }, - - { DBGBUS_SSPP0, 45, 0 }, - { DBGBUS_SSPP0, 45, 1 }, - { DBGBUS_SSPP0, 45, 2 }, - { DBGBUS_SSPP0, 45, 3 }, - { DBGBUS_SSPP0, 45, 4 }, - { DBGBUS_SSPP0, 45, 5 }, - { DBGBUS_SSPP0, 45, 6 }, - { DBGBUS_SSPP0, 45, 7 }, - - /* fetch sspp1 */ - /* vig 1 */ - { DBGBUS_SSPP1, 0, 0 }, - { DBGBUS_SSPP1, 0, 1 }, - { DBGBUS_SSPP1, 0, 2 }, - { DBGBUS_SSPP1, 0, 3 }, - { DBGBUS_SSPP1, 0, 4 }, - { DBGBUS_SSPP1, 0, 5 }, - { DBGBUS_SSPP1, 0, 6 }, - { DBGBUS_SSPP1, 0, 7 }, - - { DBGBUS_SSPP1, 1, 0 }, - { DBGBUS_SSPP1, 1, 1 }, - { DBGBUS_SSPP1, 1, 2 }, - { DBGBUS_SSPP1, 1, 3 }, - { DBGBUS_SSPP1, 1, 4 }, - { DBGBUS_SSPP1, 1, 5 }, - { DBGBUS_SSPP1, 1, 6 }, - { DBGBUS_SSPP1, 1, 7 }, - - { DBGBUS_SSPP1, 2, 0 }, - { DBGBUS_SSPP1, 2, 1 }, - { DBGBUS_SSPP1, 2, 2 }, - { DBGBUS_SSPP1, 2, 3 }, - { DBGBUS_SSPP1, 2, 4 }, - { DBGBUS_SSPP1, 2, 5 }, - { DBGBUS_SSPP1, 2, 6 }, - { DBGBUS_SSPP1, 2, 7 }, - - { DBGBUS_SSPP1, 4, 0 }, - { DBGBUS_SSPP1, 4, 1 }, - { DBGBUS_SSPP1, 4, 2 }, - { DBGBUS_SSPP1, 4, 3 }, - { DBGBUS_SSPP1, 4, 4 }, - { DBGBUS_SSPP1, 4, 5 }, - { DBGBUS_SSPP1, 4, 6 }, - { DBGBUS_SSPP1, 4, 7 }, - - { DBGBUS_SSPP1, 5, 0 }, - { DBGBUS_SSPP1, 5, 1 }, - { DBGBUS_SSPP1, 5, 2 }, - { DBGBUS_SSPP1, 5, 3 }, - { DBGBUS_SSPP1, 5, 4 }, - { DBGBUS_SSPP1, 5, 5 }, - { DBGBUS_SSPP1, 5, 6 }, - { DBGBUS_SSPP1, 5, 7 }, - - /* vig 3 */ - { DBGBUS_SSPP1, 20, 0 }, - { DBGBUS_SSPP1, 20, 1 }, - { DBGBUS_SSPP1, 20, 2 }, - { DBGBUS_SSPP1, 20, 3 }, - { DBGBUS_SSPP1, 20, 4 }, - { DBGBUS_SSPP1, 20, 5 }, - { DBGBUS_SSPP1, 20, 6 }, - { DBGBUS_SSPP1, 20, 7 }, - - { DBGBUS_SSPP1, 21, 0 }, - { DBGBUS_SSPP1, 21, 1 }, - { DBGBUS_SSPP1, 21, 2 }, - { DBGBUS_SSPP1, 21, 3 }, - { DBGBUS_SSPP1, 21, 4 }, - { DBGBUS_SSPP1, 21, 5 }, - { DBGBUS_SSPP1, 21, 6 }, - { DBGBUS_SSPP1, 21, 7 }, - - { DBGBUS_SSPP1, 22, 0 }, - { DBGBUS_SSPP1, 22, 1 }, - { DBGBUS_SSPP1, 22, 2 }, - { DBGBUS_SSPP1, 22, 3 }, - { DBGBUS_SSPP1, 22, 4 }, - { DBGBUS_SSPP1, 22, 5 }, - { DBGBUS_SSPP1, 22, 6 }, - { DBGBUS_SSPP1, 22, 7 }, - - { DBGBUS_SSPP1, 24, 0 }, - { DBGBUS_SSPP1, 24, 1 }, - { DBGBUS_SSPP1, 24, 2 }, - { DBGBUS_SSPP1, 24, 3 }, - { DBGBUS_SSPP1, 24, 4 }, - { DBGBUS_SSPP1, 24, 5 }, - { DBGBUS_SSPP1, 24, 6 }, - { DBGBUS_SSPP1, 24, 7 }, - - { DBGBUS_SSPP1, 25, 0 }, - { DBGBUS_SSPP1, 25, 1 }, - { DBGBUS_SSPP1, 25, 2 }, - { DBGBUS_SSPP1, 25, 3 }, - { DBGBUS_SSPP1, 25, 4 }, - { DBGBUS_SSPP1, 25, 5 }, - { DBGBUS_SSPP1, 25, 6 }, - { DBGBUS_SSPP1, 25, 7 }, - - /* dma 3 */ - { DBGBUS_SSPP1, 30, 0 }, - { DBGBUS_SSPP1, 30, 1 }, - { DBGBUS_SSPP1, 30, 2 }, - { DBGBUS_SSPP1, 30, 3 }, - { DBGBUS_SSPP1, 30, 4 }, - { DBGBUS_SSPP1, 30, 5 }, - { DBGBUS_SSPP1, 30, 6 }, - { DBGBUS_SSPP1, 30, 7 }, - - { DBGBUS_SSPP1, 31, 0 }, - { DBGBUS_SSPP1, 31, 1 }, - { DBGBUS_SSPP1, 31, 2 }, - { DBGBUS_SSPP1, 31, 3 }, - { DBGBUS_SSPP1, 31, 4 }, - { DBGBUS_SSPP1, 31, 5 }, - { DBGBUS_SSPP1, 31, 6 }, - { DBGBUS_SSPP1, 31, 7 }, - - { DBGBUS_SSPP1, 32, 0 }, - { DBGBUS_SSPP1, 32, 1 }, - { DBGBUS_SSPP1, 32, 2 }, - { DBGBUS_SSPP1, 32, 3 }, - { DBGBUS_SSPP1, 32, 4 }, - { DBGBUS_SSPP1, 32, 5 }, - { DBGBUS_SSPP1, 32, 6 }, - { DBGBUS_SSPP1, 32, 7 }, - - { DBGBUS_SSPP1, 33, 0 }, - { DBGBUS_SSPP1, 33, 1 }, - { DBGBUS_SSPP1, 33, 2 }, - { DBGBUS_SSPP1, 33, 3 }, - { DBGBUS_SSPP1, 33, 4 }, - { DBGBUS_SSPP1, 33, 5 }, - { DBGBUS_SSPP1, 33, 6 }, - { DBGBUS_SSPP1, 33, 7 }, - - { DBGBUS_SSPP1, 34, 0 }, - { DBGBUS_SSPP1, 34, 1 }, - { DBGBUS_SSPP1, 34, 2 }, - { DBGBUS_SSPP1, 34, 3 }, - { DBGBUS_SSPP1, 34, 4 }, - { DBGBUS_SSPP1, 34, 5 }, - { DBGBUS_SSPP1, 34, 6 }, - { DBGBUS_SSPP1, 34, 7 }, - - { DBGBUS_SSPP1, 35, 0 }, - { DBGBUS_SSPP1, 35, 1 }, - { DBGBUS_SSPP1, 35, 2 }, - - /* dma 1 */ - { DBGBUS_SSPP1, 40, 0 }, - { DBGBUS_SSPP1, 40, 1 }, - { DBGBUS_SSPP1, 40, 2 }, - { DBGBUS_SSPP1, 40, 3 }, - { DBGBUS_SSPP1, 40, 4 }, - { DBGBUS_SSPP1, 40, 5 }, - { DBGBUS_SSPP1, 40, 6 }, - { DBGBUS_SSPP1, 40, 7 }, - - { DBGBUS_SSPP1, 41, 0 }, - { DBGBUS_SSPP1, 41, 1 }, - { DBGBUS_SSPP1, 41, 2 }, - { DBGBUS_SSPP1, 41, 3 }, - { DBGBUS_SSPP1, 41, 4 }, - { DBGBUS_SSPP1, 41, 5 }, - { DBGBUS_SSPP1, 41, 6 }, - { DBGBUS_SSPP1, 41, 7 }, - - { DBGBUS_SSPP1, 42, 0 }, - { DBGBUS_SSPP1, 42, 1 }, - { DBGBUS_SSPP1, 42, 2 }, - { DBGBUS_SSPP1, 42, 3 }, - { DBGBUS_SSPP1, 42, 4 }, - { DBGBUS_SSPP1, 42, 5 }, - { DBGBUS_SSPP1, 42, 6 }, - { DBGBUS_SSPP1, 42, 7 }, - - { DBGBUS_SSPP1, 44, 0 }, - { DBGBUS_SSPP1, 44, 1 }, - { DBGBUS_SSPP1, 44, 2 }, - { DBGBUS_SSPP1, 44, 3 }, - { DBGBUS_SSPP1, 44, 4 }, - { DBGBUS_SSPP1, 44, 5 }, - { DBGBUS_SSPP1, 44, 6 }, - { DBGBUS_SSPP1, 44, 7 }, - - { DBGBUS_SSPP1, 45, 0 }, - { DBGBUS_SSPP1, 45, 1 }, - { DBGBUS_SSPP1, 45, 2 }, - { DBGBUS_SSPP1, 45, 3 }, - { DBGBUS_SSPP1, 45, 4 }, - { DBGBUS_SSPP1, 45, 5 }, - { DBGBUS_SSPP1, 45, 6 }, - { DBGBUS_SSPP1, 45, 7 }, - - /* dspp */ - { DBGBUS_DSPP, 13, 0 }, - { DBGBUS_DSPP, 19, 0 }, - { DBGBUS_DSPP, 14, 0 }, - { DBGBUS_DSPP, 14, 1 }, - { DBGBUS_DSPP, 14, 3 }, - { DBGBUS_DSPP, 20, 0 }, - { DBGBUS_DSPP, 20, 1 }, - { DBGBUS_DSPP, 20, 3 }, - - /* ppb_0 */ - { DBGBUS_DSPP, 31, 0, _dpu_debug_bus_ppb0_dump }, - { DBGBUS_DSPP, 33, 0, _dpu_debug_bus_ppb0_dump }, - { DBGBUS_DSPP, 35, 0, _dpu_debug_bus_ppb0_dump }, - { DBGBUS_DSPP, 42, 0, _dpu_debug_bus_ppb0_dump }, - - /* ppb_1 */ - { DBGBUS_DSPP, 32, 0, _dpu_debug_bus_ppb1_dump }, - { DBGBUS_DSPP, 34, 0, _dpu_debug_bus_ppb1_dump }, - { DBGBUS_DSPP, 36, 0, _dpu_debug_bus_ppb1_dump }, - { DBGBUS_DSPP, 43, 0, _dpu_debug_bus_ppb1_dump }, - - /* lm_lut */ - { DBGBUS_DSPP, 109, 0 }, - { DBGBUS_DSPP, 105, 0 }, - { DBGBUS_DSPP, 103, 0 }, - - /* crossbar */ - { DBGBUS_DSPP, 0, 0, _dpu_debug_bus_xbar_dump }, - - /* rotator */ - { DBGBUS_DSPP, 9, 0}, - - /* blend */ - /* LM0 */ - { DBGBUS_DSPP, 63, 1}, - { DBGBUS_DSPP, 63, 2}, - { DBGBUS_DSPP, 63, 3}, - { DBGBUS_DSPP, 63, 4}, - { DBGBUS_DSPP, 63, 5}, - { DBGBUS_DSPP, 63, 6}, - { DBGBUS_DSPP, 63, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 64, 1}, - { DBGBUS_DSPP, 64, 2}, - { DBGBUS_DSPP, 64, 3}, - { DBGBUS_DSPP, 64, 4}, - { DBGBUS_DSPP, 64, 5}, - { DBGBUS_DSPP, 64, 6}, - { DBGBUS_DSPP, 64, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 65, 1}, - { DBGBUS_DSPP, 65, 2}, - { DBGBUS_DSPP, 65, 3}, - { DBGBUS_DSPP, 65, 4}, - { DBGBUS_DSPP, 65, 5}, - { DBGBUS_DSPP, 65, 6}, - { DBGBUS_DSPP, 65, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 66, 1}, - { DBGBUS_DSPP, 66, 2}, - { DBGBUS_DSPP, 66, 3}, - { DBGBUS_DSPP, 66, 4}, - { DBGBUS_DSPP, 66, 5}, - { DBGBUS_DSPP, 66, 6}, - { DBGBUS_DSPP, 66, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 67, 1}, - { DBGBUS_DSPP, 67, 2}, - { DBGBUS_DSPP, 67, 3}, - { DBGBUS_DSPP, 67, 4}, - { DBGBUS_DSPP, 67, 5}, - { DBGBUS_DSPP, 67, 6}, - { DBGBUS_DSPP, 67, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 68, 1}, - { DBGBUS_DSPP, 68, 2}, - { DBGBUS_DSPP, 68, 3}, - { DBGBUS_DSPP, 68, 4}, - { DBGBUS_DSPP, 68, 5}, - { DBGBUS_DSPP, 68, 6}, - { DBGBUS_DSPP, 68, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 69, 1}, - { DBGBUS_DSPP, 69, 2}, - { DBGBUS_DSPP, 69, 3}, - { DBGBUS_DSPP, 69, 4}, - { DBGBUS_DSPP, 69, 5}, - { DBGBUS_DSPP, 69, 6}, - { DBGBUS_DSPP, 69, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 84, 1}, - { DBGBUS_DSPP, 84, 2}, - { DBGBUS_DSPP, 84, 3}, - { DBGBUS_DSPP, 84, 4}, - { DBGBUS_DSPP, 84, 5}, - { DBGBUS_DSPP, 84, 6}, - { DBGBUS_DSPP, 84, 7, _dpu_debug_bus_lm_dump }, - - - { DBGBUS_DSPP, 85, 1}, - { DBGBUS_DSPP, 85, 2}, - { DBGBUS_DSPP, 85, 3}, - { DBGBUS_DSPP, 85, 4}, - { DBGBUS_DSPP, 85, 5}, - { DBGBUS_DSPP, 85, 6}, - { DBGBUS_DSPP, 85, 7, _dpu_debug_bus_lm_dump }, - - - { DBGBUS_DSPP, 86, 1}, - { DBGBUS_DSPP, 86, 2}, - { DBGBUS_DSPP, 86, 3}, - { DBGBUS_DSPP, 86, 4}, - { DBGBUS_DSPP, 86, 5}, - { DBGBUS_DSPP, 86, 6}, - { DBGBUS_DSPP, 86, 7, _dpu_debug_bus_lm_dump }, - - - { DBGBUS_DSPP, 87, 1}, - { DBGBUS_DSPP, 87, 2}, - { DBGBUS_DSPP, 87, 3}, - { DBGBUS_DSPP, 87, 4}, - { DBGBUS_DSPP, 87, 5}, - { DBGBUS_DSPP, 87, 6}, - { DBGBUS_DSPP, 87, 7, _dpu_debug_bus_lm_dump }, - - /* LM1 */ - { DBGBUS_DSPP, 70, 1}, - { DBGBUS_DSPP, 70, 2}, - { DBGBUS_DSPP, 70, 3}, - { DBGBUS_DSPP, 70, 4}, - { DBGBUS_DSPP, 70, 5}, - { DBGBUS_DSPP, 70, 6}, - { DBGBUS_DSPP, 70, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 71, 1}, - { DBGBUS_DSPP, 71, 2}, - { DBGBUS_DSPP, 71, 3}, - { DBGBUS_DSPP, 71, 4}, - { DBGBUS_DSPP, 71, 5}, - { DBGBUS_DSPP, 71, 6}, - { DBGBUS_DSPP, 71, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 72, 1}, - { DBGBUS_DSPP, 72, 2}, - { DBGBUS_DSPP, 72, 3}, - { DBGBUS_DSPP, 72, 4}, - { DBGBUS_DSPP, 72, 5}, - { DBGBUS_DSPP, 72, 6}, - { DBGBUS_DSPP, 72, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 73, 1}, - { DBGBUS_DSPP, 73, 2}, - { DBGBUS_DSPP, 73, 3}, - { DBGBUS_DSPP, 73, 4}, - { DBGBUS_DSPP, 73, 5}, - { DBGBUS_DSPP, 73, 6}, - { DBGBUS_DSPP, 73, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 74, 1}, - { DBGBUS_DSPP, 74, 2}, - { DBGBUS_DSPP, 74, 3}, - { DBGBUS_DSPP, 74, 4}, - { DBGBUS_DSPP, 74, 5}, - { DBGBUS_DSPP, 74, 6}, - { DBGBUS_DSPP, 74, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 75, 1}, - { DBGBUS_DSPP, 75, 2}, - { DBGBUS_DSPP, 75, 3}, - { DBGBUS_DSPP, 75, 4}, - { DBGBUS_DSPP, 75, 5}, - { DBGBUS_DSPP, 75, 6}, - { DBGBUS_DSPP, 75, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 76, 1}, - { DBGBUS_DSPP, 76, 2}, - { DBGBUS_DSPP, 76, 3}, - { DBGBUS_DSPP, 76, 4}, - { DBGBUS_DSPP, 76, 5}, - { DBGBUS_DSPP, 76, 6}, - { DBGBUS_DSPP, 76, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 88, 1}, - { DBGBUS_DSPP, 88, 2}, - { DBGBUS_DSPP, 88, 3}, - { DBGBUS_DSPP, 88, 4}, - { DBGBUS_DSPP, 88, 5}, - { DBGBUS_DSPP, 88, 6}, - { DBGBUS_DSPP, 88, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 89, 1}, - { DBGBUS_DSPP, 89, 2}, - { DBGBUS_DSPP, 89, 3}, - { DBGBUS_DSPP, 89, 4}, - { DBGBUS_DSPP, 89, 5}, - { DBGBUS_DSPP, 89, 6}, - { DBGBUS_DSPP, 89, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 90, 1}, - { DBGBUS_DSPP, 90, 2}, - { DBGBUS_DSPP, 90, 3}, - { DBGBUS_DSPP, 90, 4}, - { DBGBUS_DSPP, 90, 5}, - { DBGBUS_DSPP, 90, 6}, - { DBGBUS_DSPP, 90, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 91, 1}, - { DBGBUS_DSPP, 91, 2}, - { DBGBUS_DSPP, 91, 3}, - { DBGBUS_DSPP, 91, 4}, - { DBGBUS_DSPP, 91, 5}, - { DBGBUS_DSPP, 91, 6}, - { DBGBUS_DSPP, 91, 7, _dpu_debug_bus_lm_dump }, - - /* LM2 */ - { DBGBUS_DSPP, 77, 0}, - { DBGBUS_DSPP, 77, 1}, - { DBGBUS_DSPP, 77, 2}, - { DBGBUS_DSPP, 77, 3}, - { DBGBUS_DSPP, 77, 4}, - { DBGBUS_DSPP, 77, 5}, - { DBGBUS_DSPP, 77, 6}, - { DBGBUS_DSPP, 77, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 78, 0}, - { DBGBUS_DSPP, 78, 1}, - { DBGBUS_DSPP, 78, 2}, - { DBGBUS_DSPP, 78, 3}, - { DBGBUS_DSPP, 78, 4}, - { DBGBUS_DSPP, 78, 5}, - { DBGBUS_DSPP, 78, 6}, - { DBGBUS_DSPP, 78, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 79, 0}, - { DBGBUS_DSPP, 79, 1}, - { DBGBUS_DSPP, 79, 2}, - { DBGBUS_DSPP, 79, 3}, - { DBGBUS_DSPP, 79, 4}, - { DBGBUS_DSPP, 79, 5}, - { DBGBUS_DSPP, 79, 6}, - { DBGBUS_DSPP, 79, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 80, 0}, - { DBGBUS_DSPP, 80, 1}, - { DBGBUS_DSPP, 80, 2}, - { DBGBUS_DSPP, 80, 3}, - { DBGBUS_DSPP, 80, 4}, - { DBGBUS_DSPP, 80, 5}, - { DBGBUS_DSPP, 80, 6}, - { DBGBUS_DSPP, 80, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 81, 0}, - { DBGBUS_DSPP, 81, 1}, - { DBGBUS_DSPP, 81, 2}, - { DBGBUS_DSPP, 81, 3}, - { DBGBUS_DSPP, 81, 4}, - { DBGBUS_DSPP, 81, 5}, - { DBGBUS_DSPP, 81, 6}, - { DBGBUS_DSPP, 81, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 82, 0}, - { DBGBUS_DSPP, 82, 1}, - { DBGBUS_DSPP, 82, 2}, - { DBGBUS_DSPP, 82, 3}, - { DBGBUS_DSPP, 82, 4}, - { DBGBUS_DSPP, 82, 5}, - { DBGBUS_DSPP, 82, 6}, - { DBGBUS_DSPP, 82, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 83, 0}, - { DBGBUS_DSPP, 83, 1}, - { DBGBUS_DSPP, 83, 2}, - { DBGBUS_DSPP, 83, 3}, - { DBGBUS_DSPP, 83, 4}, - { DBGBUS_DSPP, 83, 5}, - { DBGBUS_DSPP, 83, 6}, - { DBGBUS_DSPP, 83, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 92, 1}, - { DBGBUS_DSPP, 92, 2}, - { DBGBUS_DSPP, 92, 3}, - { DBGBUS_DSPP, 92, 4}, - { DBGBUS_DSPP, 92, 5}, - { DBGBUS_DSPP, 92, 6}, - { DBGBUS_DSPP, 92, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 93, 1}, - { DBGBUS_DSPP, 93, 2}, - { DBGBUS_DSPP, 93, 3}, - { DBGBUS_DSPP, 93, 4}, - { DBGBUS_DSPP, 93, 5}, - { DBGBUS_DSPP, 93, 6}, - { DBGBUS_DSPP, 93, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 94, 1}, - { DBGBUS_DSPP, 94, 2}, - { DBGBUS_DSPP, 94, 3}, - { DBGBUS_DSPP, 94, 4}, - { DBGBUS_DSPP, 94, 5}, - { DBGBUS_DSPP, 94, 6}, - { DBGBUS_DSPP, 94, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 95, 1}, - { DBGBUS_DSPP, 95, 2}, - { DBGBUS_DSPP, 95, 3}, - { DBGBUS_DSPP, 95, 4}, - { DBGBUS_DSPP, 95, 5}, - { DBGBUS_DSPP, 95, 6}, - { DBGBUS_DSPP, 95, 7, _dpu_debug_bus_lm_dump }, - - /* LM5 */ - { DBGBUS_DSPP, 110, 1}, - { DBGBUS_DSPP, 110, 2}, - { DBGBUS_DSPP, 110, 3}, - { DBGBUS_DSPP, 110, 4}, - { DBGBUS_DSPP, 110, 5}, - { DBGBUS_DSPP, 110, 6}, - { DBGBUS_DSPP, 110, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 111, 1}, - { DBGBUS_DSPP, 111, 2}, - { DBGBUS_DSPP, 111, 3}, - { DBGBUS_DSPP, 111, 4}, - { DBGBUS_DSPP, 111, 5}, - { DBGBUS_DSPP, 111, 6}, - { DBGBUS_DSPP, 111, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 112, 1}, - { DBGBUS_DSPP, 112, 2}, - { DBGBUS_DSPP, 112, 3}, - { DBGBUS_DSPP, 112, 4}, - { DBGBUS_DSPP, 112, 5}, - { DBGBUS_DSPP, 112, 6}, - { DBGBUS_DSPP, 112, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 113, 1}, - { DBGBUS_DSPP, 113, 2}, - { DBGBUS_DSPP, 113, 3}, - { DBGBUS_DSPP, 113, 4}, - { DBGBUS_DSPP, 113, 5}, - { DBGBUS_DSPP, 113, 6}, - { DBGBUS_DSPP, 113, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 114, 1}, - { DBGBUS_DSPP, 114, 2}, - { DBGBUS_DSPP, 114, 3}, - { DBGBUS_DSPP, 114, 4}, - { DBGBUS_DSPP, 114, 5}, - { DBGBUS_DSPP, 114, 6}, - { DBGBUS_DSPP, 114, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 115, 1}, - { DBGBUS_DSPP, 115, 2}, - { DBGBUS_DSPP, 115, 3}, - { DBGBUS_DSPP, 115, 4}, - { DBGBUS_DSPP, 115, 5}, - { DBGBUS_DSPP, 115, 6}, - { DBGBUS_DSPP, 115, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 116, 1}, - { DBGBUS_DSPP, 116, 2}, - { DBGBUS_DSPP, 116, 3}, - { DBGBUS_DSPP, 116, 4}, - { DBGBUS_DSPP, 116, 5}, - { DBGBUS_DSPP, 116, 6}, - { DBGBUS_DSPP, 116, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 117, 1}, - { DBGBUS_DSPP, 117, 2}, - { DBGBUS_DSPP, 117, 3}, - { DBGBUS_DSPP, 117, 4}, - { DBGBUS_DSPP, 117, 5}, - { DBGBUS_DSPP, 117, 6}, - { DBGBUS_DSPP, 117, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 118, 1}, - { DBGBUS_DSPP, 118, 2}, - { DBGBUS_DSPP, 118, 3}, - { DBGBUS_DSPP, 118, 4}, - { DBGBUS_DSPP, 118, 5}, - { DBGBUS_DSPP, 118, 6}, - { DBGBUS_DSPP, 118, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 119, 1}, - { DBGBUS_DSPP, 119, 2}, - { DBGBUS_DSPP, 119, 3}, - { DBGBUS_DSPP, 119, 4}, - { DBGBUS_DSPP, 119, 5}, - { DBGBUS_DSPP, 119, 6}, - { DBGBUS_DSPP, 119, 7, _dpu_debug_bus_lm_dump }, - - { DBGBUS_DSPP, 120, 1}, - { DBGBUS_DSPP, 120, 2}, - { DBGBUS_DSPP, 120, 3}, - { DBGBUS_DSPP, 120, 4}, - { DBGBUS_DSPP, 120, 5}, - { DBGBUS_DSPP, 120, 6}, - { DBGBUS_DSPP, 120, 7, _dpu_debug_bus_lm_dump }, - - /* csc */ - { DBGBUS_SSPP0, 7, 0}, - { DBGBUS_SSPP0, 7, 1}, - { DBGBUS_SSPP0, 27, 0}, - { DBGBUS_SSPP0, 27, 1}, - { DBGBUS_SSPP1, 7, 0}, - { DBGBUS_SSPP1, 7, 1}, - { DBGBUS_SSPP1, 27, 0}, - { DBGBUS_SSPP1, 27, 1}, - - /* pcc */ - { DBGBUS_SSPP0, 3, 3}, - { DBGBUS_SSPP0, 23, 3}, - { DBGBUS_SSPP0, 33, 3}, - { DBGBUS_SSPP0, 43, 3}, - { DBGBUS_SSPP1, 3, 3}, - { DBGBUS_SSPP1, 23, 3}, - { DBGBUS_SSPP1, 33, 3}, - { DBGBUS_SSPP1, 43, 3}, - - /* spa */ - { DBGBUS_SSPP0, 8, 0}, - { DBGBUS_SSPP0, 28, 0}, - { DBGBUS_SSPP1, 8, 0}, - { DBGBUS_SSPP1, 28, 0}, - { DBGBUS_DSPP, 13, 0}, - { DBGBUS_DSPP, 19, 0}, - - /* igc */ - { DBGBUS_SSPP0, 17, 0}, - { DBGBUS_SSPP0, 17, 1}, - { DBGBUS_SSPP0, 17, 3}, - { DBGBUS_SSPP0, 37, 0}, - { DBGBUS_SSPP0, 37, 1}, - { DBGBUS_SSPP0, 37, 3}, - { DBGBUS_SSPP0, 46, 0}, - { DBGBUS_SSPP0, 46, 1}, - { DBGBUS_SSPP0, 46, 3}, - - { DBGBUS_SSPP1, 17, 0}, - { DBGBUS_SSPP1, 17, 1}, - { DBGBUS_SSPP1, 17, 3}, - { DBGBUS_SSPP1, 37, 0}, - { DBGBUS_SSPP1, 37, 1}, - { DBGBUS_SSPP1, 37, 3}, - { DBGBUS_SSPP1, 46, 0}, - { DBGBUS_SSPP1, 46, 1}, - { DBGBUS_SSPP1, 46, 3}, - - { DBGBUS_DSPP, 14, 0}, - { DBGBUS_DSPP, 14, 1}, - { DBGBUS_DSPP, 14, 3}, - { DBGBUS_DSPP, 20, 0}, - { DBGBUS_DSPP, 20, 1}, - { DBGBUS_DSPP, 20, 3}, - - /* intf0-3 */ - { DBGBUS_PERIPH, 0, 0}, - { DBGBUS_PERIPH, 1, 0}, - { DBGBUS_PERIPH, 2, 0}, - { DBGBUS_PERIPH, 3, 0}, - - /* te counter wrapper */ - { DBGBUS_PERIPH, 60, 0}, - - /* dsc0 */ - { DBGBUS_PERIPH, 47, 0}, - { DBGBUS_PERIPH, 47, 1}, - { DBGBUS_PERIPH, 47, 2}, - { DBGBUS_PERIPH, 47, 3}, - { DBGBUS_PERIPH, 47, 4}, - { DBGBUS_PERIPH, 47, 5}, - { DBGBUS_PERIPH, 47, 6}, - { DBGBUS_PERIPH, 47, 7}, - - /* dsc1 */ - { DBGBUS_PERIPH, 48, 0}, - { DBGBUS_PERIPH, 48, 1}, - { DBGBUS_PERIPH, 48, 2}, - { DBGBUS_PERIPH, 48, 3}, - { DBGBUS_PERIPH, 48, 4}, - { DBGBUS_PERIPH, 48, 5}, - { DBGBUS_PERIPH, 48, 6}, - { DBGBUS_PERIPH, 48, 7}, - - /* dsc2 */ - { DBGBUS_PERIPH, 51, 0}, - { DBGBUS_PERIPH, 51, 1}, - { DBGBUS_PERIPH, 51, 2}, - { DBGBUS_PERIPH, 51, 3}, - { DBGBUS_PERIPH, 51, 4}, - { DBGBUS_PERIPH, 51, 5}, - { DBGBUS_PERIPH, 51, 6}, - { DBGBUS_PERIPH, 51, 7}, - - /* dsc3 */ - { DBGBUS_PERIPH, 52, 0}, - { DBGBUS_PERIPH, 52, 1}, - { DBGBUS_PERIPH, 52, 2}, - { DBGBUS_PERIPH, 52, 3}, - { DBGBUS_PERIPH, 52, 4}, - { DBGBUS_PERIPH, 52, 5}, - { DBGBUS_PERIPH, 52, 6}, - { DBGBUS_PERIPH, 52, 7}, - - /* tear-check */ - { DBGBUS_PERIPH, 63, 0 }, - { DBGBUS_PERIPH, 64, 0 }, - { DBGBUS_PERIPH, 65, 0 }, - { DBGBUS_PERIPH, 73, 0 }, - { DBGBUS_PERIPH, 74, 0 }, - - /* cdwn */ - { DBGBUS_PERIPH, 80, 0}, - { DBGBUS_PERIPH, 80, 1}, - { DBGBUS_PERIPH, 80, 2}, - - { DBGBUS_PERIPH, 81, 0}, - { DBGBUS_PERIPH, 81, 1}, - { DBGBUS_PERIPH, 81, 2}, - - { DBGBUS_PERIPH, 82, 0}, - { DBGBUS_PERIPH, 82, 1}, - { DBGBUS_PERIPH, 82, 2}, - { DBGBUS_PERIPH, 82, 3}, - { DBGBUS_PERIPH, 82, 4}, - { DBGBUS_PERIPH, 82, 5}, - { DBGBUS_PERIPH, 82, 6}, - { DBGBUS_PERIPH, 82, 7}, - - /* hdmi */ - { DBGBUS_PERIPH, 68, 0}, - { DBGBUS_PERIPH, 68, 1}, - { DBGBUS_PERIPH, 68, 2}, - { DBGBUS_PERIPH, 68, 3}, - { DBGBUS_PERIPH, 68, 4}, - { DBGBUS_PERIPH, 68, 5}, - - /* edp */ - { DBGBUS_PERIPH, 69, 0}, - { DBGBUS_PERIPH, 69, 1}, - { DBGBUS_PERIPH, 69, 2}, - { DBGBUS_PERIPH, 69, 3}, - { DBGBUS_PERIPH, 69, 4}, - { DBGBUS_PERIPH, 69, 5}, - - /* dsi0 */ - { DBGBUS_PERIPH, 70, 0}, - { DBGBUS_PERIPH, 70, 1}, - { DBGBUS_PERIPH, 70, 2}, - { DBGBUS_PERIPH, 70, 3}, - { DBGBUS_PERIPH, 70, 4}, - { DBGBUS_PERIPH, 70, 5}, - - /* dsi1 */ - { DBGBUS_PERIPH, 71, 0}, - { DBGBUS_PERIPH, 71, 1}, - { DBGBUS_PERIPH, 71, 2}, - { DBGBUS_PERIPH, 71, 3}, - { DBGBUS_PERIPH, 71, 4}, - { DBGBUS_PERIPH, 71, 5}, -}; - -static struct vbif_debug_bus_entry vbif_dbg_bus_msm8998[] = { - {0x214, 0x21c, 16, 2, 0x0, 0xd}, /* arb clients */ - {0x214, 0x21c, 16, 2, 0x80, 0xc0}, /* arb clients */ - {0x214, 0x21c, 16, 2, 0x100, 0x140}, /* arb clients */ - {0x214, 0x21c, 0, 16, 0x0, 0xf}, /* xin blocks - axi side */ - {0x214, 0x21c, 0, 16, 0x80, 0xa4}, /* xin blocks - axi side */ - {0x214, 0x21c, 0, 15, 0x100, 0x124}, /* xin blocks - axi side */ - {0x21c, 0x214, 0, 14, 0, 0xc}, /* xin blocks - clock side */ -}; - -/** - * _dpu_dbg_enable_power - use callback to turn power on for hw register access - * @enable: whether to turn power on or off - */ -static inline void _dpu_dbg_enable_power(int enable) -{ - if (enable) - pm_runtime_get_sync(dpu_dbg_base.dev); - else - pm_runtime_put_sync(dpu_dbg_base.dev); -} - -static void _dpu_dbg_dump_dpu_dbg_bus(struct dpu_dbg_dpu_debug_bus *bus) -{ - bool in_log, in_mem; - u32 **dump_mem = NULL; - u32 *dump_addr = NULL; - u32 status = 0; - struct dpu_debug_bus_entry *head; - phys_addr_t phys = 0; - int list_size; - int i; - u32 offset; - void __iomem *mem_base = NULL; - struct dpu_dbg_reg_base *reg_base; - - if (!bus || !bus->cmn.entries_size) - return; - - list_for_each_entry(reg_base, &dpu_dbg_base.reg_base_list, - reg_base_head) - if (strlen(reg_base->name) && - !strcmp(reg_base->name, bus->cmn.name)) - mem_base = reg_base->base + bus->top_blk_off; - - if (!mem_base) { - pr_err("unable to find mem_base for %s\n", bus->cmn.name); - return; - } - - dump_mem = &bus->cmn.dumped_content; - - /* will keep in memory 4 entries of 4 bytes each */ - list_size = (bus->cmn.entries_size * 4 * 4); - - in_log = (bus->cmn.enable_mask & DPU_DBG_DUMP_IN_LOG); - in_mem = (bus->cmn.enable_mask & DPU_DBG_DUMP_IN_MEM); - - if (!in_log && !in_mem) - return; - - DRM_DEV_INFO(dpu_dbg_base.dev, "======== start %s dump =========\n", - bus->cmn.name); - - if (in_mem) { - if (!(*dump_mem)) - *dump_mem = dma_alloc_coherent(dpu_dbg_base.dev, - list_size, &phys, GFP_KERNEL); - - if (*dump_mem) { - dump_addr = *dump_mem; - DRM_DEV_INFO(dpu_dbg_base.dev, - "%s: start_addr:0x%pK len:0x%x\n", - __func__, dump_addr, list_size); - } else { - in_mem = false; - pr_err("dump_mem: allocation fails\n"); - } - } - - _dpu_dbg_enable_power(true); - for (i = 0; i < bus->cmn.entries_size; i++) { - head = bus->entries + i; - writel_relaxed(TEST_MASK(head->block_id, head->test_id), - mem_base + head->wr_addr); - wmb(); /* make sure test bits were written */ - - if (bus->cmn.flags & DBGBUS_FLAGS_DSPP) { - offset = DBGBUS_DSPP_STATUS; - /* keep DSPP test point enabled */ - if (head->wr_addr != DBGBUS_DSPP) - writel_relaxed(0xF, mem_base + DBGBUS_DSPP); - } else { - offset = head->wr_addr + 0x4; - } - - status = readl_relaxed(mem_base + offset); - - if (in_log) - DRM_DEV_INFO(dpu_dbg_base.dev, - "waddr=0x%x blk=%d tst=%d val=0x%x\n", - head->wr_addr, head->block_id, - head->test_id, status); - - if (dump_addr && in_mem) { - dump_addr[i*4] = head->wr_addr; - dump_addr[i*4 + 1] = head->block_id; - dump_addr[i*4 + 2] = head->test_id; - dump_addr[i*4 + 3] = status; - } - - if (head->analyzer) - head->analyzer(mem_base, head, status); - - /* Disable debug bus once we are done */ - writel_relaxed(0, mem_base + head->wr_addr); - if (bus->cmn.flags & DBGBUS_FLAGS_DSPP && - head->wr_addr != DBGBUS_DSPP) - writel_relaxed(0x0, mem_base + DBGBUS_DSPP); - } - _dpu_dbg_enable_power(false); - - DRM_DEV_INFO(dpu_dbg_base.dev, "======== end %s dump =========\n", - bus->cmn.name); -} - -static void _dpu_dbg_dump_vbif_debug_bus_entry( - struct vbif_debug_bus_entry *head, void __iomem *mem_base, - u32 *dump_addr, bool in_log) -{ - int i, j; - u32 val; - - if (!dump_addr && !in_log) - return; - - for (i = 0; i < head->block_cnt; i++) { - writel_relaxed(1 << (i + head->bit_offset), - mem_base + head->block_bus_addr); - /* make sure that current bus blcok enable */ - wmb(); - for (j = head->test_pnt_start; j < head->test_pnt_cnt; j++) { - writel_relaxed(j, mem_base + head->block_bus_addr + 4); - /* make sure that test point is enabled */ - wmb(); - val = readl_relaxed(mem_base + MMSS_VBIF_TEST_BUS_OUT); - if (dump_addr) { - *dump_addr++ = head->block_bus_addr; - *dump_addr++ = i; - *dump_addr++ = j; - *dump_addr++ = val; - } - if (in_log) - DRM_DEV_INFO(dpu_dbg_base.dev, - "testpoint:%x arb/xin id=%d index=%d val=0x%x\n", - head->block_bus_addr, i, j, val); - } - } -} - -static void _dpu_dbg_dump_vbif_dbg_bus(struct dpu_dbg_vbif_debug_bus *bus) -{ - bool in_log, in_mem; - u32 **dump_mem = NULL; - u32 *dump_addr = NULL; - u32 value, d0, d1; - unsigned long reg, reg1, reg2; - struct vbif_debug_bus_entry *head; - phys_addr_t phys = 0; - int i, list_size = 0; - void __iomem *mem_base = NULL; - struct vbif_debug_bus_entry *dbg_bus; - u32 bus_size; - struct dpu_dbg_reg_base *reg_base; - - if (!bus || !bus->cmn.entries_size) - return; - - list_for_each_entry(reg_base, &dpu_dbg_base.reg_base_list, - reg_base_head) - if (strlen(reg_base->name) && - !strcmp(reg_base->name, bus->cmn.name)) - mem_base = reg_base->base; - - if (!mem_base) { - pr_err("unable to find mem_base for %s\n", bus->cmn.name); - return; - } - - dbg_bus = bus->entries; - bus_size = bus->cmn.entries_size; - list_size = bus->cmn.entries_size; - dump_mem = &bus->cmn.dumped_content; - - DRM_DEV_INFO(dpu_dbg_base.dev, "======== start %s dump =========\n", - bus->cmn.name); - - if (!dump_mem || !dbg_bus || !bus_size || !list_size) - return; - - /* allocate memory for each test point */ - for (i = 0; i < bus_size; i++) { - head = dbg_bus + i; - list_size += (head->block_cnt * head->test_pnt_cnt); - } - - /* 4 bytes * 4 entries for each test point*/ - list_size *= 16; - - in_log = (bus->cmn.enable_mask & DPU_DBG_DUMP_IN_LOG); - in_mem = (bus->cmn.enable_mask & DPU_DBG_DUMP_IN_MEM); - - if (!in_log && !in_mem) - return; - - if (in_mem) { - if (!(*dump_mem)) - *dump_mem = dma_alloc_coherent(dpu_dbg_base.dev, - list_size, &phys, GFP_KERNEL); - - if (*dump_mem) { - dump_addr = *dump_mem; - DRM_DEV_INFO(dpu_dbg_base.dev, - "%s: start_addr:0x%pK len:0x%x\n", - __func__, dump_addr, list_size); - } else { - in_mem = false; - pr_err("dump_mem: allocation fails\n"); - } - } - - _dpu_dbg_enable_power(true); - - value = readl_relaxed(mem_base + MMSS_VBIF_CLKON); - writel_relaxed(value | BIT(1), mem_base + MMSS_VBIF_CLKON); - - /* make sure that vbif core is on */ - wmb(); - - /** - * Extract VBIF error info based on XIN halt and error status. - * If the XIN client is not in HALT state, or an error is detected, - * then retrieve the VBIF error info for it. - */ - reg = readl_relaxed(mem_base + MMSS_VBIF_XIN_HALT_CTRL1); - reg1 = readl_relaxed(mem_base + MMSS_VBIF_PND_ERR); - reg2 = readl_relaxed(mem_base + MMSS_VBIF_SRC_ERR); - DRM_DEV_ERROR(dpu_dbg_base.dev, - "XIN HALT:0x%lX, PND ERR:0x%lX, SRC ERR:0x%lX\n", - reg, reg1, reg2); - reg >>= 16; - reg &= ~(reg1 | reg2); - for (i = 0; i < MMSS_VBIF_CLIENT_NUM; i++) { - if (!test_bit(0, ®)) { - writel_relaxed(i, mem_base + MMSS_VBIF_ERR_INFO); - /* make sure reg write goes through */ - wmb(); - - d0 = readl_relaxed(mem_base + MMSS_VBIF_ERR_INFO); - d1 = readl_relaxed(mem_base + MMSS_VBIF_ERR_INFO_1); - - DRM_DEV_ERROR(dpu_dbg_base.dev, - "Client:%d, errinfo=0x%X, errinfo1=0x%X\n", - i, d0, d1); - } - reg >>= 1; - } - - for (i = 0; i < bus_size; i++) { - head = dbg_bus + i; - - writel_relaxed(0, mem_base + head->disable_bus_addr); - writel_relaxed(BIT(0), mem_base + MMSS_VBIF_TEST_BUS_OUT_CTRL); - /* make sure that other bus is off */ - wmb(); - - _dpu_dbg_dump_vbif_debug_bus_entry(head, mem_base, dump_addr, - in_log); - if (dump_addr) - dump_addr += (head->block_cnt * head->test_pnt_cnt * 4); - } - - _dpu_dbg_enable_power(false); - - DRM_DEV_INFO(dpu_dbg_base.dev, "======== end %s dump =========\n", - bus->cmn.name); -} - -/** - * _dpu_dump_array - dump array of register bases - * @name: string indicating origin of dump - * @dump_dbgbus_dpu: whether to dump the dpu debug bus - * @dump_dbgbus_vbif_rt: whether to dump the vbif rt debug bus - */ -static void _dpu_dump_array(const char *name, bool dump_dbgbus_dpu, - bool dump_dbgbus_vbif_rt) -{ - if (dump_dbgbus_dpu) - _dpu_dbg_dump_dpu_dbg_bus(&dpu_dbg_base.dbgbus_dpu); - - if (dump_dbgbus_vbif_rt) - _dpu_dbg_dump_vbif_dbg_bus(&dpu_dbg_base.dbgbus_vbif_rt); -} - -/** - * _dpu_dump_work - deferred dump work function - * @work: work structure - */ -static void _dpu_dump_work(struct work_struct *work) -{ - _dpu_dump_array("dpudump_workitem", - dpu_dbg_base.dbgbus_dpu.cmn.include_in_deferred_work, - dpu_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work); -} - -void dpu_dbg_dump(bool queue_work, const char *name, bool dump_dbgbus_dpu, - bool dump_dbgbus_vbif_rt) -{ - if (queue_work && work_pending(&dpu_dbg_base.dump_work)) - return; - - if (!queue_work) { - _dpu_dump_array(name, dump_dbgbus_dpu, dump_dbgbus_vbif_rt); - return; - } - - /* schedule work to dump later */ - dpu_dbg_base.dbgbus_dpu.cmn.include_in_deferred_work = dump_dbgbus_dpu; - dpu_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work = - dump_dbgbus_vbif_rt; - schedule_work(&dpu_dbg_base.dump_work); -} - -/* - * dpu_dbg_debugfs_open - debugfs open handler for debug dump - * @inode: debugfs inode - * @file: file handle - */ -static int dpu_dbg_debugfs_open(struct inode *inode, struct file *file) -{ - /* non-seekable */ - file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); - file->private_data = inode->i_private; - return 0; -} - -/** - * dpu_dbg_dump_write - debugfs write handler for debug dump - * @file: file handler - * @user_buf: user buffer content from debugfs - * @count: size of user buffer - * @ppos: position offset of user buffer - */ -static ssize_t dpu_dbg_dump_write(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - _dpu_dump_array("dump_debugfs", true, true); - return count; -} - -static const struct file_operations dpu_dbg_dump_fops = { - .open = dpu_dbg_debugfs_open, - .write = dpu_dbg_dump_write, -}; - -int dpu_dbg_debugfs_register(struct dentry *debugfs_root) -{ - static struct dpu_dbg_base *dbg = &dpu_dbg_base; - char debug_name[80] = ""; - - if (!debugfs_root) - return -EINVAL; - - debugfs_create_file("dump", 0600, debugfs_root, NULL, - &dpu_dbg_dump_fops); - - if (dbg->dbgbus_dpu.entries) { - dbg->dbgbus_dpu.cmn.name = DBGBUS_NAME_DPU; - snprintf(debug_name, sizeof(debug_name), "%s_dbgbus", - dbg->dbgbus_dpu.cmn.name); - dbg->dbgbus_dpu.cmn.enable_mask = DEFAULT_DBGBUS_DPU; - debugfs_create_u32(debug_name, 0600, debugfs_root, - &dbg->dbgbus_dpu.cmn.enable_mask); - } - - if (dbg->dbgbus_vbif_rt.entries) { - dbg->dbgbus_vbif_rt.cmn.name = DBGBUS_NAME_VBIF_RT; - snprintf(debug_name, sizeof(debug_name), "%s_dbgbus", - dbg->dbgbus_vbif_rt.cmn.name); - dbg->dbgbus_vbif_rt.cmn.enable_mask = DEFAULT_DBGBUS_VBIFRT; - debugfs_create_u32(debug_name, 0600, debugfs_root, - &dbg->dbgbus_vbif_rt.cmn.enable_mask); - } - - return 0; -} - -static void _dpu_dbg_debugfs_destroy(void) -{ -} - -void dpu_dbg_init_dbg_buses(u32 hwversion) -{ - static struct dpu_dbg_base *dbg = &dpu_dbg_base; - - memset(&dbg->dbgbus_dpu, 0, sizeof(dbg->dbgbus_dpu)); - memset(&dbg->dbgbus_vbif_rt, 0, sizeof(dbg->dbgbus_vbif_rt)); - - if (IS_MSM8998_TARGET(hwversion)) { - dbg->dbgbus_dpu.entries = dbg_bus_dpu_8998; - dbg->dbgbus_dpu.cmn.entries_size = ARRAY_SIZE(dbg_bus_dpu_8998); - dbg->dbgbus_dpu.cmn.flags = DBGBUS_FLAGS_DSPP; - - dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998; - dbg->dbgbus_vbif_rt.cmn.entries_size = - ARRAY_SIZE(vbif_dbg_bus_msm8998); - } else if (IS_SDM845_TARGET(hwversion) || IS_SDM670_TARGET(hwversion)) { - dbg->dbgbus_dpu.entries = dbg_bus_dpu_sdm845; - dbg->dbgbus_dpu.cmn.entries_size = - ARRAY_SIZE(dbg_bus_dpu_sdm845); - dbg->dbgbus_dpu.cmn.flags = DBGBUS_FLAGS_DSPP; - - /* vbif is unchanged vs 8998 */ - dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998; - dbg->dbgbus_vbif_rt.cmn.entries_size = - ARRAY_SIZE(vbif_dbg_bus_msm8998); - } else { - pr_err("unsupported chipset id %X\n", hwversion); - } -} - -int dpu_dbg_init(struct device *dev) -{ - if (!dev) { - pr_err("invalid params\n"); - return -EINVAL; - } - - INIT_LIST_HEAD(&dpu_dbg_base.reg_base_list); - dpu_dbg_base.dev = dev; - - INIT_WORK(&dpu_dbg_base.dump_work, _dpu_dump_work); - - return 0; -} - -/** - * dpu_dbg_destroy - destroy dpu debug facilities - */ -void dpu_dbg_destroy(void) -{ - _dpu_dbg_debugfs_destroy(); -} - -void dpu_dbg_set_dpu_top_offset(u32 blk_off) -{ - dpu_dbg_base.dbgbus_dpu.top_blk_off = blk_off; -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h deleted file mode 100644 index 1e6fa945f98b..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_dbg.h +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef DPU_DBG_H_ -#define DPU_DBG_H_ - -#include -#include -#include - -enum dpu_dbg_dump_flag { - DPU_DBG_DUMP_IN_LOG = BIT(0), - DPU_DBG_DUMP_IN_MEM = BIT(1), -}; - -#if defined(CONFIG_DEBUG_FS) - -/** - * dpu_dbg_init_dbg_buses - initialize debug bus dumping support for the chipset - * @hwversion: Chipset revision - */ -void dpu_dbg_init_dbg_buses(u32 hwversion); - -/** - * dpu_dbg_init - initialize global dpu debug facilities: regdump - * @dev: device handle - * Returns: 0 or -ERROR - */ -int dpu_dbg_init(struct device *dev); - -/** - * dpu_dbg_debugfs_register - register entries at the given debugfs dir - * @debugfs_root: debugfs root in which to create dpu debug entries - * Returns: 0 or -ERROR - */ -int dpu_dbg_debugfs_register(struct dentry *debugfs_root); - -/** - * dpu_dbg_destroy - destroy the global dpu debug facilities - * Returns: none - */ -void dpu_dbg_destroy(void); - -/** - * dpu_dbg_dump - trigger dumping of all dpu_dbg facilities - * @queue_work: whether to queue the dumping work to the work_struct - * @name: string indicating origin of dump - * @dump_dbgbus: dump the dpu debug bus - * @dump_vbif_rt: dump the vbif rt bus - * Returns: none - */ -void dpu_dbg_dump(bool queue_work, const char *name, bool dump_dbgbus_dpu, - bool dump_dbgbus_vbif_rt); - -/** - * dpu_dbg_set_dpu_top_offset - set the target specific offset from mdss base - * address of the top registers. Used for accessing debug bus controls. - * @blk_off: offset from mdss base of the top block - */ -void dpu_dbg_set_dpu_top_offset(u32 blk_off); - -#else - -static inline void dpu_dbg_init_dbg_buses(u32 hwversion) -{ -} - -static inline int dpu_dbg_init(struct device *dev) -{ - return 0; -} - -static inline int dpu_dbg_debugfs_register(struct dentry *debugfs_root) -{ - return 0; -} - -static inline void dpu_dbg_destroy(void) -{ -} - -static inline void dpu_dbg_dump(bool queue_work, const char *name, - bool dump_dbgbus_dpu, bool dump_dbgbus_vbif_rt) -{ -} - -static inline void dpu_dbg_set_dpu_top_offset(u32 blk_off) -{ -} - -#endif /* defined(CONFIG_DEBUG_FS) */ - - -#endif /* DPU_DBG_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f60dcf217755..c1baab4c72d2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1517,10 +1517,8 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc) ctl->idx); rc = ctl->ops.reset(ctl); - if (rc) { + if (rc) DPU_ERROR_ENC(dpu_enc, "ctl %d reset failure\n", ctl->idx); - dpu_dbg_dump(false, __func__, true, true); - } phys_enc->enable_state = DPU_ENC_ENABLED; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 24a98f4e1f44..b37a0992e326 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -243,7 +243,6 @@ static int _dpu_encoder_phys_cmd_handle_ppdone_timeout( atomic_read(&phys_enc->pending_kickoff_cnt)); dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR); - dpu_dbg_dump(false, __func__, true, true); } atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 667f304c92ea..acdab5b0db18 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -613,7 +613,6 @@ static void dpu_encoder_phys_vid_prepare_for_kickoff( DPU_ERROR_VIDENC(vid_enc, "ctl %d reset failure: %d\n", ctl->idx, rc); dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_VSYNC); - dpu_dbg_dump(false, __func__, true, true); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 8fa601a9abbf..4aab04335c6d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -13,7 +13,6 @@ #include #include "dpu_hwio.h" #include "dpu_hw_ctl.h" -#include "dpu_dbg.h" #include "dpu_kms.h" #include "dpu_trace.h" diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 9c6bba0ac7c3..695d27a730e8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -13,7 +13,6 @@ #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_intf.h" -#include "dpu_dbg.h" #include "dpu_kms.h" #define INTF_TIMING_ENGINE_EN 0x000 diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index dbe48e006414..c76b5cc949fb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -15,7 +15,6 @@ #include "dpu_hwio.h" #include "dpu_hw_lm.h" #include "dpu_hw_mdss.h" -#include "dpu_dbg.h" #include "dpu_kms.h" #define LM_OP_MODE 0x00 diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 52fca13da176..cfc93816078f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -16,7 +16,6 @@ #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_pingpong.h" -#include "dpu_dbg.h" #include "dpu_kms.h" #include "dpu_trace.h" diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 8745018ffdd6..8297963d2c4c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -14,7 +14,6 @@ #include "dpu_hw_catalog.h" #include "dpu_hw_lm.h" #include "dpu_hw_sspp.h" -#include "dpu_dbg.h" #include "dpu_kms.h" #define DPU_FETCH_CONFIG_RESET_VALUE 0x00000087 diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index b8781256e21b..f7e0f661a8bb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -13,7 +13,6 @@ #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_top.h" -#include "dpu_dbg.h" #include "dpu_kms.h" #define SSPP_SPARE 0x28 @@ -361,8 +360,6 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx, goto blk_init_error; } - dpu_dbg_set_dpu_top_offset(mdp->hw.blk_off); - return mdp; blk_init_error: diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c index d43905525f92..38bfd222ed72 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c @@ -13,7 +13,6 @@ #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_vbif.h" -#include "dpu_dbg.h" #define VBIF_VERSION 0x0000 #define VBIF_CLK_FORCE_CTRL0 0x0008 diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index fe98a39eaae5..8d5cd1e7a683 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -266,12 +266,6 @@ static int _dpu_debugfs_init(struct dpu_kms *dpu_kms) return PTR_ERR(dpu_kms->debugfs_root); } - rc = dpu_dbg_debugfs_register(dpu_kms->debugfs_root); - if (rc) { - DRM_ERROR("failed to reg dpu dbg debugfs: %d\n", rc); - return rc; - } - /* allow root to be NULL */ debugfs_create_x32(DPU_DEBUGFS_HWMASKNAME, 0600, dpu_kms->debugfs_root, p); @@ -709,7 +703,6 @@ static void dpu_kms_destroy(struct msm_kms *kms) dpu_kms = to_dpu_kms(kms); - dpu_dbg_destroy(); _dpu_kms_hw_destroy(dpu_kms); } @@ -863,16 +856,10 @@ static int dpu_kms_hw_init(struct msm_kms *kms) return rc; } - rc = dpu_dbg_init(&dpu_kms->pdev->dev); - if (rc) { - DRM_ERROR("failed to init dpu dbg: %d\n", rc); - return rc; - } - priv = dev->dev_private; if (!priv) { DPU_ERROR("invalid private data\n"); - goto dbg_destroy; + return rc; } dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp", "mdp"); @@ -926,8 +913,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms) goto power_error; } - dpu_dbg_init_dbg_buses(dpu_kms->core_rev); - /* * Now we need to read the HW catalog and initialize resources such as * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc @@ -1027,8 +1012,7 @@ power_error: pm_runtime_put_sync(&dpu_kms->pdev->dev); error: _dpu_kms_hw_destroy(dpu_kms); -dbg_destroy: - dpu_dbg_destroy(); + return rc; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 59e18e2d3c59..611c88c1ba10 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -23,7 +23,6 @@ #include "msm_kms.h" #include "msm_mmu.h" #include "msm_gem.h" -#include "dpu_dbg.h" #include "dpu_hw_catalog.h" #include "dpu_hw_ctl.h" #include "dpu_hw_lm.h" From 35d600dd92489bcec8e91279a9c708e0e11f4bd4 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:15 -0700 Subject: [PATCH 82/91] drm/msm/dpu: Remove dpu_crtc_get_mixer_height dpu_crtc_get_mixer_height() is only used once and the value it returns can be easily derived from the calling function. v3: No changes Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 3 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 13 ------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 5404c330d258..ffdb90c70c34 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -495,7 +495,6 @@ static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc) static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, struct drm_crtc_state *state) { - struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); struct drm_display_mode *adj_mode = &state->adjusted_mode; u32 crtc_split_width = _dpu_crtc_get_mixer_width(cstate, adj_mode); @@ -506,7 +505,7 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, r->x1 = crtc_split_width * i; r->y1 = 0; r->x2 = r->x1 + crtc_split_width; - r->y2 = dpu_crtc_get_mixer_height(dpu_crtc, cstate, adj_mode); + r->y2 = adj_mode->vdisplay; trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index fc7123573891..b84dc5730a0e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -236,19 +236,6 @@ static inline bool dpu_crtc_state_is_stereo(struct dpu_crtc_state *cstate) return cstate->num_mixers == CRTC_DUAL_MIXERS; } -/** - * dpu_crtc_get_mixer_height - get the mixer height - * Mixer height will be same as panel height - */ -static inline int dpu_crtc_get_mixer_height(struct dpu_crtc *dpu_crtc, - struct dpu_crtc_state *cstate, struct drm_display_mode *mode) -{ - if (!dpu_crtc || !cstate || !mode) - return 0; - - return mode->vdisplay; -} - /** * dpu_crtc_frame_pending - retun the number of pending frames * @crtc: Pointer to drm crtc object From 49dfe764797b1eb0fe9e7f392645b9161d6cfce6 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:16 -0700 Subject: [PATCH 83/91] drm/msm/dpu: Remove dpu_crtc_is_enabled() The static inline function dpu_crtc_enabled() is only called once and the function that calls it in turn is only called once and the return value can be easily checked in the calling functions so collapse everything down. v3: No changes Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 17 ++++++----------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 9 --------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index bffc51e496e7..e8a87f4b8e0e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -57,18 +57,13 @@ static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) return to_dpu_kms(priv->kms); } -static bool _dpu_core_perf_crtc_is_power_on(struct drm_crtc *crtc) -{ - return dpu_crtc_is_enabled(crtc); -} - static bool _dpu_core_video_mode_intf_connected(struct drm_crtc *crtc) { struct drm_crtc *tmp_crtc; drm_for_each_crtc(tmp_crtc, crtc->dev) { if ((dpu_crtc_get_intf_mode(tmp_crtc) == INTF_MODE_VIDEO) && - _dpu_core_perf_crtc_is_power_on(tmp_crtc)) { + tmp_crtc->enabled) { DPU_DEBUG("video interface connected crtc:%d\n", tmp_crtc->base.id); return true; @@ -164,7 +159,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc, curr_client_type = dpu_crtc_get_client_type(crtc); drm_for_each_crtc(tmp_crtc, crtc->dev) { - if (_dpu_core_perf_crtc_is_power_on(tmp_crtc) && + if (tmp_crtc->enabled && (dpu_crtc_get_client_type(tmp_crtc) == curr_client_type) && (tmp_crtc != crtc)) { @@ -223,7 +218,7 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms, int ret = 0; drm_for_each_crtc(tmp_crtc, crtc->dev) { - if (_dpu_core_perf_crtc_is_power_on(tmp_crtc) && + if (tmp_crtc->enabled && curr_client_type == dpu_crtc_get_client_type(tmp_crtc)) { dpu_cstate = to_dpu_crtc_state(tmp_crtc->state); @@ -280,7 +275,7 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc) */ if (dpu_crtc_get_intf_mode(crtc) == INTF_MODE_CMD) drm_for_each_crtc(tmp_crtc, crtc->dev) { - if (_dpu_core_perf_crtc_is_power_on(tmp_crtc) && + if (tmp_crtc->enabled && dpu_crtc_get_intf_mode(tmp_crtc) == INTF_MODE_VIDEO) return; @@ -315,7 +310,7 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms) struct dpu_crtc_state *dpu_cstate; drm_for_each_crtc(crtc, kms->dev) { - if (_dpu_core_perf_crtc_is_power_on(crtc)) { + if (crtc->enabled) { dpu_cstate = to_dpu_crtc_state(crtc->state); clk_rate = max(dpu_cstate->new_perf.core_clk_rate, clk_rate); @@ -366,7 +361,7 @@ int dpu_core_perf_crtc_update(struct drm_crtc *crtc, old = &dpu_crtc->cur_perf; new = &dpu_cstate->new_perf; - if (_dpu_core_perf_crtc_is_power_on(crtc) && !stop_req) { + if (crtc->enabled && !stop_req) { for (i = 0; i < DPU_CORE_PERF_DATA_BUS_ID_MAX; i++) { /* * cases for bus bandwidth update. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index b84dc5730a0e..94f5cea4e0d2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -309,13 +309,4 @@ static inline enum dpu_crtc_client_type dpu_crtc_get_client_type( return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT; } -/** - * dpu_crtc_is_enabled - check if dpu crtc is enabled or not - * @crtc: Pointer to crtc - */ -static inline bool dpu_crtc_is_enabled(struct drm_crtc *crtc) -{ - return crtc ? crtc->enabled : false; -} - #endif /* _DPU_CRTC_H_ */ From fa79bcc3d18bf365a88134afc3211e6450feeaf0 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:17 -0700 Subject: [PATCH 84/91] drm/msm/dpu: Remove unused functions Remove some unused container_of() helper functions. v3: No changes v2: Retained still used helper functions in the name of readability Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 10 ---------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h | 10 ---------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 10 ---------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 10 ---------- 4 files changed, 40 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index 3b77df460dea..a2b0dbc23058 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -91,16 +91,6 @@ struct dpu_hw_intf { struct dpu_hw_intf_ops ops; }; -/** - * to_dpu_hw_intf - convert base object dpu_hw_base to container - * @hw: Pointer to base hardware block - * return: Pointer to hardware block container - */ -static inline struct dpu_hw_intf *to_dpu_hw_intf(struct dpu_hw_blk *hw) -{ - return container_of(hw, struct dpu_hw_intf, base); -} - /** * dpu_hw_intf_init(): Initializes the intf driver for the passed * interface idx. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h index 3caccd7d6a3e..0e02e43cee14 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h @@ -104,16 +104,6 @@ struct dpu_hw_pingpong { struct dpu_hw_pingpong_ops ops; }; -/** - * dpu_hw_pingpong - convert base object dpu_hw_base to container - * @hw: Pointer to base hardware block - * return: Pointer to hardware block container - */ -static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw) -{ - return container_of(hw, struct dpu_hw_pingpong, base); -} - /** * dpu_hw_pingpong_init - initializes the pingpong driver for the passed * pingpong idx. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 4d81e5f5ce1b..119b4e1c16be 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -391,16 +391,6 @@ struct dpu_hw_pipe { struct dpu_hw_sspp_ops ops; }; -/** - * dpu_hw_pipe - convert base object dpu_hw_base to container - * @hw: Pointer to base hardware block - * return: Pointer to hardware block container - */ -static inline struct dpu_hw_pipe *to_dpu_hw_pipe(struct dpu_hw_blk *hw) -{ - return container_of(hw, struct dpu_hw_pipe, base); -} - /** * dpu_hw_sspp_init - initializes the sspp hw driver object. * Should be called once before accessing every pipe. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h index 192e338f20bb..aa21fd834398 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h @@ -160,16 +160,6 @@ struct dpu_hw_mdp { struct dpu_hw_mdp_ops ops; }; -/** - * to_dpu_hw_mdp - convert base object dpu_hw_base to container - * @hw: Pointer to base hardware block - * return: Pointer to hardware block container - */ -static inline struct dpu_hw_mdp *to_dpu_hw_mdp(struct dpu_hw_blk *hw) -{ - return container_of(hw, struct dpu_hw_mdp, base); -} - /** * dpu_hw_mdptop_init - initializes the top driver for the passed idx * @idx: Interface index for which driver object is required From 53edf462596623f853deb70c190bf25e231fb6b5 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:18 -0700 Subject: [PATCH 85/91] drm/msm/dpu: Cleanup callers of dpu_hw_blk_init Outside of superfluous parameter checks the dpu_hw_blk_init() doesn't have any failure paths. Switch it over to be a void function and we can remove error handling paths in all the functions that call it. While we're in those functions remove unneeded initialization for a static variable. v3: No changes v2: Removed a cleanup intended for a different patch Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c | 10 +--------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 17 ++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 17 ++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 17 ++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 17 ++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 17 ++--------------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 17 ++--------------- 8 files changed, 14 insertions(+), 100 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c index 58d29e43faef..92f1c4241b9a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.c @@ -30,16 +30,10 @@ static LIST_HEAD(dpu_hw_blk_list); * @type: hw block type - enum dpu_hw_blk_type * @id: instance id of the hw block * @ops: Pointer to block operations - * return: 0 if success; error code otherwise */ -int dpu_hw_blk_init(struct dpu_hw_blk *hw_blk, u32 type, int id, +void dpu_hw_blk_init(struct dpu_hw_blk *hw_blk, u32 type, int id, struct dpu_hw_blk_ops *ops) { - if (!hw_blk) { - pr_err("invalid parameters\n"); - return -EINVAL; - } - INIT_LIST_HEAD(&hw_blk->list); hw_blk->type = type; hw_blk->id = id; @@ -51,8 +45,6 @@ int dpu_hw_blk_init(struct dpu_hw_blk *hw_blk, u32 type, int id, mutex_lock(&dpu_hw_blk_lock); list_add(&hw_blk->list, &dpu_hw_blk_list); mutex_unlock(&dpu_hw_blk_lock); - - return 0; } /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h index 0f4ca8af1ec5..1934c2f7e8fa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_blk.h @@ -44,7 +44,7 @@ struct dpu_hw_blk { struct dpu_hw_blk_ops ops; }; -int dpu_hw_blk_init(struct dpu_hw_blk *hw_blk, u32 type, int id, +void dpu_hw_blk_init(struct dpu_hw_blk *hw_blk, u32 type, int id, struct dpu_hw_blk_ops *ops); void dpu_hw_blk_destroy(struct dpu_hw_blk *hw_blk); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 4aab04335c6d..1068b4b7940f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -483,10 +483,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf; }; -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; +static struct dpu_hw_blk_ops dpu_hw_ops; struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx, void __iomem *addr, @@ -494,7 +491,6 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx, { struct dpu_hw_ctl *c; struct dpu_ctl_cfg *cfg; - int rc; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) @@ -513,18 +509,9 @@ struct dpu_hw_ctl *dpu_hw_ctl_init(enum dpu_ctl idx, c->mixer_count = m->mixer_count; c->mixer_hw_caps = m->mixer; - rc = dpu_hw_blk_init(&c->base, DPU_HW_BLK_CTL, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } + dpu_hw_blk_init(&c->base, DPU_HW_BLK_CTL, idx, &dpu_hw_ops); return c; - -blk_init_error: - kzfree(c); - - return ERR_PTR(rc); } void dpu_hw_ctl_destroy(struct dpu_hw_ctl *ctx) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 695d27a730e8..f6a83daa385b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -264,10 +264,7 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->get_line_count = dpu_hw_intf_get_line_count; } -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; +static struct dpu_hw_blk_ops dpu_hw_ops; struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, void __iomem *addr, @@ -275,7 +272,6 @@ struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, { struct dpu_hw_intf *c; struct dpu_intf_cfg *cfg; - int rc; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) @@ -296,18 +292,9 @@ struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx, c->mdss = m; _setup_intf_ops(&c->ops, c->cap->features); - rc = dpu_hw_blk_init(&c->base, DPU_HW_BLK_INTF, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } + dpu_hw_blk_init(&c->base, DPU_HW_BLK_INTF, idx, &dpu_hw_ops); return c; - -blk_init_error: - kzfree(c); - - return ERR_PTR(rc); } void dpu_hw_intf_destroy(struct dpu_hw_intf *intf) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index c76b5cc949fb..9f342af2aba7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -175,10 +175,7 @@ static void _setup_mixer_ops(struct dpu_mdss_cfg *m, ops->setup_gc = dpu_hw_lm_gc; }; -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; +static struct dpu_hw_blk_ops dpu_hw_ops; struct dpu_hw_mixer *dpu_hw_lm_init(enum dpu_lm idx, void __iomem *addr, @@ -186,7 +183,6 @@ struct dpu_hw_mixer *dpu_hw_lm_init(enum dpu_lm idx, { struct dpu_hw_mixer *c; struct dpu_lm_cfg *cfg; - int rc; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) @@ -203,18 +199,9 @@ struct dpu_hw_mixer *dpu_hw_lm_init(enum dpu_lm idx, c->cap = cfg; _setup_mixer_ops(m, &c->ops, c->cap->features); - rc = dpu_hw_blk_init(&c->base, DPU_HW_BLK_LM, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } + dpu_hw_blk_init(&c->base, DPU_HW_BLK_LM, idx, &dpu_hw_ops); return c; - -blk_init_error: - kzfree(c); - - return ERR_PTR(rc); } void dpu_hw_lm_destroy(struct dpu_hw_mixer *lm) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index cfc93816078f..3bdf47ed1845 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -199,10 +199,7 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong_ops *ops, ops->get_line_count = dpu_hw_pp_get_line_count; }; -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; +static struct dpu_hw_blk_ops dpu_hw_ops; struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx, void __iomem *addr, @@ -210,7 +207,6 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx, { struct dpu_hw_pingpong *c; struct dpu_pingpong_cfg *cfg; - int rc; c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) @@ -226,18 +222,9 @@ struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx, c->caps = cfg; _setup_pingpong_ops(&c->ops, c->caps); - rc = dpu_hw_blk_init(&c->base, DPU_HW_BLK_PINGPONG, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } + dpu_hw_blk_init(&c->base, DPU_HW_BLK_PINGPONG, idx, &dpu_hw_ops); return c; - -blk_init_error: - kzfree(c); - - return ERR_PTR(rc); } void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 8297963d2c4c..3ebdf292d8f2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -696,10 +696,7 @@ static struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp, return ERR_PTR(-ENOMEM); } -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; +static struct dpu_hw_blk_ops dpu_hw_ops; struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, void __iomem *addr, struct dpu_mdss_cfg *catalog, @@ -707,7 +704,6 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, { struct dpu_hw_pipe *hw_pipe; struct dpu_sspp_cfg *cfg; - int rc; if (!addr || !catalog) return ERR_PTR(-EINVAL); @@ -729,18 +725,9 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx, hw_pipe->cap = cfg; _setup_layer_ops(hw_pipe, hw_pipe->cap->features); - rc = dpu_hw_blk_init(&hw_pipe->base, DPU_HW_BLK_SSPP, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } + dpu_hw_blk_init(&hw_pipe->base, DPU_HW_BLK_SSPP, idx, &dpu_hw_ops); return hw_pipe; - -blk_init_error: - kzfree(hw_pipe); - - return ERR_PTR(rc); } void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index f7e0f661a8bb..a041597bb849 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -321,10 +321,7 @@ static const struct dpu_mdp_cfg *_top_offset(enum dpu_mdp mdp, return ERR_PTR(-EINVAL); } -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; +static struct dpu_hw_blk_ops dpu_hw_ops; struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx, void __iomem *addr, @@ -332,7 +329,6 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx, { struct dpu_hw_mdp *mdp; const struct dpu_mdp_cfg *cfg; - int rc; if (!addr || !m) return ERR_PTR(-EINVAL); @@ -354,18 +350,9 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx, mdp->caps = cfg; _setup_mdp_ops(&mdp->ops, mdp->caps->features); - rc = dpu_hw_blk_init(&mdp->base, DPU_HW_BLK_TOP, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } + dpu_hw_blk_init(&mdp->base, DPU_HW_BLK_TOP, idx, &dpu_hw_ops); return mdp; - -blk_init_error: - kzfree(mdp); - - return ERR_PTR(rc); } void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp) From ab07e0c19fda03712c979626178cf9e23d610aaf Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:19 -0700 Subject: [PATCH 86/91] drm/msm: Make irq_postinstall optional Allow the KMS operation 'irq_postinstall' to be optional so that the target display drivers don't need to define a dummy function if they don't need one. v3: No changes Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 79d1847f1c28..6265be8f4119 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -752,7 +752,11 @@ static int msm_irq_postinstall(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; BUG_ON(!kms); - return kms->funcs->irq_postinstall(kms); + + if (kms->funcs->irq_postinstall) + return kms->funcs->irq_postinstall(kms); + + return 0; } static void msm_irq_uninstall(struct drm_device *dev) From 8fe62a63a867184ff94b02d618d88deddfda0cc0 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:20 -0700 Subject: [PATCH 87/91] drm/msm/dpu: Remove dpu_irq and unused functions dpu_irq.c does some unneeded checks and passes control to dpu_core_irq.c The simple functions can be defined in the same file where we use them and the files and their associated hangers on can be deleted. Additionally the postinstall hook isn't used even in dpu_core_irq.c so zap that entire path. v3: No changes Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/Makefile | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c | 15 +---- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 7 --- drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c | 66 -------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h | 59 ----------------- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 22 ++++++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 5 ++ 8 files changed, 28 insertions(+), 148 deletions(-) delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 125023068ca8..56a70c74af4e 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -70,7 +70,6 @@ msm-y := \ disp/dpu1/dpu_hw_util.o \ disp/dpu1/dpu_hw_vbif.o \ disp/dpu1/dpu_io_util.o \ - disp/dpu1/dpu_irq.o \ disp/dpu1/dpu_kms.o \ disp/dpu1/dpu_mdss.o \ disp/dpu1/dpu_plane.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c index 879c13fe74e0..9d5a8d217bc6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c @@ -376,10 +376,7 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms) struct msm_drm_private *priv; int i; - if (!dpu_kms) { - DPU_ERROR("invalid dpu_kms\n"); - return; - } else if (!dpu_kms->dev) { + if (!dpu_kms->dev) { DPU_ERROR("invalid drm device\n"); return; } else if (!dpu_kms->dev->dev_private) { @@ -410,20 +407,12 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms) } } -int dpu_core_irq_postinstall(struct dpu_kms *dpu_kms) -{ - return 0; -} - void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms) { struct msm_drm_private *priv; int i; - if (!dpu_kms) { - DPU_ERROR("invalid dpu_kms\n"); - return; - } else if (!dpu_kms->dev) { + if (!dpu_kms->dev) { DPU_ERROR("invalid drm device\n"); return; } else if (!dpu_kms->dev->dev_private) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h index 5e98bba46af5..884f77fa3eb6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h @@ -23,13 +23,6 @@ */ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms); -/** - * dpu_core_irq_postinstall - perform post-installation of core IRQ handler - * @dpu_kms: DPU handle - * @return: 0 if success; error code otherwise - */ -int dpu_core_irq_postinstall(struct dpu_kms *dpu_kms); - /** * dpu_core_irq_uninstall - uninstall core IRQ handler * @dpu_kms: DPU handle diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c deleted file mode 100644 index d5e6ce0140cf..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ - -#include -#include -#include - -#include "dpu_irq.h" -#include "dpu_core_irq.h" - -irqreturn_t dpu_irq(struct msm_kms *kms) -{ - struct dpu_kms *dpu_kms = to_dpu_kms(kms); - - return dpu_core_irq(dpu_kms); -} - -void dpu_irq_preinstall(struct msm_kms *kms) -{ - struct dpu_kms *dpu_kms = to_dpu_kms(kms); - - if (!dpu_kms->dev || !dpu_kms->dev->dev) { - pr_err("invalid device handles\n"); - return; - } - - dpu_core_irq_preinstall(dpu_kms); -} - -int dpu_irq_postinstall(struct msm_kms *kms) -{ - struct dpu_kms *dpu_kms = to_dpu_kms(kms); - int rc; - - if (!kms) { - DPU_ERROR("invalid parameters\n"); - return -EINVAL; - } - - rc = dpu_core_irq_postinstall(dpu_kms); - - return rc; -} - -void dpu_irq_uninstall(struct msm_kms *kms) -{ - struct dpu_kms *dpu_kms = to_dpu_kms(kms); - - if (!kms) { - DPU_ERROR("invalid parameters\n"); - return; - } - - dpu_core_irq_uninstall(dpu_kms); -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h deleted file mode 100644 index 3e147f7176e2..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __DPU_IRQ_H__ -#define __DPU_IRQ_H__ - -#include -#include - -#include "msm_kms.h" - -/** - * dpu_irq_controller - define MDSS level interrupt controller context - * @enabled_mask: enable status of MDSS level interrupt - * @domain: interrupt domain of this controller - */ -struct dpu_irq_controller { - unsigned long enabled_mask; - struct irq_domain *domain; -}; - -/** - * dpu_irq_preinstall - perform pre-installation of MDSS IRQ handler - * @kms: pointer to kms context - * @return: none - */ -void dpu_irq_preinstall(struct msm_kms *kms); - -/** - * dpu_irq_postinstall - perform post-installation of MDSS IRQ handler - * @kms: pointer to kms context - * @return: 0 if success; error code otherwise - */ -int dpu_irq_postinstall(struct msm_kms *kms); - -/** - * dpu_irq_uninstall - uninstall MDSS IRQ handler - * @drm_dev: pointer to kms context - * @return: none - */ -void dpu_irq_uninstall(struct msm_kms *kms); - -/** - * dpu_irq - MDSS level IRQ handler - * @kms: pointer to kms context - * @return: interrupt handling status - */ -irqreturn_t dpu_irq(struct msm_kms *kms); - -#endif /* __DPU_IRQ_H__ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 8d5cd1e7a683..37dfee1ebba9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -734,10 +734,30 @@ static void _dpu_kms_set_encoder_mode(struct msm_kms *kms, encoder->base.id, rc); } +static irqreturn_t dpu_irq(struct msm_kms *kms) +{ + struct dpu_kms *dpu_kms = to_dpu_kms(kms); + + return dpu_core_irq(dpu_kms); +} + +static void dpu_irq_preinstall(struct msm_kms *kms) +{ + struct dpu_kms *dpu_kms = to_dpu_kms(kms); + + dpu_core_irq_preinstall(dpu_kms); +} + +static void dpu_irq_uninstall(struct msm_kms *kms) +{ + struct dpu_kms *dpu_kms = to_dpu_kms(kms); + + dpu_core_irq_uninstall(dpu_kms); +} + static const struct msm_kms_funcs kms_funcs = { .hw_init = dpu_kms_hw_init, .irq_preinstall = dpu_irq_preinstall, - .irq_postinstall = dpu_irq_postinstall, .irq_uninstall = dpu_irq_uninstall, .irq = dpu_irq, .prepare_commit = dpu_kms_prepare_commit, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 611c88c1ba10..c15d239e9832 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -30,7 +30,6 @@ #include "dpu_hw_top.h" #include "dpu_io_util.h" #include "dpu_rm.h" -#include "dpu_irq.h" #include "dpu_core_perf.h" #define DRMID(x) ((x) ? (x)->base.id : -1) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index 38576f8b90b6..b7963f6bb865 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -9,6 +9,11 @@ #define HW_INTR_STATUS 0x0010 +struct dpu_irq_controller { + unsigned long enabled_mask; + struct irq_domain *domain; +}; + struct dpu_mdss { struct msm_mdss base; void __iomem *mmio; From 3d688410e6419d3d9cffa160506fe954039e0cc7 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:21 -0700 Subject: [PATCH 88/91] drm/msm/dpu: Cleanup the debugfs functions Do some debugfs cleanups from across the DPU driver. The DRM destroy functions will do a recursive delete on the entire debugfs node so there is no need to store dentry pointers for the debugfs files that are persistent for the life of the driver. This also means that the destroy functions can go away too. Also, use standard API functions where applicable instead of using hand written code. v3: No changes v2: Add more code; most of the dpu debugfs files should be addressed now. Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c | 30 +---- drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h | 9 +- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 105 +++++------------- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 7 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 30 +---- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 31 +----- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 104 ++++------------- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 6 - drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 90 +++------------ drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 24 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h | 15 +-- 12 files changed, 93 insertions(+), 361 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c index 9d5a8d217bc6..e45c69044935 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c @@ -319,10 +319,8 @@ static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) unsigned long irq_flags; int i, irq_count, enable_count, cb_count; - if (!irq_obj || !irq_obj->enable_counts || !irq_obj->irq_cb_tbl) { - DPU_ERROR("invalid parameters\n"); + if (WARN_ON(!irq_obj->enable_counts || !irq_obj->irq_cb_tbl)) return 0; - } for (i = 0; i < irq_obj->total_irqs; i++) { spin_lock_irqsave(&irq_obj->cb_lock, irq_flags); @@ -343,31 +341,11 @@ static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v) DEFINE_DPU_DEBUGFS_SEQ_FOPS(dpu_debugfs_core_irq); -int dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, +void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, struct dentry *parent) { - dpu_kms->irq_obj.debugfs_file = debugfs_create_file("core_irq", 0600, - parent, &dpu_kms->irq_obj, - &dpu_debugfs_core_irq_fops); - - return 0; -} - -void dpu_debugfs_core_irq_destroy(struct dpu_kms *dpu_kms) -{ - debugfs_remove(dpu_kms->irq_obj.debugfs_file); - dpu_kms->irq_obj.debugfs_file = NULL; -} - -#else -int dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, - struct dentry *parent) -{ - return 0; -} - -void dpu_debugfs_core_irq_destroy(struct dpu_kms *dpu_kms) -{ + debugfs_create_file("core_irq", 0600, parent, &dpu_kms->irq_obj, + &dpu_debugfs_core_irq_fops); } #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h index 884f77fa3eb6..e9015a2b23fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h @@ -132,15 +132,8 @@ int dpu_core_irq_unregister_callback( * dpu_debugfs_core_irq_init - register core irq debugfs * @dpu_kms: pointer to kms * @parent: debugfs directory root - * @Return: 0 on success */ -int dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, +void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms, struct dentry *parent); -/** - * dpu_debugfs_core_irq_destroy - deregister core irq debugfs - * @dpu_kms: pointer to kms - */ -void dpu_debugfs_core_irq_destroy(struct dpu_kms *dpu_kms); - #endif /* __DPU_CORE_IRQ_H__ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index e8a87f4b8e0e..9f20f397f77d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -24,8 +24,6 @@ #include "dpu_crtc.h" #include "dpu_core_perf.h" -#define DPU_PERF_MODE_STRING_SIZE 128 - /** * enum dpu_perf_mode - performance tuning mode * @DPU_PERF_MODE_NORMAL: performance controlled by user mode client @@ -451,24 +449,14 @@ static ssize_t _dpu_core_perf_mode_write(struct file *file, struct dpu_core_perf *perf = file->private_data; struct dpu_perf_cfg *cfg = &perf->catalog->perf; u32 perf_mode = 0; - char buf[10]; + int ret; - if (!perf) - return -ENODEV; - - if (count >= sizeof(buf)) - return -EFAULT; - - if (copy_from_user(buf, user_buf, count)) - return -EFAULT; - - buf[count] = 0; /* end of string */ - - if (kstrtouint(buf, 0, &perf_mode)) - return -EFAULT; + ret = kstrtouint_from_user(user_buf, count, 0, &perf_mode); + if (ret) + return ret; if (perf_mode >= DPU_PERF_MODE_MAX) - return -EFAULT; + return -EINVAL; if (perf_mode == DPU_PERF_MODE_FIXED) { DRM_INFO("fix performance mode\n"); @@ -493,29 +481,16 @@ static ssize_t _dpu_core_perf_mode_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { struct dpu_core_perf *perf = file->private_data; - int len = 0; - char buf[DPU_PERF_MODE_STRING_SIZE] = {'\0'}; + int len; + char buf[128]; - if (!perf) - return -ENODEV; - - if (*ppos) - return 0; /* the end */ - - len = snprintf(buf, sizeof(buf), + len = scnprintf(buf, sizeof(buf), "mode %d min_mdp_clk %llu min_bus_vote %llu\n", perf->perf_tune.mode, perf->perf_tune.min_core_clk, perf->perf_tune.min_bus_vote); - if (len < 0 || len >= sizeof(buf)) - return 0; - if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) - return -EFAULT; - - *ppos += len; /* increase offset */ - - return len; + return simple_read_from_buffer(buff, count, ppos, buf, len); } static const struct file_operations dpu_core_perf_mode_fops = { @@ -524,70 +499,43 @@ static const struct file_operations dpu_core_perf_mode_fops = { .write = _dpu_core_perf_mode_write, }; -static void dpu_core_perf_debugfs_destroy(struct dpu_core_perf *perf) -{ - debugfs_remove_recursive(perf->debugfs_root); - perf->debugfs_root = NULL; -} - -int dpu_core_perf_debugfs_init(struct dpu_core_perf *perf, - struct dentry *parent) +int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent) { + struct dpu_core_perf *perf = &dpu_kms->perf; struct dpu_mdss_cfg *catalog = perf->catalog; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; + struct dentry *entry; - priv = perf->dev->dev_private; - if (!priv || !priv->kms) { - DPU_ERROR("invalid KMS reference\n"); + entry = debugfs_create_dir("core_perf", parent); + if (IS_ERR_OR_NULL(entry)) return -EINVAL; - } - dpu_kms = to_dpu_kms(priv->kms); - - perf->debugfs_root = debugfs_create_dir("core_perf", parent); - if (!perf->debugfs_root) { - DPU_ERROR("failed to create core perf debugfs\n"); - return -EINVAL; - } - - debugfs_create_u64("max_core_clk_rate", 0600, perf->debugfs_root, + debugfs_create_u64("max_core_clk_rate", 0600, entry, &perf->max_core_clk_rate); - debugfs_create_u64("core_clk_rate", 0600, perf->debugfs_root, + debugfs_create_u64("core_clk_rate", 0600, entry, &perf->core_clk_rate); - debugfs_create_u32("enable_bw_release", 0600, perf->debugfs_root, + debugfs_create_u32("enable_bw_release", 0600, entry, (u32 *)&perf->enable_bw_release); - debugfs_create_u32("threshold_low", 0600, perf->debugfs_root, + debugfs_create_u32("threshold_low", 0600, entry, (u32 *)&catalog->perf.max_bw_low); - debugfs_create_u32("threshold_high", 0600, perf->debugfs_root, + debugfs_create_u32("threshold_high", 0600, entry, (u32 *)&catalog->perf.max_bw_high); - debugfs_create_u32("min_core_ib", 0600, perf->debugfs_root, + debugfs_create_u32("min_core_ib", 0600, entry, (u32 *)&catalog->perf.min_core_ib); - debugfs_create_u32("min_llcc_ib", 0600, perf->debugfs_root, + debugfs_create_u32("min_llcc_ib", 0600, entry, (u32 *)&catalog->perf.min_llcc_ib); - debugfs_create_u32("min_dram_ib", 0600, perf->debugfs_root, + debugfs_create_u32("min_dram_ib", 0600, entry, (u32 *)&catalog->perf.min_dram_ib); - debugfs_create_file("perf_mode", 0600, perf->debugfs_root, + debugfs_create_file("perf_mode", 0600, entry, (u32 *)perf, &dpu_core_perf_mode_fops); - debugfs_create_u64("fix_core_clk_rate", 0600, perf->debugfs_root, + debugfs_create_u64("fix_core_clk_rate", 0600, entry, &perf->fix_core_clk_rate); - debugfs_create_u64("fix_core_ib_vote", 0600, perf->debugfs_root, + debugfs_create_u64("fix_core_ib_vote", 0600, entry, &perf->fix_core_ib_vote); - debugfs_create_u64("fix_core_ab_vote", 0600, perf->debugfs_root, + debugfs_create_u64("fix_core_ab_vote", 0600, entry, &perf->fix_core_ab_vote); return 0; } -#else -static void dpu_core_perf_debugfs_destroy(struct dpu_core_perf *perf) -{ -} - -int dpu_core_perf_debugfs_init(struct dpu_core_perf *perf, - struct dentry *parent) -{ - return 0; -} #endif void dpu_core_perf_destroy(struct dpu_core_perf *perf) @@ -597,7 +545,6 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf) return; } - dpu_core_perf_debugfs_destroy(perf); perf->max_core_clk_rate = 0; perf->core_clk = NULL; perf->catalog = NULL; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h index c708451a94a1..37f518815eb7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -130,12 +130,13 @@ int dpu_core_perf_init(struct dpu_core_perf *perf, struct dpu_mdss_cfg *catalog, struct dss_clk *core_clk); +struct dpu_kms; + /** * dpu_core_perf_debugfs_init - initialize debugfs for core performance context - * @perf: Pointer to core performance context + * @dpu_kms: Pointer to the dpu_kms struct * @debugfs_parent: Pointer to parent debugfs */ -int dpu_core_perf_debugfs_init(struct dpu_core_perf *perf, - struct dentry *parent); +int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent); #endif /* _DPU_CORE_PERF_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index ffdb90c70c34..3090854a8575 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1186,9 +1186,6 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) int i, out_width; - if (!s || !s->private) - return -EINVAL; - dpu_crtc = s->private; crtc = &dpu_crtc->base; @@ -1328,8 +1325,7 @@ DEFINE_DPU_DEBUGFS_SEQ_FOPS(dpu_crtc_debugfs_state); static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc) { - struct dpu_crtc *dpu_crtc; - struct dpu_kms *dpu_kms; + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); static const struct file_operations debugfs_status_fops = { .open = _dpu_debugfs_status_open, @@ -1338,12 +1334,6 @@ static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc) .release = single_release, }; - if (!crtc) - return -EINVAL; - dpu_crtc = to_dpu_crtc(crtc); - - dpu_kms = _dpu_crtc_get_kms(crtc); - dpu_crtc->debugfs_root = debugfs_create_dir(dpu_crtc->name, crtc->dev->primary->debugfs_root); if (!dpu_crtc->debugfs_root) @@ -1360,25 +1350,11 @@ static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc) return 0; } - -static void _dpu_crtc_destroy_debugfs(struct drm_crtc *crtc) -{ - struct dpu_crtc *dpu_crtc; - - if (!crtc) - return; - dpu_crtc = to_dpu_crtc(crtc); - debugfs_remove_recursive(dpu_crtc->debugfs_root); -} #else static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc) { return 0; } - -static void _dpu_crtc_destroy_debugfs(struct drm_crtc *crtc) -{ -} #endif /* CONFIG_DEBUG_FS */ static int dpu_crtc_late_register(struct drm_crtc *crtc) @@ -1388,7 +1364,9 @@ static int dpu_crtc_late_register(struct drm_crtc *crtc) static void dpu_crtc_early_unregister(struct drm_crtc *crtc) { - _dpu_crtc_destroy_debugfs(crtc); + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); + + debugfs_remove_recursive(dpu_crtc->debugfs_root); } static const struct drm_crtc_funcs dpu_crtc_funcs = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index c1baab4c72d2..0dda4a603685 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1863,14 +1863,9 @@ void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc) #ifdef CONFIG_DEBUG_FS static int _dpu_encoder_status_show(struct seq_file *s, void *data) { - struct dpu_encoder_virt *dpu_enc; + struct dpu_encoder_virt *dpu_enc = s->private; int i; - if (!s || !s->private) - return -EINVAL; - - dpu_enc = s->private; - mutex_lock(&dpu_enc->enc_lock); for (i = 0; i < dpu_enc->num_phys_encs; i++) { struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; @@ -1908,7 +1903,7 @@ static int _dpu_encoder_debugfs_status_open(struct inode *inode, static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) { - struct dpu_encoder_virt *dpu_enc; + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); struct msm_drm_private *priv; struct dpu_kms *dpu_kms; int i; @@ -1922,12 +1917,11 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) char name[DPU_NAME_SIZE]; - if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) { + if (!drm_enc->dev || !drm_enc->dev->dev_private) { DPU_ERROR("invalid encoder or kms\n"); return -EINVAL; } - dpu_enc = to_dpu_encoder_virt(drm_enc); priv = drm_enc->dev->dev_private; dpu_kms = to_dpu_kms(priv->kms); @@ -1952,26 +1946,11 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) return 0; } - -static void _dpu_encoder_destroy_debugfs(struct drm_encoder *drm_enc) -{ - struct dpu_encoder_virt *dpu_enc; - - if (!drm_enc) - return; - - dpu_enc = to_dpu_encoder_virt(drm_enc); - debugfs_remove_recursive(dpu_enc->debugfs_root); -} #else static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) { return 0; } - -static void _dpu_encoder_destroy_debugfs(struct drm_encoder *drm_enc) -{ -} #endif static int dpu_encoder_late_register(struct drm_encoder *encoder) @@ -1981,7 +1960,9 @@ static int dpu_encoder_late_register(struct drm_encoder *encoder) static void dpu_encoder_early_unregister(struct drm_encoder *encoder) { - _dpu_encoder_destroy_debugfs(encoder); + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder); + + debugfs_remove_recursive(dpu_enc->debugfs_root); } static int dpu_encoder_virt_add_phys_encs( diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 37dfee1ebba9..51a4a5f7c7f9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -81,7 +81,7 @@ static int _dpu_danger_signal_status(struct seq_file *s, struct dpu_danger_safe_status status; int i; - if (!kms || !kms->dev || !kms->dev->dev_private || !kms->hw_mdp) { + if (!kms->dev || !kms->dev->dev_private || !kms->hw_mdp) { DPU_ERROR("invalid arg(s)\n"); return 0; } @@ -138,46 +138,29 @@ static int dpu_debugfs_safe_stats_show(struct seq_file *s, void *v) } DEFINE_DPU_DEBUGFS_SEQ_FOPS(dpu_debugfs_safe_stats); -static void dpu_debugfs_danger_destroy(struct dpu_kms *dpu_kms) -{ - debugfs_remove_recursive(dpu_kms->debugfs_danger); - dpu_kms->debugfs_danger = NULL; -} - -static int dpu_debugfs_danger_init(struct dpu_kms *dpu_kms, +static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms, struct dentry *parent) { - dpu_kms->debugfs_danger = debugfs_create_dir("danger", - parent); - if (!dpu_kms->debugfs_danger) { - DPU_ERROR("failed to create danger debugfs\n"); - return -EINVAL; - } + struct dentry *entry = debugfs_create_dir("danger", parent); + if (IS_ERR_OR_NULL(entry)) + return; - debugfs_create_file("danger_status", 0600, dpu_kms->debugfs_danger, + debugfs_create_file("danger_status", 0600, entry, dpu_kms, &dpu_debugfs_danger_stats_fops); - debugfs_create_file("safe_status", 0600, dpu_kms->debugfs_danger, + debugfs_create_file("safe_status", 0600, entry, dpu_kms, &dpu_debugfs_safe_stats_fops); - - return 0; } static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data) { - struct dpu_debugfs_regset32 *regset; - struct dpu_kms *dpu_kms; + struct dpu_debugfs_regset32 *regset = s->private; + struct dpu_kms *dpu_kms = regset->dpu_kms; struct drm_device *dev; struct msm_drm_private *priv; void __iomem *base; uint32_t i, addr; - if (!s || !s->private) - return 0; - - regset = s->private; - - dpu_kms = regset->dpu_kms; - if (!dpu_kms || !dpu_kms->mmio) + if (!dpu_kms->mmio) return 0; dev = dpu_kms->dev; @@ -250,51 +233,24 @@ void *dpu_debugfs_create_regset32(const char *name, umode_t mode, static int _dpu_debugfs_init(struct dpu_kms *dpu_kms) { - void *p; - int rc; + void *p = dpu_hw_util_get_log_mask_ptr(); + struct dentry *entry; - p = dpu_hw_util_get_log_mask_ptr(); - - if (!dpu_kms || !p) + if (!p) return -EINVAL; - dpu_kms->debugfs_root = debugfs_create_dir("debug", - dpu_kms->dev->primary->debugfs_root); - if (IS_ERR_OR_NULL(dpu_kms->debugfs_root)) { - DRM_ERROR("debugfs create_dir failed %ld\n", - PTR_ERR(dpu_kms->debugfs_root)); - return PTR_ERR(dpu_kms->debugfs_root); - } + entry = debugfs_create_dir("debug", dpu_kms->dev->primary->debugfs_root); + if (IS_ERR_OR_NULL(entry)) + return -ENODEV; /* allow root to be NULL */ - debugfs_create_x32(DPU_DEBUGFS_HWMASKNAME, 0600, dpu_kms->debugfs_root, p); + debugfs_create_x32(DPU_DEBUGFS_HWMASKNAME, 0600, entry, p); - (void) dpu_debugfs_danger_init(dpu_kms, dpu_kms->debugfs_root); - (void) dpu_debugfs_vbif_init(dpu_kms, dpu_kms->debugfs_root); - (void) dpu_debugfs_core_irq_init(dpu_kms, dpu_kms->debugfs_root); + dpu_debugfs_danger_init(dpu_kms, entry); + dpu_debugfs_vbif_init(dpu_kms, entry); + dpu_debugfs_core_irq_init(dpu_kms, entry); - rc = dpu_core_perf_debugfs_init(&dpu_kms->perf, dpu_kms->debugfs_root); - if (rc) { - DPU_ERROR("failed to init perf %d\n", rc); - return rc; - } - - return 0; -} - -static void _dpu_debugfs_destroy(struct dpu_kms *dpu_kms) -{ - /* don't need to NULL check debugfs_root */ - if (dpu_kms) { - dpu_debugfs_vbif_destroy(dpu_kms); - dpu_debugfs_danger_destroy(dpu_kms); - dpu_debugfs_core_irq_destroy(dpu_kms); - debugfs_remove_recursive(dpu_kms->debugfs_root); - } -} -#else -static void _dpu_debugfs_destroy(struct dpu_kms *dpu_kms) -{ + return dpu_core_perf_debugfs_init(dpu_kms, entry); } #endif @@ -620,22 +576,7 @@ fail: #ifdef CONFIG_DEBUG_FS static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor) { - struct dpu_kms *dpu_kms = to_dpu_kms(kms); - struct drm_device *dev; - int rc; - - if (!dpu_kms || !dpu_kms->dev || !dpu_kms->dev->dev) { - DPU_ERROR("invalid dpu_kms\n"); - return -EINVAL; - } - - dev = dpu_kms->dev; - - rc = _dpu_debugfs_init(dpu_kms); - if (rc) - DPU_ERROR("dpu_debugfs init failed: %d\n", rc); - - return rc; + return _dpu_debugfs_init(to_dpu_kms(kms)); } #endif @@ -659,7 +600,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) dpu_kms->hw_intr = NULL; /* safe to call these more than once during shutdown */ - _dpu_debugfs_destroy(dpu_kms); _dpu_kms_mmu_destroy(dpu_kms); if (dpu_kms->catalog) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index c15d239e9832..ac75cfc267f4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -102,7 +102,6 @@ struct dpu_irq { atomic_t *enable_counts; atomic_t *irq_counts; spinlock_t cb_lock; - struct dentry *debugfs_file; }; struct dpu_kms { @@ -111,11 +110,6 @@ struct dpu_kms { int core_rev; struct dpu_mdss_cfg *catalog; - /* directory entry for debugfs */ - struct dentry *debugfs_root; - struct dentry *debugfs_danger; - struct dentry *debugfs_vbif; - /* io/register spaces: */ void __iomem *mmio, *vbif[VBIF_MAX], *reg_dma; unsigned long mmio_len, vbif_len[VBIF_MAX], reg_dma_len; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index b7963f6bb865..413e1ee43cf2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -120,13 +120,12 @@ static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss) return 0; } -static int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss) +static void _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss) { if (dpu_mdss->irq_controller.domain) { irq_domain_remove(dpu_mdss->irq_controller.domain); dpu_mdss->irq_controller.domain = NULL; } - return 0; } static int dpu_mdss_enable(struct msm_mdss *mdss) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index f7d9bab80dad..278d0edb41a9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1262,26 +1262,12 @@ static ssize_t _dpu_plane_danger_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { struct dpu_kms *kms = file->private_data; - struct dpu_mdss_cfg *cfg = kms->catalog; - int len = 0; - char buf[40] = {'\0'}; + int len; + char buf[40]; - if (!cfg) - return -ENODEV; + len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl); - if (*ppos) - return 0; /* the end */ - - len = snprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl); - if (len < 0 || len >= sizeof(buf)) - return 0; - - if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) - return -EFAULT; - - *ppos += len; /* increase offset */ - - return len; + return simple_read_from_buffer(buff, count, ppos, buf, len); } static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable) @@ -1311,23 +1297,12 @@ static ssize_t _dpu_plane_danger_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct dpu_kms *kms = file->private_data; - struct dpu_mdss_cfg *cfg = kms->catalog; int disable_panic; - char buf[10]; + int ret; - if (!cfg) - return -EFAULT; - - if (count >= sizeof(buf)) - return -EFAULT; - - if (copy_from_user(buf, user_buf, count)) - return -EFAULT; - - buf[count] = 0; /* end of string */ - - if (kstrtoint(buf, 0, &disable_panic)) - return -EFAULT; + ret = kstrtouint_from_user(user_buf, count, 0, &disable_panic); + if (ret) + return ret; if (disable_panic) { /* Disable panic signal for all active pipes */ @@ -1352,33 +1327,10 @@ static const struct file_operations dpu_plane_danger_enable = { static int _dpu_plane_init_debugfs(struct drm_plane *plane) { - struct dpu_plane *pdpu; - struct dpu_kms *kms; - struct msm_drm_private *priv; - const struct dpu_sspp_sub_blks *sblk = 0; - const struct dpu_sspp_cfg *cfg = 0; - - if (!plane || !plane->dev) { - DPU_ERROR("invalid arguments\n"); - return -EINVAL; - } - - priv = plane->dev->dev_private; - if (!priv || !priv->kms) { - DPU_ERROR("invalid KMS reference\n"); - return -EINVAL; - } - - kms = to_dpu_kms(priv->kms); - pdpu = to_dpu_plane(plane); - - if (pdpu && pdpu->pipe_hw) - cfg = pdpu->pipe_hw->cap; - if (cfg) - sblk = cfg->sblk; - - if (!sblk) - return 0; + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct dpu_kms *kms = _dpu_plane_get_kms(plane); + const struct dpu_sspp_cfg *cfg = pdpu->pipe_hw->cap; + const struct dpu_sspp_sub_blks *sblk = cfg->sblk; /* create overall sub-directory for the pipe */ pdpu->debugfs_root = @@ -1449,25 +1401,11 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane) return 0; } - -static void _dpu_plane_destroy_debugfs(struct drm_plane *plane) -{ - struct dpu_plane *pdpu; - - if (!plane) - return; - pdpu = to_dpu_plane(plane); - - debugfs_remove_recursive(pdpu->debugfs_root); -} #else static int _dpu_plane_init_debugfs(struct drm_plane *plane) { return 0; } -static void _dpu_plane_destroy_debugfs(struct drm_plane *plane) -{ -} #endif static int dpu_plane_late_register(struct drm_plane *plane) @@ -1477,7 +1415,9 @@ static int dpu_plane_late_register(struct drm_plane *plane) static void dpu_plane_early_unregister(struct drm_plane *plane) { - _dpu_plane_destroy_debugfs(plane); + struct dpu_plane *pdpu = to_dpu_plane(plane); + + debugfs_remove_recursive(pdpu->debugfs_root); } static const struct drm_plane_funcs dpu_plane_funcs = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c index ff5091d2555d..ef753ea9c499 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c @@ -310,31 +310,25 @@ void dpu_vbif_init_memtypes(struct dpu_kms *dpu_kms) } #ifdef CONFIG_DEBUG_FS -void dpu_debugfs_vbif_destroy(struct dpu_kms *dpu_kms) -{ - debugfs_remove_recursive(dpu_kms->debugfs_vbif); - dpu_kms->debugfs_vbif = NULL; -} -int dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root) +void dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root) { char vbif_name[32]; - struct dentry *debugfs_vbif; + struct dentry *entry, *debugfs_vbif; int i, j; - dpu_kms->debugfs_vbif = debugfs_create_dir("vbif", debugfs_root); - if (!dpu_kms->debugfs_vbif) { - DPU_ERROR("failed to create vbif debugfs\n"); - return -EINVAL; - } + entry = debugfs_create_dir("vbif", debugfs_root); + if (IS_ERR_OR_NULL(entry)) + return; for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i]; snprintf(vbif_name, sizeof(vbif_name), "%d", vbif->id); - debugfs_vbif = debugfs_create_dir(vbif_name, - dpu_kms->debugfs_vbif); + debugfs_vbif = debugfs_create_dir(vbif_name, entry); + if (IS_ERR_OR_NULL(debugfs_vbif)) + continue; debugfs_create_u32("features", 0600, debugfs_vbif, (u32 *)&vbif->features); @@ -376,7 +370,5 @@ int dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root) (u32 *)&cfg->ot_limit); } } - - return 0; } #endif diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h index f17af52dbbd5..6356876d7a66 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.h @@ -78,17 +78,6 @@ void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms); */ void dpu_vbif_init_memtypes(struct dpu_kms *dpu_kms); -#ifdef CONFIG_DEBUG_FS -int dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root); -void dpu_debugfs_vbif_destroy(struct dpu_kms *dpu_kms); -#else -static inline int dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, - struct dentry *debugfs_root) -{ - return 0; -} -static inline void dpu_debugfs_vbif_destroy(struct dpu_kms *dpu_kms) -{ -} -#endif +void dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root); + #endif /* __DPU_VBIF_H__ */ From 3804a9824186af7c10f36fd4262b4e97326f1ef1 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:22 -0700 Subject: [PATCH 89/91] drm/msm/dpu: Further cleanups for static inline functions Remove more static inline functions that are lightly used and/or very simple and easy to build into the calling functions. v3: Fix a nit from Sean Paul v2: Removed another unused function from dpu_hw_lm.c and add back dpu_crtc_get_client_type() since there was a question regarding its usefulness. Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 12 +++--------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 10 ---------- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 2 +- .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 11 ++--------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 9 --------- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 6 ------ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h | 5 ----- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 8 +------- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++-------------- 10 files changed, 13 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 3090854a8575..a6f0c38a0a95 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -46,12 +46,6 @@ #define LEFT_MIXER 0 #define RIGHT_MIXER 1 -static inline int _dpu_crtc_get_mixer_width(struct dpu_crtc_state *cstate, - struct drm_display_mode *mode) -{ - return mode->hdisplay / cstate->num_mixers; -} - static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) { struct msm_drm_private *priv = crtc->dev->dev_private; @@ -497,7 +491,7 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, { struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); struct drm_display_mode *adj_mode = &state->adjusted_mode; - u32 crtc_split_width = _dpu_crtc_get_mixer_width(cstate, adj_mode); + u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; int i; for (i = 0; i < cstate->num_mixers; i++) { @@ -952,7 +946,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, memset(pipe_staged, 0, sizeof(pipe_staged)); - mixer_width = _dpu_crtc_get_mixer_width(cstate, mode); + mixer_width = mode->hdisplay / cstate->num_mixers; _dpu_crtc_setup_lm_bounds(crtc, state); @@ -1193,7 +1187,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) cstate = to_dpu_crtc_state(crtc->state); mode = &crtc->state->adjusted_mode; - out_width = _dpu_crtc_get_mixer_width(cstate, mode); + out_width = mode->hdisplay / cstate->num_mixers; seq_printf(s, "crtc:%d width:%d height:%d\n", crtc->base.id, mode->hdisplay, mode->vdisplay); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 94f5cea4e0d2..dbfb38a1986c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -226,16 +226,6 @@ struct dpu_crtc_state { #define to_dpu_crtc_state(x) \ container_of(x, struct dpu_crtc_state, base) -/** - * dpu_crtc_state_is_stereo - Is crtc virtualized with two mixers? - * @cstate: Pointer to dpu crtc state - * @Return: true - has two mixers, false - has one mixer - */ -static inline bool dpu_crtc_state_is_stereo(struct dpu_crtc_state *cstate) -{ - return cstate->num_mixers == CRTC_DUAL_MIXERS; -} - /** * dpu_crtc_frame_pending - retun the number of pending frames * @crtc: Pointer to drm crtc object diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index 3a67bb9f9d9d..44e6f8b68e70 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -350,7 +350,7 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state); if (phys_enc->split_role == ENC_ROLE_SOLO && - dpu_crtc_state_is_stereo(dpu_cstate)) + dpu_cstate->num_mixers == CRTC_DUAL_MIXERS) return BLEND_3D_H_ROW_INT; return BLEND_3D_NONE; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index b37a0992e326..99ab5ca9bed3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -44,14 +44,7 @@ #define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000 -static inline int _dpu_encoder_phys_cmd_get_idle_timeout( - struct dpu_encoder_phys_cmd *cmd_enc) -{ - return KICKOFF_TIMEOUT_MS; -} - -static inline bool dpu_encoder_phys_cmd_is_master( - struct dpu_encoder_phys *phys_enc) +static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc) { return (phys_enc->split_role != ENC_ROLE_SLAVE) ? true : false; } @@ -723,7 +716,7 @@ static int dpu_encoder_phys_cmd_wait_for_vblank( wait_info.wq = &cmd_enc->pending_vblank_wq; wait_info.atomic_cnt = &cmd_enc->pending_vblank_cnt; - wait_info.timeout_ms = _dpu_encoder_phys_cmd_get_idle_timeout(cmd_enc); + wait_info.timeout_ms = KICKOFF_TIMEOUT_MS; atomic_inc(&cmd_enc->pending_vblank_cnt); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index dc060e7358e4..144358a3d0fb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -736,13 +736,4 @@ struct dpu_mdss_cfg *dpu_hw_catalog_init(u32 hw_rev); */ void dpu_hw_catalog_deinit(struct dpu_mdss_cfg *dpu_cfg); -/** - * dpu_hw_sspp_multirect_enabled - check multirect enabled for the sspp - * @cfg: pointer to sspp cfg - */ -static inline bool dpu_hw_sspp_multirect_enabled(const struct dpu_sspp_cfg *cfg) -{ - return test_bit(DPU_SSPP_SMART_DMA_V1, &cfg->features) || - test_bit(DPU_SSPP_SMART_DMA_V2, &cfg->features); -} #endif /* _DPU_HW_CATALOG_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index 9f342af2aba7..018df2c3b7ed 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -156,11 +156,6 @@ static void dpu_hw_lm_setup_color3(struct dpu_hw_mixer *ctx, DPU_REG_WRITE(c, LM_OP_MODE, op_mode); } -static void dpu_hw_lm_gc(struct dpu_hw_mixer *mixer, - void *cfg) -{ -} - static void _setup_mixer_ops(struct dpu_mdss_cfg *m, struct dpu_hw_lm_ops *ops, unsigned long features) @@ -172,7 +167,6 @@ static void _setup_mixer_ops(struct dpu_mdss_cfg *m, ops->setup_blend_config = dpu_hw_lm_setup_blend_config; ops->setup_alpha_out = dpu_hw_lm_setup_color3; ops->setup_border_color = dpu_hw_lm_setup_border_color; - ops->setup_gc = dpu_hw_lm_gc; }; static struct dpu_hw_blk_ops dpu_hw_ops; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h index 5b036aca8340..6aee839a6a23 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h @@ -61,11 +61,6 @@ struct dpu_hw_lm_ops { void (*setup_border_color)(struct dpu_hw_mixer *ctx, struct dpu_mdss_color *color, u8 border_en); - /** - * setup_gc : enable/disable gamma correction feature - */ - void (*setup_gc)(struct dpu_hw_mixer *mixer, - void *cfg); }; struct dpu_hw_mixer { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 3ebdf292d8f2..e9132bf5166b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -661,7 +661,8 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c, test_bit(DPU_SSPP_CSC_10BIT, &features)) c->ops.setup_csc = dpu_hw_sspp_setup_csc; - if (dpu_hw_sspp_multirect_enabled(c->cap)) + if (test_bit(DPU_SSPP_SMART_DMA_V1, &c->cap->features) || + test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features)) c->ops.setup_multirect = dpu_hw_sspp_setup_multirect; if (test_bit(DPU_SSPP_SCALER_QSEED3, &features)) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 51a4a5f7c7f9..4d67b3c96702 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -716,12 +716,6 @@ static const struct msm_kms_funcs kms_funcs = { #endif }; -/* the caller api needs to turn on clock before calling it */ -static inline void _dpu_kms_core_hw_rev_init(struct dpu_kms *dpu_kms) -{ - dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0); -} - static int _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms) { struct msm_mmu *mmu; @@ -859,7 +853,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms) pm_runtime_get_sync(&dpu_kms->pdev->dev); - _dpu_kms_core_hw_rev_init(dpu_kms); + dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0); pr_info("dpu hardware revision:0x%x\n", dpu_kms->core_rev); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 278d0edb41a9..fd75870eb17f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -430,24 +430,14 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane) dpu_vbif_set_qos_remap(dpu_kms, &qos_params); } -/** - * _dpu_plane_get_aspace: gets the address space - */ -static inline struct msm_gem_address_space *_dpu_plane_get_aspace( - struct dpu_plane *pdpu) -{ - struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); - - return kms->base.aspace; -} - static void _dpu_plane_set_scanout(struct drm_plane *plane, struct dpu_plane_state *pstate, struct dpu_hw_pipe_cfg *pipe_cfg, struct drm_framebuffer *fb) { struct dpu_plane *pdpu = to_dpu_plane(plane); - struct msm_gem_address_space *aspace = _dpu_plane_get_aspace(pdpu); + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); + struct msm_gem_address_space *aspace = kms->base.aspace; int ret; ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout); @@ -801,7 +791,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, struct drm_gem_object *obj; struct msm_gem_object *msm_obj; struct dma_fence *fence; - struct msm_gem_address_space *aspace = _dpu_plane_get_aspace(pdpu); + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); int ret; if (!new_state->fb) @@ -810,7 +800,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", fb->base.id); /* cache aspace */ - pstate->aspace = aspace; + pstate->aspace = kms->base.aspace; /* * TODO: Need to sort out the msm_framebuffer_prepare() call below so From 7adc4a343f94589f1954e93fcadee3f55e263a0d Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Mon, 3 Dec 2018 15:47:23 -0700 Subject: [PATCH 90/91] drm/msm/dpu: Clean up dpu_media_info.h static inline functions Do some cleanup in the static inline functions defined in dpu_media_info.h by cleaning up gotos and unneeded local variables. v3: Added spaces between operators per Seal Paul and Sam Ravnborg Reviewed-by: Sean Paul Signed-off-by: Jordan Crouse Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- .../gpu/drm/msm/disp/dpu1/msm_media_info.h | 164 ++++++------------ 1 file changed, 57 insertions(+), 107 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h b/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h index 75470ee5b18f..9fc9dbde8a27 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h +++ b/drivers/gpu/drm/msm/disp/dpu1/msm_media_info.h @@ -822,36 +822,30 @@ enum color_fmts { */ static unsigned int VENUS_Y_STRIDE(int color_fmt, int width) { - unsigned int alignment, stride = 0; + unsigned int stride = 0; if (!width) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV21: case COLOR_FMT_NV12: case COLOR_FMT_NV12_MVTB: case COLOR_FMT_NV12_UBWC: - alignment = 128; - stride = MSM_MEDIA_ALIGN(width, alignment); + stride = MSM_MEDIA_ALIGN(width, 128); break; case COLOR_FMT_NV12_BPP10_UBWC: - alignment = 256; stride = MSM_MEDIA_ALIGN(width, 192); - stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment); + stride = MSM_MEDIA_ALIGN(stride * 4 / 3, 256); break; case COLOR_FMT_P010_UBWC: - alignment = 256; - stride = MSM_MEDIA_ALIGN(width * 2, alignment); + stride = MSM_MEDIA_ALIGN(width * 2, 256); break; case COLOR_FMT_P010: - alignment = 128; - stride = MSM_MEDIA_ALIGN(width*2, alignment); - break; - default: + stride = MSM_MEDIA_ALIGN(width * 2, 128); break; } -invalid_input: + return stride; } @@ -864,36 +858,30 @@ invalid_input: */ static unsigned int VENUS_UV_STRIDE(int color_fmt, int width) { - unsigned int alignment, stride = 0; + unsigned int stride = 0; if (!width) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV21: case COLOR_FMT_NV12: case COLOR_FMT_NV12_MVTB: case COLOR_FMT_NV12_UBWC: - alignment = 128; - stride = MSM_MEDIA_ALIGN(width, alignment); + stride = MSM_MEDIA_ALIGN(width, 128); break; case COLOR_FMT_NV12_BPP10_UBWC: - alignment = 256; stride = MSM_MEDIA_ALIGN(width, 192); - stride = MSM_MEDIA_ALIGN(stride * 4/3, alignment); + stride = MSM_MEDIA_ALIGN(stride * 4 / 3, 256); break; case COLOR_FMT_P010_UBWC: - alignment = 256; - stride = MSM_MEDIA_ALIGN(width * 2, alignment); + stride = MSM_MEDIA_ALIGN(width * 2, 256); break; case COLOR_FMT_P010: - alignment = 128; - stride = MSM_MEDIA_ALIGN(width*2, alignment); - break; - default: + stride = MSM_MEDIA_ALIGN(width * 2, 128); break; } -invalid_input: + return stride; } @@ -906,10 +894,10 @@ invalid_input: */ static unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) { - unsigned int alignment, sclines = 0; + unsigned int sclines = 0; if (!height) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV21: @@ -917,17 +905,14 @@ static unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) case COLOR_FMT_NV12_MVTB: case COLOR_FMT_NV12_UBWC: case COLOR_FMT_P010: - alignment = 32; + sclines = MSM_MEDIA_ALIGN(height, 32); break; case COLOR_FMT_NV12_BPP10_UBWC: case COLOR_FMT_P010_UBWC: - alignment = 16; + sclines = MSM_MEDIA_ALIGN(height, 16); break; - default: - return 0; } - sclines = MSM_MEDIA_ALIGN(height, alignment); -invalid_input: + return sclines; } @@ -940,10 +925,10 @@ invalid_input: */ static unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) { - unsigned int alignment, sclines = 0; + unsigned int sclines = 0; if (!height) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV21: @@ -952,18 +937,13 @@ static unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) case COLOR_FMT_NV12_BPP10_UBWC: case COLOR_FMT_P010_UBWC: case COLOR_FMT_P010: - alignment = 16; + sclines = MSM_MEDIA_ALIGN((height + 1) >> 1, 16); break; case COLOR_FMT_NV12_UBWC: - alignment = 32; + sclines = MSM_MEDIA_ALIGN((height + 1) >> 1, 32); break; - default: - goto invalid_input; } - sclines = MSM_MEDIA_ALIGN((height+1)>>1, alignment); - -invalid_input: return sclines; } @@ -976,10 +956,10 @@ invalid_input: */ static unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width) { - int y_tile_width = 0, y_meta_stride = 0; + int y_tile_width = 0, y_meta_stride; if (!width) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV12_UBWC: @@ -990,14 +970,11 @@ static unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width) y_tile_width = 48; break; default: - goto invalid_input; + return 0; } y_meta_stride = MSM_MEDIA_ROUNDUP(width, y_tile_width); - y_meta_stride = MSM_MEDIA_ALIGN(y_meta_stride, 64); - -invalid_input: - return y_meta_stride; + return MSM_MEDIA_ALIGN(y_meta_stride, 64); } /* @@ -1009,10 +986,10 @@ invalid_input: */ static unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height) { - int y_tile_height = 0, y_meta_scanlines = 0; + int y_tile_height = 0, y_meta_scanlines; if (!height) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV12_UBWC: @@ -1023,14 +1000,11 @@ static unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height) y_tile_height = 4; break; default: - goto invalid_input; + return 0; } y_meta_scanlines = MSM_MEDIA_ROUNDUP(height, y_tile_height); - y_meta_scanlines = MSM_MEDIA_ALIGN(y_meta_scanlines, 16); - -invalid_input: - return y_meta_scanlines; + return MSM_MEDIA_ALIGN(y_meta_scanlines, 16); } /* @@ -1042,10 +1016,10 @@ invalid_input: */ static unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width) { - int uv_tile_width = 0, uv_meta_stride = 0; + int uv_tile_width = 0, uv_meta_stride; if (!width) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV12_UBWC: @@ -1056,14 +1030,11 @@ static unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width) uv_tile_width = 24; break; default: - goto invalid_input; + return 0; } uv_meta_stride = MSM_MEDIA_ROUNDUP((width+1)>>1, uv_tile_width); - uv_meta_stride = MSM_MEDIA_ALIGN(uv_meta_stride, 64); - -invalid_input: - return uv_meta_stride; + return MSM_MEDIA_ALIGN(uv_meta_stride, 64); } /* @@ -1075,10 +1046,10 @@ invalid_input: */ static unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height) { - int uv_tile_height = 0, uv_meta_scanlines = 0; + int uv_tile_height = 0, uv_meta_scanlines; if (!height) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_NV12_UBWC: @@ -1089,22 +1060,19 @@ static unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height) uv_tile_height = 4; break; default: - goto invalid_input; + return 0; } uv_meta_scanlines = MSM_MEDIA_ROUNDUP((height+1)>>1, uv_tile_height); - uv_meta_scanlines = MSM_MEDIA_ALIGN(uv_meta_scanlines, 16); - -invalid_input: - return uv_meta_scanlines; + return MSM_MEDIA_ALIGN(uv_meta_scanlines, 16); } static unsigned int VENUS_RGB_STRIDE(int color_fmt, int width) { - unsigned int alignment = 0, stride = 0, bpp = 4; + unsigned int alignment = 0, bpp = 4; if (!width) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_RGBA8888: @@ -1119,21 +1087,18 @@ static unsigned int VENUS_RGB_STRIDE(int color_fmt, int width) alignment = 256; break; default: - goto invalid_input; + return 0; } - stride = MSM_MEDIA_ALIGN(width * bpp, alignment); - -invalid_input: - return stride; + return MSM_MEDIA_ALIGN(width * bpp, alignment); } static unsigned int VENUS_RGB_SCANLINES(int color_fmt, int height) { - unsigned int alignment = 0, scanlines = 0; + unsigned int alignment = 0; if (!height) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_RGBA8888: @@ -1145,61 +1110,46 @@ static unsigned int VENUS_RGB_SCANLINES(int color_fmt, int height) alignment = 16; break; default: - goto invalid_input; + return 0; } - scanlines = MSM_MEDIA_ALIGN(height, alignment); - -invalid_input: - return scanlines; + return MSM_MEDIA_ALIGN(height, alignment); } static unsigned int VENUS_RGB_META_STRIDE(int color_fmt, int width) { - int rgb_tile_width = 0, rgb_meta_stride = 0; + int rgb_meta_stride; if (!width) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_RGBA8888_UBWC: case COLOR_FMT_RGBA1010102_UBWC: case COLOR_FMT_RGB565_UBWC: - rgb_tile_width = 16; - break; - default: - goto invalid_input; + rgb_meta_stride = MSM_MEDIA_ROUNDUP(width, 16); + return MSM_MEDIA_ALIGN(rgb_meta_stride, 64); } - rgb_meta_stride = MSM_MEDIA_ROUNDUP(width, rgb_tile_width); - rgb_meta_stride = MSM_MEDIA_ALIGN(rgb_meta_stride, 64); - -invalid_input: - return rgb_meta_stride; + return 0; } static unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height) { - int rgb_tile_height = 0, rgb_meta_scanlines = 0; + int rgb_meta_scanlines; if (!height) - goto invalid_input; + return 0; switch (color_fmt) { case COLOR_FMT_RGBA8888_UBWC: case COLOR_FMT_RGBA1010102_UBWC: case COLOR_FMT_RGB565_UBWC: - rgb_tile_height = 4; - break; - default: - goto invalid_input; + rgb_meta_scanlines = MSM_MEDIA_ROUNDUP(height, 4); + return MSM_MEDIA_ALIGN(rgb_meta_scanlines, 16); } - rgb_meta_scanlines = MSM_MEDIA_ROUNDUP(height, rgb_tile_height); - rgb_meta_scanlines = MSM_MEDIA_ALIGN(rgb_meta_scanlines, 16); - -invalid_input: - return rgb_meta_scanlines; + return 0; } #endif From ba0ede185ef4c74bfecfe1c992be5dbcc5c5ac04 Mon Sep 17 00:00:00 2001 From: Jayant Shekhar Date: Wed, 5 Dec 2018 21:51:47 +0530 Subject: [PATCH 91/91] drm/msm/dpu: Fix clock issue after bind failure In case of msm drm bind failure, pm runtime put sync is called from dsi driver which issues an asynchronous put on mdss device. Subsequently when dpu_mdss_destroy is triggered the change will make sure to put the mdss device in suspend and clearing pending work if not scheduled. Signed-off-by: Jayant Shekhar Signed-off-by: Sean Paul Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index 413e1ee43cf2..cb307a2abf06 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -160,6 +160,7 @@ static void dpu_mdss_destroy(struct drm_device *dev) struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss); struct dss_module_power *mp = &dpu_mdss->mp; + pm_runtime_suspend(dev->dev); pm_runtime_disable(dev->dev); _dpu_mdss_irq_domain_fini(dpu_mdss); free_irq(platform_get_irq(pdev, 0), dpu_mdss);