Commit 9e154001 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-for-v4.13-rc7' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "Fixes for rc7, nothing too crazy, some core, i915, and sunxi fixes,
  Intel CI has been responsible for some of these fixes being required"

* tag 'drm-fixes-for-v4.13-rc7' of git://people.freedesktop.org/~airlied/linux:
  drm/i915/gvt: Fix the kernel null pointer error
  drm: Release driver tracking before making the object available again
  drm/i915: Clear lost context-switch interrupts across reset
  drm/i915/bxt: use NULL for GPIO connection ID
  drm/i915/cnl: Fix LSPCON support.
  drm/i915/vbt: ignore extraneous child devices for a port
  drm/i915: Initialize 'data' in intel_dsi_dcs_backlight.c
  drm/atomic: If the atomic check fails, return its value first
  drm/atomic: Handle -EDEADLK with out-fences correctly
  drm: Fix framebuffer leak
  drm/imx: ipuv3-plane: fix YUV framebuffer scanout on the base plane
  gpu: ipu-v3: add DRM dependency
  drm/rockchip: Fix suspend crash when drm is not bound
  drm/sun4i: Implement drm_driver lastclose to restore fbdev console
parents 90a6cd50 da611979
...@@ -1655,6 +1655,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state) ...@@ -1655,6 +1655,9 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
if (config->funcs->atomic_check) if (config->funcs->atomic_check)
ret = config->funcs->atomic_check(state->dev, state); ret = config->funcs->atomic_check(state->dev, state);
if (ret)
return ret;
if (!state->allow_modeset) { if (!state->allow_modeset) {
for_each_new_crtc_in_state(state, crtc, crtc_state, i) { for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
if (drm_atomic_crtc_needs_modeset(crtc_state)) { if (drm_atomic_crtc_needs_modeset(crtc_state)) {
...@@ -1665,7 +1668,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state) ...@@ -1665,7 +1668,7 @@ int drm_atomic_check_only(struct drm_atomic_state *state)
} }
} }
return ret; return 0;
} }
EXPORT_SYMBOL(drm_atomic_check_only); EXPORT_SYMBOL(drm_atomic_check_only);
...@@ -2167,10 +2170,10 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, ...@@ -2167,10 +2170,10 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
struct drm_atomic_state *state; struct drm_atomic_state *state;
struct drm_modeset_acquire_ctx ctx; struct drm_modeset_acquire_ctx ctx;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_out_fence_state *fence_state = NULL; struct drm_out_fence_state *fence_state;
unsigned plane_mask; unsigned plane_mask;
int ret = 0; int ret = 0;
unsigned int i, j, num_fences = 0; unsigned int i, j, num_fences;
/* disallow for drivers not supporting atomic: */ /* disallow for drivers not supporting atomic: */
if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
...@@ -2211,6 +2214,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, ...@@ -2211,6 +2214,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
plane_mask = 0; plane_mask = 0;
copied_objs = 0; copied_objs = 0;
copied_props = 0; copied_props = 0;
fence_state = NULL;
num_fences = 0;
for (i = 0; i < arg->count_objs; i++) { for (i = 0; i < arg->count_objs; i++) {
uint32_t obj_id, count_props; uint32_t obj_id, count_props;
......
...@@ -255,13 +255,13 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) ...@@ -255,13 +255,13 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
struct drm_gem_object *obj = ptr; struct drm_gem_object *obj = ptr;
struct drm_device *dev = obj->dev; struct drm_device *dev = obj->dev;
if (dev->driver->gem_close_object)
dev->driver->gem_close_object(obj, file_priv);
if (drm_core_check_feature(dev, DRIVER_PRIME)) if (drm_core_check_feature(dev, DRIVER_PRIME))
drm_gem_remove_prime_handles(obj, file_priv); drm_gem_remove_prime_handles(obj, file_priv);
drm_vma_node_revoke(&obj->vma_node, file_priv); drm_vma_node_revoke(&obj->vma_node, file_priv);
if (dev->driver->gem_close_object)
dev->driver->gem_close_object(obj, file_priv);
drm_gem_object_handle_put_unlocked(obj); drm_gem_object_handle_put_unlocked(obj);
return 0; return 0;
......
...@@ -601,6 +601,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, ...@@ -601,6 +601,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
crtc = drm_crtc_find(dev, plane_req->crtc_id); crtc = drm_crtc_find(dev, plane_req->crtc_id);
if (!crtc) { if (!crtc) {
drm_framebuffer_put(fb);
DRM_DEBUG_KMS("Unknown crtc ID %d\n", DRM_DEBUG_KMS("Unknown crtc ID %d\n",
plane_req->crtc_id); plane_req->crtc_id);
return -ENOENT; return -ENOENT;
......
...@@ -2714,7 +2714,7 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx) ...@@ -2714,7 +2714,7 @@ static int shadow_indirect_ctx(struct intel_shadow_wa_ctx *wa_ctx)
unmap_src: unmap_src:
i915_gem_object_unpin_map(obj); i915_gem_object_unpin_map(obj);
put_obj: put_obj:
i915_gem_object_put(wa_ctx->indirect_ctx.obj); i915_gem_object_put(obj);
return ret; return ret;
} }
......
...@@ -1120,8 +1120,8 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, ...@@ -1120,8 +1120,8 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
bool is_dvi, is_hdmi, is_dp, is_edp, is_crt; bool is_dvi, is_hdmi, is_dp, is_edp, is_crt;
uint8_t aux_channel, ddc_pin; uint8_t aux_channel, ddc_pin;
/* Each DDI port can have more than one value on the "DVO Port" field, /* Each DDI port can have more than one value on the "DVO Port" field,
* so look for all the possible values for each port and abort if more * so look for all the possible values for each port.
* than one is found. */ */
int dvo_ports[][3] = { int dvo_ports[][3] = {
{DVO_PORT_HDMIA, DVO_PORT_DPA, -1}, {DVO_PORT_HDMIA, DVO_PORT_DPA, -1},
{DVO_PORT_HDMIB, DVO_PORT_DPB, -1}, {DVO_PORT_HDMIB, DVO_PORT_DPB, -1},
...@@ -1130,7 +1130,10 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, ...@@ -1130,7 +1130,10 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
{DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE}, {DVO_PORT_CRT, DVO_PORT_HDMIE, DVO_PORT_DPE},
}; };
/* Find the child device to use, abort if more than one found. */ /*
* Find the first child device to reference the port, report if more
* than one found.
*/
for (i = 0; i < dev_priv->vbt.child_dev_num; i++) { for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
it = dev_priv->vbt.child_dev + i; it = dev_priv->vbt.child_dev + i;
...@@ -1140,11 +1143,11 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, ...@@ -1140,11 +1143,11 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
if (it->common.dvo_port == dvo_ports[port][j]) { if (it->common.dvo_port == dvo_ports[port][j]) {
if (child) { if (child) {
DRM_DEBUG_KMS("More than one child device for port %c in VBT.\n", DRM_DEBUG_KMS("More than one child device for port %c in VBT, using the first.\n",
port_name(port)); port_name(port));
return; } else {
child = it;
} }
child = it;
} }
} }
} }
......
...@@ -46,7 +46,7 @@ static u32 dcs_get_backlight(struct intel_connector *connector) ...@@ -46,7 +46,7 @@ static u32 dcs_get_backlight(struct intel_connector *connector)
struct intel_encoder *encoder = connector->encoder; struct intel_encoder *encoder = connector->encoder;
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
struct mipi_dsi_device *dsi_device; struct mipi_dsi_device *dsi_device;
u8 data; u8 data = 0;
enum port port; enum port port;
/* FIXME: Need to take care of 16 bit brightness level */ /* FIXME: Need to take care of 16 bit brightness level */
......
...@@ -306,7 +306,7 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv, ...@@ -306,7 +306,7 @@ static void bxt_exec_gpio(struct drm_i915_private *dev_priv,
if (!gpio_desc) { if (!gpio_desc) {
gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev, gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev,
"panel", gpio_index, NULL, gpio_index,
value ? GPIOD_OUT_LOW : value ? GPIOD_OUT_LOW :
GPIOD_OUT_HIGH); GPIOD_OUT_HIGH);
......
...@@ -1221,6 +1221,14 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine) ...@@ -1221,6 +1221,14 @@ static int intel_init_workaround_bb(struct intel_engine_cs *engine)
return ret; return ret;
} }
static u8 gtiir[] = {
[RCS] = 0,
[BCS] = 0,
[VCS] = 1,
[VCS2] = 1,
[VECS] = 3,
};
static int gen8_init_common_ring(struct intel_engine_cs *engine) static int gen8_init_common_ring(struct intel_engine_cs *engine)
{ {
struct drm_i915_private *dev_priv = engine->i915; struct drm_i915_private *dev_priv = engine->i915;
...@@ -1245,9 +1253,22 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine) ...@@ -1245,9 +1253,22 @@ static int gen8_init_common_ring(struct intel_engine_cs *engine)
DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name); DRM_DEBUG_DRIVER("Execlists enabled for %s\n", engine->name);
/* After a GPU reset, we may have requests to replay */ GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));
/*
* Clear any pending interrupt state.
*
* We do it twice out of paranoia that some of the IIR are double
* buffered, and if we only reset it once there may still be
* an interrupt pending.
*/
I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
GT_CONTEXT_SWITCH_INTERRUPT << engine->irq_shift);
clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
/* After a GPU reset, we may have requests to replay */
submit = false; submit = false;
for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) { for (n = 0; n < ARRAY_SIZE(engine->execlist_port); n++) {
if (!port_isset(&port[n])) if (!port_isset(&port[n]))
......
...@@ -210,8 +210,8 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port) ...@@ -210,8 +210,8 @@ bool lspcon_init(struct intel_digital_port *intel_dig_port)
struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_device *dev = intel_dig_port->base.base.dev;
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
if (!IS_GEN9(dev_priv)) { if (!HAS_LSPCON(dev_priv)) {
DRM_ERROR("LSPCON is supported on GEN9 only\n"); DRM_ERROR("LSPCON is not supported on this platform\n");
return false; return false;
} }
......
...@@ -545,15 +545,13 @@ static void ipu_plane_atomic_update(struct drm_plane *plane, ...@@ -545,15 +545,13 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
return; return;
} }
ics = ipu_drm_fourcc_to_colorspace(fb->format->format);
switch (ipu_plane->dp_flow) { switch (ipu_plane->dp_flow) {
case IPU_DP_FLOW_SYNC_BG: case IPU_DP_FLOW_SYNC_BG:
ipu_dp_setup_channel(ipu_plane->dp, ipu_dp_setup_channel(ipu_plane->dp, ics, IPUV3_COLORSPACE_RGB);
IPUV3_COLORSPACE_RGB,
IPUV3_COLORSPACE_RGB);
ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true); ipu_dp_set_global_alpha(ipu_plane->dp, true, 0, true);
break; break;
case IPU_DP_FLOW_SYNC_FG: case IPU_DP_FLOW_SYNC_FG:
ics = ipu_drm_fourcc_to_colorspace(state->fb->format->format);
ipu_dp_setup_channel(ipu_plane->dp, ics, ipu_dp_setup_channel(ipu_plane->dp, ics,
IPUV3_COLORSPACE_UNKNOWN); IPUV3_COLORSPACE_UNKNOWN);
/* Enable local alpha on partial plane */ /* Enable local alpha on partial plane */
......
...@@ -275,11 +275,15 @@ static void rockchip_drm_fb_resume(struct drm_device *drm) ...@@ -275,11 +275,15 @@ static void rockchip_drm_fb_resume(struct drm_device *drm)
static int rockchip_drm_sys_suspend(struct device *dev) static int rockchip_drm_sys_suspend(struct device *dev)
{ {
struct drm_device *drm = dev_get_drvdata(dev); struct drm_device *drm = dev_get_drvdata(dev);
struct rockchip_drm_private *priv = drm->dev_private; struct rockchip_drm_private *priv;
if (!drm)
return 0;
drm_kms_helper_poll_disable(drm); drm_kms_helper_poll_disable(drm);
rockchip_drm_fb_suspend(drm); rockchip_drm_fb_suspend(drm);
priv = drm->dev_private;
priv->state = drm_atomic_helper_suspend(drm); priv->state = drm_atomic_helper_suspend(drm);
if (IS_ERR(priv->state)) { if (IS_ERR(priv->state)) {
rockchip_drm_fb_resume(drm); rockchip_drm_fb_resume(drm);
...@@ -293,8 +297,12 @@ static int rockchip_drm_sys_suspend(struct device *dev) ...@@ -293,8 +297,12 @@ static int rockchip_drm_sys_suspend(struct device *dev)
static int rockchip_drm_sys_resume(struct device *dev) static int rockchip_drm_sys_resume(struct device *dev)
{ {
struct drm_device *drm = dev_get_drvdata(dev); struct drm_device *drm = dev_get_drvdata(dev);
struct rockchip_drm_private *priv = drm->dev_private; struct rockchip_drm_private *priv;
if (!drm)
return 0;
priv = drm->dev_private;
drm_atomic_helper_resume(drm, priv->state); drm_atomic_helper_resume(drm, priv->state);
rockchip_drm_fb_resume(drm); rockchip_drm_fb_resume(drm);
drm_kms_helper_poll_enable(drm); drm_kms_helper_poll_enable(drm);
......
...@@ -25,12 +25,20 @@ ...@@ -25,12 +25,20 @@
#include "sun4i_framebuffer.h" #include "sun4i_framebuffer.h"
#include "sun4i_tcon.h" #include "sun4i_tcon.h"
static void sun4i_drv_lastclose(struct drm_device *dev)
{
struct sun4i_drv *drv = dev->dev_private;
drm_fbdev_cma_restore_mode(drv->fbdev);
}
DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops); DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops);
static struct drm_driver sun4i_drv_driver = { static struct drm_driver sun4i_drv_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC, .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
/* Generic Operations */ /* Generic Operations */
.lastclose = sun4i_drv_lastclose,
.fops = &sun4i_drv_fops, .fops = &sun4i_drv_fops,
.name = "sun4i-drm", .name = "sun4i-drm",
.desc = "Allwinner sun4i Display Engine", .desc = "Allwinner sun4i Display Engine",
......
config IMX_IPUV3_CORE config IMX_IPUV3_CORE
tristate "IPUv3 core support" tristate "IPUv3 core support"
depends on SOC_IMX5 || SOC_IMX6Q || ARCH_MULTIPLATFORM depends on SOC_IMX5 || SOC_IMX6Q || ARCH_MULTIPLATFORM
depends on DRM || !DRM # if DRM=m, this can't be 'y'
select GENERIC_IRQ_CHIP select GENERIC_IRQ_CHIP
help help
Choose this if you have a i.MX5/6 system and want to use the Image Choose this if you have a i.MX5/6 system and want to use the Image
......
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