From a1cccdcf330e2a59b72b1588a7ef87cbaaa8a4e9 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 20 Sep 2018 12:27:04 +0200 Subject: drm/i915: Clean up casts to crtc_state in intel_atomic_commit_tail() Use old/new_intel_crtc_state, and get rid of all the conversion casts where they don't add anything. Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20180920102711.4184-2-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 376173eb733d..835203ed7eee 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12664,8 +12664,9 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct drm_i915_private *dev_priv = to_i915(dev); struct drm_crtc_state *old_crtc_state, *new_crtc_state; + struct intel_crtc_state *new_intel_crtc_state, *old_intel_crtc_state; struct drm_crtc *crtc; - struct intel_crtc_state *intel_cstate; + struct intel_crtc *intel_crtc; u64 put_domains[I915_MAX_PIPES] = {}; int i; @@ -12677,21 +12678,22 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + old_intel_crtc_state = to_intel_crtc_state(old_crtc_state); + new_intel_crtc_state = to_intel_crtc_state(new_crtc_state); + intel_crtc = to_intel_crtc(crtc); if (needs_modeset(new_crtc_state) || to_intel_crtc_state(new_crtc_state)->update_pipe) { - put_domains[to_intel_crtc(crtc)->pipe] = + put_domains[intel_crtc->pipe] = modeset_get_crtc_power_domains(crtc, - to_intel_crtc_state(new_crtc_state)); + new_intel_crtc_state); } if (!needs_modeset(new_crtc_state)) continue; - intel_pre_plane_update(to_intel_crtc_state(old_crtc_state), - to_intel_crtc_state(new_crtc_state)); + intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state); if (old_crtc_state->active) { intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask); @@ -12702,7 +12704,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) */ intel_crtc_disable_pipe_crc(intel_crtc); - dev_priv->display.crtc_disable(to_intel_crtc_state(old_crtc_state), state); + dev_priv->display.crtc_disable(old_intel_crtc_state, state); intel_crtc->active = false; intel_fbc_disable(intel_crtc); intel_disable_shared_dpll(intel_crtc); @@ -12723,7 +12725,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) */ if (INTEL_GEN(dev_priv) >= 9) dev_priv->display.initial_watermarks(intel_state, - to_intel_crtc_state(new_crtc_state)); + new_intel_crtc_state); } } } @@ -12783,11 +12785,11 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) * TODO: Move this (and other cleanup) to an async worker eventually. */ for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) { - intel_cstate = to_intel_crtc_state(new_crtc_state); + new_intel_crtc_state = to_intel_crtc_state(new_crtc_state); if (dev_priv->display.optimize_watermarks) dev_priv->display.optimize_watermarks(intel_state, - intel_cstate); + new_intel_crtc_state); } for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { -- cgit v1.2.3-59-g8ed1b From c249c5f64336ca7f8b314c16dbf440b091514f50 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 20 Sep 2018 12:27:05 +0200 Subject: drm/i915: Handle cursor updating active_planes correctly, v2. While we may not update new_crtc_state, we may clear active_planes if the new cursor update state will disable the cursor, but we fail after. If this is immediately followed by a modeset disable, we may soon not disable the planes correctly when we start depending on active_planes. Changes since v1: - Clarify why we cannot swap crtc_state. (Matt) Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20180920102711.4184-3-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 835203ed7eee..afeb7baa3b44 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13514,14 +13514,16 @@ intel_legacy_cursor_update(struct drm_plane *plane, struct drm_plane_state *old_plane_state, *new_plane_state; struct intel_plane *intel_plane = to_intel_plane(plane); struct drm_framebuffer *old_fb; - struct drm_crtc_state *crtc_state = crtc->state; + struct intel_crtc_state *crtc_state = + to_intel_crtc_state(crtc->state); + struct intel_crtc_state *new_crtc_state; /* * When crtc is inactive or there is a modeset pending, * wait for it to complete in the slowpath */ - if (!crtc_state->active || needs_modeset(crtc_state) || - to_intel_crtc_state(crtc_state)->update_pipe) + if (!crtc_state->base.active || needs_modeset(&crtc_state->base) || + crtc_state->update_pipe) goto slow; old_plane_state = plane->state; @@ -13551,6 +13553,12 @@ intel_legacy_cursor_update(struct drm_plane *plane, if (!new_plane_state) return -ENOMEM; + new_crtc_state = to_intel_crtc_state(intel_crtc_duplicate_state(crtc)); + if (!new_crtc_state) { + ret = -ENOMEM; + goto out_free; + } + drm_atomic_set_fb_for_plane(new_plane_state, fb); new_plane_state->src_x = src_x; @@ -13562,9 +13570,8 @@ intel_legacy_cursor_update(struct drm_plane *plane, new_plane_state->crtc_w = crtc_w; new_plane_state->crtc_h = crtc_h; - ret = intel_plane_atomic_check_with_state(to_intel_crtc_state(crtc->state), - to_intel_crtc_state(crtc->state), /* FIXME need a new crtc state? */ - to_intel_plane_state(plane->state), + ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state, + to_intel_plane_state(old_plane_state), to_intel_plane_state(new_plane_state)); if (ret) goto out_free; @@ -13586,10 +13593,21 @@ intel_legacy_cursor_update(struct drm_plane *plane, /* Swap plane state */ plane->state = new_plane_state; + /* + * We cannot swap crtc_state as it may be in use by an atomic commit or + * page flip that's running simultaneously. If we swap crtc_state and + * destroy the old state, we will cause a use-after-free there. + * + * Only update active_planes, which is needed for our internal + * bookkeeping. Either value will do the right thing when updating + * planes atomically. If the cursor was part of the atomic update then + * we would have taken the slowpath. + */ + crtc_state->active_planes = new_crtc_state->active_planes; + if (plane->state->visible) { trace_intel_update_plane(plane, to_intel_crtc(crtc)); - intel_plane->update_plane(intel_plane, - to_intel_crtc_state(crtc->state), + intel_plane->update_plane(intel_plane, crtc_state, to_intel_plane_state(plane->state)); } else { trace_intel_disable_plane(plane, to_intel_crtc(crtc)); @@ -13601,6 +13619,8 @@ intel_legacy_cursor_update(struct drm_plane *plane, out_unlock: mutex_unlock(&dev_priv->drm.struct_mutex); out_free: + if (new_crtc_state) + intel_crtc_destroy_state(crtc, &new_crtc_state->base); if (ret) intel_plane_destroy_state(plane, new_plane_state); else -- cgit v1.2.3-59-g8ed1b From 62ef0dd3cc0c217c3d58a1e92577c66c08598f7b Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 20 Sep 2018 12:27:06 +0200 Subject: drm/i915: Unconditionally clear plane visibility, v2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to assume the plane has been visible before, even if no CRTC is assigned to the plane. This is because when enabling a nv12 plane on gen11, we will have to enable an extra plane and make it visible by marking it in crtc_state->active_planes for intel_update_planes_on_crtc(). Additionally, clear visible flag in intel_plane_atomic_check, in case we ever hit a bug with visibility. Our code implicitly assumes that plane_state->visible is only true when crtc and fb are set, so we will either null deref in intel_fbc_choose_crtc() or do something bad during the actual commit which cares even more. Changes since v1: - Unconditionally clear crtc_state->active_planes as well. - Reword commit message, since this is now a preparation patch for NV12 Y / UV plane linking. Signed-off-by: Maarten Lankhorst [mlankhorst: Clear nv12_planes in the beginning as well, clarify commit message] Reviewed-by: Matt Roper Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180920102711.4184-4-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_atomic_plane.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index aabebe0d2e9b..59f6ab60904d 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -117,10 +117,14 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ struct intel_plane *intel_plane = to_intel_plane(plane); int ret; + crtc_state->active_planes &= ~BIT(intel_plane->id); + crtc_state->nv12_planes &= ~BIT(intel_plane->id); + intel_state->base.visible = false; + + /* If this is a cursor plane, no further checks are needed. */ if (!intel_state->base.crtc && !old_plane_state->base.crtc) return 0; - intel_state->base.visible = false; ret = intel_plane->check_plane(crtc_state, intel_state); if (ret) return ret; @@ -128,13 +132,9 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_ /* FIXME pre-g4x don't work like this */ if (state->visible) crtc_state->active_planes |= BIT(intel_plane->id); - else - crtc_state->active_planes &= ~BIT(intel_plane->id); if (state->visible && state->fb->format->format == DRM_FORMAT_NV12) crtc_state->nv12_planes |= BIT(intel_plane->id); - else - crtc_state->nv12_planes &= ~BIT(intel_plane->id); return intel_plane_atomic_calc_changes(old_crtc_state, &crtc_state->base, @@ -152,6 +152,7 @@ static int intel_plane_atomic_check(struct drm_plane *plane, const struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *new_crtc_state; + new_plane_state->visible = false; if (!crtc) return 0; -- cgit v1.2.3-59-g8ed1b From f59e9701dbdc275a3042e1357574e0e1779b3082 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 20 Sep 2018 12:27:07 +0200 Subject: drm/i915: Make intel_crtc_disable_planes() use active planes mask. This will only disable planes we actually had marked as visible in crtc_state->visible_planes and cleans up intel_crtc_disable_plane() slightly. This is also useful for when we start enabling NV12 support for gen11, in which we will make the separate Y plane visible, but ignore the Y plane's state. Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20180920102711.4184-5-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index afeb7baa3b44..c0e431c59c4f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5401,24 +5401,23 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state, intel_update_watermarks(crtc); } -static void intel_crtc_disable_planes(struct drm_crtc *crtc, unsigned plane_mask) +static void intel_crtc_disable_planes(struct intel_crtc *crtc, unsigned plane_mask) { - struct drm_device *dev = crtc->dev; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_plane *p; - int pipe = intel_crtc->pipe; + struct drm_device *dev = crtc->base.dev; + struct intel_plane *plane; + unsigned fb_bits = 0; - intel_crtc_dpms_overlay_disable(intel_crtc); + intel_crtc_dpms_overlay_disable(crtc); - drm_for_each_plane_mask(p, dev, plane_mask) - to_intel_plane(p)->disable_plane(to_intel_plane(p), intel_crtc); + for_each_intel_plane_on_crtc(dev, crtc, plane) { + if (plane_mask & BIT(plane->id)) { + plane->disable_plane(plane, crtc); - /* - * FIXME: Once we grow proper nuclear flip support out of this we need - * to compute the mask of flip planes precisely. For the time being - * consider this a flip to a NULL plane. - */ - intel_frontbuffer_flip(to_i915(dev), INTEL_FRONTBUFFER_ALL_MASK(pipe)); + fb_bits |= plane->frontbuffer_bit; + } + } + + intel_frontbuffer_flip(to_i915(dev), fb_bits); } static void intel_encoders_pre_pll_enable(struct drm_crtc *crtc, @@ -12696,7 +12695,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) intel_pre_plane_update(old_intel_crtc_state, new_intel_crtc_state); if (old_crtc_state->active) { - intel_crtc_disable_planes(crtc, old_crtc_state->plane_mask); + intel_crtc_disable_planes(intel_crtc, old_intel_crtc_state->active_planes); /* * We need to disable pipe CRC before disabling the pipe, -- cgit v1.2.3-59-g8ed1b From 6c246b81f9380855b13433d1d8fbd67ff7f67583 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 20 Sep 2018 12:27:08 +0200 Subject: drm/i915: Replace call to commit_planes_on_crtc with internal update, v2. drm_atomic_helper_commit_planes_on_crtc calls begin_commit, then plane_update hooks, then flush_commit. Because we keep our own visibility tracking through plane_state->visible there's no need to rely on the atomic hooks for this. By explicitly writing our own helper, we can update visible planes as needed, which is useful to make NV12 support work as intended. Changes since v1: - Reword commit message. (Matt Roper) - Rename to intel_update_planes_on_crtc(). (Matt) Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20180920102711.4184-6-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_atomic_plane.c | 41 +++++++++++++++++-------------- drivers/gpu/drm/i915/intel_display.c | 10 +++++--- drivers/gpu/drm/i915/intel_drv.h | 4 +++ 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index 59f6ab60904d..984bc1f26625 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -165,29 +165,33 @@ static int intel_plane_atomic_check(struct drm_plane *plane, to_intel_plane_state(new_plane_state)); } -static void intel_plane_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) +void intel_update_planes_on_crtc(struct intel_atomic_state *old_state, + struct intel_crtc *crtc, + struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *new_crtc_state) { - struct intel_atomic_state *state = to_intel_atomic_state(old_state->state); - struct intel_plane *intel_plane = to_intel_plane(plane); - const struct intel_plane_state *new_plane_state = - intel_atomic_get_new_plane_state(state, intel_plane); - struct drm_crtc *crtc = new_plane_state->base.crtc ?: old_state->crtc; + struct intel_plane_state *new_plane_state; + struct intel_plane *plane; + u32 update_mask; + int i; + + update_mask = old_crtc_state->active_planes; + update_mask |= new_crtc_state->active_planes; - if (new_plane_state->base.visible) { - const struct intel_crtc_state *new_crtc_state = - intel_atomic_get_new_crtc_state(state, to_intel_crtc(crtc)); + for_each_new_intel_plane_in_state(old_state, plane, new_plane_state, i) { + if (crtc->pipe != plane->pipe || + !(update_mask & BIT(plane->id))) + continue; - trace_intel_update_plane(plane, - to_intel_crtc(crtc)); + if (new_plane_state->base.visible) { + trace_intel_update_plane(&plane->base, crtc); - intel_plane->update_plane(intel_plane, - new_crtc_state, new_plane_state); - } else { - trace_intel_disable_plane(plane, - to_intel_crtc(crtc)); + plane->update_plane(plane, new_crtc_state, new_plane_state); + } else { + trace_intel_disable_plane(&plane->base, crtc); - intel_plane->disable_plane(intel_plane, to_intel_crtc(crtc)); + plane->disable_plane(plane, crtc); + } } } @@ -195,7 +199,6 @@ const struct drm_plane_helper_funcs intel_plane_helper_funcs = { .prepare_fb = intel_prepare_plane_fb, .cleanup_fb = intel_cleanup_plane_fb, .atomic_check = intel_plane_atomic_check, - .atomic_update = intel_plane_atomic_update, }; /** diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c0e431c59c4f..ac1e0db4cb16 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10812,8 +10812,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, } static const struct drm_crtc_helper_funcs intel_helper_funcs = { - .atomic_begin = intel_begin_crtc_commit, - .atomic_flush = intel_finish_crtc_commit, .atomic_check = intel_crtc_atomic_check, }; @@ -12482,6 +12480,7 @@ static void intel_update_crtc(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_crtc_state *old_intel_cstate = to_intel_crtc_state(old_crtc_state); struct intel_crtc_state *pipe_config = to_intel_crtc_state(new_crtc_state); bool modeset = needs_modeset(new_crtc_state); struct intel_plane_state *new_plane_state = @@ -12502,7 +12501,12 @@ static void intel_update_crtc(struct drm_crtc *crtc, if (new_plane_state) intel_fbc_enable(intel_crtc, pipe_config, new_plane_state); - drm_atomic_helper_commit_planes_on_crtc(old_crtc_state); + intel_begin_crtc_commit(crtc, old_crtc_state); + + intel_update_planes_on_crtc(to_intel_atomic_state(state), intel_crtc, + old_intel_cstate, pipe_config); + + intel_finish_crtc_commit(crtc, old_crtc_state); } static void intel_update_crtcs(struct drm_atomic_state *state) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 521d6aaa2d44..07707728e4b6 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2186,6 +2186,10 @@ struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane); void intel_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; +void intel_update_planes_on_crtc(struct intel_atomic_state *old_state, + struct intel_crtc *crtc, + struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *new_crtc_state); int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state, struct intel_crtc_state *crtc_state, const struct intel_plane_state *old_plane_state, -- cgit v1.2.3-59-g8ed1b From 0aaf29b35f93f68128f92ea826ebfee8df9ab1ef Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 21 Sep 2018 16:44:37 +0200 Subject: drm/i915: Clean up scaler setup, v2. On skylake we can switch to a high quality scaler mode when only 1 out of 2 scalers are used, but on GLK and later bit 28 has a different meaning. Don't set it, and make clear the distinction between SKL and later PS values. Changes since v1: - Add missing break statement. Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper [mlankhorst: Remove extra newline] Link: https://patchwork.freedesktop.org/patch/msgid/20180921144437.20037-1-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/i915_reg.h | 7 ++- drivers/gpu/drm/i915/intel_atomic.c | 108 ++++++++++++++++++++--------------- drivers/gpu/drm/i915/intel_display.c | 2 +- 3 files changed, 66 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 4948b352bf4c..e7e6ca7f9665 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6850,11 +6850,12 @@ enum { #define _PS_2B_CTRL 0x68A80 #define _PS_1C_CTRL 0x69180 #define PS_SCALER_EN (1 << 31) -#define PS_SCALER_MODE_MASK (3 << 28) -#define PS_SCALER_MODE_DYN (0 << 28) -#define PS_SCALER_MODE_HQ (1 << 28) +#define SKL_PS_SCALER_MODE_MASK (3 << 28) +#define SKL_PS_SCALER_MODE_DYN (0 << 28) +#define SKL_PS_SCALER_MODE_HQ (1 << 28) #define SKL_PS_SCALER_MODE_NV12 (2 << 28) #define PS_SCALER_MODE_PLANAR (1 << 29) +#define PS_SCALER_MODE_PACKED (0 << 29) #define PS_PLANE_SEL_MASK (7 << 25) #define PS_PLANE_SEL(plane) (((plane) + 1) << 25) #define PS_FILTER_MASK (3 << 23) diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c index b04952bacf77..760758ad21c1 100644 --- a/drivers/gpu/drm/i915/intel_atomic.c +++ b/drivers/gpu/drm/i915/intel_atomic.c @@ -203,6 +203,62 @@ intel_crtc_destroy_state(struct drm_crtc *crtc, drm_atomic_helper_crtc_destroy_state(crtc, state); } +static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state, + int num_scalers_need, struct intel_crtc *intel_crtc, + const char *name, int idx, + struct intel_plane_state *plane_state, + int *scaler_id) +{ + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); + int j; + u32 mode; + + if (*scaler_id < 0) { + /* find a free scaler */ + for (j = 0; j < intel_crtc->num_scalers; j++) { + if (scaler_state->scalers[j].in_use) + continue; + + *scaler_id = j; + scaler_state->scalers[*scaler_id].in_use = 1; + break; + } + } + + if (WARN(*scaler_id < 0, "Cannot find scaler for %s:%d\n", name, idx)) + return; + + /* set scaler mode */ + if (plane_state && plane_state->base.fb && + plane_state->base.fb->format->is_yuv && + plane_state->base.fb->format->num_planes > 1) { + if (INTEL_GEN(dev_priv) == 9 && + !IS_GEMINILAKE(dev_priv)) + mode = SKL_PS_SCALER_MODE_NV12; + else + mode = PS_SCALER_MODE_PLANAR; + + } else if (INTEL_GEN(dev_priv) > 9 || IS_GEMINILAKE(dev_priv)) { + mode = PS_SCALER_MODE_PACKED; + } else if (num_scalers_need == 1 && intel_crtc->num_scalers > 1) { + /* + * when only 1 scaler is in use on a pipe with 2 scalers + * scaler 0 operates in high quality (HQ) mode. + * In this case use scaler 0 to take advantage of HQ mode + */ + scaler_state->scalers[*scaler_id].in_use = 0; + *scaler_id = 0; + scaler_state->scalers[0].in_use = 1; + mode = SKL_PS_SCALER_MODE_HQ; + } else { + mode = SKL_PS_SCALER_MODE_DYN; + } + + DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n", + intel_crtc->pipe, *scaler_id, name, idx); + scaler_state->scalers[*scaler_id].mode = mode; +} + /** * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests * @dev_priv: i915 device @@ -232,7 +288,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, struct drm_atomic_state *drm_state = crtc_state->base.state; struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state); int num_scalers_need; - int i, j; + int i; num_scalers_need = hweight32(scaler_state->scaler_users); @@ -304,59 +360,17 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv, idx = plane->base.id; /* plane on different crtc cannot be a scaler user of this crtc */ - if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) { + if (WARN_ON(intel_plane->pipe != intel_crtc->pipe)) continue; - } plane_state = intel_atomic_get_new_plane_state(intel_state, intel_plane); scaler_id = &plane_state->scaler_id; } - if (*scaler_id < 0) { - /* find a free scaler */ - for (j = 0; j < intel_crtc->num_scalers; j++) { - if (!scaler_state->scalers[j].in_use) { - scaler_state->scalers[j].in_use = 1; - *scaler_id = j; - DRM_DEBUG_KMS("Attached scaler id %u.%u to %s:%d\n", - intel_crtc->pipe, *scaler_id, name, idx); - break; - } - } - } - - if (WARN_ON(*scaler_id < 0)) { - DRM_DEBUG_KMS("Cannot find scaler for %s:%d\n", name, idx); - continue; - } - - /* set scaler mode */ - if ((INTEL_GEN(dev_priv) >= 9) && - plane_state && plane_state->base.fb && - plane_state->base.fb->format->format == - DRM_FORMAT_NV12) { - if (INTEL_GEN(dev_priv) == 9 && - !IS_GEMINILAKE(dev_priv) && - !IS_SKYLAKE(dev_priv)) - scaler_state->scalers[*scaler_id].mode = - SKL_PS_SCALER_MODE_NV12; - else - scaler_state->scalers[*scaler_id].mode = - PS_SCALER_MODE_PLANAR; - } else if (num_scalers_need == 1 && intel_crtc->pipe != PIPE_C) { - /* - * when only 1 scaler is in use on either pipe A or B, - * scaler 0 operates in high quality (HQ) mode. - * In this case use scaler 0 to take advantage of HQ mode - */ - *scaler_id = 0; - scaler_state->scalers[0].in_use = 1; - scaler_state->scalers[0].mode = PS_SCALER_MODE_HQ; - scaler_state->scalers[1].in_use = 0; - } else { - scaler_state->scalers[*scaler_id].mode = PS_SCALER_MODE_DYN; - } + intel_atomic_setup_scaler(scaler_state, num_scalers_need, + intel_crtc, name, idx, + plane_state, scaler_id); } return 0; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ac1e0db4cb16..d3c679ee3fbf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13962,7 +13962,7 @@ static void intel_crtc_init_scalers(struct intel_crtc *crtc, struct intel_scaler *scaler = &scaler_state->scalers[i]; scaler->in_use = 0; - scaler->mode = PS_SCALER_MODE_DYN; + scaler->mode = 0; } scaler_state->scaler_id = -1; -- cgit v1.2.3-59-g8ed1b From ab5c60bf76755d24ae8de5c1c6ac594934656ace Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 20 Sep 2018 12:27:10 +0200 Subject: drm/i915: Move programming plane scaler to its own function. This cleans the code up slightly, and will make other changes easier. Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20180920102711.4184-8-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_sprite.c | 90 +++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index d4c8e10fc90b..7d3c7469d271 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -280,13 +280,63 @@ skl_plane_max_stride(struct intel_plane *plane, return min(8192 * cpp, 32768); } +static void +skl_program_scaler(struct drm_i915_private *dev_priv, + struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) +{ + enum plane_id plane_id = plane->id; + enum pipe pipe = plane->pipe; + int scaler_id = plane_state->scaler_id; + const struct intel_scaler *scaler = + &crtc_state->scaler_state.scalers[scaler_id]; + int crtc_x = plane_state->base.dst.x1; + int crtc_y = plane_state->base.dst.y1; + uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); + uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); + u16 y_hphase, uv_rgb_hphase; + u16 y_vphase, uv_rgb_vphase; + + /* Sizes are 0 based */ + crtc_w--; + crtc_h--; + + /* TODO: handle sub-pixel coordinates */ + if (plane_state->base.fb->format->format == DRM_FORMAT_NV12) { + y_hphase = skl_scaler_calc_phase(1, false); + y_vphase = skl_scaler_calc_phase(1, false); + + /* MPEG2 chroma siting convention */ + uv_rgb_hphase = skl_scaler_calc_phase(2, true); + uv_rgb_vphase = skl_scaler_calc_phase(2, false); + } else { + /* not used */ + y_hphase = 0; + y_vphase = 0; + + uv_rgb_hphase = skl_scaler_calc_phase(1, false); + uv_rgb_vphase = skl_scaler_calc_phase(1, false); + } + + I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), + PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode); + I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0); + I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id), + PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); + I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id), + PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); + I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); + I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), + ((crtc_w + 1) << 16)|(crtc_h + 1)); +} + void skl_update_plane(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { struct drm_i915_private *dev_priv = to_i915(plane->base.dev); - const struct drm_framebuffer *fb = plane_state->base.fb; enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; u32 plane_ctl = plane_state->ctl; @@ -296,8 +346,6 @@ skl_update_plane(struct intel_plane *plane, u32 aux_stride = skl_plane_stride(plane_state, 1); int crtc_x = plane_state->base.dst.x1; int crtc_y = plane_state->base.dst.y1; - uint32_t crtc_w = drm_rect_width(&plane_state->base.dst); - uint32_t crtc_h = drm_rect_height(&plane_state->base.dst); uint32_t x = plane_state->color_plane[0].x; uint32_t y = plane_state->color_plane[0].y; uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16; @@ -307,8 +355,6 @@ skl_update_plane(struct intel_plane *plane, /* Sizes are 0 based */ src_w--; src_h--; - crtc_w--; - crtc_h--; spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); @@ -333,39 +379,7 @@ skl_update_plane(struct intel_plane *plane, /* program plane scaler */ if (plane_state->scaler_id >= 0) { - int scaler_id = plane_state->scaler_id; - const struct intel_scaler *scaler = - &crtc_state->scaler_state.scalers[scaler_id]; - u16 y_hphase, uv_rgb_hphase; - u16 y_vphase, uv_rgb_vphase; - - /* TODO: handle sub-pixel coordinates */ - if (fb->format->format == DRM_FORMAT_NV12) { - y_hphase = skl_scaler_calc_phase(1, false); - y_vphase = skl_scaler_calc_phase(1, false); - - /* MPEG2 chroma siting convention */ - uv_rgb_hphase = skl_scaler_calc_phase(2, true); - uv_rgb_vphase = skl_scaler_calc_phase(2, false); - } else { - /* not used */ - y_hphase = 0; - y_vphase = 0; - - uv_rgb_hphase = skl_scaler_calc_phase(1, false); - uv_rgb_vphase = skl_scaler_calc_phase(1, false); - } - - I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id), - PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode); - I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0); - I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id), - PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); - I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id), - PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase)); - I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); - I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), - ((crtc_w + 1) << 16)|(crtc_h + 1)); + skl_program_scaler(dev_priv, plane, crtc_state, plane_state); I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0); } else { -- cgit v1.2.3-59-g8ed1b From 945ac78928faab3de7919f0f3135240db5c514c7 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 20 Sep 2018 12:27:11 +0200 Subject: drm/i915: Force planar YUV coordinates to be a multiple of 2, v2. We can't make NV12 work any other way. The scaler doesn't handle odd coordinates well, and we will get visual corruption on the screen. Changes since v1: - Put the check in intel_plane_check_src_coordinates. (Ville) Signed-off-by: Maarten Lankhorst Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20180920102711.4184-9-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/i915/intel_sprite.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 7d3c7469d271..46c6336cb858 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -253,13 +253,20 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) src->y2 = (src_y + src_h) << 16; if (fb->format->is_yuv && - fb->format->format != DRM_FORMAT_NV12 && (src_x & 1 || src_w & 1)) { DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n", src_x, src_w); return -EINVAL; } + if (fb->format->is_yuv && + fb->format->num_planes > 1 && + (src_y & 1 || src_h & 1)) { + DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of 2 for planar YUV planes\n", + src_y, src_h); + return -EINVAL; + } + return 0; } -- cgit v1.2.3-59-g8ed1b From fc41001d97083fba638b9bbbf84c72db735c1680 Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Sun, 16 Sep 2018 16:23:24 +0530 Subject: drm/i915/icl: Configure lane sequencing of combo phy transmitter This patch set the loadgen select and latency optimization for aux and transmit lanes of combo phy transmitters. It will be used for MIPI DSI HS operations. v2: Rebase v3: Add empty line to make code more legible (Ville). Signed-off-by: Madhav Chauhan Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1537095223-5184-2-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 13830e43a4d1..1607cacccdb1 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -105,10 +105,49 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder) } } +static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; + u32 tmp; + int lane; + + /* Step 4b(i) set loadgen select for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp &= ~LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + for (lane = 0; lane <= 3; lane++) { + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp &= ~LOADGEN_SELECT; + if (lane != 2) + tmp |= LOADGEN_SELECT; + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } + + /* Step 4b(ii) set latency optimization for transmit and aux lanes */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp &= ~FRC_LATENCY_OPTIM_MASK; + tmp |= FRC_LATENCY_OPTIM_VAL(0x5); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + } + +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ gen11_dsi_power_up_lanes(encoder); + + /* step 4b: configure lane sequencing of the Combo-PHY transmitters */ + gen11_dsi_config_phy_lanes_sequence(encoder); } static void __attribute__((unused)) -- cgit v1.2.3-59-g8ed1b From 3f4b9d9d02c6239f5d0eae6f59af5252ef8beefd Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Sun, 16 Sep 2018 16:23:25 +0530 Subject: drm/i915/icl: DSI vswing programming sequence This patch setup voltage swing before enabling combo PHY DDI (shared with DSI). Note that DSI voltage swing programming is for high speed data buffers. HW automatically handles the voltage swing for the low power data buffers. v2: Rebase v3: Address various review comments related to VSWING programming (Jani N) Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1537095223-5184-3-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 120 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 1607cacccdb1..e5c18a8e6458 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -27,6 +27,71 @@ #include "intel_dsi.h" +static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + enum port port; + u32 tmp; + int lane; + + for_each_dsi_port(port, intel_dsi->ports) { + + /* + * Program voltage swing and pre-emphasis level values as per + * table in BSPEC under DDI buffer programing + */ + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK); + tmp |= SCALING_MODE_SEL(0x2); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + tmp |= RTERM_SELECT(0x6); + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK); + tmp |= SCALING_MODE_SEL(0x2); + tmp |= TAP2_DISABLE | TAP3_DISABLE; + tmp |= RTERM_SELECT(0x6); + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port)); + tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK | + RCOMP_SCALAR_MASK); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port)); + tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK | + RCOMP_SCALAR_MASK); + tmp |= SWING_SEL_UPPER(0x2); + tmp |= SWING_SEL_LOWER(0x2); + tmp |= RCOMP_SCALAR(0x98); + I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp); + + tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port)); + tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | + CURSOR_COEFF_MASK); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x3f); + I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp); + + for (lane = 0; lane <= 3; lane++) { + /* Bspec: must not use GRP register for write */ + tmp = I915_READ(ICL_PORT_TX_DW4_LN(port, lane)); + tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | + CURSOR_COEFF_MASK); + tmp |= POST_CURSOR_1(0x0); + tmp |= POST_CURSOR_2(0x0); + tmp |= CURSOR_COEFF(0x3f); + I915_WRITE(ICL_PORT_TX_DW4_LN(port, lane), tmp); + } + } +} + static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); @@ -141,6 +206,58 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder) } +static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + u32 tmp; + enum port port; + + /* clear common keeper enable bit */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(port)); + tmp &= ~COMMON_KEEPER_EN; + I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(port)); + tmp &= ~COMMON_KEEPER_EN; + I915_WRITE(ICL_PORT_PCS_DW1_AUX(port), tmp); + } + + /* + * Set SUS Clock Config bitfield to 11b + * Note: loadgen select program is done + * as part of lane phy sequence configuration + */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_CL_DW5(port)); + tmp |= SUS_CLOCK_CONFIG; + I915_WRITE(ICL_PORT_CL_DW5(port), tmp); + } + + /* Clear training enable to change swing values */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp &= ~TX_TRAINING_EN; + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp &= ~TX_TRAINING_EN; + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + } + + /* Program swing and de-emphasis */ + dsi_program_swing_and_deemphasis(encoder); + + /* Set training enable to trigger update */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port)); + tmp |= TX_TRAINING_EN; + I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp); + tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port)); + tmp |= TX_TRAINING_EN; + I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -148,6 +265,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) /* step 4b: configure lane sequencing of the Combo-PHY transmitters */ gen11_dsi_config_phy_lanes_sequence(encoder); + + /* step 4c: configure voltage swing and skew */ + gen11_dsi_voltage_swing_program_seq(encoder); } static void __attribute__((unused)) -- cgit v1.2.3-59-g8ed1b From ba3df888be909a8850e695a3d9631cfb49afede2 Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Sun, 16 Sep 2018 16:23:26 +0530 Subject: drm/i915/icl: Enable DDI Buffer This patch enables DDI buffer by writing to DDI_BUF_CTL register and wait for DDI status to be *not idle* for a port. v2: Rebase v3: Remove step hard coding comments (Jani N) Signed-off-by: Madhav Chauhan Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1537095223-5184-4-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index e5c18a8e6458..190316c4c4c2 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -258,6 +258,25 @@ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder) } } +static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + u32 tmp; + enum port port; + + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(DDI_BUF_CTL(port)); + tmp |= DDI_BUF_CTL_ENABLE; + I915_WRITE(DDI_BUF_CTL(port), tmp); + + if (wait_for_us(!(I915_READ(DDI_BUF_CTL(port)) & + DDI_BUF_IS_IDLE), + 500)) + DRM_ERROR("DDI port:%c buffer idle\n", port_name(port)); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -268,6 +287,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) /* step 4c: configure voltage swing and skew */ gen11_dsi_voltage_swing_program_seq(encoder); + + /* enable DDI buffer */ + gen11_dsi_enable_ddi_buffer(encoder); } static void __attribute__((unused)) -- cgit v1.2.3-59-g8ed1b From 70a7b83628fa3f6599bd1a7c500f6a8fcdb81ab0 Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Sun, 16 Sep 2018 16:23:27 +0530 Subject: drm/i915/icl: Program T_INIT_MASTER registers This patch programs the time (in escape clocks) to drive the link in the initialization (i.e. LP-11) state. v2: Rebase v3: Remove step hard coding comments (Jani N) Signed-off-by: Madhav Chauhan Reviewed-by: Jani Nikula Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1537095223-5184-5-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/icl_dsi.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c index 190316c4c4c2..ff5b285ca495 100644 --- a/drivers/gpu/drm/i915/icl_dsi.c +++ b/drivers/gpu/drm/i915/icl_dsi.c @@ -277,6 +277,22 @@ static void gen11_dsi_enable_ddi_buffer(struct intel_encoder *encoder) } } +static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + u32 tmp; + enum port port; + + /* Program T-INIT master registers */ + for_each_dsi_port(port, intel_dsi->ports) { + tmp = I915_READ(ICL_DSI_T_INIT_MASTER(port)); + tmp &= ~MASTER_INIT_TIMER_MASK; + tmp |= intel_dsi->init_count; + I915_WRITE(ICL_DSI_T_INIT_MASTER(port), tmp); + } +} + static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) { /* step 4a: power up all lanes of the DDI used by DSI */ @@ -290,6 +306,9 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder) /* enable DDI buffer */ gen11_dsi_enable_ddi_buffer(encoder); + + /* setup D-PHY timings */ + gen11_dsi_setup_dphy_timings(encoder); } static void __attribute__((unused)) -- cgit v1.2.3-59-g8ed1b From 8db05f5947132bc69c8ad3fe65753400888aa483 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 19 Sep 2018 20:55:16 +0100 Subject: drm/i915/execlists: Assert the queue is non-empty on unsubmitting In the sequence <0>[ 531.960431] drv_self-4806 7.... 527402570us : intel_gpu_reset: engine_mask=1, ret=0, retry=0 <0>[ 531.960431] drv_self-4806 7.... 527402571us : execlists_reset: rcs0 request global=115de, current=71133 <0>[ 531.960431] drv_self-4806 7d..1 527402571us : execlists_cancel_port_requests: rcs0:port0 global=71134 (fence 826b:198), (current 71133) <0>[ 531.960431] drv_self-4806 7d..1 527402572us : execlists_cancel_port_requests: rcs0:port1 global=71135 (fence 826c:53), (current 71133) <0>[ 531.960431] drv_self-4806 7d..1 527402572us : __i915_request_unsubmit: rcs0 fence 826c:53 <- global=71135, current 71133 <0>[ 531.960431] drv_self-4806 7d..1 527402579us : __i915_request_unsubmit: rcs0 fence 826b:198 <- global=71134, current 71133 <0>[ 531.960431] drv_self-4806 7.... 527402613us : intel_engine_cancel_stop_cs: rcs0 <0>[ 531.960431] drv_self-4806 7.... 527402624us : execlists_reset_finish: rcs0 we are missing the execlists_submission_tasklet() invocation before the execlists_reset_fini() implying that either the queue is empty, or we failed to schedule and run the tasklet on finish. Add an assert so we are sure that on unsubmitting the incomplete request after reset, the queue is indeed populated. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20180919195544.1511-12-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/intel_lrc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 43957bb37a42..5b58c10bc600 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -344,6 +344,7 @@ static void __unwind_incomplete_requests(struct intel_engine_cs *engine) last_prio = rq_prio(rq); p = lookup_priolist(engine, last_prio); } + GEM_BUG_ON(RB_EMPTY_ROOT(&engine->execlists.queue.rb_root)); GEM_BUG_ON(p->priority != rq_prio(rq)); list_add(&rq->sched.link, &p->requests); -- cgit v1.2.3-59-g8ed1b From 570b16b559beca0f6a01dfb8944d5abadc1cfb31 Mon Sep 17 00:00:00 2001 From: Mahesh Kumar Date: Wed, 19 Sep 2018 14:01:26 +0530 Subject: drm/i915: use for_each_pipe loop to assign crtc_mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This cleanup patch makes changes to use for_each_pipe loop during bit-mask assignment of allowed crtc with encoder. changes: - use BIT(i) macro instead of (1 << i) (Chris) changes from V2: - use int for consistency (Jani) changes from V3: - instead use enum pipe (Ville) changes from V4: - drop DP/HDMI changes, as already part of patch from ville Cc: Jani Nikula Cc: Rodrigo Vivi Signed-off-by: Mahesh Kumar Reviewed-by: Ville Syrjälä Reviewed-by: Lucas De Marchi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20180919083126.31805-1-mahesh1.kumar@intel.com --- drivers/gpu/drm/i915/intel_ddi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b6910c8b4e08..7f34d3955ca1 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -3751,6 +3751,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) struct intel_encoder *intel_encoder; struct drm_encoder *encoder; bool init_hdmi, init_dp, init_lspcon = false; + enum pipe pipe; init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi || @@ -3801,8 +3802,9 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) intel_encoder->type = INTEL_OUTPUT_DDI; intel_encoder->power_domain = intel_port_to_power_domain(port); intel_encoder->port = port; - intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); intel_encoder->cloneable = 0; + for_each_pipe(dev_priv, pipe) + intel_encoder->crtc_mask |= BIT(pipe); if (INTEL_GEN(dev_priv) >= 11) intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & -- cgit v1.2.3-59-g8ed1b From 4a3d3f6785bed372daaa4c57d9d90cad01da9d8e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 22 Sep 2018 15:18:03 +0100 Subject: drm/i915: Match code to comment and enforce ppgtt for execlists Our execlist dispatch code requires a ppGTT so make sure we enforce that option in intel_sanitize_enable_ppgtt(). The comment already tries to explain that execlists requires ppgtt, but was written when gen8 may have also taken the legacy path; so rewrite the code to match the comment by using HAS_EXECLISTS() feature instead of the gen. Signed-off-by: Chris Wilson Cc: Matthew Auld Reviewed-by: Joonas Lahtinen Link: https://patchwork.freedesktop.org/patch/msgid/20180922141804.21183-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_gem_gtt.c | 4 ++-- drivers/gpu/drm/i915/intel_lrc.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 56c7f8637311..f6c7ab413081 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -152,10 +152,10 @@ int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, } /* - * We don't allow disabling PPGTT for gen9+ as it's a requirement for + * We don't allow disabling PPGTT for gen8+ as it's a requirement for * execlists, the sole mechanism available to submit work. */ - if (enable_ppgtt == 0 && INTEL_GEN(dev_priv) < 9) + if (enable_ppgtt == 0 && !HAS_EXECLISTS(dev_priv)) return 0; if (enable_ppgtt == 1) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5b58c10bc600..4b28225320ff 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -430,7 +430,7 @@ static u64 execlists_update_context(struct i915_request *rq) * PML4 is allocated during ppgtt init, so this is not needed * in 48-bit mode. */ - if (ppgtt && !i915_vm_is_48bit(&ppgtt->vm)) + if (!i915_vm_is_48bit(&ppgtt->vm)) execlists_update_context_pdps(ppgtt, reg_state); return ce->lrc_desc; @@ -1376,6 +1376,7 @@ execlists_context_pin(struct intel_engine_cs *engine, struct intel_context *ce = to_intel_context(ctx, engine); lockdep_assert_held(&ctx->i915->drm.struct_mutex); + GEM_BUG_ON(!(ctx->ppgtt ?: ctx->i915->mm.aliasing_ppgtt)); if (likely(ce->pin_count++)) return ce; @@ -2705,7 +2706,7 @@ static void execlists_init_reg_state(u32 *regs, CTX_REG(regs, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(engine, 0), 0); CTX_REG(regs, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(engine, 0), 0); - if (ppgtt && i915_vm_is_48bit(&ppgtt->vm)) { + if (i915_vm_is_48bit(&ppgtt->vm)) { /* 64b PPGTT (48bit canonical) * PDP0_DESCRIPTOR contains the base address to PML4 and * other PDP Descriptors are ignored. -- cgit v1.2.3-59-g8ed1b From 0a3c561da12b9ac64c5b77dde3f9db0be515c167 Mon Sep 17 00:00:00 2001 From: Juha-Pekka Heikkila Date: Mon, 27 Aug 2018 15:37:53 +0300 Subject: drm/i915: Enable RGB565 90/270 plane rotation for gen11 onwards. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From gen11 onwards RGB565 90/270 plane rotation is supported on hardware. IGT: https://patchwork.freedesktop.org/series/48756/ Signed-off-by: Juha-Pekka Heikkila Reviewed-by: Ville Syrjälä [mlankhorst: Rebase on top of current dinq (self), fix grammar (Ville).] Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/1535373473-3594-3-git-send-email-juhapekka.heikkila@gmail.com --- drivers/gpu/drm/i915/intel_sprite.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 46c6336cb858..96de5a33dbaf 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1203,6 +1203,8 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state, static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); const struct drm_framebuffer *fb = plane_state->base.fb; unsigned int rotation = plane_state->base.rotation; struct drm_format_name_buf format_name; @@ -1231,13 +1233,17 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state, } /* - * 90/270 is not allowed with RGB64 16:16:16:16, - * RGB 16-bit 5:6:5, and Indexed 8-bit. - * TBD: Add RGB64 case once its added in supported format list. + * 90/270 is not allowed with RGB64 16:16:16:16 and + * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards. + * TBD: Add RGB64 case once its added in supported format + * list. */ switch (fb->format->format) { - case DRM_FORMAT_C8: case DRM_FORMAT_RGB565: + if (INTEL_GEN(dev_priv) >= 11) + break; + /* fall through */ + case DRM_FORMAT_C8: DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n", drm_get_format_name(fb->format->format, &format_name)); -- cgit v1.2.3-59-g8ed1b From fc3fed5d297b51f9e2c7d4f969c95c0d6e50ca57 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 18 Sep 2018 17:02:43 +0300 Subject: drm/i915: Check fb stride against plane max stride MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 4e0b83a567e2 ("drm/i915: Extract per-platform plane->check() functions") removed the plane max stride check for sprite planes. I was going to add it back when introducing GTT remapping for the display, but after further thought it seems better to re-introduce it separately. So let's add the max stride check back. And let's do it in a nicer form than what we had before and do it for all plane types (easy now that we have the ->max_stride() plane vfunc). Only sprite planes really need this for now since primary planes are capable of scanning out the current max fb size we allow, and cursors have more stringent stride checks elsewhere. Cc: José Roberto de Souza Fixes: 4e0b83a567e2 ("drm/i915: Extract per-platform plane->check() functions") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180918140243.12207-1-ville.syrjala@linux.intel.com Reviewed-by: Dhinakaran Pandiyan --- drivers/gpu/drm/i915/intel_display.c | 14 ++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_sprite.c | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d3c679ee3fbf..5e7b907e54d6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3150,6 +3150,10 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state) plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation); plane_state->color_plane[1].stride = intel_fb_pitch(fb, 1, rotation); + ret = intel_plane_check_stride(plane_state); + if (ret) + return ret; + if (!plane_state->base.visible) return 0; @@ -3285,10 +3289,15 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) int src_x = plane_state->base.src.x1 >> 16; int src_y = plane_state->base.src.y1 >> 16; u32 offset; + int ret; intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation); plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation); + ret = intel_plane_check_stride(plane_state); + if (ret) + return ret; + intel_add_fb_offsets(&src_x, &src_y, plane_state, 0); if (INTEL_GEN(dev_priv) >= 4) @@ -9683,10 +9692,15 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state) unsigned int rotation = plane_state->base.rotation; int src_x, src_y; u32 offset; + int ret; intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation); plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation); + ret = intel_plane_check_stride(plane_state); + if (ret) + return ret; + src_x = plane_state->base.src_x >> 16; src_y = plane_state->base.src_y >> 16; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 07707728e4b6..8de41ac75d84 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2138,6 +2138,7 @@ unsigned int skl_plane_max_stride(struct intel_plane *plane, unsigned int rotation); int skl_plane_check(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); +int intel_plane_check_stride(const struct intel_plane_state *plane_state); int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); int chv_plane_check_rotation(const struct intel_plane_state *plane_state); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 96de5a33dbaf..d9e407d837b9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -230,6 +230,28 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) #endif } +int intel_plane_check_stride(const struct intel_plane_state *plane_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); + const struct drm_framebuffer *fb = plane_state->base.fb; + unsigned int rotation = plane_state->base.rotation; + u32 stride, max_stride; + + /* FIXME other color planes? */ + stride = plane_state->color_plane[0].stride; + max_stride = plane->max_stride(plane, fb->format->format, + fb->modifier, rotation); + + if (stride > max_stride) { + DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n", + fb->base.id, stride, + plane->base.base.id, plane->base.name, max_stride); + return -EINVAL; + } + + return 0; +} + int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) { const struct drm_framebuffer *fb = plane_state->base.fb; -- cgit v1.2.3-59-g8ed1b From 74f6e183913b5dc90a004cafa84159ddb61cd0f0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 26 Sep 2018 11:47:07 +0100 Subject: drm/i915: Convert to BITS_PER_TYPE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 9144d75e22ca ("include/linux/bitops.h: introduce BITS_PER_TYPE"), we made BITS_PER_TYPE available to all and now we can use the macro to replace some open-coded computation of sizeof(T) * BITS_PER_BYTE. Suggested-by: Ville Syrjälä Signed-off-by: Chris Wilson Cc: Ville Syrjälä Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Reviewed-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180926104707.17410-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 4 ++-- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_query.c | 2 +- drivers/gpu/drm/i915/i915_syncmap.c | 2 +- drivers/gpu/drm/i915/i915_utils.h | 2 +- drivers/gpu/drm/i915/intel_device_info.c | 3 +-- drivers/gpu/drm/i915/intel_engine_cs.c | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 44e2c0f5ec50..ade9bca250fa 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1649,8 +1649,8 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) device_info->device_id = pdev->device; BUILD_BUG_ON(INTEL_MAX_PLATFORMS > - sizeof(device_info->platform_mask) * BITS_PER_BYTE); - BUG_ON(device_info->gen > sizeof(device_info->gen_mask) * BITS_PER_BYTE); + BITS_PER_TYPE(device_info->platform_mask)); + BUG_ON(device_info->gen > BITS_PER_TYPE(device_info->gen_mask)); return i915; } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index db9688d14912..717f4321e987 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5959,7 +5959,7 @@ void i915_gem_track_fb(struct drm_i915_gem_object *old, * the bits. */ BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES > - sizeof(atomic_t) * BITS_PER_BYTE); + BITS_PER_TYPE(atomic_t)); if (old) { WARN_ON(!(atomic_read(&old->frontbuffer_bits) & frontbuffer_bits)); diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c index 3f502eef2431..5821002cad42 100644 --- a/drivers/gpu/drm/i915/i915_query.c +++ b/drivers/gpu/drm/i915/i915_query.c @@ -28,7 +28,7 @@ static int query_topology_info(struct drm_i915_private *dev_priv, slice_length = sizeof(sseu->slice_mask); subslice_length = sseu->max_slices * DIV_ROUND_UP(sseu->max_subslices, - sizeof(sseu->subslice_mask[0]) * BITS_PER_BYTE); + BITS_PER_TYPE(sseu->subslice_mask[0])); eu_length = sseu->max_slices * sseu->max_subslices * DIV_ROUND_UP(sseu->max_eus_per_subslice, BITS_PER_BYTE); diff --git a/drivers/gpu/drm/i915/i915_syncmap.c b/drivers/gpu/drm/i915/i915_syncmap.c index 58f8d0cc125c..60404dbb2e9f 100644 --- a/drivers/gpu/drm/i915/i915_syncmap.c +++ b/drivers/gpu/drm/i915/i915_syncmap.c @@ -92,7 +92,7 @@ void i915_syncmap_init(struct i915_syncmap **root) { BUILD_BUG_ON_NOT_POWER_OF_2(KSYNCMAP); BUILD_BUG_ON_NOT_POWER_OF_2(SHIFT); - BUILD_BUG_ON(KSYNCMAP > BITS_PER_BYTE * sizeof((*root)->bitmap)); + BUILD_BUG_ON(KSYNCMAP > BITS_PER_TYPE((*root)->bitmap)); *root = NULL; } diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 395dd2511568..5858a43e19da 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -68,7 +68,7 @@ /* Note we don't consider signbits :| */ #define overflows_type(x, T) \ - (sizeof(x) > sizeof(T) && (x) >> (sizeof(T) * BITS_PER_BYTE)) + (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T)) #define ptr_mask_bits(ptr, n) ({ \ unsigned long __v = (unsigned long)(ptr); \ diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 0ef0c6448d53..31f6be774833 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -750,8 +750,7 @@ void intel_device_info_runtime_init(struct intel_device_info *info) info->num_scalers[PIPE_C] = 1; } - BUILD_BUG_ON(I915_NUM_ENGINES > - sizeof(intel_ring_mask_t) * BITS_PER_BYTE); + BUILD_BUG_ON(I915_NUM_ENGINES > BITS_PER_TYPE(intel_ring_mask_t)); /* * Skylake and Broxton currently don't expose the topmost plane as its diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 217ed3ee1cab..6726d57f018f 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -335,7 +335,7 @@ int intel_engines_init_mmio(struct drm_i915_private *dev_priv) WARN_ON(ring_mask == 0); WARN_ON(ring_mask & - GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES)); + GENMASK(BITS_PER_TYPE(mask) - 1, I915_NUM_ENGINES)); for (i = 0; i < ARRAY_SIZE(intel_engines); i++) { if (!HAS_ENGINE(dev_priv, i)) -- cgit v1.2.3-59-g8ed1b From 7a90938332d80faf973fbcffdf6e674e7b8f0914 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 26 Sep 2018 11:47:18 +0100 Subject: drm/i915: Avoid compiler warning for maybe unused gu_misc_iir /kisskb/src/drivers/gpu/drm/i915/i915_irq.c: warning: 'gu_misc_iir' may be used uninitialized in this function [-Wuninitialized]: => 3120:10 Silence the compiler warning by ensuring that the local variable is initialised and removing the guard that is confusing the older gcc. Reported-by: Geert Uytterhoeven Fixes: df0d28c185ad ("drm/i915/icl: GSE interrupt moves from DE_MISC to GU_MISC") Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Paulo Zanoni Reviewed-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20180926104718.17462-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_irq.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 10f28a2ee2e6..2e242270e270 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3088,36 +3088,27 @@ gen11_gt_irq_handler(struct drm_i915_private * const i915, spin_unlock(&i915->irq_lock); } -static void -gen11_gu_misc_irq_ack(struct drm_i915_private *dev_priv, const u32 master_ctl, - u32 *iir) +static u32 +gen11_gu_misc_irq_ack(struct drm_i915_private *dev_priv, const u32 master_ctl) { void __iomem * const regs = dev_priv->regs; + u32 iir; if (!(master_ctl & GEN11_GU_MISC_IRQ)) - return; + return 0; + + iir = raw_reg_read(regs, GEN11_GU_MISC_IIR); + if (likely(iir)) + raw_reg_write(regs, GEN11_GU_MISC_IIR, iir); - *iir = raw_reg_read(regs, GEN11_GU_MISC_IIR); - if (likely(*iir)) - raw_reg_write(regs, GEN11_GU_MISC_IIR, *iir); + return iir; } static void -gen11_gu_misc_irq_handler(struct drm_i915_private *dev_priv, - const u32 master_ctl, const u32 iir) +gen11_gu_misc_irq_handler(struct drm_i915_private *dev_priv, const u32 iir) { - if (!(master_ctl & GEN11_GU_MISC_IRQ)) - return; - - if (unlikely(!iir)) { - DRM_ERROR("GU_MISC iir blank!\n"); - return; - } - if (iir & GEN11_GU_MISC_GSE) intel_opregion_asle_intr(dev_priv); - else - DRM_ERROR("Unexpected GU_MISC interrupt 0x%x\n", iir); } static irqreturn_t gen11_irq_handler(int irq, void *arg) @@ -3154,12 +3145,12 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg) enable_rpm_wakeref_asserts(i915); } - gen11_gu_misc_irq_ack(i915, master_ctl, &gu_misc_iir); + gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl); /* Acknowledge and enable interrupts. */ raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, GEN11_MASTER_IRQ | master_ctl); - gen11_gu_misc_irq_handler(i915, master_ctl, gu_misc_iir); + gen11_gu_misc_irq_handler(i915, gu_misc_iir); return IRQ_HANDLED; } -- cgit v1.2.3-59-g8ed1b From 33868a91c1d9627b5003b8e299c46c6cfee4ff18 Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Sun, 16 Sep 2018 16:23:28 +0530 Subject: drm/i915/icl: Define data/clock lanes dphy timing registers This patch defines DSI_CLK_TIMING_PARAM, DPHY_CLK_TIMING_PARAM, DSI_DATA_TIMING_PARAM, DPHY_DATA_TIMING_PARAM register used in dphy programming. v2: Define mask/shift for bitfields and keep names as per BSPEC (Jani N) Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1537095223-5184-6-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 58 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e7e6ca7f9665..f8a35fa9eeb5 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10286,6 +10286,64 @@ enum skl_power_gate { _ICL_DSI_T_INIT_MASTER_0,\ _ICL_DSI_T_INIT_MASTER_1) +#define _DPHY_CLK_TIMING_PARAM_0 0x162180 +#define _DPHY_CLK_TIMING_PARAM_1 0x6c180 +#define DPHY_CLK_TIMING_PARAM(port) _MMIO_PORT(port, \ + _DPHY_CLK_TIMING_PARAM_0,\ + _DPHY_CLK_TIMING_PARAM_1) +#define _DSI_CLK_TIMING_PARAM_0 0x6b080 +#define _DSI_CLK_TIMING_PARAM_1 0x6b880 +#define DSI_CLK_TIMING_PARAM(port) _MMIO_PORT(port, \ + _DSI_CLK_TIMING_PARAM_0,\ + _DSI_CLK_TIMING_PARAM_1) +#define CLK_PREPARE_OVERRIDE (1 << 31) +#define CLK_PREPARE(x) ((x) << 28) +#define CLK_PREPARE_MASK (0x7 << 28) +#define CLK_PREPARE_SHIFT 28 +#define CLK_ZERO_OVERRIDE (1 << 27) +#define CLK_ZERO(x) ((x) << 20) +#define CLK_ZERO_MASK (0xf << 20) +#define CLK_ZERO_SHIFT 20 +#define CLK_PRE_OVERRIDE (1 << 19) +#define CLK_PRE(x) ((x) << 16) +#define CLK_PRE_MASK (0x3 << 16) +#define CLK_PRE_SHIFT 16 +#define CLK_POST_OVERRIDE (1 << 15) +#define CLK_POST(x) ((x) << 8) +#define CLK_POST_MASK (0x7 << 8) +#define CLK_POST_SHIFT 8 +#define CLK_TRAIL_OVERRIDE (1 << 7) +#define CLK_TRAIL(x) ((x) << 0) +#define CLK_TRAIL_MASK (0xf << 0) +#define CLK_TRAIL_SHIFT 0 + +#define _DPHY_DATA_TIMING_PARAM_0 0x162184 +#define _DPHY_DATA_TIMING_PARAM_1 0x6c184 +#define DPHY_DATA_TIMING_PARAM(port) _MMIO_PORT(port, \ + _DPHY_DATA_TIMING_PARAM_0,\ + _DPHY_DATA_TIMING_PARAM_1) +#define _DSI_DATA_TIMING_PARAM_0 0x6B084 +#define _DSI_DATA_TIMING_PARAM_1 0x6B884 +#define DSI_DATA_TIMING_PARAM(port) _MMIO_PORT(port, \ + _DSI_DATA_TIMING_PARAM_0,\ + _DSI_DATA_TIMING_PARAM_1) +#define HS_PREPARE_OVERRIDE (1 << 31) +#define HS_PREPARE(x) ((x) << 24) +#define HS_PREPARE_MASK (0x7 << 24) +#define HS_PREPARE_SHIFT 24 +#define HS_ZERO_OVERRIDE (1 << 23) +#define HS_ZERO(x) ((x) << 16) +#define HS_ZERO_MASK (0xf << 16) +#define HS_ZERO_SHIFT 16 +#define HS_TRAIL_OVERRIDE (1 << 15) +#define HS_TRAIL(x) ((x) << 8) +#define HS_TRAIL_MASK (0x7 << 8) +#define HS_TRAIL_SHIFT 8 +#define HS_EXIT_OVERRIDE (1 << 7) +#define HS_EXIT(x) ((x) << 0) +#define HS_EXIT_MASK (0x7 << 0) +#define HS_EXIT_SHIFT 0 + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884) -- cgit v1.2.3-59-g8ed1b From 35c37ade79cdfe731ca1cae50c6628fef98a69a5 Mon Sep 17 00:00:00 2001 From: Madhav Chauhan Date: Sun, 16 Sep 2018 16:23:30 +0530 Subject: drm/i915/icl: Define TA_TIMING_PARAM registers This patch defines DSI_TA_TIMING_PARAM and DPHY_TA_TIMING_PARAM registers used in dphy programming. v2: Changes (Jani N) - Define mask/shift for bitfields - Use bitfields name as per BSPEC - Define remaining bitfields Signed-off-by: Madhav Chauhan Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/1537095223-5184-8-git-send-email-madhav.chauhan@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f8a35fa9eeb5..27e650fe591b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -10344,6 +10344,29 @@ enum skl_power_gate { #define HS_EXIT_MASK (0x7 << 0) #define HS_EXIT_SHIFT 0 +#define _DPHY_TA_TIMING_PARAM_0 0x162188 +#define _DPHY_TA_TIMING_PARAM_1 0x6c188 +#define DPHY_TA_TIMING_PARAM(port) _MMIO_PORT(port, \ + _DPHY_TA_TIMING_PARAM_0,\ + _DPHY_TA_TIMING_PARAM_1) +#define _DSI_TA_TIMING_PARAM_0 0x6b098 +#define _DSI_TA_TIMING_PARAM_1 0x6b898 +#define DSI_TA_TIMING_PARAM(port) _MMIO_PORT(port, \ + _DSI_TA_TIMING_PARAM_0,\ + _DSI_TA_TIMING_PARAM_1) +#define TA_SURE_OVERRIDE (1 << 31) +#define TA_SURE(x) ((x) << 16) +#define TA_SURE_MASK (0x1f << 16) +#define TA_SURE_SHIFT 16 +#define TA_GO_OVERRIDE (1 << 15) +#define TA_GO(x) ((x) << 8) +#define TA_GO_MASK (0xf << 8) +#define TA_GO_SHIFT 8 +#define TA_GET_OVERRIDE (1 << 7) +#define TA_GET(x) ((x) << 0) +#define TA_GET_MASK (0xf << 0) +#define TA_GET_SHIFT 0 + /* bits 31:0 */ #define _MIPIA_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb084) #define _MIPIC_DBI_BW_CTRL (dev_priv->mipi_mmio_base + 0xb884) -- cgit v1.2.3-59-g8ed1b From 7c86828d564574759c20793ced59df2a60950c1d Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 18 Sep 2018 13:47:09 -0700 Subject: drm/i915/runtime_pm: Share code to enable/disable PCH reset handshake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of have the same code spread into 4 platforms lets share it. BXT do not have a PCH so here also handling this case by unseting RESET_PCH_HANDSHAKE_ENABLE. v2(Rodrigo): - renamed to intel_pch_reset_handshake() - added comment about why BXT need the bit to be unset v3(Rodrigo and Ville): - added bool have_pch to intel_pch_reset_handshake() - added back BXT comment Cc: Ville Syrjälä Cc: Rodrigo Vivi Signed-off-by: José Roberto de Souza Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180918204714.27306-1-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_runtime_pm.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 0fdabce647ab..d051b0d440c4 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -3240,18 +3240,29 @@ static void icl_mbus_init(struct drm_i915_private *dev_priv) I915_WRITE(MBUS_ABOX_CTL, val); } +static void intel_pch_reset_handshake(struct drm_i915_private *dev_priv, + bool enable) +{ + u32 val = I915_READ(HSW_NDE_RSTWRN_OPT); + + if (enable) + val |= RESET_PCH_HANDSHAKE_ENABLE; + else + val &= ~RESET_PCH_HANDSHAKE_ENABLE; + + I915_WRITE(HSW_NDE_RSTWRN_OPT, val); +} + static void skl_display_core_init(struct drm_i915_private *dev_priv, bool resume) { struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_well *well; - uint32_t val; gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); /* enable PCH reset handshake */ - val = I915_READ(HSW_NDE_RSTWRN_OPT); - I915_WRITE(HSW_NDE_RSTWRN_OPT, val | RESET_PCH_HANDSHAKE_ENABLE); + intel_pch_reset_handshake(dev_priv, true); /* enable PG1 and Misc I/O */ mutex_lock(&power_domains->lock); @@ -3307,7 +3318,6 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv, { struct i915_power_domains *power_domains = &dev_priv->power_domains; struct i915_power_well *well; - uint32_t val; gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); @@ -3317,9 +3327,7 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv, * Move the handshake programming to initialization sequence. * Previously was left up to BIOS. */ - val = I915_READ(HSW_NDE_RSTWRN_OPT); - val &= ~RESET_PCH_HANDSHAKE_ENABLE; - I915_WRITE(HSW_NDE_RSTWRN_OPT, val); + intel_pch_reset_handshake(dev_priv, false); /* Enable PG1 */ mutex_lock(&power_domains->lock); @@ -3440,9 +3448,7 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); /* 1. Enable PCH Reset Handshake */ - val = I915_READ(HSW_NDE_RSTWRN_OPT); - val |= RESET_PCH_HANDSHAKE_ENABLE; - I915_WRITE(HSW_NDE_RSTWRN_OPT, val); + intel_pch_reset_handshake(dev_priv, true); /* 2. Enable Comp */ val = I915_READ(CHICKEN_MISC_2); @@ -3525,9 +3531,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); /* 1. Enable PCH reset handshake. */ - val = I915_READ(HSW_NDE_RSTWRN_OPT); - val |= RESET_PCH_HANDSHAKE_ENABLE; - I915_WRITE(HSW_NDE_RSTWRN_OPT, val); + intel_pch_reset_handshake(dev_priv, true); for (port = PORT_A; port <= PORT_B; port++) { /* 2. Enable DDI combo PHY comp. */ -- cgit v1.2.3-59-g8ed1b From 6edafc4eb3e4ae26b1b5dbc0cabfc82d96d6b9bb Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 18 Sep 2018 13:47:10 -0700 Subject: drm/i915: Unset reset pch handshake when PCH is not present in one place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right now RESET_PCH_HANDSHAKE_ENABLE is enabled all the times inside of intel_power_domains_init_hw() and if PCH is NOP it is unsed in i915_gem_init_hw(). So making skl_pch_reset_handshake() handle both cases and calling it for the missing gens in intel_power_domains_init_hw(). Ivybridge have a different register and bits but with the same objective so moving it too. v2(Rodrigo): - handling IVYBRIDGE case inside intel_pch_reset_handshake() v4(Rodrigo and Ville): - moving the enable/disable decision to callers Cc: Rodrigo Vivi Signed-off-by: José Roberto de Souza Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180918204714.27306-2-jose.souza@intel.com --- drivers/gpu/drm/i915/i915_gem.c | 12 ------------ drivers/gpu/drm/i915/intel_runtime_pm.c | 28 ++++++++++++++++++++-------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 717f4321e987..627b1c8a7ea3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5301,18 +5301,6 @@ int i915_gem_init_hw(struct drm_i915_private *dev_priv) I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev_priv) ? LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED); - if (HAS_PCH_NOP(dev_priv)) { - if (IS_IVYBRIDGE(dev_priv)) { - u32 temp = I915_READ(GEN7_MSG_CTL); - temp &= ~(WAIT_FOR_PCH_FLR_ACK | WAIT_FOR_PCH_RESET_ACK); - I915_WRITE(GEN7_MSG_CTL, temp); - } else if (INTEL_GEN(dev_priv) >= 7) { - u32 temp = I915_READ(HSW_NDE_RSTWRN_OPT); - temp &= ~RESET_PCH_HANDSHAKE_ENABLE; - I915_WRITE(HSW_NDE_RSTWRN_OPT, temp); - } - } - intel_gt_workarounds_apply(dev_priv); i915_gem_init_swizzling(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index d051b0d440c4..3cf8533e0834 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -3243,14 +3243,25 @@ static void icl_mbus_init(struct drm_i915_private *dev_priv) static void intel_pch_reset_handshake(struct drm_i915_private *dev_priv, bool enable) { - u32 val = I915_READ(HSW_NDE_RSTWRN_OPT); + i915_reg_t reg; + u32 reset_bits, val; + + if (IS_IVYBRIDGE(dev_priv)) { + reg = GEN7_MSG_CTL; + reset_bits = WAIT_FOR_PCH_FLR_ACK | WAIT_FOR_PCH_RESET_ACK; + } else { + reg = HSW_NDE_RSTWRN_OPT; + reset_bits = RESET_PCH_HANDSHAKE_ENABLE; + } + + val = I915_READ(reg); if (enable) - val |= RESET_PCH_HANDSHAKE_ENABLE; + val |= reset_bits; else - val &= ~RESET_PCH_HANDSHAKE_ENABLE; + val &= ~reset_bits; - I915_WRITE(HSW_NDE_RSTWRN_OPT, val); + I915_WRITE(reg, val); } static void skl_display_core_init(struct drm_i915_private *dev_priv, @@ -3262,7 +3273,7 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv, gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); /* enable PCH reset handshake */ - intel_pch_reset_handshake(dev_priv, true); + intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); /* enable PG1 and Misc I/O */ mutex_lock(&power_domains->lock); @@ -3448,7 +3459,7 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); /* 1. Enable PCH Reset Handshake */ - intel_pch_reset_handshake(dev_priv, true); + intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); /* 2. Enable Comp */ val = I915_READ(CHICKEN_MISC_2); @@ -3531,7 +3542,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, gen9_set_dc_state(dev_priv, DC_STATE_DISABLE); /* 1. Enable PCH reset handshake. */ - intel_pch_reset_handshake(dev_priv, true); + intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); for (port = PORT_A; port <= PORT_B; port++) { /* 2. Enable DDI combo PHY comp. */ @@ -3763,7 +3774,8 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume) mutex_lock(&power_domains->lock); vlv_cmnlane_wa(dev_priv); mutex_unlock(&power_domains->lock); - } + } else if (IS_IVYBRIDGE(dev_priv) || INTEL_GEN(dev_priv) >= 7) + intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv)); /* * Keep all power wells enabled for any dependent HW access during -- cgit v1.2.3-59-g8ed1b From fd847b8e60e0db72fd7d8922da0d1b07c1454efa Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 18 Sep 2018 13:47:11 -0700 Subject: drm/i915: Do not modifiy reserved bit in gens that do not have IPC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IPC was only added in SKL+(actually we don't even enable for SKL due WA) so without this change, driver was writing to a reserved bit. Also removing the uncessary dev_priv->ipc_enabled = false; as now gens without IPC will not have IPC enabled. v2(Rodrigo): - moved the new handling of WA #0477 to the next patch Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180918204714.27306-3-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1db9b8328275..e2ca04534e23 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6117,6 +6117,9 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv) { u32 val; + if (!HAS_IPC(dev_priv)) + return; + /* Display WA #0477 WaDisableIPC: skl */ if (IS_SKYLAKE(dev_priv)) dev_priv->ipc_enabled = false; @@ -6138,7 +6141,6 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv) void intel_init_ipc(struct drm_i915_private *dev_priv) { - dev_priv->ipc_enabled = false; if (!HAS_IPC(dev_priv)) return; -- cgit v1.2.3-59-g8ed1b From 6323113b7af6ef2f095f159752b06e83a64d8b9a Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 18 Sep 2018 13:47:12 -0700 Subject: drm/i915: Move SKL IPC WA to HAS_IPC() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SKL has IPC but it should not be set according to the WA, so lets just mark as it don't have it to simply the code and avoid unnecessary MMIO writes at every call to intel_enable_ipc(). Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180918204714.27306-4-jose.souza@intel.com --- drivers/gpu/drm/i915/i915_pci.c | 2 ++ drivers/gpu/drm/i915/intel_pm.c | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index d6f7b9fe1d26..adac75e5d5f7 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -472,6 +472,8 @@ static const struct intel_device_info intel_cherryview_info = { #define SKL_PLATFORM \ GEN9_FEATURES, \ + /* Display WA #0477 WaDisableIPC: skl */ \ + .has_ipc = 0, \ PLATFORM(INTEL_SKYLAKE) static const struct intel_device_info intel_skylake_gt1_info = { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index e2ca04534e23..538bcde0bf7d 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6120,10 +6120,6 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv) if (!HAS_IPC(dev_priv)) return; - /* Display WA #0477 WaDisableIPC: skl */ - if (IS_SKYLAKE(dev_priv)) - dev_priv->ipc_enabled = false; - /* Display WA #1141: SKL:all KBL:all CFL */ if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && !dev_priv->dram_info.symmetric_memory) -- cgit v1.2.3-59-g8ed1b From c9b818d3f9f4eca54a2ad3083b4584f453b20bed Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 18 Sep 2018 13:47:13 -0700 Subject: drm/i915: Move IPC WA #1141 to init_ipc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit symmetric_memory do not change after initialization so lets just set ipc_enabled once for this WA. Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180918204714.27306-5-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_pm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 538bcde0bf7d..1392aa56a55a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6120,11 +6120,6 @@ void intel_enable_ipc(struct drm_i915_private *dev_priv) if (!HAS_IPC(dev_priv)) return; - /* Display WA #1141: SKL:all KBL:all CFL */ - if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && - !dev_priv->dram_info.symmetric_memory) - dev_priv->ipc_enabled = false; - val = I915_READ(DISP_ARB_CTL2); if (dev_priv->ipc_enabled) @@ -6140,7 +6135,12 @@ void intel_init_ipc(struct drm_i915_private *dev_priv) if (!HAS_IPC(dev_priv)) return; - dev_priv->ipc_enabled = true; + /* Display WA #1141: SKL:all KBL:all CFL */ + if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) + dev_priv->ipc_enabled = dev_priv->dram_info.symmetric_memory; + else + dev_priv->ipc_enabled = true; + intel_enable_ipc(dev_priv); } -- cgit v1.2.3-59-g8ed1b From 029c33add915d5c688364ef189304f986baba45e Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 18 Sep 2018 13:47:14 -0700 Subject: drm/i915: Remove duplicated definition of intel_update_rawclk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A few line above we have another definition of intel_update_rawclk() keeping that one as the function is implemented in intel_cdclk.c. Reviewed-by: Rodrigo Vivi Signed-off-by: José Roberto de Souza Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20180918204714.27306-6-jose.souza@intel.com --- drivers/gpu/drm/i915/intel_drv.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4fcba99d12c0..5e904c15bd53 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1488,7 +1488,6 @@ void intel_dump_cdclk_state(const struct intel_cdclk_state *cdclk_state, void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe); enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc); -void intel_update_rawclk(struct drm_i915_private *dev_priv); int vlv_get_hpll_vco(struct drm_i915_private *dev_priv); int vlv_get_cck_clock(struct drm_i915_private *dev_priv, const char *name, u32 reg, int ref_freq); -- cgit v1.2.3-59-g8ed1b From 180e9d230efe7acad72a6a6ba47de82bcbc13fc4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Sep 2018 16:34:12 +0300 Subject: drm/i915/csr: keep firmware name and required version together Having two separate if ladders gets increasingly hard to maintain. Put them together. v2: Rebase Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20180926133414.22073-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_csr.c | 59 ++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8624b4bdc242..37f5fcf1644d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -465,6 +465,7 @@ struct drm_i915_display_funcs { struct intel_csr { struct work_struct work; const char *fw_path; + uint32_t required_version; uint32_t *dmc_payload; uint32_t dmc_fw_size; uint32_t version; diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 4aa8f3d6b64c..ee277ec33996 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -287,7 +287,6 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, uint32_t max_fw_size = 0; uint32_t i; uint32_t *dmc_payload; - uint32_t required_version; if (!fw) return NULL; @@ -302,38 +301,19 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, return NULL; } - csr->version = css_header->version; - - if (csr->fw_path == i915_modparams.dmc_firmware_path) { - /* Bypass version check for firmware override. */ - required_version = csr->version; - } else if (IS_ICELAKE(dev_priv)) { - required_version = ICL_CSR_VERSION_REQUIRED; - } else if (IS_CANNONLAKE(dev_priv)) { - required_version = CNL_CSR_VERSION_REQUIRED; - } else if (IS_GEMINILAKE(dev_priv)) { - required_version = GLK_CSR_VERSION_REQUIRED; - } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { - required_version = KBL_CSR_VERSION_REQUIRED; - } else if (IS_SKYLAKE(dev_priv)) { - required_version = SKL_CSR_VERSION_REQUIRED; - } else if (IS_BROXTON(dev_priv)) { - required_version = BXT_CSR_VERSION_REQUIRED; - } else { - MISSING_CASE(INTEL_REVID(dev_priv)); - required_version = 0; - } - - if (csr->version != required_version) { + if (csr->required_version && + css_header->version != csr->required_version) { DRM_INFO("Refusing to load DMC firmware v%u.%u," " please use v%u.%u\n", - CSR_VERSION_MAJOR(csr->version), - CSR_VERSION_MINOR(csr->version), - CSR_VERSION_MAJOR(required_version), - CSR_VERSION_MINOR(required_version)); + CSR_VERSION_MAJOR(css_header->version), + CSR_VERSION_MINOR(css_header->version), + CSR_VERSION_MAJOR(csr->required_version), + CSR_VERSION_MINOR(csr->required_version)); return NULL; } + csr->version = css_header->version; + readcount += sizeof(struct intel_css_header); /* Extract Package Header information*/ @@ -474,20 +454,29 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) if (!HAS_CSR(dev_priv)) return; - if (i915_modparams.dmc_firmware_path) + if (i915_modparams.dmc_firmware_path) { csr->fw_path = i915_modparams.dmc_firmware_path; - else if (IS_ICELAKE(dev_priv)) + /* Bypass version check for firmware override. */ + csr->required_version = 0; + } else if (IS_ICELAKE(dev_priv)) { csr->fw_path = I915_CSR_ICL; - else if (IS_CANNONLAKE(dev_priv)) + csr->required_version = ICL_CSR_VERSION_REQUIRED; + } else if (IS_CANNONLAKE(dev_priv)) { csr->fw_path = I915_CSR_CNL; - else if (IS_GEMINILAKE(dev_priv)) + csr->required_version = CNL_CSR_VERSION_REQUIRED; + } else if (IS_GEMINILAKE(dev_priv)) { csr->fw_path = I915_CSR_GLK; - else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) + csr->required_version = GLK_CSR_VERSION_REQUIRED; + } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { csr->fw_path = I915_CSR_KBL; - else if (IS_SKYLAKE(dev_priv)) + csr->required_version = KBL_CSR_VERSION_REQUIRED; + } else if (IS_SKYLAKE(dev_priv)) { csr->fw_path = I915_CSR_SKL; - else if (IS_BROXTON(dev_priv)) + csr->required_version = SKL_CSR_VERSION_REQUIRED; + } else if (IS_BROXTON(dev_priv)) { csr->fw_path = I915_CSR_BXT; + csr->required_version = BXT_CSR_VERSION_REQUIRED; + } /* * Obtain a runtime pm reference, until CSR is loaded, -- cgit v1.2.3-59-g8ed1b From d8a5b7d79fb7de60d9f0b9c56ebd8ef9f507d362 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Sep 2018 16:34:13 +0300 Subject: drm/i915/csr: keep max firmware size together with firmare name and version Move max firmware size to the same if ladder with firmware name and required version. This allows us to detect the missing max size for a platform without actually loading the firmware, and makes the whole thing easier to maintain. We need to move the power get earlier to allow for early return in the missing platform case. While at it, extend the comment on why we return with the reference held on errors. We also need to move the module parameter override later to reuse the max firmware size, which is independent of the override. v2: Add comment on why we leak the wakeref on errors (Chris) v3: Rebase Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20180926133414.22073-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/intel_csr.c | 46 +++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 37f5fcf1644d..9e185f0a822a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -466,8 +466,9 @@ struct intel_csr { struct work_struct work; const char *fw_path; uint32_t required_version; + uint32_t max_fw_size; /* bytes */ uint32_t *dmc_payload; - uint32_t dmc_fw_size; + uint32_t dmc_fw_size; /* dwords */ uint32_t version; uint32_t mmio_count; i915_reg_t mmioaddr[8]; diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index ee277ec33996..b3a084c48a94 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -284,7 +284,6 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, struct intel_csr *csr = &dev_priv->csr; const struct stepping_info *si = intel_get_stepping_info(dev_priv); uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; - uint32_t max_fw_size = 0; uint32_t i; uint32_t *dmc_payload; @@ -381,15 +380,7 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */ nbytes = dmc_header->fw_size * 4; - if (INTEL_GEN(dev_priv) >= 11) - max_fw_size = ICL_CSR_MAX_FW_SIZE; - else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) - max_fw_size = GLK_CSR_MAX_FW_SIZE; - else if (IS_GEN9(dev_priv)) - max_fw_size = BXT_CSR_MAX_FW_SIZE; - else - MISSING_CASE(INTEL_REVID(dev_priv)); - if (nbytes > max_fw_size) { + if (nbytes > csr->max_fw_size) { DRM_ERROR("DMC FW too big (%u bytes)\n", nbytes); return NULL; } @@ -454,35 +445,50 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) if (!HAS_CSR(dev_priv)) return; - if (i915_modparams.dmc_firmware_path) { - csr->fw_path = i915_modparams.dmc_firmware_path; - /* Bypass version check for firmware override. */ - csr->required_version = 0; - } else if (IS_ICELAKE(dev_priv)) { + /* + * Obtain a runtime pm reference, until CSR is loaded, to avoid entering + * runtime-suspend. + * + * On error, we return with the rpm wakeref held to prevent runtime + * suspend as runtime suspend *requires* a working CSR for whatever + * reason. + */ + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); + + if (IS_ICELAKE(dev_priv)) { csr->fw_path = I915_CSR_ICL; csr->required_version = ICL_CSR_VERSION_REQUIRED; + csr->max_fw_size = ICL_CSR_MAX_FW_SIZE; } else if (IS_CANNONLAKE(dev_priv)) { csr->fw_path = I915_CSR_CNL; csr->required_version = CNL_CSR_VERSION_REQUIRED; + csr->max_fw_size = GLK_CSR_MAX_FW_SIZE; } else if (IS_GEMINILAKE(dev_priv)) { csr->fw_path = I915_CSR_GLK; csr->required_version = GLK_CSR_VERSION_REQUIRED; + csr->max_fw_size = GLK_CSR_MAX_FW_SIZE; } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { csr->fw_path = I915_CSR_KBL; csr->required_version = KBL_CSR_VERSION_REQUIRED; + csr->max_fw_size = BXT_CSR_MAX_FW_SIZE; } else if (IS_SKYLAKE(dev_priv)) { csr->fw_path = I915_CSR_SKL; csr->required_version = SKL_CSR_VERSION_REQUIRED; + csr->max_fw_size = BXT_CSR_MAX_FW_SIZE; } else if (IS_BROXTON(dev_priv)) { csr->fw_path = I915_CSR_BXT; csr->required_version = BXT_CSR_VERSION_REQUIRED; + csr->max_fw_size = BXT_CSR_MAX_FW_SIZE; + } else { + MISSING_CASE(INTEL_REVID(dev_priv)); + return; } - /* - * Obtain a runtime pm reference, until CSR is loaded, - * to avoid entering runtime-suspend. - */ - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); + if (i915_modparams.dmc_firmware_path) { + csr->fw_path = i915_modparams.dmc_firmware_path; + /* Bypass version check for firmware override. */ + csr->required_version = 0; + } if (csr->fw_path == NULL) { DRM_DEBUG_KMS("No known CSR firmware for platform, disabling runtime PM\n"); -- cgit v1.2.3-59-g8ed1b From e7351a8474d2df929751ef1397ac7f9c6d3c4e22 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 26 Sep 2018 16:34:14 +0300 Subject: drm/i915/csr: bypass firmware request on i915.dmc_firmware_path="" With i915.dmc_firmware_path="" it's obvious the intention is to disable CSR firmware loading. Bypass the firmware request altogether in this case, with more obvious debug logging. v2: Use DRM_INFO for logging (Chris) Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20180926133414.22073-3-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_csr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index b3a084c48a94..81935da9cd6b 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -485,6 +485,12 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) } if (i915_modparams.dmc_firmware_path) { + if (strlen(i915_modparams.dmc_firmware_path) == 0) { + csr->fw_path = NULL; + DRM_INFO("Disabling CSR firmare and runtime PM\n"); + return; + } + csr->fw_path = i915_modparams.dmc_firmware_path; /* Bypass version check for firmware override. */ csr->required_version = 0; -- cgit v1.2.3-59-g8ed1b From dee4a0f8e70db36105e43dba5652737df5812190 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 25 Sep 2018 09:31:58 +0100 Subject: drm/i915/selftests: Smoketest preemption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Very light stress test to bombard the submission backends with a large stream with requests of randomly assigned priorities. Preemption will be occasionally requested, but unlikely to ever succeed! (Although we may build a long queue of requests and so may trigger an attempt to inject a preempt context, as we emit no batch, the arbitration window is limited to between requests inside the ringbuffer. The likelihood of actually causing a preemption event is therefore very small. A later variant should try to improve the likelihood of preemption events!) v2: Include a second pattern with more frequent preemption Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20180925083205.2229-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/selftests/intel_lrc.c | 137 +++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index 1aea7a8f2224..3a474bb64c05 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -6,6 +6,7 @@ #include "../i915_selftest.h" #include "igt_flush_test.h" +#include "i915_random.h" #include "mock_context.h" @@ -573,6 +574,141 @@ err_unlock: return err; } +static int random_range(struct rnd_state *rnd, int min, int max) +{ + return i915_prandom_u32_max_state(max - min, rnd) + min; +} + +static int random_priority(struct rnd_state *rnd) +{ + return random_range(rnd, I915_PRIORITY_MIN, I915_PRIORITY_MAX); +} + +struct preempt_smoke { + struct drm_i915_private *i915; + struct i915_gem_context **contexts; + unsigned int ncontext; + struct rnd_state prng; +}; + +static struct i915_gem_context *smoke_context(struct preempt_smoke *smoke) +{ + return smoke->contexts[i915_prandom_u32_max_state(smoke->ncontext, + &smoke->prng)]; +} + +static int smoke_crescendo(struct preempt_smoke *smoke) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + unsigned long count; + + count = 0; + for_each_engine(engine, smoke->i915, id) { + IGT_TIMEOUT(end_time); + + do { + struct i915_gem_context *ctx = smoke_context(smoke); + struct i915_request *rq; + + ctx->sched.priority = count % I915_PRIORITY_MAX; + + rq = i915_request_alloc(engine, ctx); + if (IS_ERR(rq)) + return PTR_ERR(rq); + + i915_request_add(rq); + count++; + } while (!__igt_timeout(end_time, NULL)); + } + + pr_info("Submitted %lu crescendo requests across %d engines and %d contexts\n", + count, INTEL_INFO(smoke->i915)->num_rings, smoke->ncontext); + return 0; +} + +static int smoke_random(struct preempt_smoke *smoke) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + IGT_TIMEOUT(end_time); + unsigned long count; + + count = 0; + do { + for_each_engine(engine, smoke->i915, id) { + struct i915_gem_context *ctx = smoke_context(smoke); + struct i915_request *rq; + + ctx->sched.priority = random_priority(&smoke->prng); + + rq = i915_request_alloc(engine, ctx); + if (IS_ERR(rq)) + return PTR_ERR(rq); + + i915_request_add(rq); + count++; + } + } while (!__igt_timeout(end_time, NULL)); + + pr_info("Submitted %lu random requests across %d engines and %d contexts\n", + count, INTEL_INFO(smoke->i915)->num_rings, smoke->ncontext); + return 0; +} + +static int live_preempt_smoke(void *arg) +{ + struct preempt_smoke smoke = { + .i915 = arg, + .prng = I915_RND_STATE_INITIALIZER(i915_selftest.random_seed), + .ncontext = 1024, + }; + int err = -ENOMEM; + int n; + + if (!HAS_LOGICAL_RING_PREEMPTION(smoke.i915)) + return 0; + + smoke.contexts = kmalloc_array(smoke.ncontext, + sizeof(*smoke.contexts), + GFP_KERNEL); + if (!smoke.contexts) + return -ENOMEM; + + mutex_lock(&smoke.i915->drm.struct_mutex); + intel_runtime_pm_get(smoke.i915); + + for (n = 0; n < smoke.ncontext; n++) { + smoke.contexts[n] = kernel_context(smoke.i915); + if (!smoke.contexts[n]) + goto err_ctx; + } + + err = smoke_crescendo(&smoke); + if (err) + goto err_ctx; + + err = smoke_random(&smoke); + if (err) + goto err_ctx; + +err_ctx: + if (igt_flush_test(smoke.i915, I915_WAIT_LOCKED)) + err = -EIO; + + for (n = 0; n < smoke.ncontext; n++) { + if (!smoke.contexts[n]) + break; + kernel_context_close(smoke.contexts[n]); + } + + intel_runtime_pm_put(smoke.i915); + mutex_unlock(&smoke.i915->drm.struct_mutex); + kfree(smoke.contexts); + + return err; +} + int intel_execlists_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { @@ -580,6 +716,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915) SUBTEST(live_preempt), SUBTEST(live_late_preempt), SUBTEST(live_preempt_hang), + SUBTEST(live_preempt_smoke), }; if (!HAS_EXECLISTS(i915)) -- cgit v1.2.3-59-g8ed1b From 9cb5f4873b993497d462b9406f9a1d8a148e461b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Sun, 1 Jul 2018 15:24:15 +0200 Subject: drm/atmel-hlcdc: Replace drm_dev_unref with drm_dev_put This patch unifies the naming of DRM functions for reference counting of struct drm_device. The resulting code is more aligned with the rest of the Linux kernel interfaces. Signed-off-by: Thomas Zimmermann Signed-off-by: Boris Brezillon Link: https://patchwork.freedesktop.org/patch/msgid/20180701132415.10161-1-contact@tzimmermann.org --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 843cac222e60..fedbfa333bb0 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -763,7 +763,7 @@ static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev) ret = atmel_hlcdc_dc_load(ddev); if (ret) - goto err_unref; + goto err_put; ret = drm_dev_register(ddev, 0); if (ret) @@ -774,8 +774,8 @@ static int atmel_hlcdc_dc_drm_probe(struct platform_device *pdev) err_unload: atmel_hlcdc_dc_unload(ddev); -err_unref: - drm_dev_unref(ddev); +err_put: + drm_dev_put(ddev); return ret; } @@ -786,7 +786,7 @@ static int atmel_hlcdc_dc_drm_remove(struct platform_device *pdev) drm_dev_unregister(ddev); atmel_hlcdc_dc_unload(ddev); - drm_dev_unref(ddev); + drm_dev_put(ddev); return 0; } -- cgit v1.2.3-59-g8ed1b From 4f297df89d29b531fa834ff4958456ecd82ee753 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Sun, 23 Sep 2018 14:37:30 +0200 Subject: drm/rockchip: vop: add rk3188 hs_start interrupt as dsp_hold equivalent The hs_start interrupt on rk3188 fires at the start of a new frame, so serves essentially the same purpose as the dsp_hold_valid irq in checking when the last frame got delivered when going to standby. So define it to fix a hang on atomic_disable of the vop because the completion never really completed before. Fixes: 428e15cc41e3 ("drm/rockchip: vop: add rk3188 vop definitions") Signed-off-by: Heiko Stuebner Reviewed-by: Sandy Huang Link: https://patchwork.freedesktop.org/patch/msgid/20180923123730.14706-1-heiko@sntech.de --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index a6db3cd5544b..047a8867af90 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -361,7 +361,11 @@ static const struct vop_win_data rk3188_vop_win_data[] = { }; static const int rk3188_vop_intrs[] = { - 0, + /* + * hs_start interrupt fires at frame-start, so serves + * the same purpose as dsp_hold in the driver. + */ + DSP_HOLD_VALID_INTR, FS_INTR, LINE_FLAG_INTR, BUS_ERROR_INTR, -- cgit v1.2.3-59-g8ed1b From f8e57863f81f962a1837d6a17825752de5bc23f7 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 26 Sep 2018 09:03:53 +0100 Subject: drm/i915: Trim partial view sg lists Partial views are small but there can be many of them, and since the sg list space for them is allocated pessimistically, we can save some slab by trimming the unused tail entries. Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Cc: Joonas Lahtinen Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20180926080353.20867-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9e185f0a822a..ab52657cc3d0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2325,6 +2325,8 @@ static inline struct scatterlist *__sg_next(struct scatterlist *sg) (((__iter).curr += PAGE_SIZE) >= (__iter).max) ? \ (__iter) = __sgt_iter(__sg_next((__iter).sgp), false), 0 : 0) +bool i915_sg_trim(struct sg_table *orig_st); + static inline unsigned int i915_sg_page_sizes(struct scatterlist *sg) { unsigned int page_sizes; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 627b1c8a7ea3..28e943ee8b5e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2491,7 +2491,7 @@ unlock: mutex_unlock(&obj->mm.lock); } -static bool i915_sg_trim(struct sg_table *orig_st) +bool i915_sg_trim(struct sg_table *orig_st) { struct sg_table new_st; struct scatterlist *sg, *new_sg; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index f6c7ab413081..1ec721c20581 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -3835,6 +3835,8 @@ intel_partial_pages(const struct i915_ggtt_view *view, count -= len >> PAGE_SHIFT; if (count == 0) { sg_mark_end(sg); + i915_sg_trim(st); /* Drop any unused tail entries. */ + return st; } -- cgit v1.2.3-59-g8ed1b From c5f6d578956a4304b6bb5393423768fecafff385 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Wed, 26 Sep 2018 15:50:33 +0100 Subject: drm/i915: Log HWS seqno consistently We mix hexa- and decimal which is confusing when reading the logs. So make the single odd one out instance decimal for consistency. v2: * Do the intel_ringbuffer.c as well. (Chris Wilson) Signed-off-by: Tvrtko Ursulin Cc: Chris Wilson Reviewed-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20180926145033.16318-1-tvrtko.ursulin@linux.intel.com --- drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 4b28225320ff..ad93aa4b0a6e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1904,7 +1904,7 @@ static void execlists_reset(struct intel_engine_cs *engine, unsigned long flags; u32 *regs; - GEM_TRACE("%s request global=%x, current=%d\n", + GEM_TRACE("%s request global=%d, current=%d\n", engine->name, request ? request->global_seqno : 0, intel_engine_get_seqno(engine)); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d0ef50bf930a..c092d5099ebf 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -574,7 +574,9 @@ static void skip_request(struct i915_request *rq) static void reset_ring(struct intel_engine_cs *engine, struct i915_request *rq) { - GEM_TRACE("%s seqno=%x\n", engine->name, rq ? rq->global_seqno : 0); + GEM_TRACE("%s request global=%d, current=%d\n", + engine->name, rq ? rq->global_seqno : 0, + intel_engine_get_seqno(engine)); /* * Try to restore the logical GPU state to match the continuation -- cgit v1.2.3-59-g8ed1b From 4bdafb9ddfa4b3d970e2194d00e1c6d5002f513f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 26 Sep 2018 21:12:22 +0100 Subject: drm/i915: Remove i915.enable_ppgtt override Now that we are confident in providing full-ppgtt where supported, remove the ability to override the context isolation. v2: Remove faked aliasing-ppgtt for testing as it no longer is accepted. v3: s/USES/HAS/ to match usage and reject attempts to load the module on old GVT-g setups that do not provide support for full-ppgtt. v4: Insulate ABI ppGTT values from our internal enum (later plans involve moving ppGTT depth out of the enum, thus potentially breaking ABI unless we document the current values). Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Matthew Auld Reviewed-by: Joonas Lahtinen Acked-by: Zhi Wang Link: https://patchwork.freedesktop.org/patch/msgid/20180926201222.5643-1-chris@chris-wilson.co.uk --- drivers/gpu/drm/i915/i915_drv.c | 22 +++--- drivers/gpu/drm/i915/i915_drv.h | 14 ++-- drivers/gpu/drm/i915/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 88 ++--------------------- drivers/gpu/drm/i915/i915_gpu_error.c | 4 +- drivers/gpu/drm/i915/i915_params.c | 4 -- drivers/gpu/drm/i915/i915_params.h | 1 - drivers/gpu/drm/i915/i915_pci.c | 17 ++--- drivers/gpu/drm/i915/intel_device_info.c | 5 ++ drivers/gpu/drm/i915/intel_device_info.h | 13 +++- drivers/gpu/drm/i915/intel_lrc.c | 13 ++-- drivers/gpu/drm/i915/selftests/huge_pages.c | 12 ++-- drivers/gpu/drm/i915/selftests/i915_gem_context.c | 59 +-------------- drivers/gpu/drm/i915/selftests/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 4 +- include/uapi/drm/i915_drm.h | 8 +++ 16 files changed, 71 insertions(+), 197 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ade9bca250fa..1b028f429e92 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -345,7 +345,7 @@ static int i915_getparam_ioctl(struct drm_device *dev, void *data, value = HAS_WT(dev_priv); break; case I915_PARAM_HAS_ALIASING_PPGTT: - value = USES_PPGTT(dev_priv); + value = min_t(int, INTEL_PPGTT(dev_priv), I915_GEM_PPGTT_FULL); break; case I915_PARAM_HAS_SEMAPHORES: value = HAS_LEGACY_SEMAPHORES(dev_priv); @@ -1049,17 +1049,6 @@ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) static void intel_sanitize_options(struct drm_i915_private *dev_priv) { - /* - * i915.enable_ppgtt is read-only, so do an early pass to validate the - * user's requested state against the hardware/driver capabilities. We - * do this now so that we can print out any log messages once rather - * than every time we check intel_enable_ppgtt(). - */ - i915_modparams.enable_ppgtt = - intel_sanitize_enable_ppgtt(dev_priv, - i915_modparams.enable_ppgtt); - DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915_modparams.enable_ppgtt); - intel_gvt_sanitize_options(dev_priv); } @@ -1374,6 +1363,15 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) intel_device_info_runtime_init(mkwrite_device_info(dev_priv)); + if (HAS_PPGTT(dev_priv)) { + if (intel_vgpu_active(dev_priv) && + !intel_vgpu_has_full_48bit_ppgtt(dev_priv)) { + i915_report_error(dev_priv, + "incompatible vGPU found, support for isolated ppGTT required\n"); + return -ENXIO; + } + } + intel_sanitize_options(dev_priv); i915_perf_init(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ab52657cc3d0..30191523c309 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2597,9 +2597,14 @@ intel_info(const struct drm_i915_private *dev_priv) #define HAS_EXECLISTS(dev_priv) HAS_LOGICAL_RING_CONTEXTS(dev_priv) -#define USES_PPGTT(dev_priv) (i915_modparams.enable_ppgtt) -#define USES_FULL_PPGTT(dev_priv) (i915_modparams.enable_ppgtt >= 2) -#define USES_FULL_48BIT_PPGTT(dev_priv) (i915_modparams.enable_ppgtt == 3) +#define INTEL_PPGTT(dev_priv) (INTEL_INFO(dev_priv)->ppgtt) +#define HAS_PPGTT(dev_priv) \ + (INTEL_PPGTT(dev_priv) != INTEL_PPGTT_NONE) +#define HAS_FULL_PPGTT(dev_priv) \ + (INTEL_PPGTT(dev_priv) >= INTEL_PPGTT_FULL) +#define HAS_FULL_48BIT_PPGTT(dev_priv) \ + (INTEL_PPGTT(dev_priv) >= INTEL_PPGTT_FULL_4LVL) + #define HAS_PAGE_SIZES(dev_priv, sizes) ({ \ GEM_BUG_ON((sizes) == 0); \ ((sizes) & ~(dev_priv)->info.page_sizes) == 0; \ @@ -2747,9 +2752,6 @@ intel_ggtt_update_needs_vtd_wa(struct drm_i915_private *dev_priv) return IS_BROXTON(dev_priv) && intel_vtd_active(); } -int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, - int enable_ppgtt); - /* i915_drv.c */ void __printf(3, 4) __i915_printk(struct drm_i915_private *dev_priv, const char *level, diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index f772593b99ab..15c92f75b1b8 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -414,7 +414,7 @@ i915_gem_create_context(struct drm_i915_private *dev_priv, if (IS_ERR(ctx)) return ctx; - if (USES_FULL_PPGTT(dev_priv)) { + if (HAS_FULL_PPGTT(dev_priv)) { struct i915_hw_ppgtt *ppgtt; ppgtt = i915_ppgtt_create(dev_priv, file_priv); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 1ec721c20581..29ca9007a704 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -133,55 +133,6 @@ static inline void i915_ggtt_invalidate(struct drm_i915_private *i915) i915->ggtt.invalidate(i915); } -int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv, - int enable_ppgtt) -{ - bool has_full_ppgtt; - bool has_full_48bit_ppgtt; - - if (!dev_priv->info.has_aliasing_ppgtt) - return 0; - - has_full_ppgtt = dev_priv->info.has_full_ppgtt; - has_full_48bit_ppgtt = dev_priv->info.has_full_48bit_ppgtt; - - if (intel_vgpu_active(dev_priv)) { - /* GVT-g has no support for 32bit ppgtt */ - has_full_ppgtt = false; - has_full_48bit_ppgtt = intel_vgpu_has_full_48bit_ppgtt(dev_priv); - } - - /* - * We don't allow disabling PPGTT for gen8+ as it's a requirement for - * execlists, the sole mechanism available to submit work. - */ - if (enable_ppgtt == 0 && !HAS_EXECLISTS(dev_priv)) - return 0; - - if (enable_ppgtt == 1) - return 1; - - if (enable_ppgtt == 2 && has_full_ppgtt) - return 2; - - if (enable_ppgtt == 3 && has_full_48bit_ppgtt) - return 3; - - /* Disable ppgtt on SNB if VT-d is on. */ - if (IS_GEN6(dev_priv) && intel_vtd_active()) { - DRM_INFO("Disabling PPGTT because VT-d is on\n"); - return 0; - } - - if (has_full_48bit_ppgtt) - return 3; - - if (has_full_ppgtt) - return 2; - - return 1; -} - static int ppgtt_bind_vma(struct i915_vma *vma, enum i915_cache_level cache_level, u32 unused) @@ -1647,7 +1598,7 @@ static struct i915_hw_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915) ppgtt->vm.i915 = i915; ppgtt->vm.dma = &i915->drm.pdev->dev; - ppgtt->vm.total = USES_FULL_48BIT_PPGTT(i915) ? + ppgtt->vm.total = HAS_FULL_48BIT_PPGTT(i915) ? 1ULL << 48 : 1ULL << 32; @@ -1782,19 +1733,6 @@ static inline void gen6_write_pde(const struct gen6_hw_ppgtt *ppgtt, ppgtt->pd_addr + pde); } -static void gen8_ppgtt_enable(struct drm_i915_private *dev_priv) -{ - struct intel_engine_cs *engine; - enum intel_engine_id id; - - for_each_engine(engine, dev_priv, id) { - u32 four_level = USES_FULL_48BIT_PPGTT(dev_priv) ? - GEN8_GFX_PPGTT_48B : 0; - I915_WRITE(RING_MODE_GEN7(engine), - _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level)); - } -} - static void gen7_ppgtt_enable(struct drm_i915_private *dev_priv) { struct intel_engine_cs *engine; @@ -1834,7 +1772,8 @@ static void gen6_ppgtt_enable(struct drm_i915_private *dev_priv) ecochk = I915_READ(GAM_ECOCHK); I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | ECOCHK_PPGTT_CACHE64B); - I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); + if (HAS_PPGTT(dev_priv)) /* may be disabled for VT-d */ + I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); } /* PPGTT support for Sandybdrige/Gen6 and later */ @@ -2237,23 +2176,10 @@ int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv) { gtt_write_workarounds(dev_priv); - /* In the case of execlists, PPGTT is enabled by the context descriptor - * and the PDPs are contained within the context itself. We don't - * need to do anything here. */ - if (HAS_LOGICAL_RING_CONTEXTS(dev_priv)) - return 0; - - if (!USES_PPGTT(dev_priv)) - return 0; - if (IS_GEN6(dev_priv)) gen6_ppgtt_enable(dev_priv); else if (IS_GEN7(dev_priv)) gen7_ppgtt_enable(dev_priv); - else if (INTEL_GEN(dev_priv) >= 8) - gen8_ppgtt_enable(dev_priv); - else - MISSING_CASE(INTEL_GEN(dev_priv)); return 0; } @@ -2952,7 +2878,7 @@ int i915_gem_init_ggtt(struct drm_i915_private *dev_priv) /* And finally clear the reserved guard page */ ggtt->vm.clear_range(&ggtt->vm, ggtt->vm.total - PAGE_SIZE, PAGE_SIZE); - if (USES_PPGTT(dev_priv) && !USES_FULL_PPGTT(dev_priv)) { + if (INTEL_PPGTT(dev_priv) == INTEL_PPGTT_ALIASING) { ret = i915_gem_init_aliasing_ppgtt(dev_priv); if (ret) goto err; @@ -3275,7 +3201,7 @@ static void bdw_setup_private_ppat(struct intel_ppat *ppat) ppat->match = bdw_private_pat_match; ppat->clear_value = GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3); - if (!USES_PPGTT(ppat->i915)) { + if (!HAS_PPGTT(ppat->i915)) { /* Spec: "For GGTT, there is NO pat_sel[2:0] from the entry, * so RTL will always use the value corresponding to * pat_sel = 000". @@ -3402,7 +3328,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) ggtt->vm.cleanup = gen6_gmch_remove; ggtt->vm.insert_page = gen8_ggtt_insert_page; ggtt->vm.clear_range = nop_clear_range; - if (!USES_FULL_PPGTT(dev_priv) || intel_scanout_needs_vtd_wa(dev_priv)) + if (intel_scanout_needs_vtd_wa(dev_priv)) ggtt->vm.clear_range = gen8_ggtt_clear_range; ggtt->vm.insert_entries = gen8_ggtt_insert_entries; @@ -3609,7 +3535,7 @@ int i915_ggtt_init_hw(struct drm_i915_private *dev_priv) /* Only VLV supports read-only GGTT mappings */ ggtt->vm.has_read_only = IS_VALLEYVIEW(dev_priv); - if (!HAS_LLC(dev_priv) && !USES_PPGTT(dev_priv)) + if (!HAS_LLC(dev_priv) && !HAS_PPGTT(dev_priv)) ggtt->vm.mm.color_adjust = i915_gtt_color_adjust; mutex_unlock(&dev_priv->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 2835cacd0d08..3d5554f14dfd 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -474,7 +474,7 @@ static void error_print_engine(struct drm_i915_error_state_buf *m, err_printf(m, " SYNC_2: 0x%08x\n", ee->semaphore_mboxes[2]); } - if (USES_PPGTT(m->i915)) { + if (HAS_PPGTT(m->i915)) { err_printf(m, " GFX_MODE: 0x%08x\n", ee->vm_info.gfx_mode); if (INTEL_GEN(m->i915) >= 8) { @@ -1230,7 +1230,7 @@ static void error_record_engine_registers(struct i915_gpu_state *error, ee->reset_count = i915_reset_engine_count(&dev_priv->gpu_error, engine); - if (USES_PPGTT(dev_priv)) { + if (HAS_PPGTT(dev_priv)) { int i; ee->vm_info.gfx_mode = I915_READ(RING_MODE_GEN7(engine)); diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 295e981e4a39..bd6bd8879cab 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -82,10 +82,6 @@ i915_param_named_unsafe(enable_hangcheck, bool, 0644, "WARNING: Disabling this can cause system wide hangs. " "(default: true)"); -i915_param_named_unsafe(enable_ppgtt, int, 0400, - "Override PPGTT usage. " - "(-1=auto [default], 0=disabled, 1=aliasing, 2=full, 3=full with extended address space)"); - i915_param_named_unsafe(enable_psr, int, 0600, "Enable PSR " "(0=disabled, 1=enabled) " diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 6c4d4a21474b..7e56c516c815 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -41,7 +41,6 @@ struct drm_printer; param(int, vbt_sdvo_panel_type, -1) \ param(int, enable_dc, -1) \ param(int, enable_fbc, -1) \ - param(int, enable_ppgtt, -1) \ param(int, enable_psr, -1) \ param(int, disable_power_well, -1) \ param(int, enable_ips, 1) \ diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index adac75e5d5f7..9ddd2db906ce 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -252,7 +252,7 @@ static const struct intel_device_info intel_ironlake_m_info = { .has_llc = 1, \ .has_rc6 = 1, \ .has_rc6p = 1, \ - .has_aliasing_ppgtt = 1, \ + .ppgtt = INTEL_PPGTT_ALIASING, \ GEN_DEFAULT_PIPEOFFSETS, \ GEN_DEFAULT_PAGE_SIZES, \ CURSOR_OFFSETS @@ -297,8 +297,7 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info = { .has_llc = 1, \ .has_rc6 = 1, \ .has_rc6p = 1, \ - .has_aliasing_ppgtt = 1, \ - .has_full_ppgtt = 1, \ + .ppgtt = INTEL_PPGTT_FULL, \ GEN_DEFAULT_PIPEOFFSETS, \ GEN_DEFAULT_PAGE_SIZES, \ IVB_CURSOR_OFFSETS @@ -351,8 +350,7 @@ static const struct intel_device_info intel_valleyview_info = { .has_rc6 = 1, .has_gmch_display = 1, .has_hotplug = 1, - .has_aliasing_ppgtt = 1, - .has_full_ppgtt = 1, + .ppgtt = INTEL_PPGTT_FULL, .has_snoop = true, .has_coherent_ggtt = false, .ring_mask = RENDER_RING | BSD_RING | BLT_RING, @@ -399,7 +397,7 @@ static const struct intel_device_info intel_haswell_gt3_info = { .page_sizes = I915_GTT_PAGE_SIZE_4K | \ I915_GTT_PAGE_SIZE_2M, \ .has_logical_ring_contexts = 1, \ - .has_full_48bit_ppgtt = 1, \ + .ppgtt = INTEL_PPGTT_FULL_4LVL, \ .has_64bit_reloc = 1, \ .has_reset_engine = 1 @@ -443,8 +441,7 @@ static const struct intel_device_info intel_cherryview_info = { .has_rc6 = 1, .has_logical_ring_contexts = 1, .has_gmch_display = 1, - .has_aliasing_ppgtt = 1, - .has_full_ppgtt = 1, + .ppgtt = INTEL_PPGTT_FULL, .has_reset_engine = 1, .has_snoop = true, .has_coherent_ggtt = false, @@ -520,9 +517,7 @@ static const struct intel_device_info intel_skylake_gt4_info = { .has_logical_ring_contexts = 1, \ .has_logical_ring_preemption = 1, \ .has_guc = 1, \ - .has_aliasing_ppgtt = 1, \ - .has_full_ppgtt = 1, \ - .has_full_48bit_ppgtt = 1, \ + .ppgtt = INTEL_PPGTT_FULL_4LVL, \ .has_reset_engine = 1, \ .has_snoop = true, \ .has_coherent_ggtt = false, \ diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 31f6be774833..03df4e33763d 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -850,6 +850,11 @@ void intel_device_info_runtime_init(struct intel_device_info *info) else if (INTEL_GEN(dev_priv) >= 11) gen11_sseu_info_init(dev_priv); + if (IS_GEN6(dev_priv) && intel_vtd_active()) { + DRM_INFO("Disabling ppGTT for VT-d support\n"); + info->ppgtt = INTEL_PPGTT_NONE; + } + /* Initialize command stream timestamp frequency */ info->cs_timestamp_frequency_khz = read_timestamp_frequency(dev_priv); } diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 6eecd64734d5..af7002640cdf 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -25,6 +25,8 @@ #ifndef _INTEL_DEVICE_INFO_H_ #define _INTEL_DEVICE_INFO_H_ +#include + #include "intel_display.h" struct drm_printer; @@ -74,21 +76,25 @@ enum intel_platform { INTEL_MAX_PLATFORMS }; +enum intel_ppgtt { + INTEL_PPGTT_NONE = I915_GEM_PPGTT_NONE, + INTEL_PPGTT_ALIASING = I915_GEM_PPGTT_ALIASING, + INTEL_PPGTT_FULL = I915_GEM_PPGTT_FULL, + INTEL_PPGTT_FULL_4LVL, +}; + #define DEV_INFO_FOR_EACH_FLAG(func) \ func(is_mobile); \ func(is_lp); \ func(is_alpha_support); \ /* Keep has_* in alphabetical order */ \ func(has_64bit_reloc); \ - func(has_aliasing_ppgtt); \ func(has_csr); \ func(has_ddi); \ func(has_dp_mst); \ func(has_reset_engine); \ func(has_fbc); \ func(has_fpga_dbg); \ - func(has_full_ppgtt); \ - func(has_full_48bit_ppgtt); \ func(has_gmch_display); \ func(has_guc); \ func(has_guc_ct); \ @@ -154,6 +160,7 @@ struct intel_device_info { enum intel_platform platform; u32 platform_mask; + enum intel_ppgtt ppgtt; unsigned int page_sizes; /* page sizes supported by the HW */ u32 display_mmio_offset; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index ad93aa4b0a6e..593999c1e2aa 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -418,9 +418,8 @@ execlists_update_context_pdps(struct i915_hw_ppgtt *ppgtt, u32 *reg_state) static u64 execlists_update_context(struct i915_request *rq) { + struct i915_hw_ppgtt *ppgtt = rq->gem_context->ppgtt; struct intel_context *ce = rq->hw_context; - struct i915_hw_ppgtt *ppgtt = - rq->gem_context->ppgtt ?: rq->i915->mm.aliasing_ppgtt; u32 *reg_state = ce->lrc_reg_state; reg_state[CTX_RING_TAIL+1] = intel_ring_set_tail(rq->ring, rq->tail); @@ -1376,7 +1375,7 @@ execlists_context_pin(struct intel_engine_cs *engine, struct intel_context *ce = to_intel_context(ctx, engine); lockdep_assert_held(&ctx->i915->drm.struct_mutex); - GEM_BUG_ON(!(ctx->ppgtt ?: ctx->i915->mm.aliasing_ppgtt)); + GEM_BUG_ON(!ctx->ppgtt); if (likely(ce->pin_count++)) return ce; @@ -2031,8 +2030,7 @@ static int gen8_emit_bb_start(struct i915_request *rq, * it is unsafe in case of lite-restore (because the ctx is * not idle). PML4 is allocated during ppgtt init so this is * not needed in 48-bit.*/ - if (rq->gem_context->ppgtt && - (intel_engine_flag(rq->engine) & rq->gem_context->ppgtt->pd_dirty_rings) && + if ((intel_engine_flag(rq->engine) & rq->gem_context->ppgtt->pd_dirty_rings) && !i915_vm_is_48bit(&rq->gem_context->ppgtt->vm) && !intel_vgpu_active(rq->i915)) { ret = intel_logical_ring_emit_pdps(rq); @@ -2634,7 +2632,6 @@ static void execlists_init_reg_state(u32 *regs, struct intel_ring *ring) { struct drm_i915_private *dev_priv = engine->i915; - struct i915_hw_ppgtt *ppgtt = ctx->ppgtt ?: dev_priv->mm.aliasing_ppgtt; u32 base = engine->mmio_base; bool rcs = engine->class == RENDER_CLASS; @@ -2706,12 +2703,12 @@ static void execlists_init_reg_state(u32 *regs, CTX_REG(regs, CTX_PDP0_UDW, GEN8_RING_PDP_UDW(engine, 0), 0); CTX_REG(regs, CTX_PDP0_LDW, GEN8_RING_PDP_LDW(engine, 0), 0); - if (i915_vm_is_48bit(&ppgtt->vm)) { + if (i915_vm_is_48bit(&ctx->ppgtt->vm)) { /* 64b PPGTT (48bit canonical) * PDP0_DESCRIPTOR contains the base address to PML4 and * other PDP Descriptors are ignored. */ - ASSIGN_CTX_PML4(ppgtt, regs); + ASSIGN_CTX_PML4(ctx->ppgtt, regs); } if (rcs) { diff --git a/drivers/gpu/drm/i915/selftests/huge_pages.c b/drivers/gpu/drm/i915/selftests/huge_pages.c index 8d03f64eabd7..09ea65a29d98 100644 --- a/drivers/gpu/drm/i915/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/selftests/huge_pages.c @@ -1436,7 +1436,7 @@ static int igt_ppgtt_pin_update(void *arg) * huge-gtt-pages. */ - if (!USES_FULL_48BIT_PPGTT(dev_priv)) { + if (!HAS_FULL_48BIT_PPGTT(dev_priv)) { pr_info("48b PPGTT not supported, skipping\n"); return 0; } @@ -1687,10 +1687,9 @@ int i915_gem_huge_page_mock_selftests(void) SUBTEST(igt_mock_ppgtt_huge_fill), SUBTEST(igt_mock_ppgtt_64K), }; - int saved_ppgtt = i915_modparams.enable_ppgtt; struct drm_i915_private *dev_priv; - struct pci_dev *pdev; struct i915_hw_ppgtt *ppgtt; + struct pci_dev *pdev; int err; dev_priv = mock_gem_device(); @@ -1698,7 +1697,7 @@ int i915_gem_huge_page_mock_selftests(void) return -ENOMEM; /* Pretend to be a device which supports the 48b PPGTT */ - i915_modparams.enable_ppgtt = 3; + mkwrite_device_info(dev_priv)->ppgtt = INTEL_PPGTT_FULL_4LVL; pdev = dev_priv->drm.pdev; dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(39)); @@ -1731,9 +1730,6 @@ out_close: out_unlock: mutex_unlock(&dev_priv->drm.struct_mutex); - - i915_modparams.enable_ppgtt = saved_ppgtt; - drm_dev_put(&dev_priv->drm); return err; @@ -1753,7 +1749,7 @@ int i915_gem_huge_page_live_selftests(struct drm_i915_private *dev_priv) struct i915_gem_context *ctx; int err; - if (!USES_PPGTT(dev_priv)) { + if (!HAS_PPGTT(dev_priv)) { pr_info("PPGTT not supported, skipping live-selftests\n"); return 0; } diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/selftests/i915_gem_context.c index 76df25aa90c9..913c0f83f86a 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_context.c @@ -535,7 +535,6 @@ static int igt_ctx_exec(void *arg) IGT_TIMEOUT(end_time); LIST_HEAD(objects); unsigned long ncontexts, ndwords, dw; - bool first_shared_gtt = true; int err = -ENODEV; /* @@ -561,12 +560,7 @@ static int igt_ctx_exec(void *arg) struct i915_gem_context *ctx; unsigned int id; - if (first_shared_gtt) { - ctx = __create_hw_context(i915, file->driver_priv); - first_shared_gtt = false; - } else { - ctx = i915_gem_create_context(i915, file->driver_priv); - } + ctx = i915_gem_create_context(i915, file->driver_priv); if (IS_ERR(ctx)) { err = PTR_ERR(ctx); goto out_unlock; @@ -865,33 +859,6 @@ out_unlock: return err; } -static int fake_aliasing_ppgtt_enable(struct drm_i915_private *i915) -{ - struct drm_i915_gem_object *obj; - int err; - - err = i915_gem_init_aliasing_ppgtt(i915); - if (err) - return err; - - list_for_each_entry(obj, &i915->mm.bound_list, mm.link) { - struct i915_vma *vma; - - vma = i915_vma_instance(obj, &i915->ggtt.vm, NULL); - if (IS_ERR(vma)) - continue; - - vma->flags &= ~I915_VMA_LOCAL_BIND; - } - - return 0; -} - -static void fake_aliasing_ppgtt_disable(struct drm_i915_private *i915) -{ - i915_gem_fini_aliasing_ppgtt(i915); -} - int i915_gem_context_mock_selftests(void) { static const struct i915_subtest tests[] = { @@ -918,31 +885,9 @@ int i915_gem_context_live_selftests(struct drm_i915_private *dev_priv) SUBTEST(igt_ctx_exec), SUBTEST(igt_ctx_readonly), }; - bool fake_alias = false; - int err; if (i915_terminally_wedged(&dev_priv->gpu_error)) return 0; - /* Install a fake aliasing gtt for exercise */ - if (USES_PPGTT(dev_priv) && !dev_priv->mm.aliasing_ppgtt) { - mutex_lock(&dev_priv->drm.struct_mutex); - err = fake_aliasing_ppgtt_enable(dev_priv); - mutex_unlock(&dev_priv->drm.struct_mutex); - if (err) - return err; - - GEM_BUG_ON(!dev_priv->mm.aliasing_ppgtt); - fake_alias = true; - } - - err = i915_subtests(tests, dev_priv); - - if (fake_alias) { - mutex_lock(&dev_priv->drm.struct_mutex); - fake_aliasing_ppgtt_disable(dev_priv); - mutex_unlock(&dev_priv->drm.struct_mutex); - } - - return err; + return i915_subtests(tests, dev_priv); } diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index 128ad1cf0647..4365979d8222 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -351,7 +351,7 @@ static int igt_evict_contexts(void *arg) * where the GTT space of the request is separate from the GGTT * allocation required to build the request. */ - if (!USES_FULL_PPGTT(i915)) + if (!HAS_FULL_PPGTT(i915)) return 0; mutex_lock(&i915->drm.struct_mutex); diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 8e2e269db97e..17b5aaaa7a50 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -153,7 +153,7 @@ static int igt_ppgtt_alloc(void *arg) /* Allocate a ppggt and try to fill the entire range */ - if (!USES_PPGTT(dev_priv)) + if (!HAS_PPGTT(dev_priv)) return 0; ppgtt = __hw_ppgtt_create(dev_priv); @@ -1001,7 +1001,7 @@ static int exercise_ppgtt(struct drm_i915_private *dev_priv, IGT_TIMEOUT(end_time); int err; - if (!USES_FULL_PPGTT(dev_priv)) + if (!HAS_FULL_PPGTT(dev_priv)) return 0; file = mock_file(dev_priv); diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index a4446f452040..298b2e197744 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -412,6 +412,14 @@ typedef struct drm_i915_irq_wait { int irq_seq; } drm_i915_irq_wait_t; +/* + * Different modes of per-process Graphics Translation Table, + * see I915_PARAM_HAS_ALIASING_PPGTT + */ +#define I915_GEM_PPGTT_NONE 0 +#define I915_GEM_PPGTT_ALIASING 1 +#define I915_GEM_PPGTT_FULL 2 + /* Ioctl to query kernel params: */ #define I915_PARAM_IRQ_ACTIVE 1 -- cgit v1.2.3-59-g8ed1b From 064b06bbf117f8b5e64a5143e970d5a1cf602fd6 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 26 Sep 2018 21:38:36 +0200 Subject: drm/imx: fix build failure without CONFIG_DRM_FBDEV_EMULATION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The variable is declared in an #ifdef section, but the user is now unconditional, which leads to a build failure: drivers/gpu/drm/imx/imx-drm-core.c: In function 'imx_drm_bind': drivers/gpu/drm/imx/imx-drm-core.c:264:6: error: 'legacyfb_depth' undeclared (first use in this function); did you mean 'lockdep_depth'? Remove the remaining #ifdef as well. Fixes: f53705fd9803 ("drm/imx: Use drm_fbdev_generic_setup()") Signed-off-by: Arnd Bergmann Signed-off-by: Noralf Trønnes Link: https://patchwork.freedesktop.org/patch/msgid/20180926193846.2490574-1-arnd@arndb.de --- drivers/gpu/drm/imx/imx-drm-core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index a70f3131a377..0e6942f21a4e 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -35,10 +35,8 @@ #define MAX_CRTC 4 -#if IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) static int legacyfb_depth = 16; module_param(legacyfb_depth, int, 0444); -#endif DEFINE_DRM_GEM_CMA_FOPS(imx_drm_driver_fops); -- cgit v1.2.3-59-g8ed1b From 9531221df8f0cadcf4c03151e2a0204787a77b74 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 9 Sep 2018 15:34:56 +0200 Subject: drm/i915: Check for panel orientation quirks on eDP panels So far we have only been calling drm_connector_init_panel_orientation_property(), which checks for panel orientation quirks in the drm_panel_orientation_quirks.c file, for DSI panels as so far only devices with DSI panels have had panels which are not mounted up right. The new GPD win2 device uses a portrait screen in a landscape case, so now we've a device with an eDP panel which needs the panel-orientation property to let the fbcon code and userspace know that the image needs to be fixed-up. This commit makes intel_edp_init_connector() call drm_connector_init_panel_orientation_property() so that the property gets added. Reported-and-tested-by: russianneuromancer@ya.ru Reviewed-by: Jani Nikula Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20180909133457.10636-2-hdegoede@redhat.com --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6b4c19123f2a..256a71c8c093 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -6490,6 +6490,10 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, intel_connector->panel.backlight.power = intel_edp_backlight_power; intel_panel_setup_backlight(connector, pipe); + if (fixed_mode) + drm_connector_init_panel_orientation_property( + connector, fixed_mode->hdisplay, fixed_mode->vdisplay); + return true; out_vdd_off: -- cgit v1.2.3-59-g8ed1b From 1f0eb8b81089d2bb428521f46bbb78e8073cf5d5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 9 Sep 2018 15:34:57 +0200 Subject: drm: panel-orientation-quirks: Add quirk for GPD win2 GPD has done it again, make a nice device (good), use way too generic DMI strings (bad) and use a portrait screen rotated 90 degrees (ugly). Because of the too generic DMI strings this entry is also doing bios-date matching, so the gpd_win2 data struct may very well need to be updated with some extra bios-dates in the future. Reported-and-tested-by: russianneuromancer@ya.ru Acked-by: Jani Nikula Signed-off-by: Hans de Goede Link: https://patchwork.freedesktop.org/patch/msgid/20180909133457.10636-3-hdegoede@redhat.com --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index fe9c6c731e87..280a41d33081 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -53,6 +53,14 @@ static const struct drm_dmi_panel_orientation_data gpd_win = { .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +static const struct drm_dmi_panel_orientation_data gpd_win2 = { + .width = 720, + .height = 1280, + .bios_dates = (const char * const []){ + "12/07/2017", "05/24/2018", NULL }, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct drm_dmi_panel_orientation_data itworks_tw891 = { .width = 800, .height = 1280, @@ -94,6 +102,14 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), }, .driver_data = (void *)&gpd_win, + }, { /* GPD Win 2 (too generic strings, also match on bios date) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), + }, + .driver_data = (void *)&gpd_win2, }, { /* I.T.Works TW891 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), -- cgit v1.2.3-59-g8ed1b From e077e2f5f8106ed22c245b538f1fba412f864e94 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Wed, 25 Jul 2018 17:46:43 +0200 Subject: drm/panel: simple: fix BOE/HV070WSA-100 timings Panel timings were taken from vendor code and are not fully correct - refresh rate is about 50Hz instead of 60Hz. The patch fixes it. Signed-off-by: Andrzej Hajda Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180725154644.25412-9-a.hajda@samsung.com --- drivers/gpu/drm/panel/panel-simple.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 97964f7f2ace..b5af264ea721 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -773,15 +773,15 @@ static const struct panel_desc avic_tm070ddh03 = { }; static const struct drm_display_mode boe_hv070wsa_mode = { - .clock = 40800, + .clock = 42105, .hdisplay = 1024, - .hsync_start = 1024 + 90, - .hsync_end = 1024 + 90 + 90, - .htotal = 1024 + 90 + 90 + 90, + .hsync_start = 1024 + 30, + .hsync_end = 1024 + 30 + 30, + .htotal = 1024 + 30 + 30 + 30, .vdisplay = 600, - .vsync_start = 600 + 3, - .vsync_end = 600 + 3 + 4, - .vtotal = 600 + 3 + 4 + 3, + .vsync_start = 600 + 10, + .vsync_end = 600 + 10 + 10, + .vtotal = 600 + 10 + 10 + 10, .vrefresh = 60, }; -- cgit v1.2.3-59-g8ed1b From 6bf18d84f768a02618f5518ebc88adb4e71ae2b4 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 26 Jul 2018 00:19:26 -0300 Subject: drm/panel: seiko-43wvf1g: Switch to SPDX identifier Adopt the SPDX license identifier headers to ease license compliance management. Signed-off-by: Fabio Estevam Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/1532575167-14754-1-git-send-email-festevam@gmail.com --- drivers/gpu/drm/panel/panel-seiko-43wvf1g.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c index 75f925390551..70654f9570d3 100644 --- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c +++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2017 NXP Semiconductors. * Author: Marco Franchi * * Based on Panel Simple driver by Thierry Reding - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. */ #include -- cgit v1.2.3-59-g8ed1b From db2b0e5ffc707c709496d55c5bad30e9f36bc238 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 26 Jul 2018 00:19:27 -0300 Subject: drm/panel: seiko-43wvf1g: Add missing ">" character in author's email There is a missing ">" character in Marco's email. Fix it. Signed-off-by: Fabio Estevam Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/1532575167-14754-2-git-send-email-festevam@gmail.com --- drivers/gpu/drm/panel/panel-seiko-43wvf1g.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c index 70654f9570d3..2d99e28ff117 100644 --- a/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c +++ b/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c @@ -363,6 +363,6 @@ static struct platform_driver seiko_panel_platform_driver = { }; module_platform_driver(seiko_panel_platform_driver); -MODULE_AUTHOR("Marco Franchi "); MODULE_DESCRIPTION("Seiko 43WVF1G panel driver"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From 7fe78985cd0881ab60b13320f74df0ed6655f2fe Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 27 Sep 2018 10:53:11 +0300 Subject: drm/i915/csr: restructure CSR firmware definition macros Use uniform prefixes for firmware path, version and size. Unify alignments. Order macro groups as in the if ladder using them. Add platform specific max firmware size macros for all platforms for clarity in the if ladder. Place the max firmware size macros in the platform specific macro groups. No functional changes. Reviewed-by: Chris Wilson Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20180927075311.5076-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_csr.c | 54 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 81935da9cd6b..735ce3ed3159 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c @@ -34,33 +34,35 @@ * low-power state and comes back to normal. */ -#define I915_CSR_ICL "i915/icl_dmc_ver1_07.bin" +#define ICL_CSR_PATH "i915/icl_dmc_ver1_07.bin" #define ICL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) +#define ICL_CSR_MAX_FW_SIZE 0x6000 -#define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" -MODULE_FIRMWARE(I915_CSR_GLK); -#define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) - -#define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin" -MODULE_FIRMWARE(I915_CSR_CNL); +#define CNL_CSR_PATH "i915/cnl_dmc_ver1_07.bin" #define CNL_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) +#define CNL_CSR_MAX_FW_SIZE GLK_CSR_MAX_FW_SIZE +MODULE_FIRMWARE(CNL_CSR_PATH); -#define I915_CSR_KBL "i915/kbl_dmc_ver1_04.bin" -MODULE_FIRMWARE(I915_CSR_KBL); +#define GLK_CSR_PATH "i915/glk_dmc_ver1_04.bin" +#define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) +#define GLK_CSR_MAX_FW_SIZE 0x4000 +MODULE_FIRMWARE(GLK_CSR_PATH); + +#define KBL_CSR_PATH "i915/kbl_dmc_ver1_04.bin" #define KBL_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) +#define KBL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE +MODULE_FIRMWARE(KBL_CSR_PATH); -#define I915_CSR_SKL "i915/skl_dmc_ver1_27.bin" -MODULE_FIRMWARE(I915_CSR_SKL); +#define SKL_CSR_PATH "i915/skl_dmc_ver1_27.bin" #define SKL_CSR_VERSION_REQUIRED CSR_VERSION(1, 27) +#define SKL_CSR_MAX_FW_SIZE BXT_CSR_MAX_FW_SIZE +MODULE_FIRMWARE(SKL_CSR_PATH); -#define I915_CSR_BXT "i915/bxt_dmc_ver1_07.bin" -MODULE_FIRMWARE(I915_CSR_BXT); +#define BXT_CSR_PATH "i915/bxt_dmc_ver1_07.bin" #define BXT_CSR_VERSION_REQUIRED CSR_VERSION(1, 7) - - #define BXT_CSR_MAX_FW_SIZE 0x3000 -#define GLK_CSR_MAX_FW_SIZE 0x4000 -#define ICL_CSR_MAX_FW_SIZE 0x6000 +MODULE_FIRMWARE(BXT_CSR_PATH); + #define CSR_DEFAULT_FW_OFFSET 0xFFFFFFFF struct intel_css_header { @@ -456,27 +458,27 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); if (IS_ICELAKE(dev_priv)) { - csr->fw_path = I915_CSR_ICL; + csr->fw_path = ICL_CSR_PATH; csr->required_version = ICL_CSR_VERSION_REQUIRED; csr->max_fw_size = ICL_CSR_MAX_FW_SIZE; } else if (IS_CANNONLAKE(dev_priv)) { - csr->fw_path = I915_CSR_CNL; + csr->fw_path = CNL_CSR_PATH; csr->required_version = CNL_CSR_VERSION_REQUIRED; - csr->max_fw_size = GLK_CSR_MAX_FW_SIZE; + csr->max_fw_size = CNL_CSR_MAX_FW_SIZE; } else if (IS_GEMINILAKE(dev_priv)) { - csr->fw_path = I915_CSR_GLK; + csr->fw_path = GLK_CSR_PATH; csr->required_version = GLK_CSR_VERSION_REQUIRED; csr->max_fw_size = GLK_CSR_MAX_FW_SIZE; } else if (IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) { - csr->fw_path = I915_CSR_KBL; + csr->fw_path = KBL_CSR_PATH; csr->required_version = KBL_CSR_VERSION_REQUIRED; - csr->max_fw_size = BXT_CSR_MAX_FW_SIZE; + csr->max_fw_size = KBL_CSR_MAX_FW_SIZE; } else if (IS_SKYLAKE(dev_priv)) { - csr->fw_path = I915_CSR_SKL; + csr->fw_path = SKL_CSR_PATH; csr->required_version = SKL_CSR_VERSION_REQUIRED; - csr->max_fw_size = BXT_CSR_MAX_FW_SIZE; + csr->max_fw_size = SKL_CSR_MAX_FW_SIZE; } else if (IS_BROXTON(dev_priv)) { - csr->fw_path = I915_CSR_BXT; + csr->fw_path = BXT_CSR_PATH; csr->required_version = BXT_CSR_VERSION_REQUIRED; csr->max_fw_size = BXT_CSR_MAX_FW_SIZE; } else { -- cgit v1.2.3-59-g8ed1b From 21295ceacff7db926544067c2835d87b52eeefdb Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Tue, 31 Jul 2018 01:11:13 +0200 Subject: dt-bindings: Add vendor prefix for CDTech(H.K.) Electronics Limited This adds a vendor prefix "cdtech" for CDTech(H.K.) Electronics Limited Website: www.cdtech-lcd.com Signed-off-by: Giulio Benetti Reviewed-by: Rob Herring Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180730231117.5631-2-giulio.benetti@micronovasrl.com --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 2c3fc512e746..0f5453d1823c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -67,6 +67,7 @@ capella Capella Microsystems, Inc cascoda Cascoda, Ltd. cavium Cavium, Inc. cdns Cadence Design Systems Inc. +cdtech CDTech(H.K.) Electronics Limited ceva Ceva, Inc. chipidea Chipidea, Inc chipone ChipOne -- cgit v1.2.3-59-g8ed1b From 982f944ed7cff2d656dce1a9679de45d052b7a07 Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Tue, 31 Jul 2018 01:11:14 +0200 Subject: drm/panel: add panel CDTech S070WV95-CT16 to panel-simple This patch adds support for CDTech S070WV95-CT16 800x480 7" panel to DRM simple panel driver. Signed-off-by: Giulio Benetti Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180730231117.5631-3-giulio.benetti@micronovasrl.com --- drivers/gpu/drm/panel/panel-simple.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index b5af264ea721..ad90dc1e2e6b 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -836,6 +836,30 @@ static const struct panel_desc boe_nv101wxmn51 = { }, }; +static const struct drm_display_mode cdtech_s070wv95_ct16_mode = { + .clock = 35000, + .hdisplay = 800, + .hsync_start = 800 + 40, + .hsync_end = 800 + 40 + 40, + .htotal = 800 + 40 + 40 + 48, + .vdisplay = 480, + .vsync_start = 480 + 29, + .vsync_end = 480 + 29 + 13, + .vtotal = 480 + 29 + 13 + 3, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, +}; + +static const struct panel_desc cdtech_s070wv95_ct16 = { + .modes = &cdtech_s070wv95_ct16_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 154, + .height = 85, + }, +}; + static const struct drm_display_mode chunghwa_claa070wp03xg_mode = { .clock = 66770, .hdisplay = 800, @@ -2375,6 +2399,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "boe,nv101wxmn51", .data = &boe_nv101wxmn51, + }, { + .compatible = "cdtech,s070wv95-ct16", + .data = &cdtech_s070wv95_ct16, }, { .compatible = "chunghwa,claa070wp03xg", .data = &chunghwa_claa070wp03xg, -- cgit v1.2.3-59-g8ed1b From 1a4d3f24efcb2a733cab7a872bb0a0634cfdec5a Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Tue, 31 Jul 2018 01:11:15 +0200 Subject: dt-bindings: Add CDTech S070WV95-CT16 panel bindings Add documentation for S070WV95-CT16 panel Signed-off-by: Giulio Benetti Reviewed-by: Rob Herring Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180730231117.5631-4-giulio.benetti@micronovasrl.com --- .../bindings/display/panel/cdtech,s070wv95-ct16.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/cdtech,s070wv95-ct16.txt diff --git a/Documentation/devicetree/bindings/display/panel/cdtech,s070wv95-ct16.txt b/Documentation/devicetree/bindings/display/panel/cdtech,s070wv95-ct16.txt new file mode 100644 index 000000000000..505615dfa0df --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/cdtech,s070wv95-ct16.txt @@ -0,0 +1,12 @@ +CDTech(H.K.) Electronics Limited 7" 800x480 color TFT-LCD panel + +Required properties: +- compatible: should be "cdtech,s070wv95-ct16" +- power-supply: as specified in the base binding + +Optional properties: +- backlight: as specified in the base binding +- enable-gpios: as specified in the base binding + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. -- cgit v1.2.3-59-g8ed1b From e58edce616ac0845fb3e6e368b2e9c08f3b04006 Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Tue, 31 Jul 2018 01:11:16 +0200 Subject: drm/panel: add panel CDTech S043WQ26H-CT7 to panel-simple This patch adds support for CDTech S043WQ26H-CT7 480x272 4.3" panel to DRM simple panel driver. Signed-off-by: Giulio Benetti Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180730231117.5631-5-giulio.benetti@micronovasrl.com --- drivers/gpu/drm/panel/panel-simple.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index ad90dc1e2e6b..5e5547b42f5a 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -836,6 +836,31 @@ static const struct panel_desc boe_nv101wxmn51 = { }, }; +static const struct drm_display_mode cdtech_s043wq26h_ct7_mode = { + .clock = 9000, + .hdisplay = 480, + .hsync_start = 480 + 5, + .hsync_end = 480 + 5 + 5, + .htotal = 480 + 5 + 5 + 40, + .vdisplay = 272, + .vsync_start = 272 + 8, + .vsync_end = 272 + 8 + 8, + .vtotal = 272 + 8 + 8 + 8, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, +}; + +static const struct panel_desc cdtech_s043wq26h_ct7 = { + .modes = &cdtech_s043wq26h_ct7_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 95, + .height = 54, + }, + .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE, +}; + static const struct drm_display_mode cdtech_s070wv95_ct16_mode = { .clock = 35000, .hdisplay = 800, @@ -2399,6 +2424,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "boe,nv101wxmn51", .data = &boe_nv101wxmn51, + }, { + .compatible = "cdtech,s043wq26h-ct7", + .data = &cdtech_s043wq26h_ct7, }, { .compatible = "cdtech,s070wv95-ct16", .data = &cdtech_s070wv95_ct16, -- cgit v1.2.3-59-g8ed1b From 94889b487bb9c2560226fc7dac08d28561e340b4 Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Tue, 31 Jul 2018 01:11:17 +0200 Subject: dt-bindings: Add CDTech S043WQ26H-CT7 panel bindings Add documentation for S043WQ26H-CT7 panel Signed-off-by: Giulio Benetti Reviewed-by: Rob Herring Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180730231117.5631-6-giulio.benetti@micronovasrl.com --- .../bindings/display/panel/cdtech,s043wq26h-ct7.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/cdtech,s043wq26h-ct7.txt diff --git a/Documentation/devicetree/bindings/display/panel/cdtech,s043wq26h-ct7.txt b/Documentation/devicetree/bindings/display/panel/cdtech,s043wq26h-ct7.txt new file mode 100644 index 000000000000..057f7f3f6dbe --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/cdtech,s043wq26h-ct7.txt @@ -0,0 +1,12 @@ +CDTech(H.K.) Electronics Limited 4.3" 480x272 color TFT-LCD panel + +Required properties: +- compatible: should be "cdtech,s043wq26h-ct7" +- power-supply: as specified in the base binding + +Optional properties: +- backlight: as specified in the base binding +- enable-gpios: as specified in the base binding + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. -- cgit v1.2.3-59-g8ed1b From 882c35af565a352d3183bd4cb2f9e59414521f87 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Thu, 16 Aug 2018 16:09:20 +0200 Subject: drm/panel: p079zca: unconditionally remove the panel on removal There is no need to check innolux->base.dev when trying to remove the panel, as that variable is always set directly before the panel gets added and will still be available on panel_remove. Signed-off-by: Heiko Stuebner Reviewed-by: Philipp Zabel Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180816140920.5009-1-heiko@sntech.de --- drivers/gpu/drm/panel/panel-innolux-p079zca.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c index 72edb334d997..ca4ae45dd307 100644 --- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c +++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c @@ -506,8 +506,7 @@ static int innolux_panel_add(struct mipi_dsi_device *dsi, static void innolux_panel_del(struct innolux_panel *innolux) { - if (innolux->base.dev) - drm_panel_remove(&innolux->base); + drm_panel_remove(&innolux->base); } static int innolux_panel_probe(struct mipi_dsi_device *dsi) -- cgit v1.2.3-59-g8ed1b From 7ad8b41cd8f5c2842646d01cdd576663caee04a7 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 7 Sep 2018 12:19:46 +0800 Subject: drm/panel: simple: Add support for Banana Pi 7" S070WV20-CT16 panel This panel is marketed as Banana Pi 7" LCD display. On the back is a sticker denoting the model name S070WV20-CT16. This is a 7" 800x480 panel connected through a 24-bit RGB interface. However the panel only does 262k colors. Depending on the variant, the PCB attached to the panel module either supports DSI, or DSI + 24-bit RGB. DSI is converted to 24-bit RGB via an onboard ICN6211 MIPI DSI - RGB bridge chip, then fed to the panel itself. Signed-off-by: Chen-Yu Tsai Reviewed-by: Rob Herring Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180907041948.19913-5-wens@csie.org --- .../display/panel/bananapi,s070wv20-ct16.txt | 12 +++++++++++ drivers/gpu/drm/panel/panel-simple.c | 25 ++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/bananapi,s070wv20-ct16.txt diff --git a/Documentation/devicetree/bindings/display/panel/bananapi,s070wv20-ct16.txt b/Documentation/devicetree/bindings/display/panel/bananapi,s070wv20-ct16.txt new file mode 100644 index 000000000000..35bc0c839f49 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/bananapi,s070wv20-ct16.txt @@ -0,0 +1,12 @@ +Banana Pi 7" (S070WV20-CT16) TFT LCD Panel + +Required properties: +- compatible: should be "bananapi,s070wv20-ct16" +- power-supply: see ./panel-common.txt + +Optional properties: +- enable-gpios: see ./simple-panel.txt +- backlight: see ./simple-panel.txt + +This binding is compatible with the simple-panel binding, which is specified +in ./simple-panel.txt. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5e5547b42f5a..5f3f061aed5f 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -772,6 +772,28 @@ static const struct panel_desc avic_tm070ddh03 = { }, }; +static const struct drm_display_mode bananapi_s070wv20_ct16_mode = { + .clock = 30000, + .hdisplay = 800, + .hsync_start = 800 + 40, + .hsync_end = 800 + 40 + 48, + .htotal = 800 + 40 + 48 + 40, + .vdisplay = 480, + .vsync_start = 480 + 13, + .vsync_end = 480 + 13 + 3, + .vtotal = 480 + 13 + 3 + 29, +}; + +static const struct panel_desc bananapi_s070wv20_ct16 = { + .modes = &bananapi_s070wv20_ct16_mode, + .num_modes = 1, + .bpc = 6, + .size = { + .width = 154, + .height = 86, + }, +}; + static const struct drm_display_mode boe_hv070wsa_mode = { .clock = 42105, .hdisplay = 1024, @@ -2418,6 +2440,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "avic,tm070ddh03", .data = &avic_tm070ddh03, + }, { + .compatible = "bananapi,s070wv20-ct16", + .data = &bananapi_s070wv20_ct16, }, { .compatible = "boe,hv070wsa-100", .data = &boe_hv070wsa -- cgit v1.2.3-59-g8ed1b From 6cbe7cd15f953a8bb49cab9b85077e1ee4e0e999 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Mon, 24 Sep 2018 17:26:10 +0200 Subject: drm/panel: simple: Add DLC1010GIG panel Add support for the DLC DLC1010GIG 1280x800 10.1" LVDS panel to the simple-panel driver. Signed-off-by: Marco Felsch Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/20180924152610.25939-1-m.felsch@pengutronix.de --- .../bindings/display/panel/dlc,dlc1010gig.txt | 12 ++++++++ drivers/gpu/drm/panel/panel-simple.c | 33 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/dlc,dlc1010gig.txt diff --git a/Documentation/devicetree/bindings/display/panel/dlc,dlc1010gig.txt b/Documentation/devicetree/bindings/display/panel/dlc,dlc1010gig.txt new file mode 100644 index 000000000000..fbf5dcd15661 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/dlc,dlc1010gig.txt @@ -0,0 +1,12 @@ +DLC Display Co. DLC1010GIG 10.1" WXGA TFT LCD Panel + +Required properties: +- compatible: should be "dlc,dlc1010gig" +- power-supply: See simple-panel.txt + +Optional properties: +- enable-gpios: See simple-panel.txt +- backlight: See simple-panel.txt + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5f3f061aed5f..90296090340e 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1032,6 +1032,36 @@ static const struct panel_desc dlc_dlc0700yzg_1 = { .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, }; +static const struct display_timing dlc_dlc1010gig_timing = { + .pixelclock = { 68900000, 71100000, 73400000 }, + .hactive = { 1280, 1280, 1280 }, + .hfront_porch = { 43, 53, 63 }, + .hback_porch = { 43, 53, 63 }, + .hsync_len = { 44, 54, 64 }, + .vactive = { 800, 800, 800 }, + .vfront_porch = { 5, 8, 11 }, + .vback_porch = { 5, 8, 11 }, + .vsync_len = { 5, 7, 11 }, + .flags = DISPLAY_FLAGS_DE_HIGH, +}; + +static const struct panel_desc dlc_dlc1010gig = { + .timings = &dlc_dlc1010gig_timing, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 216, + .height = 135, + }, + .delay = { + .prepare = 60, + .enable = 150, + .disable = 100, + .unprepare = 60, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, +}; + static const struct drm_display_mode edt_et057090dhu_mode = { .clock = 25175, .hdisplay = 640, @@ -2470,6 +2500,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "dlc,dlc0700yzg-1", .data = &dlc_dlc0700yzg_1, + }, { + .compatible = "dlc,dlc1010gig", + .data = &dlc_dlc1010gig, }, { .compatible = "edt,et057090dhu", .data = &edt_et057090dhu, -- cgit v1.2.3-59-g8ed1b From 17fd7a9d324fd3af613ddd76f0439481acaad23d Mon Sep 17 00:00:00 2001 From: Stefan Mavrodiev Date: Thu, 12 Jul 2018 11:21:53 +0300 Subject: drm/panel: Add support for Olimex LCD-OLinuXino panel This patch adds Olimex Ltd. LCD-OLinuXino bridge panel driver. The panel is used with different LCDs (currently from 480x272 to 1280x800). A small EEPROM chip is used for identification, which holds some factory data and timing requirements. Signed-off-by: Stefan Mavrodiev Reviewed-by: Rob Herring Signed-off-by: Thierry Reding Link: https://patchwork.freedesktop.org/patch/msgid/1531383729-13932-1-git-send-email-stefan@olimex.com --- .../display/panel/olimex,lcd-olinuxino.txt | 42 +++ MAINTAINERS | 6 + drivers/gpu/drm/panel/Kconfig | 12 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c | 330 +++++++++++++++++++++ 5 files changed, 391 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt create mode 100644 drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c diff --git a/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt b/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt new file mode 100644 index 000000000000..a89f9c830a85 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt @@ -0,0 +1,42 @@ +Binding for Olimex Ltd. LCD-OLinuXino bridge panel. + +This device can be used as bridge between a host controller and LCD panels. +Currently supported LCDs are: + - LCD-OLinuXino-4.3TS + - LCD-OLinuXino-5 + - LCD-OLinuXino-7 + - LCD-OLinuXino-10 + +The panel itself contains: + - AT24C16C EEPROM holding panel identification and timing requirements + - AR1021 resistive touch screen controller (optional) + - FT5x6 capacitive touch screnn controller (optional) + - GT911/GT928 capacitive touch screen controller (optional) + +The above chips share same I2C bus. The EEPROM is factory preprogrammed with +device information (id, serial, etc.) and timing requirements. + +Touchscreen bingings can be found in these files: + - input/touchscreen/goodix.txt + - input/touchscreen/edt-ft5x06.txt + - input/touchscreen/ar1021.txt + +Required properties: + - compatible: should be "olimex,lcd-olinuxino" + - reg: address of the configuration EEPROM, should be <0x50> + - power-supply: phandle of the regulator that provides the supply voltage + +Optional properties: + - enable-gpios: GPIO pin to enable or disable the panel + - backlight: phandle of the backlight device attacked to the panel + +Example: +&i2c2 { + panel@50 { + compatible = "olimex,lcd-olinuxino"; + reg = <0x50>; + power-supply = <®_vcc5v0>; + enable-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>; + backlight = <&backlight>; + }; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 94c1fef3279b..39c3f6682ace 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4664,6 +4664,12 @@ S: Supported F: drivers/gpu/drm/nouveau/ F: include/uapi/drm/nouveau_drm.h +DRM DRIVER FOR OLIMEX LCD-OLINUXINO PANELS +M: Stefan Mavrodiev +S: Maintained +F: drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c +F: Documentation/devicetree/bindings/display/panel/olimex,lcd-olinuxino.txt + DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS M: Noralf Trønnes S: Maintained diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 6020c30a33b3..3af05c868373 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -90,6 +90,18 @@ config DRM_PANEL_LG_LG4573 Say Y here if you want to enable support for LG4573 RGB panel. To compile this driver as a module, choose M here. +config DRM_PANEL_OLIMEX_LCD_OLINUXINO + tristate "Olimex LCD-OLinuXino panel" + depends on OF + depends on I2C + depends on BACKLIGHT_CLASS_DEVICE + help + The panel is used with different sizes LCDs, from 480x272 to + 1280x800, and 24 bit per pixel. + + Say Y here if you want to enable support for Olimex Ltd. + LCD-OLinuXino panel. + config DRM_PANEL_ORISETECH_OTM8009A tristate "Orise Technology otm8009a 480x800 dsi 2dl panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 5ccaaa9d13af..9153e451b6b1 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o +obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o diff --git a/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c new file mode 100644 index 000000000000..5e8d4523e9ed --- /dev/null +++ b/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * LCD-OLinuXino support for panel driver + * + * Copyright (C) 2018 Olimex Ltd. + * Author: Stefan Mavrodiev + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include