Commit cb7cbaae authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-next-2022-03-25' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "Some fixes were queued up in and in light of the fbdev regressions,
  I've pulled those in as well.

  core:
   - Make audio and color plane support checking only happen when a CEA
     extension block is found.
   - Small selftest fix.

  fbdev:
   - two regressions fixes from speedup patches.

  ttm:
   - Fix a small regression from ttm_resource_fini()

  i915:
   - Reject unsupported TMDS rates on ICL+
   - Treat SAGV block time 0 as SAGV disabled
   - Fix PSF GV point mask when SAGV is not possible
   - Fix renamed INTEL_INFO->media.arch/ver field"

* tag 'drm-next-2022-03-25' of git://anongit.freedesktop.org/drm/drm:
  fbdev: Fix cfb_imageblit() for arbitrary image widths
  fbdev: Fix sys_imageblit() for arbitrary image widths
  drm/edid: fix CEA extension byte #3 parsing
  drm/edid: check basic audio support on CEA extension block
  drm/i915: Fix renamed struct field
  drm/i915: Fix PSF GV point mask when SAGV is not possible
  drm/i915: Treat SAGV block time 0 as SAGV disabled
  drm/i915: Reject unsupported TMDS rates on ICL+
  drm/selftest: plane_helper: Put test structures in static storage
  drm/ttm: Fix a kernel oops due to an invalid read
