Commit c2f3850d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-2020-07-29' of git://anongit.freedesktop.org/drm/drm into master

Pull drm fixes from Dave Airlie:
 "The nouveau fixes missed the last pull by a few hours, and we had a
  few arm driver/panel/bridge fixes come in.

  This is possibly a bit more than I'm comfortable sending at this
  stage, but I've looked at each patch, the core + nouveau patches fix
  regressions, and the arm related ones are all around screens turning
  on and working, and are mostly trivial patches, the line count is
  mostly in comments.

  core:
   - fix possible use-after-free

  drm_fb_helper:
   - regression fix to use memcpy_io on bochs' sparc64

  nouveau:
   - format modifiers fixes
   - HDA regression fix
   - turing modesetting race fix

  of:
   - fix a double free

  dbi:
   - fix SPI Type 1 transfer

  mcde:
   - fix screen stability crash

  panel:
   - panel: fix display noise on auo,kd101n80-45na
   - panel: delay HPD checks for boe_nv133fhm_n61

  bridge:
   - bridge: drop connector check in nwl-dsi bridge
   - bridge: set proper bridge type for adv7511"

* tag 'drm-fixes-2020-07-29' of git://anongit.freedesktop.org/drm/drm:
  drm: hold gem reference until object is no longer accessed
  drm/dbi: Fix SPI Type 1 (9-bit) transfer
  drm/drm_fb_helper: fix fbdev with sparc64
  drm/mcde: Fix stability issue
  drm/bridge: nwl-dsi: Drop DRM_BRIDGE_ATTACH_NO_CONNECTOR check.
  drm/panel: Fix auo, kd101n80-45na horizontal noise on edges of panel
  drm: panel: simple: Delay HPD checking on boe_nv133fhm_n61 for 15 ms
  drm/bridge/adv7511: set the bridge type properly
  drm: of: Fix double-free bug
  drm/nouveau/fbcon: zero-initialise the mode_cmd2 structure
  drm/nouveau/fbcon: fix module unload when fbcon init has failed for some reason
  drm/nouveau/kms/tu102: wait for core update to complete when assigning windows
  drm/nouveau/kms/gf100: use correct format modifiers
  drm/nouveau/disp/gm200-: fix regression from HDA SOR selection changes
