diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-29 20:51:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-29 20:51:26 -0400 |
commit | ed8c37e158cb697df905d6b4933bc107c69e8936 (patch) | |
tree | 9d3cf697d33194526cf60661b8ec071b387ebfc4 | |
parent | 2aafe1a4d451866e3e7b476e2fa0813b69b313c1 (diff) | |
parent | b8eade24c9891b8f153c40cf310ef4696c873af9 (diff) |
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie:
"Smattering of fixes, i915, exynos, tegra, msm, vmwgfx.
A bit of framebuffer reference counting fallout fixes, i915 GM45
regression fix, DVI regression fix, vmware info leak between processes
fix"
* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
drm/exynos: use %pad for dma_addr_t
drm/exynos: dsi: use IS_ERR() to check devm_ioremap_resource() results
MAINTAINERS: update maintainer entry for Exynos DP driver
drm/exynos: balance framebuffer refcount
drm/i915: Move all ring resets before setting the HWS page
drm/i915: Don't WARN nor handle unexpected hpd interrupts on gmch platforms
drm/msm/mdp4: cure for the cursor blues (v2)
drm/msm: default to XR24 rather than AR24
drm/msm: fix memory leak
drm/tegra: restrict plane loops to legacy planes
drm/i915: Allow full PPGTT with param override
drm/i915: Discard BIOS framebuffers too small to accommodate chosen mode
drm/vmwgfx: Make sure user-space can't DMA across buffer object boundaries v2
drm/i915: get power domain in case the BIOS enabled eDP VDD
drm/i915: Don't check gmch state on inherited configs
drm/i915: Allow user modes to exceed DVI 165MHz limit
24 files changed, 166 insertions, 56 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index e67ea2442041..ea44a57f790e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3485,6 +3485,12 @@ S: Maintained | |||
3485 | F: drivers/extcon/ | 3485 | F: drivers/extcon/ |
3486 | F: Documentation/extcon/ | 3486 | F: Documentation/extcon/ |
3487 | 3487 | ||
3488 | EXYNOS DP DRIVER | ||
3489 | M: Jingoo Han <jg1.han@samsung.com> | ||
3490 | L: dri-devel@lists.freedesktop.org | ||
3491 | S: Maintained | ||
3492 | F: drivers/gpu/drm/exynos/exynos_dp* | ||
3493 | |||
3488 | EXYNOS MIPI DISPLAY DRIVERS | 3494 | EXYNOS MIPI DISPLAY DRIVERS |
3489 | M: Inki Dae <inki.dae@samsung.com> | 3495 | M: Inki Dae <inki.dae@samsung.com> |
3490 | M: Donghwa Lee <dh09.lee@samsung.com> | 3496 | M: Donghwa Lee <dh09.lee@samsung.com> |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index e930d4fe29c7..1ef5ab9c9d51 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -145,6 +145,7 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
145 | 145 | ||
146 | plane->crtc = crtc; | 146 | plane->crtc = crtc; |
147 | plane->fb = crtc->primary->fb; | 147 | plane->fb = crtc->primary->fb; |
148 | drm_framebuffer_reference(plane->fb); | ||
148 | 149 | ||
149 | return 0; | 150 | return 0; |
150 | } | 151 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index c786cd4f457b..2a3ad24276f8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | |||
@@ -263,7 +263,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, | |||
263 | buffer->sgt = sgt; | 263 | buffer->sgt = sgt; |
264 | exynos_gem_obj->base.import_attach = attach; | 264 | exynos_gem_obj->base.import_attach = attach; |
265 | 265 | ||
266 | DRM_DEBUG_PRIME("dma_addr = 0x%x, size = 0x%lx\n", buffer->dma_addr, | 266 | DRM_DEBUG_PRIME("dma_addr = %pad, size = 0x%lx\n", &buffer->dma_addr, |
267 | buffer->size); | 267 | buffer->size); |
268 | 268 | ||
269 | return &exynos_gem_obj->base; | 269 | return &exynos_gem_obj->base; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index eb73e3bf2a0c..4ac438187568 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c | |||
@@ -1426,9 +1426,9 @@ static int exynos_dsi_probe(struct platform_device *pdev) | |||
1426 | 1426 | ||
1427 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1427 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1428 | dsi->reg_base = devm_ioremap_resource(&pdev->dev, res); | 1428 | dsi->reg_base = devm_ioremap_resource(&pdev->dev, res); |
1429 | if (!dsi->reg_base) { | 1429 | if (IS_ERR(dsi->reg_base)) { |
1430 | dev_err(&pdev->dev, "failed to remap io region\n"); | 1430 | dev_err(&pdev->dev, "failed to remap io region\n"); |
1431 | return -EADDRNOTAVAIL; | 1431 | return PTR_ERR(dsi->reg_base); |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | dsi->phy = devm_phy_get(&pdev->dev, "dsim"); | 1434 | dsi->phy = devm_phy_get(&pdev->dev, "dsim"); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 7afead9c3f30..852f2dadaebd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -220,7 +220,7 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) | |||
220 | 220 | ||
221 | win_data->enabled = true; | 221 | win_data->enabled = true; |
222 | 222 | ||
223 | DRM_DEBUG_KMS("dma_addr = 0x%x\n", win_data->dma_addr); | 223 | DRM_DEBUG_KMS("dma_addr = %pad\n", &win_data->dma_addr); |
224 | 224 | ||
225 | if (ctx->vblank_on) | 225 | if (ctx->vblank_on) |
226 | schedule_work(&ctx->work); | 226 | schedule_work(&ctx->work); |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index ab5e93c30aa2..62a5c3627b90 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -50,7 +50,7 @@ bool intel_enable_ppgtt(struct drm_device *dev, bool full) | |||
50 | 50 | ||
51 | /* Full ppgtt disabled by default for now due to issues. */ | 51 | /* Full ppgtt disabled by default for now due to issues. */ |
52 | if (full) | 52 | if (full) |
53 | return false; /* HAS_PPGTT(dev) */ | 53 | return HAS_PPGTT(dev) && (i915.enable_ppgtt == 2); |
54 | else | 54 | else |
55 | return HAS_ALIASING_PPGTT(dev); | 55 | return HAS_ALIASING_PPGTT(dev); |
56 | } | 56 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7753249b3a95..f98ba4e6e70b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1362,10 +1362,20 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, | |||
1362 | spin_lock(&dev_priv->irq_lock); | 1362 | spin_lock(&dev_priv->irq_lock); |
1363 | for (i = 1; i < HPD_NUM_PINS; i++) { | 1363 | for (i = 1; i < HPD_NUM_PINS; i++) { |
1364 | 1364 | ||
1365 | WARN_ONCE(hpd[i] & hotplug_trigger && | 1365 | if (hpd[i] & hotplug_trigger && |
1366 | dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED, | 1366 | dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED) { |
1367 | "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", | 1367 | /* |
1368 | hotplug_trigger, i, hpd[i]); | 1368 | * On GMCH platforms the interrupt mask bits only |
1369 | * prevent irq generation, not the setting of the | ||
1370 | * hotplug bits itself. So only WARN about unexpected | ||
1371 | * interrupts on saner platforms. | ||
1372 | */ | ||
1373 | WARN_ONCE(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev), | ||
1374 | "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", | ||
1375 | hotplug_trigger, i, hpd[i]); | ||
1376 | |||
1377 | continue; | ||
1378 | } | ||
1369 | 1379 | ||
1370 | if (!(hpd[i] & hotplug_trigger) || | 1380 | if (!(hpd[i] & hotplug_trigger) || |
1371 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) | 1381 | dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9f5b18d9d885..c77af69c2d8f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -827,6 +827,7 @@ enum punit_power_well { | |||
827 | # define MI_FLUSH_ENABLE (1 << 12) | 827 | # define MI_FLUSH_ENABLE (1 << 12) |
828 | # define ASYNC_FLIP_PERF_DISABLE (1 << 14) | 828 | # define ASYNC_FLIP_PERF_DISABLE (1 << 14) |
829 | # define MODE_IDLE (1 << 9) | 829 | # define MODE_IDLE (1 << 9) |
830 | # define STOP_RING (1 << 8) | ||
830 | 831 | ||
831 | #define GEN6_GT_MODE 0x20d0 | 832 | #define GEN6_GT_MODE 0x20d0 |
832 | #define GEN7_GT_MODE 0x7008 | 833 | #define GEN7_GT_MODE 0x7008 |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dae976f51d83..69bcc42a0e44 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -9654,11 +9654,22 @@ intel_pipe_config_compare(struct drm_device *dev, | |||
9654 | PIPE_CONF_CHECK_I(pipe_src_w); | 9654 | PIPE_CONF_CHECK_I(pipe_src_w); |
9655 | PIPE_CONF_CHECK_I(pipe_src_h); | 9655 | PIPE_CONF_CHECK_I(pipe_src_h); |
9656 | 9656 | ||
9657 | PIPE_CONF_CHECK_I(gmch_pfit.control); | 9657 | /* |
9658 | /* pfit ratios are autocomputed by the hw on gen4+ */ | 9658 | * FIXME: BIOS likes to set up a cloned config with lvds+external |
9659 | if (INTEL_INFO(dev)->gen < 4) | 9659 | * screen. Since we don't yet re-compute the pipe config when moving |
9660 | PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); | 9660 | * just the lvds port away to another pipe the sw tracking won't match. |
9661 | PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); | 9661 | * |
9662 | * Proper atomic modesets with recomputed global state will fix this. | ||
9663 | * Until then just don't check gmch state for inherited modes. | ||
9664 | */ | ||
9665 | if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) { | ||
9666 | PIPE_CONF_CHECK_I(gmch_pfit.control); | ||
9667 | /* pfit ratios are autocomputed by the hw on gen4+ */ | ||
9668 | if (INTEL_INFO(dev)->gen < 4) | ||
9669 | PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); | ||
9670 | PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); | ||
9671 | } | ||
9672 | |||
9662 | PIPE_CONF_CHECK_I(pch_pfit.enabled); | 9673 | PIPE_CONF_CHECK_I(pch_pfit.enabled); |
9663 | if (current_config->pch_pfit.enabled) { | 9674 | if (current_config->pch_pfit.enabled) { |
9664 | PIPE_CONF_CHECK_I(pch_pfit.pos); | 9675 | PIPE_CONF_CHECK_I(pch_pfit.pos); |
@@ -11616,6 +11627,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
11616 | base.head) { | 11627 | base.head) { |
11617 | memset(&crtc->config, 0, sizeof(crtc->config)); | 11628 | memset(&crtc->config, 0, sizeof(crtc->config)); |
11618 | 11629 | ||
11630 | crtc->config.quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE; | ||
11631 | |||
11619 | crtc->active = dev_priv->display.get_pipe_config(crtc, | 11632 | crtc->active = dev_priv->display.get_pipe_config(crtc, |
11620 | &crtc->config); | 11633 | &crtc->config); |
11621 | 11634 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d2a55884ad52..dfa85289f28f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -3619,7 +3619,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
3619 | { | 3619 | { |
3620 | struct drm_connector *connector = &intel_connector->base; | 3620 | struct drm_connector *connector = &intel_connector->base; |
3621 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 3621 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
3622 | struct drm_device *dev = intel_dig_port->base.base.dev; | 3622 | struct intel_encoder *intel_encoder = &intel_dig_port->base; |
3623 | struct drm_device *dev = intel_encoder->base.dev; | ||
3623 | struct drm_i915_private *dev_priv = dev->dev_private; | 3624 | struct drm_i915_private *dev_priv = dev->dev_private; |
3624 | struct drm_display_mode *fixed_mode = NULL; | 3625 | struct drm_display_mode *fixed_mode = NULL; |
3625 | bool has_dpcd; | 3626 | bool has_dpcd; |
@@ -3629,6 +3630,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, | |||
3629 | if (!is_edp(intel_dp)) | 3630 | if (!is_edp(intel_dp)) |
3630 | return true; | 3631 | return true; |
3631 | 3632 | ||
3633 | /* The VDD bit needs a power domain reference, so if the bit is already | ||
3634 | * enabled when we boot, grab this reference. */ | ||
3635 | if (edp_have_panel_vdd(intel_dp)) { | ||
3636 | enum intel_display_power_domain power_domain; | ||
3637 | power_domain = intel_display_port_power_domain(intel_encoder); | ||
3638 | intel_display_power_get(dev_priv, power_domain); | ||
3639 | } | ||
3640 | |||
3632 | /* Cache DPCD and EDID for edp. */ | 3641 | /* Cache DPCD and EDID for edp. */ |
3633 | intel_edp_panel_vdd_on(intel_dp); | 3642 | intel_edp_panel_vdd_on(intel_dp); |
3634 | has_dpcd = intel_dp_get_dpcd(intel_dp); | 3643 | has_dpcd = intel_dp_get_dpcd(intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0542de982260..328b1a70264b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -236,7 +236,8 @@ struct intel_crtc_config { | |||
236 | * tracked with quirk flags so that fastboot and state checker can act | 236 | * tracked with quirk flags so that fastboot and state checker can act |
237 | * accordingly. | 237 | * accordingly. |
238 | */ | 238 | */ |
239 | #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ | 239 | #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ |
240 | #define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */ | ||
240 | unsigned long quirks; | 241 | unsigned long quirks; |
241 | 242 | ||
242 | /* User requested mode, only valid as a starting point to | 243 | /* User requested mode, only valid as a starting point to |
diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index b4d44e62f0c7..fce4a0d93c0b 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c | |||
@@ -132,6 +132,16 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
132 | 132 | ||
133 | mutex_lock(&dev->struct_mutex); | 133 | mutex_lock(&dev->struct_mutex); |
134 | 134 | ||
135 | if (intel_fb && | ||
136 | (sizes->fb_width > intel_fb->base.width || | ||
137 | sizes->fb_height > intel_fb->base.height)) { | ||
138 | DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d)," | ||
139 | " releasing it\n", | ||
140 | intel_fb->base.width, intel_fb->base.height, | ||
141 | sizes->fb_width, sizes->fb_height); | ||
142 | drm_framebuffer_unreference(&intel_fb->base); | ||
143 | intel_fb = ifbdev->fb = NULL; | ||
144 | } | ||
135 | if (!intel_fb || WARN_ON(!intel_fb->obj)) { | 145 | if (!intel_fb || WARN_ON(!intel_fb->obj)) { |
136 | DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); | 146 | DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); |
137 | ret = intelfb_alloc(helper, sizes); | 147 | ret = intelfb_alloc(helper, sizes); |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index b0413e190625..157267aa3561 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -821,11 +821,11 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) | |||
821 | } | 821 | } |
822 | } | 822 | } |
823 | 823 | ||
824 | static int hdmi_portclock_limit(struct intel_hdmi *hdmi) | 824 | static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) |
825 | { | 825 | { |
826 | struct drm_device *dev = intel_hdmi_to_dev(hdmi); | 826 | struct drm_device *dev = intel_hdmi_to_dev(hdmi); |
827 | 827 | ||
828 | if (!hdmi->has_hdmi_sink || IS_G4X(dev)) | 828 | if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev)) |
829 | return 165000; | 829 | return 165000; |
830 | else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) | 830 | else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) |
831 | return 300000; | 831 | return 300000; |
@@ -837,7 +837,8 @@ static enum drm_mode_status | |||
837 | intel_hdmi_mode_valid(struct drm_connector *connector, | 837 | intel_hdmi_mode_valid(struct drm_connector *connector, |
838 | struct drm_display_mode *mode) | 838 | struct drm_display_mode *mode) |
839 | { | 839 | { |
840 | if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector))) | 840 | if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector), |
841 | true)) | ||
841 | return MODE_CLOCK_HIGH; | 842 | return MODE_CLOCK_HIGH; |
842 | if (mode->clock < 20000) | 843 | if (mode->clock < 20000) |
843 | return MODE_CLOCK_LOW; | 844 | return MODE_CLOCK_LOW; |
@@ -879,7 +880,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, | |||
879 | struct drm_device *dev = encoder->base.dev; | 880 | struct drm_device *dev = encoder->base.dev; |
880 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; | 881 | struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; |
881 | int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2; | 882 | int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2; |
882 | int portclock_limit = hdmi_portclock_limit(intel_hdmi); | 883 | int portclock_limit = hdmi_portclock_limit(intel_hdmi, false); |
883 | int desired_bpp; | 884 | int desired_bpp; |
884 | 885 | ||
885 | if (intel_hdmi->color_range_auto) { | 886 | if (intel_hdmi->color_range_auto) { |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6bc68bdcf433..79fb4cc2137c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -437,32 +437,41 @@ static void ring_setup_phys_status_page(struct intel_ring_buffer *ring) | |||
437 | I915_WRITE(HWS_PGA, addr); | 437 | I915_WRITE(HWS_PGA, addr); |
438 | } | 438 | } |
439 | 439 | ||
440 | static int init_ring_common(struct intel_ring_buffer *ring) | 440 | static bool stop_ring(struct intel_ring_buffer *ring) |
441 | { | 441 | { |
442 | struct drm_device *dev = ring->dev; | 442 | struct drm_i915_private *dev_priv = to_i915(ring->dev); |
443 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
444 | struct drm_i915_gem_object *obj = ring->obj; | ||
445 | int ret = 0; | ||
446 | u32 head; | ||
447 | 443 | ||
448 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | 444 | if (!IS_GEN2(ring->dev)) { |
445 | I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); | ||
446 | if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { | ||
447 | DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); | ||
448 | return false; | ||
449 | } | ||
450 | } | ||
449 | 451 | ||
450 | /* Stop the ring if it's running. */ | ||
451 | I915_WRITE_CTL(ring, 0); | 452 | I915_WRITE_CTL(ring, 0); |
452 | I915_WRITE_HEAD(ring, 0); | 453 | I915_WRITE_HEAD(ring, 0); |
453 | ring->write_tail(ring, 0); | 454 | ring->write_tail(ring, 0); |
454 | if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) | ||
455 | DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); | ||
456 | 455 | ||
457 | if (I915_NEED_GFX_HWS(dev)) | 456 | if (!IS_GEN2(ring->dev)) { |
458 | intel_ring_setup_status_page(ring); | 457 | (void)I915_READ_CTL(ring); |
459 | else | 458 | I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); |
460 | ring_setup_phys_status_page(ring); | 459 | } |
461 | 460 | ||
462 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 461 | return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0; |
462 | } | ||
463 | 463 | ||
464 | /* G45 ring initialization fails to reset head to zero */ | 464 | static int init_ring_common(struct intel_ring_buffer *ring) |
465 | if (head != 0) { | 465 | { |
466 | struct drm_device *dev = ring->dev; | ||
467 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
468 | struct drm_i915_gem_object *obj = ring->obj; | ||
469 | int ret = 0; | ||
470 | |||
471 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | ||
472 | |||
473 | if (!stop_ring(ring)) { | ||
474 | /* G45 ring initialization often fails to reset head to zero */ | ||
466 | DRM_DEBUG_KMS("%s head not reset to zero " | 475 | DRM_DEBUG_KMS("%s head not reset to zero " |
467 | "ctl %08x head %08x tail %08x start %08x\n", | 476 | "ctl %08x head %08x tail %08x start %08x\n", |
468 | ring->name, | 477 | ring->name, |
@@ -471,9 +480,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
471 | I915_READ_TAIL(ring), | 480 | I915_READ_TAIL(ring), |
472 | I915_READ_START(ring)); | 481 | I915_READ_START(ring)); |
473 | 482 | ||
474 | I915_WRITE_HEAD(ring, 0); | 483 | if (!stop_ring(ring)) { |
475 | |||
476 | if (I915_READ_HEAD(ring) & HEAD_ADDR) { | ||
477 | DRM_ERROR("failed to set %s head to zero " | 484 | DRM_ERROR("failed to set %s head to zero " |
478 | "ctl %08x head %08x tail %08x start %08x\n", | 485 | "ctl %08x head %08x tail %08x start %08x\n", |
479 | ring->name, | 486 | ring->name, |
@@ -481,9 +488,16 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
481 | I915_READ_HEAD(ring), | 488 | I915_READ_HEAD(ring), |
482 | I915_READ_TAIL(ring), | 489 | I915_READ_TAIL(ring), |
483 | I915_READ_START(ring)); | 490 | I915_READ_START(ring)); |
491 | ret = -EIO; | ||
492 | goto out; | ||
484 | } | 493 | } |
485 | } | 494 | } |
486 | 495 | ||
496 | if (I915_NEED_GFX_HWS(dev)) | ||
497 | intel_ring_setup_status_page(ring); | ||
498 | else | ||
499 | ring_setup_phys_status_page(ring); | ||
500 | |||
487 | /* Initialize the ring. This must happen _after_ we've cleared the ring | 501 | /* Initialize the ring. This must happen _after_ we've cleared the ring |
488 | * registers with the above sequence (the readback of the HEAD registers | 502 | * registers with the above sequence (the readback of the HEAD registers |
489 | * also enforces ordering), otherwise the hw might lose the new ring | 503 | * also enforces ordering), otherwise the hw might lose the new ring |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 270a6a973438..2b91c4b4d34b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -34,6 +34,7 @@ struct intel_hw_status_page { | |||
34 | #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) | 34 | #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) |
35 | 35 | ||
36 | #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base)) | 36 | #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base)) |
37 | #define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val) | ||
37 | 38 | ||
38 | enum intel_ring_hangcheck_action { | 39 | enum intel_ring_hangcheck_action { |
39 | HANGCHECK_IDLE = 0, | 40 | HANGCHECK_IDLE = 0, |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 3e6c0f3ed592..ef9957dbac94 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
@@ -510,9 +510,8 @@ static void update_cursor(struct drm_crtc *crtc) | |||
510 | MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN); | 510 | MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN); |
511 | } else { | 511 | } else { |
512 | /* disable cursor: */ | 512 | /* disable cursor: */ |
513 | mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), 0); | 513 | mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), |
514 | mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma), | 514 | mdp4_kms->blank_cursor_iova); |
515 | MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB)); | ||
516 | } | 515 | } |
517 | 516 | ||
518 | /* and drop the iova ref + obj rev when done scanning out: */ | 517 | /* and drop the iova ref + obj rev when done scanning out: */ |
@@ -574,11 +573,9 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, | |||
574 | 573 | ||
575 | if (old_bo) { | 574 | if (old_bo) { |
576 | /* drop our previous reference: */ | 575 | /* drop our previous reference: */ |
577 | msm_gem_put_iova(old_bo, mdp4_kms->id); | 576 | drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, old_bo); |
578 | drm_gem_object_unreference_unlocked(old_bo); | ||
579 | } | 577 | } |
580 | 578 | ||
581 | crtc_flush(crtc); | ||
582 | request_pending(crtc, PENDING_CURSOR); | 579 | request_pending(crtc, PENDING_CURSOR); |
583 | 580 | ||
584 | return 0; | 581 | return 0; |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c index c740ccd1cc67..8edd531cb621 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c | |||
@@ -70,12 +70,12 @@ irqreturn_t mdp4_irq(struct msm_kms *kms) | |||
70 | 70 | ||
71 | VERB("status=%08x", status); | 71 | VERB("status=%08x", status); |
72 | 72 | ||
73 | mdp_dispatch_irqs(mdp_kms, status); | ||
74 | |||
73 | for (id = 0; id < priv->num_crtcs; id++) | 75 | for (id = 0; id < priv->num_crtcs; id++) |
74 | if (status & mdp4_crtc_vblank(priv->crtcs[id])) | 76 | if (status & mdp4_crtc_vblank(priv->crtcs[id])) |
75 | drm_handle_vblank(dev, id); | 77 | drm_handle_vblank(dev, id); |
76 | 78 | ||
77 | mdp_dispatch_irqs(mdp_kms, status); | ||
78 | |||
79 | return IRQ_HANDLED; | 79 | return IRQ_HANDLED; |
80 | } | 80 | } |
81 | 81 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 272e707c9487..0bb4faa17523 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | |||
@@ -144,6 +144,10 @@ static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file) | |||
144 | static void mdp4_destroy(struct msm_kms *kms) | 144 | static void mdp4_destroy(struct msm_kms *kms) |
145 | { | 145 | { |
146 | struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); | 146 | struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); |
147 | if (mdp4_kms->blank_cursor_iova) | ||
148 | msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id); | ||
149 | if (mdp4_kms->blank_cursor_bo) | ||
150 | drm_gem_object_unreference(mdp4_kms->blank_cursor_bo); | ||
147 | kfree(mdp4_kms); | 151 | kfree(mdp4_kms); |
148 | } | 152 | } |
149 | 153 | ||
@@ -372,6 +376,23 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) | |||
372 | goto fail; | 376 | goto fail; |
373 | } | 377 | } |
374 | 378 | ||
379 | mutex_lock(&dev->struct_mutex); | ||
380 | mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC); | ||
381 | mutex_unlock(&dev->struct_mutex); | ||
382 | if (IS_ERR(mdp4_kms->blank_cursor_bo)) { | ||
383 | ret = PTR_ERR(mdp4_kms->blank_cursor_bo); | ||
384 | dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); | ||
385 | mdp4_kms->blank_cursor_bo = NULL; | ||
386 | goto fail; | ||
387 | } | ||
388 | |||
389 | ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id, | ||
390 | &mdp4_kms->blank_cursor_iova); | ||
391 | if (ret) { | ||
392 | dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret); | ||
393 | goto fail; | ||
394 | } | ||
395 | |||
375 | return kms; | 396 | return kms; |
376 | 397 | ||
377 | fail: | 398 | fail: |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 66a4d31aec80..715520c54cde 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | |||
@@ -44,6 +44,10 @@ struct mdp4_kms { | |||
44 | struct clk *lut_clk; | 44 | struct clk *lut_clk; |
45 | 45 | ||
46 | struct mdp_irq error_handler; | 46 | struct mdp_irq error_handler; |
47 | |||
48 | /* empty/blank cursor bo to use when cursor is "disabled" */ | ||
49 | struct drm_gem_object *blank_cursor_bo; | ||
50 | uint32_t blank_cursor_iova; | ||
47 | }; | 51 | }; |
48 | #define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base) | 52 | #define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base) |
49 | 53 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 353d494a497f..f2b985bc2adf 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | |||
@@ -71,11 +71,11 @@ static void mdp5_irq_mdp(struct mdp_kms *mdp_kms) | |||
71 | 71 | ||
72 | VERB("status=%08x", status); | 72 | VERB("status=%08x", status); |
73 | 73 | ||
74 | mdp_dispatch_irqs(mdp_kms, status); | ||
75 | |||
74 | for (id = 0; id < priv->num_crtcs; id++) | 76 | for (id = 0; id < priv->num_crtcs; id++) |
75 | if (status & mdp5_crtc_vblank(priv->crtcs[id])) | 77 | if (status & mdp5_crtc_vblank(priv->crtcs[id])) |
76 | drm_handle_vblank(dev, id); | 78 | drm_handle_vblank(dev, id); |
77 | |||
78 | mdp_dispatch_irqs(mdp_kms, status); | ||
79 | } | 79 | } |
80 | 80 | ||
81 | irqreturn_t mdp5_irq(struct msm_kms *kms) | 81 | irqreturn_t mdp5_irq(struct msm_kms *kms) |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 6c6d7d4c9b4e..a752ab83b810 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
@@ -62,11 +62,8 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, | |||
62 | dma_addr_t paddr; | 62 | dma_addr_t paddr; |
63 | int ret, size; | 63 | int ret, size; |
64 | 64 | ||
65 | /* only doing ARGB32 since this is what is needed to alpha-blend | ||
66 | * with video overlays: | ||
67 | */ | ||
68 | sizes->surface_bpp = 32; | 65 | sizes->surface_bpp = 32; |
69 | sizes->surface_depth = 32; | 66 | sizes->surface_depth = 24; |
70 | 67 | ||
71 | DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width, | 68 | DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width, |
72 | sizes->surface_height, sizes->surface_bpp, | 69 | sizes->surface_height, sizes->surface_bpp, |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 3da8264d3039..bb8026daebc9 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
@@ -118,8 +118,10 @@ static void put_pages(struct drm_gem_object *obj) | |||
118 | 118 | ||
119 | if (iommu_present(&platform_bus_type)) | 119 | if (iommu_present(&platform_bus_type)) |
120 | drm_gem_put_pages(obj, msm_obj->pages, true, false); | 120 | drm_gem_put_pages(obj, msm_obj->pages, true, false); |
121 | else | 121 | else { |
122 | drm_mm_remove_node(msm_obj->vram_node); | 122 | drm_mm_remove_node(msm_obj->vram_node); |
123 | drm_free_large(msm_obj->pages); | ||
124 | } | ||
123 | 125 | ||
124 | msm_obj->pages = NULL; | 126 | msm_obj->pages = NULL; |
125 | } | 127 | } |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 36c717af6cf9..edb871d7d395 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
@@ -312,7 +312,7 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) | |||
312 | struct drm_device *drm = crtc->dev; | 312 | struct drm_device *drm = crtc->dev; |
313 | struct drm_plane *plane; | 313 | struct drm_plane *plane; |
314 | 314 | ||
315 | list_for_each_entry(plane, &drm->mode_config.plane_list, head) { | 315 | drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) { |
316 | if (plane->crtc == crtc) { | 316 | if (plane->crtc == crtc) { |
317 | tegra_plane_disable(plane); | 317 | tegra_plane_disable(plane); |
318 | plane->crtc = NULL; | 318 | plane->crtc = NULL; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 931490b9cfed..87df0b3674fd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -1214,14 +1214,36 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
1214 | SVGA3dCmdSurfaceDMA dma; | 1214 | SVGA3dCmdSurfaceDMA dma; |
1215 | } *cmd; | 1215 | } *cmd; |
1216 | int ret; | 1216 | int ret; |
1217 | SVGA3dCmdSurfaceDMASuffix *suffix; | ||
1218 | uint32_t bo_size; | ||
1217 | 1219 | ||
1218 | cmd = container_of(header, struct vmw_dma_cmd, header); | 1220 | cmd = container_of(header, struct vmw_dma_cmd, header); |
1221 | suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma + | ||
1222 | header->size - sizeof(*suffix)); | ||
1223 | |||
1224 | /* Make sure device and verifier stays in sync. */ | ||
1225 | if (unlikely(suffix->suffixSize != sizeof(*suffix))) { | ||
1226 | DRM_ERROR("Invalid DMA suffix size.\n"); | ||
1227 | return -EINVAL; | ||
1228 | } | ||
1229 | |||
1219 | ret = vmw_translate_guest_ptr(dev_priv, sw_context, | 1230 | ret = vmw_translate_guest_ptr(dev_priv, sw_context, |
1220 | &cmd->dma.guest.ptr, | 1231 | &cmd->dma.guest.ptr, |
1221 | &vmw_bo); | 1232 | &vmw_bo); |
1222 | if (unlikely(ret != 0)) | 1233 | if (unlikely(ret != 0)) |
1223 | return ret; | 1234 | return ret; |
1224 | 1235 | ||
1236 | /* Make sure DMA doesn't cross BO boundaries. */ | ||
1237 | bo_size = vmw_bo->base.num_pages * PAGE_SIZE; | ||
1238 | if (unlikely(cmd->dma.guest.ptr.offset > bo_size)) { | ||
1239 | DRM_ERROR("Invalid DMA offset.\n"); | ||
1240 | return -EINVAL; | ||
1241 | } | ||
1242 | |||
1243 | bo_size -= cmd->dma.guest.ptr.offset; | ||
1244 | if (unlikely(suffix->maximumOffset > bo_size)) | ||
1245 | suffix->maximumOffset = bo_size; | ||
1246 | |||
1225 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, | 1247 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, |
1226 | user_surface_converter, &cmd->dma.host.sid, | 1248 | user_surface_converter, &cmd->dma.host.sid, |
1227 | NULL); | 1249 | NULL); |