From d758619ba6a5d250914b06b2b923a65e48bdd002 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 10 Jun 2017 11:59:43 +0300 Subject: drm: dw-hdmi: Fix compilation breakage by selecting REGMAP_MMIO The dw-hdmi driver switched to regmap-mmio, but lacks the dependency in Kconfig. This can result in compilation breakages. Fix it by selecting REGMAP_MMIO. Fixes: 80e2f97968b5 ("drm: bridge: dw-hdmi: Switch to regmap for register access") Reported-by: kbuild test robot Signed-off-by: Laurent Pinchart Signed-off-by: Archit Taneja Link: http://patchwork.freedesktop.org/patch/msgid/20170610085943.15788-1-laurent.pinchart+renesas@ideasonboard.com --- drivers/gpu/drm/bridge/synopsys/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/synopsys/Kconfig b/drivers/gpu/drm/bridge/synopsys/Kconfig index 40d2827a6d19..53e78d092d18 100644 --- a/drivers/gpu/drm/bridge/synopsys/Kconfig +++ b/drivers/gpu/drm/bridge/synopsys/Kconfig @@ -1,6 +1,7 @@ config DRM_DW_HDMI tristate select DRM_KMS_HELPER + select REGMAP_MMIO config DRM_DW_HDMI_AHB_AUDIO tristate "Synopsys Designware AHB Audio interface" -- cgit v1.2.3-70-g09d2 From 9a775e0308b575e3a17c66a586ed049b07f48199 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 8 Jun 2017 17:40:01 +0300 Subject: drm/i915: Fix scaling check for 90/270 degree plane rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting from commit b63a16f6cd89 ("drm/i915: Compute display surface offset in the plane check hook for SKL+") we've already rotated the src coordinates by 270 degrees by the time we check if a scaler is needed or not, so we must not account for the rotation a second time. Previously we did these steps in the opposite order and hence the scaler check had to deal with rotation itself. The double rotation handling causes us to enable a scaler pretty much every time 90/270 degree plane rotation is requested, leading to fuzzier fonts and whatnot. v2: s/unsigned/unsigned int/ to appease checkpatch v3: s/DRM_ROTATE_0/DRM_MODE_ROTATE_0/ Cc: stable@vger.kernel.org Cc: Tvrtko Ursulin Reported-by: Tvrtko Ursulin Tested-by: Tvrtko Ursulin Fixes: b63a16f6cd89 ("drm/i915: Compute display surface offset in the plane check hook for SKL+") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/20170331180056.14086-2-ville.syrjala@linux.intel.com Reviewed-by: Maarten Lankhorst (cherry picked from commit d96a7d2adb040a67e163a82dad6316f9f572498a) Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/20170608144002.1605-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_display.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 569717a12723..96b0b01677e2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4598,7 +4598,7 @@ static void cpt_verify_modeset(struct drm_device *dev, int pipe) static int skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, - unsigned scaler_user, int *scaler_id, unsigned int rotation, + unsigned int scaler_user, int *scaler_id, int src_w, int src_h, int dst_w, int dst_h) { struct intel_crtc_scaler_state *scaler_state = @@ -4607,9 +4607,12 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach, to_intel_crtc(crtc_state->base.crtc); int need_scaling; - need_scaling = drm_rotation_90_or_270(rotation) ? - (src_h != dst_w || src_w != dst_h): - (src_w != dst_w || src_h != dst_h); + /* + * Src coordinates are already rotated by 270 degrees for + * the 90/270 degree plane rotation cases (to match the + * GTT mapping), hence no need to account for rotation here. + */ + need_scaling = src_w != dst_w || src_h != dst_h; /* * if plane is being disabled or scaler is no more required or force detach @@ -4671,7 +4674,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state) const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode; return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX, - &state->scaler_state.scaler_id, DRM_ROTATE_0, + &state->scaler_state.scaler_id, state->pipe_src_w, state->pipe_src_h, adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay); } @@ -4700,7 +4703,6 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state, ret = skl_update_scaler(crtc_state, force_detach, drm_plane_index(&intel_plane->base), &plane_state->scaler_id, - plane_state->base.rotation, drm_rect_width(&plane_state->base.src) >> 16, drm_rect_height(&plane_state->base.src) >> 16, drm_rect_width(&plane_state->base.dst), -- cgit v1.2.3-70-g09d2 From 1c2d6bbf0433ddf7c978ac5f2bd582e9e7d34687 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 8 Jun 2017 17:40:02 +0300 Subject: drm/i915: Fix SKL+ watermarks for 90/270 rotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit skl_check_plane_surface() already rotates the clipped plane source coordinates to match the scanout direction because that's the way the GTT mapping is set up. Thus we no longer need to rotate the coordinates in the watermark code. For cursors we use the non-clipped coordinates which are not rotated appropriately, but that doesn't actually matter since cursors don't even support 90/270 degree rotation. v2: Resolve conflicts from SKL+ wm rework Cc: stable@vger.kernel.org Cc: Tvrtko Ursulin Fixes: b63a16f6cd89 ("drm/i915: Compute display surface offset in the plane check hook for SKL+") Signed-off-by: Ville Syrjälä Link: http://patchwork.freedesktop.org/patch/msgid/20170331180056.14086-3-ville.syrjala@linux.intel.com Tested-by: Tvrtko Ursulin Reviewed-by: Maarten Lankhorst (cherry picked from commit fce5adf568abb1e8264d677156e2e0deb529194d) Signed-off-by: Jani Nikula Link: http://patchwork.freedesktop.org/patch/msgid/20170608144002.1605-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/intel_pm.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2ca481b5aa69..078fd1bfa5ea 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3373,20 +3373,26 @@ skl_plane_downscale_amount(const struct intel_crtc_state *cstate, /* n.b., src is 16.16 fixed point, dst is whole integer */ if (plane->id == PLANE_CURSOR) { + /* + * Cursors only support 0/180 degree rotation, + * hence no need to account for rotation here. + */ src_w = pstate->base.src_w; src_h = pstate->base.src_h; dst_w = pstate->base.crtc_w; dst_h = pstate->base.crtc_h; } else { + /* + * Src coordinates are already rotated by 270 degrees for + * the 90/270 degree plane rotation cases (to match the + * GTT mapping), hence no need to account for rotation here. + */ src_w = drm_rect_width(&pstate->base.src); src_h = drm_rect_height(&pstate->base.src); dst_w = drm_rect_width(&pstate->base.dst); dst_h = drm_rect_height(&pstate->base.dst); } - if (drm_rotation_90_or_270(pstate->base.rotation)) - swap(dst_w, dst_h); - downscale_h = max(src_h / dst_h, (uint32_t)DRM_PLANE_HELPER_NO_SCALING); downscale_w = max(src_w / dst_w, (uint32_t)DRM_PLANE_HELPER_NO_SCALING); @@ -3417,12 +3423,14 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, if (y && format != DRM_FORMAT_NV12) return 0; + /* + * Src coordinates are already rotated by 270 degrees for + * the 90/270 degree plane rotation cases (to match the + * GTT mapping), hence no need to account for rotation here. + */ width = drm_rect_width(&intel_pstate->base.src) >> 16; height = drm_rect_height(&intel_pstate->base.src) >> 16; - if (drm_rotation_90_or_270(pstate->rotation)) - swap(width, height); - /* for planar format */ if (format == DRM_FORMAT_NV12) { if (y) /* y-plane data rate */ @@ -3505,12 +3513,14 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate, fb->modifier != I915_FORMAT_MOD_Yf_TILED) return 8; + /* + * Src coordinates are already rotated by 270 degrees for + * the 90/270 degree plane rotation cases (to match the + * GTT mapping), hence no need to account for rotation here. + */ src_w = drm_rect_width(&intel_pstate->base.src) >> 16; src_h = drm_rect_height(&intel_pstate->base.src) >> 16; - if (drm_rotation_90_or_270(pstate->rotation)) - swap(src_w, src_h); - /* Halve UV plane width and height for NV12 */ if (fb->format->format == DRM_FORMAT_NV12 && !y) { src_w /= 2; @@ -3794,13 +3804,15 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, width = intel_pstate->base.crtc_w; height = intel_pstate->base.crtc_h; } else { + /* + * Src coordinates are already rotated by 270 degrees for + * the 90/270 degree plane rotation cases (to match the + * GTT mapping), hence no need to account for rotation here. + */ width = drm_rect_width(&intel_pstate->base.src) >> 16; height = drm_rect_height(&intel_pstate->base.src) >> 16; } - if (drm_rotation_90_or_270(pstate->rotation)) - swap(width, height); - cpp = fb->format->cpp[0]; plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate); -- cgit v1.2.3-70-g09d2 From c380f681245d7ae57f17d9ebbbe8f8f1557ee1fb Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 9 Jun 2017 15:48:05 +0800 Subject: drm/i915: Fix GVT-g PVINFO version compatibility check Current it's strictly checked if PVINFO version matches 1.0 for GVT-g i915 guest which doesn't help for compatibility at all and forces GVT-g host can't extend PVINFO easily with version bump for real compatibility check. This fixes that to check minimal required PVINFO version instead. v2: - drop unneeded version macro - use only major version for sanity check v3: - fix up PVInfo value with kernel type - one indent fix Reviewed-by: Joonas Lahtinen Cc: Chuanxiao Dong Cc: Joonas Lahtinen Cc: stable@vger.kernel.org # v4.10+ Signed-off-by: Zhenyu Wang Signed-off-by: Joonas Lahtinen Link: http://patchwork.freedesktop.org/patch/msgid/20170609074805.5101-1-zhenyuw@linux.intel.com (cherry picked from commit 0c8792d00d38de85b6ceb1dd67d3ee009d7c8e42) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_pvinfo.h | 8 ++------ drivers/gpu/drm/i915/i915_vgpu.c | 10 ++++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h index c0cb2974caac..2cfe96d3e5d1 100644 --- a/drivers/gpu/drm/i915/i915_pvinfo.h +++ b/drivers/gpu/drm/i915/i915_pvinfo.h @@ -36,10 +36,6 @@ #define VGT_VERSION_MAJOR 1 #define VGT_VERSION_MINOR 0 -#define INTEL_VGT_IF_VERSION_ENCODE(major, minor) ((major) << 16 | (minor)) -#define INTEL_VGT_IF_VERSION \ - INTEL_VGT_IF_VERSION_ENCODE(VGT_VERSION_MAJOR, VGT_VERSION_MINOR) - /* * notifications from guest to vgpu device model */ @@ -55,8 +51,8 @@ enum vgt_g2v_type { struct vgt_if { u64 magic; /* VGT_MAGIC */ - uint16_t version_major; - uint16_t version_minor; + u16 version_major; + u16 version_minor; u32 vgt_id; /* ID of vGT instance */ u32 rsv1[12]; /* pad to offset 0x40 */ /* diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c index 4ab8a973b61f..2e739018fb4c 100644 --- a/drivers/gpu/drm/i915/i915_vgpu.c +++ b/drivers/gpu/drm/i915/i915_vgpu.c @@ -60,8 +60,8 @@ */ void i915_check_vgpu(struct drm_i915_private *dev_priv) { - uint64_t magic; - uint32_t version; + u64 magic; + u16 version_major; BUILD_BUG_ON(sizeof(struct vgt_if) != VGT_PVINFO_SIZE); @@ -69,10 +69,8 @@ void i915_check_vgpu(struct drm_i915_private *dev_priv) if (magic != VGT_MAGIC) return; - version = INTEL_VGT_IF_VERSION_ENCODE( - __raw_i915_read16(dev_priv, vgtif_reg(version_major)), - __raw_i915_read16(dev_priv, vgtif_reg(version_minor))); - if (version != INTEL_VGT_IF_VERSION) { + version_major = __raw_i915_read16(dev_priv, vgtif_reg(version_major)); + if (version_major < VGT_VERSION_MAJOR) { DRM_INFO("VGT interface version mismatch!\n"); return; } -- cgit v1.2.3-70-g09d2 From c0f83da96b906ea331e2eea2bd5d2e7f221d27ab Mon Sep 17 00:00:00 2001 From: Christian König Date: Thu, 18 May 2017 10:31:01 +0200 Subject: drm/radeon: fix "force the UVD DPB into VRAM as well" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DPB must be in VRAM, but not in the first segment. Signed-off-by: Christian König Tested-by: Arthur Marsh Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_uvd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 7431eb4a11b7..d34d1cf33895 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -621,7 +621,7 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, } /* TODO: is this still necessary on NI+ ? */ - if ((cmd == 0 || cmd == 1 || cmd == 0x3) && + if ((cmd == 0 || cmd == 0x3) && (start >> 28) != (p->rdev->uvd.gpu_addr >> 28)) { DRM_ERROR("msg/fb buffer %LX-%LX out of 256MB segment!\n", start, end); -- cgit v1.2.3-70-g09d2 From bea10413934dcf98cb9b2dfcdc56e1d28f192897 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Tue, 13 Jun 2017 07:17:10 +0200 Subject: drm/amdgpu: Fix overflow of watermark calcs at > 4k resolutions. Commit d63c277dc672e0 ("drm/amdgpu: Make display watermark calculations more accurate") made watermark calculations more accurate, but not for > 4k resolutions on 32-Bit architectures, as it introduced an integer overflow for those setups and resolutions. Fix this by proper u64 casting and division. Signed-off-by: Mario Kleiner Reported-by: Ben Hutchings Fixes: d63c277dc672 ("drm/amdgpu: Make display watermark calculations more accurate") Cc: Ben Hutchings Cc: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 7 +++++-- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 7 +++++-- drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 7 +++++-- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 7 +++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 0cdeb6a2e4a0..5dffa27afa45 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -1207,8 +1207,11 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { - active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; - line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, + (u32)mode->clock); + line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, + (u32)mode->clock); + line_time = min(line_time, (u32)65535); /* watermark for high clocks */ if (adev->pm.dpm_enabled) { diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 773654a19749..47bbc87f96d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -1176,8 +1176,11 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { - active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; - line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, + (u32)mode->clock); + line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, + (u32)mode->clock); + line_time = min(line_time, (u32)65535); /* watermark for high clocks */ if (adev->pm.dpm_enabled) { diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index 1f3552967ba3..d8c9a959493e 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -983,8 +983,11 @@ static void dce_v6_0_program_watermarks(struct amdgpu_device *adev, fixed20_12 a, b, c; if (amdgpu_crtc->base.enabled && num_heads && mode) { - active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; - line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, + (u32)mode->clock); + line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, + (u32)mode->clock); + line_time = min(line_time, (u32)65535); priority_a_cnt = 0; priority_b_cnt = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 3c558c170e5e..db30c6ba563a 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -1091,8 +1091,11 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { - active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; - line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, + (u32)mode->clock); + line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, + (u32)mode->clock); + line_time = min(line_time, (u32)65535); /* watermark for high clocks */ if (adev->pm.dpm_enabled) { -- cgit v1.2.3-70-g09d2 From 55f61a040e1b1ea0ba962e53ae341b4c51915bd1 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Tue, 13 Jun 2017 07:17:11 +0200 Subject: drm/radeon: Fix overflow of watermark calcs at > 4k resolutions. Commit e6b9a6c84b93 ("drm/radeon: Make display watermark calculations more accurate") made watermark calculations more accurate, but not for > 4k resolutions on 32-Bit architectures, as it introduced an integer overflow for those setups and resolutions. Fix this by proper u64 casting and division. Signed-off-by: Mario Kleiner Reported-by: Ben Hutchings Fixes: e6b9a6c84b93 ("drm/radeon: Make display watermark calculations more accurate") Cc: Ben Hutchings Cc: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/cik.c | 7 +++++-- drivers/gpu/drm/radeon/evergreen.c | 7 +++++-- drivers/gpu/drm/radeon/si.c | 7 +++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 008c145b7f29..ca44233ceacc 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -9267,8 +9267,11 @@ static void dce8_program_watermarks(struct radeon_device *rdev, u32 tmp, wm_mask; if (radeon_crtc->base.enabled && num_heads && mode) { - active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; - line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, + (u32)mode->clock); + line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, + (u32)mode->clock); + line_time = min(line_time, (u32)65535); /* watermark for high clocks */ if ((rdev->pm.pm_method == PM_METHOD_DPM) && diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 0bf103536404..534637203e70 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2266,8 +2266,11 @@ static void evergreen_program_watermarks(struct radeon_device *rdev, fixed20_12 a, b, c; if (radeon_crtc->base.enabled && num_heads && mode) { - active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; - line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, + (u32)mode->clock); + line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, + (u32)mode->clock); + line_time = min(line_time, (u32)65535); priority_a_cnt = 0; priority_b_cnt = 0; dram_channels = evergreen_get_number_of_dram_channels(rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 76d1888528e6..5303f25d5280 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2284,8 +2284,11 @@ static void dce6_program_watermarks(struct radeon_device *rdev, fixed20_12 a, b, c; if (radeon_crtc->base.enabled && num_heads && mode) { - active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock; - line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535); + active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, + (u32)mode->clock); + line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, + (u32)mode->clock); + line_time = min(line_time, (u32)65535); priority_a_cnt = 0; priority_b_cnt = 0; -- cgit v1.2.3-70-g09d2 From 59e04bc20de4bd1bd5bfa810bf04a4e50a27b9c1 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 10 Apr 2017 22:29:22 +0200 Subject: gpu: host1x: Fix error handling If 'devm_reset_control_get' returns an error, then we erroneously return success because error code is taken from 'host->clk' instead of 'host->rst'. Fixes: b386c6b73ac6 ("gpu: host1x: Support module reset") Signed-off-by: Christophe JAILLET Reviewed-by: Mikko Perttunen Signed-off-by: Thierry Reding Link: http://patchwork.freedesktop.org/patch/msgid/20170410202922.17665-1-christophe.jaillet@wanadoo.fr --- drivers/gpu/host1x/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index f05ebb14fa63..ac65f52850a6 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -172,7 +172,7 @@ static int host1x_probe(struct platform_device *pdev) host->rst = devm_reset_control_get(&pdev->dev, "host1x"); if (IS_ERR(host->rst)) { - err = PTR_ERR(host->clk); + err = PTR_ERR(host->rst); dev_err(&pdev->dev, "failed to get reset: %d\n", err); return err; } -- cgit v1.2.3-70-g09d2 From 1066a8959d04785b9d2e9cbb91aaef922b710c4a Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 15 Jun 2017 02:18:24 +0300 Subject: drm/tegra: Fix lockup on a use of staging API Commit bdd2f9cd10eb ("Don't leak kernel pointer to userspace") added a mutex around staging IOCTL's, some of those mutexes are taken twice. Fixes: bdd2f9cd10eb ("drm/tegra: Don't leak kernel pointer to userspace") Signed-off-by: Dmitry Osipenko Reviewed-by: Mikko Perttunen Reviewed-by: Erik Faye-Lund Signed-off-by: Thierry Reding Link: http://patchwork.freedesktop.org/patch/msgid/7b70a506a9d2355ea6ff19a8c4f4d726b67719b3.1497480754.git.digetx@gmail.com --- drivers/gpu/drm/tegra/drm.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 9a1e34e48f64..fefa715c4315 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -451,18 +451,6 @@ fail: #ifdef CONFIG_DRM_TEGRA_STAGING -static struct tegra_drm_context * -tegra_drm_file_get_context(struct tegra_drm_file *file, u32 id) -{ - struct tegra_drm_context *context; - - mutex_lock(&file->lock); - context = idr_find(&file->contexts, id); - mutex_unlock(&file->lock); - - return context; -} - static int tegra_gem_create(struct drm_device *drm, void *data, struct drm_file *file) { @@ -606,7 +594,7 @@ static int tegra_close_channel(struct drm_device *drm, void *data, mutex_lock(&fpriv->lock); - context = tegra_drm_file_get_context(fpriv, args->context); + context = idr_find(&fpriv->contexts, args->context); if (!context) { err = -EINVAL; goto unlock; @@ -631,7 +619,7 @@ static int tegra_get_syncpt(struct drm_device *drm, void *data, mutex_lock(&fpriv->lock); - context = tegra_drm_file_get_context(fpriv, args->context); + context = idr_find(&fpriv->contexts, args->context); if (!context) { err = -ENODEV; goto unlock; @@ -660,7 +648,7 @@ static int tegra_submit(struct drm_device *drm, void *data, mutex_lock(&fpriv->lock); - context = tegra_drm_file_get_context(fpriv, args->context); + context = idr_find(&fpriv->contexts, args->context); if (!context) { err = -ENODEV; goto unlock; @@ -685,7 +673,7 @@ static int tegra_get_syncpt_base(struct drm_device *drm, void *data, mutex_lock(&fpriv->lock); - context = tegra_drm_file_get_context(fpriv, args->context); + context = idr_find(&fpriv->contexts, args->context); if (!context) { err = -ENODEV; goto unlock; -- cgit v1.2.3-70-g09d2 From d6c153ec85856f5ad29adc20739ec28edeb7c042 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Thu, 15 Jun 2017 02:18:25 +0300 Subject: drm/tegra: Correct idr_alloc() minimum id The client ID 0 is reserved by the host1x/cdma to mark the timeout timer work as already been scheduled and context ID is used as the clients one. This fixes spurious CDMA timeouts. Fixes: bdd2f9cd10eb ("drm/tegra: Don't leak kernel pointer to userspace") Signed-off-by: Dmitry Osipenko Reviewed-by: Mikko Perttunen Signed-off-by: Thierry Reding Link: http://patchwork.freedesktop.org/patch/msgid/9c19a44219acd988e678cf9abe21363911184625.1497480754.git.digetx@gmail.com --- drivers/gpu/drm/tegra/drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index fefa715c4315..81f86a67c10d 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -539,7 +539,7 @@ static int tegra_client_open(struct tegra_drm_file *fpriv, if (err < 0) return err; - err = idr_alloc(&fpriv->contexts, context, 0, 0, GFP_KERNEL); + err = idr_alloc(&fpriv->contexts, context, 1, 0, GFP_KERNEL); if (err < 0) { client->ops->close_channel(context); return err; -- cgit v1.2.3-70-g09d2 From 0cbb738108927916a659b5b0b96e386fcd7cc6e1 Mon Sep 17 00:00:00 2001 From: Mathieu Larouche Date: Wed, 14 Jun 2017 10:39:42 -0400 Subject: drm/mgag200: Fix to always set HiPri for G200e4 V2 - Changed the HiPri value for G200e4 to always be 0. - Added Bandwith limitation to block resolution above 1920x1200x60Hz Signed-off-by: Mathieu Larouche Acked-by: Dave Airlie [seanpaul removed some trailing whitespace from the patch] Signed-off-by: Sean Paul Link: http://patchwork.freedesktop.org/patch/msgid/ec0f8568d7ec41904dfe593c5deccf3f062d7bd8.1497450944.git.mathieu.larouche@matrox.com --- drivers/gpu/drm/mgag200/mgag200_mode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index adb411a078e8..f4b53588e071 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1173,7 +1173,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if (IS_G200_SE(mdev)) { - if (mdev->unique_rev_id >= 0x02) { + if (mdev->unique_rev_id >= 0x04) { + WREG8(MGAREG_CRTCEXT_INDEX, 0x06); + WREG8(MGAREG_CRTCEXT_DATA, 0); + } else if (mdev->unique_rev_id >= 0x02) { u8 hi_pri_lvl; u32 bpp; u32 mb; @@ -1639,6 +1642,10 @@ static int mga_vga_mode_valid(struct drm_connector *connector, if (mga_vga_calculate_mode_bandwidth(mode, bpp) > (30100 * 1024)) return MODE_BANDWIDTH; + } else { + if (mga_vga_calculate_mode_bandwidth(mode, bpp) + > (55000 * 1024)) + return MODE_BANDWIDTH; } } else if (mdev->type == G200_WB) { if (mode->hdisplay > 1280) -- cgit v1.2.3-70-g09d2 From 0f933328f018c118ded2035f12068bbdfdef399d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 5 May 2017 15:01:41 -0300 Subject: drm: mxsfb_crtc: Reset the eLCDIF controller According to the eLCDIF initialization steps listed in the MX6SX Reference Manual the eLCDIF block reset is mandatory. Without performing the eLCDIF reset the display shows garbage content when the kernel boots. In earlier tests this issue has not been observed because the bootloader was previously showing a splash screen and the bootloader display driver does properly implement the eLCDIF reset. Add the eLCDIF reset to the driver, so that it can operate correctly independently of the bootloader. Tested on a imx6sx-sdb board. Cc: Signed-off-by: Fabio Estevam Signed-off-by: Sean Paul Link: http://patchwork.freedesktop.org/patch/msgid/1494007301-14535-1-git-send-email-fabio.estevam@nxp.com --- drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c index 1144e0c9e894..0abe77675b76 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c @@ -35,6 +35,13 @@ #include "mxsfb_drv.h" #include "mxsfb_regs.h" +#define MXS_SET_ADDR 0x4 +#define MXS_CLR_ADDR 0x8 +#define MODULE_CLKGATE BIT(30) +#define MODULE_SFTRST BIT(31) +/* 1 second delay should be plenty of time for block reset */ +#define RESET_TIMEOUT 1000000 + static u32 set_hsync_pulse_width(struct mxsfb_drm_private *mxsfb, u32 val) { return (val & mxsfb->devdata->hs_wdth_mask) << @@ -159,6 +166,36 @@ static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb) clk_disable_unprepare(mxsfb->clk_disp_axi); } +/* + * Clear the bit and poll it cleared. This is usually called with + * a reset address and mask being either SFTRST(bit 31) or CLKGATE + * (bit 30). + */ +static int clear_poll_bit(void __iomem *addr, u32 mask) +{ + u32 reg; + + writel(mask, addr + MXS_CLR_ADDR); + return readl_poll_timeout(addr, reg, !(reg & mask), 0, RESET_TIMEOUT); +} + +static int mxsfb_reset_block(void __iomem *reset_addr) +{ + int ret; + + ret = clear_poll_bit(reset_addr, MODULE_SFTRST); + if (ret) + return ret; + + writel(MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR); + + ret = clear_poll_bit(reset_addr, MODULE_SFTRST); + if (ret) + return ret; + + return clear_poll_bit(reset_addr, MODULE_CLKGATE); +} + static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb) { struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode; @@ -173,6 +210,11 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb) */ mxsfb_enable_axi_clk(mxsfb); + /* Mandatory eLCDIF reset as per the Reference Manual */ + err = mxsfb_reset_block(mxsfb->base); + if (err) + return; + /* Clear the FIFOs */ writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET); -- cgit v1.2.3-70-g09d2