parents f227e3ec a4a2739b
......@@ -146,6 +146,7 @@ int bochs_kms_init(struct bochs_device *bochs)
bochs->dev->mode_config.preferred_depth = 24;
bochs->dev->mode_config.prefer_shadow = 0;
bochs->dev->mode_config.prefer_shadow_fbdev = 1;
bochs->dev->mode_config.fbdev_use_iomem = true;
bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true;
bochs->dev->mode_config.funcs = &bochs_mode_funcs;
......
......@@ -1224,6 +1224,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
adv7511->bridge.funcs = &adv7511_bridge_funcs;
adv7511->bridge.of_node = dev->of_node;
adv7511->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
drm_bridge_add(&adv7511->bridge);
......
......@@ -917,11 +917,6 @@ static int nwl_dsi_bridge_attach(struct drm_bridge *bridge,
struct drm_panel *panel;
int ret;
if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
DRM_ERROR("Fix bridge driver to make connector optional!");
return -EINVAL;
}
ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
&panel_bridge);
if (ret)
......
......@@ -399,7 +399,11 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper,
unsigned int y;
for (y = clip->y1; y < clip->y2; y++) {
memcpy(dst, src, len);
if (!fb_helper->dev->mode_config.fbdev_use_iomem)
memcpy(dst, src, len);
else
memcpy_toio((void __iomem *)dst, src, len);
src += fb->pitches[0];
dst += fb->pitches[0];
}
......
......@@ -871,9 +871,6 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
* @file_priv: drm file-private structure
*
* Open an object using the global name, returning a handle and the size.
*
* This handle (of course) holds a reference to the object, so the object
* will not go away until the handle is deleted.
*/
int
drm_gem_open_ioctl(struct drm_device *dev, void *data,
......@@ -898,14 +895,15 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
/* drm_gem_handle_create_tail unlocks dev->object_name_lock. */
ret = drm_gem_handle_create_tail(file_priv, obj, &handle);
drm_gem_object_put_unlocked(obj);
if (ret)
return ret;
goto err;
args->handle = handle;
args->size = obj->size;
return 0;
err:
drm_gem_object_put_unlocked(obj);
return ret;
}
/**
......
......@@ -923,7 +923,7 @@ static int mipi_dbi_spi1_transfer(struct mipi_dbi *dbi, int dc,
}
}
tr.len = chunk;
tr.len = chunk * 2;
len -= chunk;
ret = spi_sync(spi, &m);
......
......@@ -322,10 +322,8 @@ static int drm_of_lvds_get_remote_pixels_type(
* configurations by passing the endpoints explicitly to
* drm_of_lvds_get_dual_link_pixel_order().
*/
if (!current_pt || pixels_type != current_pt) {
of_node_put(remote_port);
if (!current_pt || pixels_type != current_pt)
return -EINVAL;
}
}
return pixels_type;
......
......@@ -1060,9 +1060,14 @@ static void mcde_display_update(struct drm_simple_display_pipe *pipe,
*/
if (fb) {
mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0));
if (!mcde->video_mode)
/* Send a single frame using software sync */
mcde_display_send_one_frame(mcde);
if (!mcde->video_mode) {
/*
* Send a single frame using software sync if the flow
* is not active yet.
*/
if (mcde->flow_active == 0)
mcde_display_send_one_frame(mcde);
}
dev_info_once(mcde->dev, "sent first display update\n");
} else {
/*
......
......@@ -2073,7 +2073,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
*/
if (core->assign_windows) {
core->func->wndw.owner(core);
core->func->update(core, interlock, false);
nv50_disp_atomic_commit_core(state, interlock);
core->assign_windows = false;
interlock[NV50_DISP_INTERLOCK_CORE] = 0;
}
......@@ -2506,7 +2506,7 @@ nv50_display_create(struct drm_device *dev)
if (disp->disp->object.oclass >= TU102_DISP)
nouveau_display(dev)->format_modifiers = wndwc57e_modifiers;
else
if (disp->disp->object.oclass >= GF110_DISP)
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_FERMI)
nouveau_display(dev)->format_modifiers = disp90xx_modifiers;
else
nouveau_display(dev)->format_modifiers = disp50xx_modifiers;
......
......@@ -315,7 +315,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
struct drm_framebuffer *fb;
struct nouveau_channel *chan;
struct nouveau_bo *nvbo;
struct drm_mode_fb_cmd2 mode_cmd;
struct drm_mode_fb_cmd2 mode_cmd = {};
int ret;
mode_cmd.width = sizes->surface_width;
......@@ -590,6 +590,7 @@ nouveau_fbcon_init(struct drm_device *dev)
drm_fb_helper_fini(&fbcon->helper);
free:
kfree(fbcon);
drm->fbcon = NULL;
return ret;
}
......
......@@ -117,15 +117,6 @@ nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type,
{
struct nvkm_ior *ior;
/* First preference is to reuse the OR that is currently armed
* on HW, if any, in order to prevent unnecessary switching.
*/
list_for_each_entry(ior, &outp->disp->ior, head) {
if (!ior->identity && !!ior->func->hda.hpd == hda &&
!ior->asy.outp && ior->arm.outp == outp)
return nvkm_outp_acquire_ior(outp, user, ior);
}
/* Failing that, a completely unused OR is the next best thing. */
list_for_each_entry(ior, &outp->disp->ior, head) {
if (!ior->identity && !!ior->func->hda.hpd == hda &&
......@@ -173,6 +164,27 @@ nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda)
return nvkm_outp_acquire_ior(outp, user, ior);
}
/* First preference is to reuse the OR that is currently armed
* on HW, if any, in order to prevent unnecessary switching.
*/
list_for_each_entry(ior, &outp->disp->ior, head) {
if (!ior->identity && !ior->asy.outp && ior->arm.outp == outp) {
/*XXX: For various complicated reasons, we can't outright switch
* the boot-time OR on the first modeset without some fairly
* invasive changes.
*
* The systems that were fixed by modifying the OR selection
* code to account for HDA support shouldn't regress here as
* the HDA-enabled ORs match the relevant output's pad macro
* index, and the firmware seems to select an OR this way.
*
* This warning is to make it obvious if that proves wrong.
*/
WARN_ON(hda && !ior->func->hda.hpd);
return nvkm_outp_acquire_ior(outp, user, ior);
}
}
/* If we don't need HDA, first try to acquire an OR that doesn't
* support it to leave free the ones that do.
*/
......
......@@ -615,9 +615,9 @@ static const struct panel_desc boe_tv101wum_nl6_desc = {
static const struct drm_display_mode auo_kd101n80_45na_default_mode = {
.clock = 157000,
.hdisplay = 1200,
.hsync_start = 1200 + 80,
.hsync_end = 1200 + 80 + 24,
.htotal = 1200 + 80 + 24 + 36,
.hsync_start = 1200 + 60,
.hsync_end = 1200 + 60 + 24,
.htotal = 1200 + 60 + 24 + 56,
.vdisplay = 1920,
.vsync_start = 1920 + 16,
.vsync_end = 1920 + 16 + 4,
......
......@@ -1250,7 +1250,21 @@ static const struct panel_desc boe_nv133fhm_n61 = {
.height = 165,
},
.delay = {
.hpd_absent_delay = 200,
/*
* When power is first given to the panel there's a short
* spike on the HPD line. It was explained that this spike
* was until the TCON data download was complete. On
* one system this was measured at 8 ms. We'll put 15 ms
* in the prepare delay just to be safe and take it away
* from the hpd_absent_delay (which would otherwise be 200 ms)
* to handle this. That means:
* - If HPD isn't hooked up you still have 200 ms delay.
* - If HPD is hooked up we won't try to look at it for the
* first 15 ms.
*/
.prepare = 15,
.hpd_absent_delay = 185,
.unprepare = 500,
},
.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
......
......@@ -865,6 +865,18 @@ struct drm_mode_config {
*/
bool prefer_shadow_fbdev;
/**
* @fbdev_use_iomem:
*
* Set to true if framebuffer reside in iomem.
* When set to true memcpy_toio() is used when copying the framebuffer in
* drm_fb_helper.drm_fb_helper_dirty_blit_real().
*
* FIXME: This should be replaced with a per-mapping is_iomem
* flag (like ttm does), and then used everywhere in fbdev code.
*/
bool fbdev_use_iomem;
/**
* @quirk_addfb_prefer_xbgr_30bpp:
*
......
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