Merge tag 'v5.8' into drm-next
I need to backmerge 5.8 as I've got a bunch of fixes sitting on an rc7 base that I want to land. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -707,9 +707,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
||||
return n ? -EFAULT : 0;
|
||||
}
|
||||
case AMDGPU_INFO_DEV_INFO: {
|
||||
struct drm_amdgpu_info_device dev_info = {};
|
||||
struct drm_amdgpu_info_device dev_info;
|
||||
uint64_t vm_size;
|
||||
|
||||
memset(&dev_info, 0, sizeof(dev_info));
|
||||
dev_info.device_id = dev->pdev->device;
|
||||
dev_info.chip_rev = adev->rev_id;
|
||||
dev_info.external_rev = adev->external_rev_id;
|
||||
|
||||
@@ -8759,20 +8759,38 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
|
||||
* the same resource. If we have a new DC context as part of
|
||||
* the DM atomic state from validation we need to free it and
|
||||
* retain the existing one instead.
|
||||
*
|
||||
* Furthermore, since the DM atomic state only contains the DC
|
||||
* context and can safely be annulled, we can free the state
|
||||
* and clear the associated private object now to free
|
||||
* some memory and avoid a possible use-after-free later.
|
||||
*/
|
||||
struct dm_atomic_state *new_dm_state, *old_dm_state;
|
||||
|
||||
new_dm_state = dm_atomic_get_new_state(state);
|
||||
old_dm_state = dm_atomic_get_old_state(state);
|
||||
for (i = 0; i < state->num_private_objs; i++) {
|
||||
struct drm_private_obj *obj = state->private_objs[i].ptr;
|
||||
|
||||
if (new_dm_state && old_dm_state) {
|
||||
if (new_dm_state->context)
|
||||
dc_release_state(new_dm_state->context);
|
||||
if (obj->funcs == adev->dm.atomic_obj.funcs) {
|
||||
int j = state->num_private_objs-1;
|
||||
|
||||
new_dm_state->context = old_dm_state->context;
|
||||
dm_atomic_destroy_state(obj,
|
||||
state->private_objs[i].state);
|
||||
|
||||
if (old_dm_state->context)
|
||||
dc_retain_state(old_dm_state->context);
|
||||
/* If i is not at the end of the array then the
|
||||
* last element needs to be moved to where i was
|
||||
* before the array can safely be truncated.
|
||||
*/
|
||||
if (i != j)
|
||||
state->private_objs[i] =
|
||||
state->private_objs[j];
|
||||
|
||||
state->private_objs[j].ptr = NULL;
|
||||
state->private_objs[j].state = NULL;
|
||||
state->private_objs[j].old_state = NULL;
|
||||
state->private_objs[j].new_state = NULL;
|
||||
|
||||
state->num_private_objs = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +151,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;
|
||||
|
||||
@@ -1283,6 +1283,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
|
||||
adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID
|
||||
| DRM_BRIDGE_OP_HPD;
|
||||
adv7511->bridge.of_node = dev->of_node;
|
||||
adv7511->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
|
||||
drm_bridge_add(&adv7511->bridge);
|
||||
|
||||
|
||||
@@ -918,11 +918,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];
|
||||
}
|
||||
|
||||
@@ -879,9 +879,6 @@ err:
|
||||
* @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,
|
||||
@@ -906,14 +903,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(obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
args->handle = handle;
|
||||
args->size = obj->size;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
drm_gem_object_put(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -918,7 +918,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);
|
||||
|
||||
@@ -331,10 +331,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;
|
||||
|
||||
@@ -271,6 +271,8 @@ void lima_pp_fini(struct lima_ip *ip)
|
||||
|
||||
int lima_pp_bcast_resume(struct lima_ip *ip)
|
||||
{
|
||||
/* PP has been reset by individual PP resume */
|
||||
ip->data.async_reset = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
/*
|
||||
|
||||
@@ -2157,7 +2157,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;
|
||||
}
|
||||
@@ -2613,7 +2613,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;
|
||||
|
||||
@@ -139,6 +139,7 @@ nouveau_decode_mod(struct nouveau_drm *drm,
|
||||
uint32_t *tile_mode,
|
||||
uint8_t *kind)
|
||||
{
|
||||
struct nouveau_display *disp = nouveau_display(drm->dev);
|
||||
BUG_ON(!tile_mode || !kind);
|
||||
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
@@ -150,6 +151,12 @@ nouveau_decode_mod(struct nouveau_drm *drm,
|
||||
* Extract the block height and kind from the corresponding
|
||||
* modifier fields. See drm_fourcc.h for details.
|
||||
*/
|
||||
|
||||
if ((modifier & (0xffull << 12)) == 0ull) {
|
||||
/* Legacy modifier. Translate to this dev's 'kind.' */
|
||||
modifier |= disp->format_modifiers[0] & (0xffull << 12);
|
||||
}
|
||||
|
||||
*tile_mode = (uint32_t)(modifier & 0xF);
|
||||
*kind = (uint8_t)((modifier >> 12) & 0xFF);
|
||||
|
||||
@@ -175,6 +182,16 @@ nouveau_framebuffer_get_layout(struct drm_framebuffer *fb,
|
||||
}
|
||||
}
|
||||
|
||||
static const u64 legacy_modifiers[] = {
|
||||
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0),
|
||||
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1),
|
||||
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2),
|
||||
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3),
|
||||
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4),
|
||||
DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5),
|
||||
DRM_FORMAT_MOD_INVALID
|
||||
};
|
||||
|
||||
static int
|
||||
nouveau_validate_decode_mod(struct nouveau_drm *drm,
|
||||
uint64_t modifier,
|
||||
@@ -195,8 +212,14 @@ nouveau_validate_decode_mod(struct nouveau_drm *drm,
|
||||
(disp->format_modifiers[mod] != modifier);
|
||||
mod++);
|
||||
|
||||
if (disp->format_modifiers[mod] == DRM_FORMAT_MOD_INVALID)
|
||||
return -EINVAL;
|
||||
if (disp->format_modifiers[mod] == DRM_FORMAT_MOD_INVALID) {
|
||||
for (mod = 0;
|
||||
(legacy_modifiers[mod] != DRM_FORMAT_MOD_INVALID) &&
|
||||
(legacy_modifiers[mod] != modifier);
|
||||
mod++);
|
||||
if (legacy_modifiers[mod] == DRM_FORMAT_MOD_INVALID)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nouveau_decode_mod(drm, modifier, tile_mode, kind);
|
||||
|
||||
|
||||
@@ -317,7 +317,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;
|
||||
@@ -592,6 +592,7 @@ fini:
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -614,9 +614,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,
|
||||
|
||||
@@ -1260,7 +1260,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,
|
||||
|
||||
@@ -260,7 +260,7 @@ sun4i_hdmi_connector_detect(struct drm_connector *connector, bool force)
|
||||
unsigned long reg;
|
||||
|
||||
reg = readl(hdmi->base + SUN4I_HDMI_HPD_REG);
|
||||
if (reg & SUN4I_HDMI_HPD_HIGH) {
|
||||
if (!(reg & SUN4I_HDMI_HPD_HIGH)) {
|
||||
cec_phys_addr_invalidate(hdmi->cec_adap);
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user