parents 46f538bf 2a81dba4
...@@ -4859,7 +4859,8 @@ bool drm_detect_monitor_audio(struct edid *edid) ...@@ -4859,7 +4859,8 @@ bool drm_detect_monitor_audio(struct edid *edid)
if (!edid_ext) if (!edid_ext)
goto end; goto end;
has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0); has_audio = (edid_ext[0] == CEA_EXT &&
(edid_ext[3] & EDID_BASIC_AUDIO) != 0);
if (has_audio) { if (has_audio) {
DRM_DEBUG_KMS("Monitor has basic audio support\n"); DRM_DEBUG_KMS("Monitor has basic audio support\n");
...@@ -5187,10 +5188,14 @@ static void drm_parse_cea_ext(struct drm_connector *connector, ...@@ -5187,10 +5188,14 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
/* The existence of a CEA block should imply RGB support */ /* The existence of a CEA block should imply RGB support */
info->color_formats = DRM_COLOR_FORMAT_RGB444; info->color_formats = DRM_COLOR_FORMAT_RGB444;
/* CTA DisplayID Data Block does not have byte #3 */
if (edid_ext[0] == CEA_EXT) {
if (edid_ext[3] & EDID_CEA_YCRCB444) if (edid_ext[3] & EDID_CEA_YCRCB444)
info->color_formats |= DRM_COLOR_FORMAT_YCBCR444; info->color_formats |= DRM_COLOR_FORMAT_YCBCR444;
if (edid_ext[3] & EDID_CEA_YCRCB422) if (edid_ext[3] & EDID_CEA_YCRCB422)
info->color_formats |= DRM_COLOR_FORMAT_YCBCR422; info->color_formats |= DRM_COLOR_FORMAT_YCBCR422;
}
if (cea_db_offsets(edid_ext, &start, &end)) if (cea_db_offsets(edid_ext, &start, &end))
return; return;
......
...@@ -992,7 +992,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) ...@@ -992,7 +992,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
* cause. * cause.
*/ */
if (!intel_can_enable_sagv(dev_priv, new_bw_state)) { if (!intel_can_enable_sagv(dev_priv, new_bw_state)) {
allowed_points = BIT(max_bw_point); allowed_points &= ADLS_PSF_PT_MASK;
allowed_points |= BIT(max_bw_point);
drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n", drm_dbg_kms(&dev_priv->drm, "No SAGV, using single QGV point %d\n",
max_bw_point); max_bw_point);
} }
......
...@@ -1836,6 +1836,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, ...@@ -1836,6 +1836,7 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
bool has_hdmi_sink) bool has_hdmi_sink)
{ {
struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi); struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi);
enum phy phy = intel_port_to_phy(dev_priv, hdmi_to_dig_port(hdmi)->base.port);
if (clock < 25000) if (clock < 25000)
return MODE_CLOCK_LOW; return MODE_CLOCK_LOW;
...@@ -1856,6 +1857,14 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, ...@@ -1856,6 +1857,14 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000) if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000)
return MODE_CLOCK_RANGE; return MODE_CLOCK_RANGE;
/* ICL+ combo PHY PLL can't generate 500-533.2 MHz */
if (intel_phy_is_combo(dev_priv, phy) && clock > 500000 && clock < 533200)
return MODE_CLOCK_RANGE;
/* ICL+ TC PHY PLL can't generate 500-532.8 MHz */
if (intel_phy_is_tc(dev_priv, phy) && clock > 500000 && clock < 532800)
return MODE_CLOCK_RANGE;
/* /*
* SNPS PHYs' MPLLB table-based programming can only handle a fixed * SNPS PHYs' MPLLB table-based programming can only handle a fixed
* set of link rates. * set of link rates.
......
...@@ -947,7 +947,7 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915) ...@@ -947,7 +947,7 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915)
(GRAPHICS_VER(i915) >= (from) && GRAPHICS_VER(i915) <= (until)) (GRAPHICS_VER(i915) >= (from) && GRAPHICS_VER(i915) <= (until))
#define MEDIA_VER(i915) (INTEL_INFO(i915)->media.ver) #define MEDIA_VER(i915) (INTEL_INFO(i915)->media.ver)
#define MEDIA_VER_FULL(i915) IP_VER(INTEL_INFO(i915)->media.arch, \ #define MEDIA_VER_FULL(i915) IP_VER(INTEL_INFO(i915)->media.ver, \
INTEL_INFO(i915)->media.rel) INTEL_INFO(i915)->media.rel)
#define IS_MEDIA_VER(i915, from, until) \ #define IS_MEDIA_VER(i915, from, until) \
(MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until)) (MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until))
......
...@@ -3698,8 +3698,7 @@ skl_setup_sagv_block_time(struct drm_i915_private *dev_priv) ...@@ -3698,8 +3698,7 @@ skl_setup_sagv_block_time(struct drm_i915_private *dev_priv)
MISSING_CASE(DISPLAY_VER(dev_priv)); MISSING_CASE(DISPLAY_VER(dev_priv));
} }
/* Default to an unusable block time */ dev_priv->sagv_block_time_us = 0;
dev_priv->sagv_block_time_us = -1;
} }
/* /*
...@@ -5645,7 +5644,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, ...@@ -5645,7 +5644,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
result->min_ddb_alloc = max(min_ddb_alloc, blocks) + 1; result->min_ddb_alloc = max(min_ddb_alloc, blocks) + 1;
result->enable = true; result->enable = true;
if (DISPLAY_VER(dev_priv) < 12) if (DISPLAY_VER(dev_priv) < 12 && dev_priv->sagv_block_time_us)
result->can_sagv = latency >= dev_priv->sagv_block_time_us; result->can_sagv = latency >= dev_priv->sagv_block_time_us;
} }
...@@ -5678,7 +5677,10 @@ static void tgl_compute_sagv_wm(const struct intel_crtc_state *crtc_state, ...@@ -5678,7 +5677,10 @@ static void tgl_compute_sagv_wm(const struct intel_crtc_state *crtc_state,
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
struct skl_wm_level *sagv_wm = &plane_wm->sagv.wm0; struct skl_wm_level *sagv_wm = &plane_wm->sagv.wm0;
struct skl_wm_level *levels = plane_wm->wm; struct skl_wm_level *levels = plane_wm->wm;
unsigned int latency = dev_priv->wm.skl_latency[0] + dev_priv->sagv_block_time_us; unsigned int latency = 0;
if (dev_priv->sagv_block_time_us)
latency = dev_priv->sagv_block_time_us + dev_priv->wm.skl_latency[0];
skl_compute_plane_wm(crtc_state, plane, 0, latency, skl_compute_plane_wm(crtc_state, plane, 0, latency,
wm_params, &levels[0], wm_params, &levels[0],
......
...@@ -77,7 +77,7 @@ int igt_check_plane_state(void *ignored) ...@@ -77,7 +77,7 @@ int igt_check_plane_state(void *ignored)
{ {
int ret; int ret;
const struct drm_crtc_state crtc_state = { static const struct drm_crtc_state crtc_state = {
.crtc = ZERO_SIZE_PTR, .crtc = ZERO_SIZE_PTR,
.enable = true, .enable = true,
.active = true, .active = true,
...@@ -87,14 +87,14 @@ int igt_check_plane_state(void *ignored) ...@@ -87,14 +87,14 @@ int igt_check_plane_state(void *ignored)
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
}, },
}; };
struct drm_plane plane = { static struct drm_plane plane = {
.dev = NULL .dev = NULL
}; };
struct drm_framebuffer fb = { static struct drm_framebuffer fb = {
.width = 2048, .width = 2048,
.height = 2048 .height = 2048
}; };
struct drm_plane_state plane_state = { static struct drm_plane_state plane_state = {
.plane = &plane, .plane = &plane,
.crtc = ZERO_SIZE_PTR, .crtc = ZERO_SIZE_PTR,
.fb = &fb, .fb = &fb,
......
...@@ -89,7 +89,7 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man, ...@@ -89,7 +89,7 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man,
spin_unlock(&rman->lock); spin_unlock(&rman->lock);
if (unlikely(ret)) { if (unlikely(ret)) {
ttm_resource_fini(man, *res); ttm_resource_fini(man, &node->base);
kfree(node); kfree(node);
return ret; return ret;
} }
......
...@@ -218,7 +218,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * ...@@ -218,7 +218,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
{ {
u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
u32 ppw = 32/bpp, spitch = (image->width + 7)/8; u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
u32 bit_mask, eorx; u32 bit_mask, eorx, shift;
const char *s = image->data, *src; const char *s = image->data, *src;
u32 __iomem *dst; u32 __iomem *dst;
const u32 *tab = NULL; const u32 *tab = NULL;
...@@ -259,17 +259,23 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * ...@@ -259,17 +259,23 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
for (i = image->height; i--; ) { for (i = image->height; i--; ) {
dst = (u32 __iomem *)dst1; dst = (u32 __iomem *)dst1;
shift = 8;
src = s; src = s;
/*
* Manually unroll the per-line copying loop for better
* performance. This works until we processed the last
* completely filled source byte (inclusive).
*/
switch (ppw) { switch (ppw) {
case 4: /* 8 bpp */ case 4: /* 8 bpp */
for (j = k; j; j -= 2, ++src) { for (j = k; j >= 2; j -= 2, ++src) {
FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++);
FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 0) & bit_mask], dst++);
} }
break; break;
case 2: /* 16 bpp */ case 2: /* 16 bpp */
for (j = k; j; j -= 4, ++src) { for (j = k; j >= 4; j -= 4, ++src) {
FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++);
FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 4) & bit_mask], dst++);
FB_WRITEL(colortab[(*src >> 2) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 2) & bit_mask], dst++);
...@@ -277,7 +283,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * ...@@ -277,7 +283,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
} }
break; break;
case 1: /* 32 bpp */ case 1: /* 32 bpp */
for (j = k; j; j -= 8, ++src) { for (j = k; j >= 8; j -= 8, ++src) {
FB_WRITEL(colortab[(*src >> 7) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 7) & bit_mask], dst++);
FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 6) & bit_mask], dst++);
FB_WRITEL(colortab[(*src >> 5) & bit_mask], dst++); FB_WRITEL(colortab[(*src >> 5) & bit_mask], dst++);
...@@ -290,6 +296,20 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * ...@@ -290,6 +296,20 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
break; break;
} }
/*
* For image widths that are not a multiple of 8, there
* are trailing pixels left on the current line. Print
* them as well.
*/
for (; j--; ) {
shift -= ppw;
FB_WRITEL(colortab[(*src >> shift) & bit_mask], dst++);
if (!shift) {
shift = 8;
++src;
}
}
dst1 += p->fix.line_length; dst1 += p->fix.line_length;
s += spitch; s += spitch;
} }
......
...@@ -188,7 +188,7 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, ...@@ -188,7 +188,7 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
{ {
u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
u32 ppw = 32/bpp, spitch = (image->width + 7)/8; u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
u32 bit_mask, eorx; u32 bit_mask, eorx, shift;
const char *s = image->data, *src; const char *s = image->data, *src;
u32 *dst; u32 *dst;
const u32 *tab; const u32 *tab;
...@@ -229,17 +229,23 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, ...@@ -229,17 +229,23 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
for (i = image->height; i--; ) { for (i = image->height; i--; ) {
dst = dst1; dst = dst1;
shift = 8;
src = s; src = s;
/*
* Manually unroll the per-line copying loop for better
* performance. This works until we processed the last
* completely filled source byte (inclusive).
*/
switch (ppw) { switch (ppw) {
case 4: /* 8 bpp */ case 4: /* 8 bpp */
for (j = k; j; j -= 2, ++src) { for (j = k; j >= 2; j -= 2, ++src) {
*dst++ = colortab[(*src >> 4) & bit_mask]; *dst++ = colortab[(*src >> 4) & bit_mask];
*dst++ = colortab[(*src >> 0) & bit_mask]; *dst++ = colortab[(*src >> 0) & bit_mask];
} }
break; break;
case 2: /* 16 bpp */ case 2: /* 16 bpp */
for (j = k; j; j -= 4, ++src) { for (j = k; j >= 4; j -= 4, ++src) {
*dst++ = colortab[(*src >> 6) & bit_mask]; *dst++ = colortab[(*src >> 6) & bit_mask];
*dst++ = colortab[(*src >> 4) & bit_mask]; *dst++ = colortab[(*src >> 4) & bit_mask];
*dst++ = colortab[(*src >> 2) & bit_mask]; *dst++ = colortab[(*src >> 2) & bit_mask];
...@@ -247,7 +253,7 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, ...@@ -247,7 +253,7 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
} }
break; break;
case 1: /* 32 bpp */ case 1: /* 32 bpp */
for (j = k; j; j -= 8, ++src) { for (j = k; j >= 8; j -= 8, ++src) {
*dst++ = colortab[(*src >> 7) & bit_mask]; *dst++ = colortab[(*src >> 7) & bit_mask];
*dst++ = colortab[(*src >> 6) & bit_mask]; *dst++ = colortab[(*src >> 6) & bit_mask];
*dst++ = colortab[(*src >> 5) & bit_mask]; *dst++ = colortab[(*src >> 5) & bit_mask];
...@@ -259,6 +265,21 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, ...@@ -259,6 +265,21 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
} }
break; break;
} }
/*
* For image widths that are not a multiple of 8, there
* are trailing pixels left on the current line. Print
* them as well.
*/
for (; j--; ) {
shift -= ppw;
*dst++ = colortab[(*src >> shift) & bit_mask];
if (!shift) {
shift = 8;
++src;
}
}
dst1 += p->fix.line_length; dst1 += p->fix.line_length;
s += spitch; s += spitch;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment