Pull drm fixes from Dave Airlie: "This contains fixes for exynos, amdgpu, radeon, i915 and qxl. It also contains some fixes to the core drm edid parser. qxl: - fix for a cursor hotspot issue radeon: - some MST fixes that I've been running locally and make my monitor a bit happier exynos: - fix some regressions and build fixes amdgpu: - a couple of small fixes i915: - two DP MST fixes and a couple of other regression fixes Nothing too out of the ordinary or surprising at this point" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/exynos: Use VIDEO_SAMSUNG_S5P_G2D=n as G2D Kconfig dependency drm/exynos: fix a warning message drm/exynos: mic: fix an error code drm/exynos: fimd: fix broken dp_clock control drm/exynos: build fbdev code conditionally drm/exynos: fix adjusted_mode pointer in exynos_plane_mode_set drm/exynos: fix error handling in exynos_drm_subdrv_open drm/amd/amdgpu: fix irq domain remove for tonga ih drm/i915: fix deadlock on lid open drm/radeon: use helper for mst connector dpms. drm/radeon/mst: port some MST setup code from DAL. drm/amdgpu: add invisible pin size statistic drm/edid: Fix DMT 1024x768@43Hz (interlaced) timings drm/i915: Exit cherryview_irq_handler() after one pass drm/i915: Call intel_dp_mst_resume() before resuming displays drm/i915: Fix race condition in intel_dp_destroy_mst_connector() drm/edid: Fix parsing of EDID 1.4 Established Timings III descriptor drm/edid: Fix EDID Established Timings I and II drm/qxl: fix cursor position with non-zero hotspot
Unified · Split
| @@ -2034,6 +2034,7 @@ struct amdgpu_device { · 2033 unmodified lines | ||
| 2034 | 2034 | |
| 2035 | 2035 | /* tracking pinned memory */ |
| 2036 | 2036 | u64 vram_pin_size; |
| 2037 | + u64 invisible_pin_size; | |
| 2037 | 2038 | u64 gart_pin_size; |
| 2038 | 2039 | |
| 2039 | 2040 | /* amdkfd interface */ |
| @@ -384,7 +384,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file · 383 unmodified lines | ||
| 384 | 384 | vram_gtt.vram_size = adev->mc.real_vram_size; |
| 385 | 385 | vram_gtt.vram_size -= adev->vram_pin_size; |
| 386 | 386 | vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size; |
| 387 | − vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size; | |
| 387 | + vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size); | |
| 388 | 388 | vram_gtt.gtt_size = adev->mc.gtt_size; |
| 389 | 389 | vram_gtt.gtt_size -= adev->gart_pin_size; |
| 390 | 390 | return copy_to_user(out, &vram_gtt, |
| @@ -424,9 +424,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, · 423 unmodified lines | ||
| 424 | 424 | bo->pin_count = 1; |
| 425 | 425 | if (gpu_addr != NULL) |
| 426 | 426 | *gpu_addr = amdgpu_bo_gpu_offset(bo); |
| 427 | − if (domain == AMDGPU_GEM_DOMAIN_VRAM) | |
| 427 | + if (domain == AMDGPU_GEM_DOMAIN_VRAM) { | |
| 428 | 428 | bo->adev->vram_pin_size += amdgpu_bo_size(bo); |
| 429 | − else | |
| 429 | + if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) | |
| 430 | + bo->adev->invisible_pin_size += amdgpu_bo_size(bo); | |
| 431 | + } else | |
| 430 | 432 | bo->adev->gart_pin_size += amdgpu_bo_size(bo); |
| 431 | 433 | } else { |
| 432 | 434 | dev_err(bo->adev->dev, "%p pin failed\n", bo); |
| @@ -456,9 +458,11 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo) · 23 unmodified lines | ||
| 456 | 458 | } |
| 457 | 459 | r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); |
| 458 | 460 | if (likely(r == 0)) { |
| 459 | − if (bo->tbo.mem.mem_type == TTM_PL_VRAM) | |
| 461 | + if (bo->tbo.mem.mem_type == TTM_PL_VRAM) { | |
| 460 | 462 | bo->adev->vram_pin_size -= amdgpu_bo_size(bo); |
| 461 | − else | |
| 463 | + if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) | |
| 464 | + bo->adev->invisible_pin_size -= amdgpu_bo_size(bo); | |
| 465 | + } else | |
| 462 | 466 | bo->adev->gart_pin_size -= amdgpu_bo_size(bo); |
| 463 | 467 | } else { |
| 464 | 468 | dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo); |
| @@ -307,7 +307,7 @@ static int tonga_ih_sw_fini(void *handle) · 306 unmodified lines | ||
| 307 | 307 | |
| 308 | 308 | amdgpu_irq_fini(adev); |
| 309 | 309 | amdgpu_ih_ring_fini(adev); |
| 310 | − amdgpu_irq_add_domain(adev); | |
| 310 | + amdgpu_irq_remove_domain(adev); | |
| 311 | 311 | |
| 312 | 312 | return 0; |
| 313 | 313 | } |
| @@ -205,7 +205,7 @@ static const struct drm_display_mode drm_dmt_modes[] = { · 204 unmodified lines | ||
| 205 | 205 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
| 206 | 206 | /* 0x0f - 1024x768@43Hz, interlace */ |
| 207 | 207 | { DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032, |
| 208 | − 1208, 1264, 0, 768, 768, 772, 817, 0, | |
| 208 | + 1208, 1264, 0, 768, 768, 776, 817, 0, | |
| 209 | 209 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
| 210 | 210 | DRM_MODE_FLAG_INTERLACE) }, |
| 211 | 211 | /* 0x10 - 1024x768@60Hz */ |
| @@ -522,12 +522,12 @@ static const struct drm_display_mode edid_est_modes[] = { · 310 unmodified lines | ||
| 522 | 522 | 720, 840, 0, 480, 481, 484, 500, 0, |
| 523 | 523 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */ |
| 524 | 524 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, |
| 525 | − 704, 832, 0, 480, 489, 491, 520, 0, | |
| 525 | + 704, 832, 0, 480, 489, 492, 520, 0, | |
| 526 | 526 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */ |
| 527 | 527 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704, |
| 528 | 528 | 768, 864, 0, 480, 483, 486, 525, 0, |
| 529 | 529 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */ |
| 530 | − { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656, | |
| 530 | + { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, | |
| 531 | 531 | 752, 800, 0, 480, 490, 492, 525, 0, |
| 532 | 532 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */ |
| 533 | 533 | { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738, |
| @@ -539,7 +539,7 @@ static const struct drm_display_mode edid_est_modes[] = { · 5 unmodified lines | ||
| 539 | 539 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, |
| 540 | 540 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, |
| 541 | 541 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */ |
| 542 | − { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040, | |
| 542 | + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040, | |
| 543 | 543 | 1136, 1312, 0, 768, 769, 772, 800, 0, |
| 544 | 544 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */ |
| 545 | 545 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, |
| @@ -2241,7 +2241,7 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) · 1695 unmodified lines | ||
| 2241 | 2241 | { |
| 2242 | 2242 | int i, j, m, modes = 0; |
| 2243 | 2243 | struct drm_display_mode *mode; |
| 2244 | − u8 *est = ((u8 *)timing) + 5; | |
| 2244 | + u8 *est = ((u8 *)timing) + 6; | |
| 2245 | 2245 | |
| 2246 | 2246 | for (i = 0; i < 6; i++) { |
| 2247 | 2247 | for (j = 7; j >= 0; j--) { |
| @@ -94,7 +94,7 @@ comment "Sub-drivers" · 93 unmodified lines | ||
| 94 | 94 | |
| 95 | 95 | config DRM_EXYNOS_G2D |
| 96 | 96 | bool "G2D" |
| 97 | − depends on !VIDEO_SAMSUNG_S5P_G2D | |
| 97 | + depends on VIDEO_SAMSUNG_S5P_G2D=n | |
| 98 | 98 | select FRAME_VECTOR |
| 99 | 99 | help |
| 100 | 100 | Choose this option if you want to use Exynos G2D for DRM. |
| @@ -2,10 +2,10 @@ · 1 unmodified line | ||
| 2 | 2 | # Makefile for the drm device driver. This driver provides support for the |
| 3 | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
| 4 | 4 | |
| 5 | −exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \ | |
| 6 | − exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \ | |
| 7 | − exynos_drm_plane.o | |
| 5 | +exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \ | |
| 6 | + exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o | |
| 8 | 7 | |
| 8 | +exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o | |
| 9 | 9 | exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o |
| 10 | 10 | exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o |
| 11 | 11 | exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o |
| @@ -101,7 +101,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) · 100 unmodified lines | ||
| 101 | 101 | return 0; |
| 102 | 102 | |
| 103 | 103 | err: |
| 104 | − list_for_each_entry_reverse(subdrv, &subdrv->list, list) { | |
| 104 | + list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) { | |
| 105 | 105 | if (subdrv->close) |
| 106 | 106 | subdrv->close(dev, subdrv->dev, file); |
| 107 | 107 | } |
| @@ -199,17 +199,6 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index) · 198 unmodified lines | ||
| 199 | 199 | return exynos_fb->dma_addr[index]; |
| 200 | 200 | } |
| 201 | 201 | |
| 202 | −static void exynos_drm_output_poll_changed(struct drm_device *dev) | |
| 203 | −{ | |
| 204 | − struct exynos_drm_private *private = dev->dev_private; | |
| 205 | − struct drm_fb_helper *fb_helper = private->fb_helper; | |
| 206 | − | |
| 207 | − if (fb_helper) | |
| 208 | − drm_fb_helper_hotplug_event(fb_helper); | |
| 209 | − else | |
| 210 | − exynos_drm_fbdev_init(dev); | |
| 211 | −} | |
| 212 | − | |
| 213 | 202 | static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { |
| 214 | 203 | .fb_create = exynos_user_fb_create, |
| 215 | 204 | .output_poll_changed = exynos_drm_output_poll_changed, |
| @@ -317,3 +317,14 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev) · 316 unmodified lines | ||
| 317 | 317 | |
| 318 | 318 | drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper); |
| 319 | 319 | } |
| 320 | + | |
| 321 | +void exynos_drm_output_poll_changed(struct drm_device *dev) | |
| 322 | +{ | |
| 323 | + struct exynos_drm_private *private = dev->dev_private; | |
| 324 | + struct drm_fb_helper *fb_helper = private->fb_helper; | |
| 325 | + | |
| 326 | + if (fb_helper) | |
| 327 | + drm_fb_helper_hotplug_event(fb_helper); | |
| 328 | + else | |
| 329 | + exynos_drm_fbdev_init(dev); | |
| 330 | +} | |
| @@ -15,9 +15,30 @@ · 14 unmodified lines | ||
| 15 | 15 | #ifndef _EXYNOS_DRM_FBDEV_H_ |
| 16 | 16 | #define _EXYNOS_DRM_FBDEV_H_ |
| 17 | 17 | |
| 18 | +#ifdef CONFIG_DRM_FBDEV_EMULATION | |
| 19 | + | |
| 18 | 20 | int exynos_drm_fbdev_init(struct drm_device *dev); |
| 19 | −int exynos_drm_fbdev_reinit(struct drm_device *dev); | |
| 20 | 21 | void exynos_drm_fbdev_fini(struct drm_device *dev); |
| 21 | 22 | void exynos_drm_fbdev_restore_mode(struct drm_device *dev); |
| 23 | +void exynos_drm_output_poll_changed(struct drm_device *dev); | |
| 24 | + | |
| 25 | +#else | |
| 26 | + | |
| 27 | +static inline int exynos_drm_fbdev_init(struct drm_device *dev) | |
| 28 | +{ | |
| 29 | + return 0; | |
| 30 | +} | |
| 31 | + | |
| 32 | +static inline void exynos_drm_fbdev_fini(struct drm_device *dev) | |
| 33 | +{ | |
| 34 | +} | |
| 35 | + | |
| 36 | +static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev) | |
| 37 | +{ | |
| 38 | +} | |
| 39 | + | |
| 40 | +#define exynos_drm_output_poll_changed (NULL) | |
| 41 | + | |
| 42 | +#endif | |
| 22 | 43 | |
| 23 | 44 | #endif |
| @@ -888,7 +888,7 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable) · 887 unmodified lines | ||
| 888 | 888 | * clock. On these SoCs the bootloader may enable it but any |
| 889 | 889 | * power domain off/on will reset it to disable state. |
| 890 | 890 | */ |
| 891 | − if (ctx->driver_data != &exynos5_fimd_driver_data || | |
| 891 | + if (ctx->driver_data != &exynos5_fimd_driver_data && | |
| 892 | 892 | ctx->driver_data != &exynos5420_fimd_driver_data) |
| 893 | 893 | return; |
| 894 | 894 | |
| @@ -129,7 +129,7 @@ static void mic_set_path(struct exynos_mic *mic, bool enable) · 128 unmodified lines | ||
| 129 | 129 | } else |
| 130 | 130 | val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX); |
| 131 | 131 | |
| 132 | − regmap_write(mic->sysreg, DSD_CFG_MUX, val); | |
| 132 | + ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val); | |
| 133 | 133 | if (ret) |
| 134 | 134 | DRM_ERROR("mic: Failed to read system register\n"); |
| 135 | 135 | } |
| @@ -457,6 +457,7 @@ static int exynos_mic_probe(struct platform_device *pdev) · 321 unmodified lines | ||
| 457 | 457 | "samsung,disp-syscon"); |
| 458 | 458 | if (IS_ERR(mic->sysreg)) { |
| 459 | 459 | DRM_ERROR("mic: Failed to get system register.\n"); |
| 460 | + ret = PTR_ERR(mic->sysreg); | |
| 460 | 461 | goto err; |
| 461 | 462 | } |
| 462 | 463 | |
| @@ -11,9 +11,10 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #include <drm/drmP.h> |
| 13 | 13 | |
| 14 | −#include <drm/exynos_drm.h> | |
| 15 | −#include <drm/drm_plane_helper.h> | |
| 14 | +#include <drm/drm_atomic.h> | |
| 16 | 15 | #include <drm/drm_atomic_helper.h> |
| 16 | +#include <drm/drm_plane_helper.h> | |
| 17 | +#include <drm/exynos_drm.h> | |
| 17 | 18 | #include "exynos_drm_drv.h" |
| 18 | 19 | #include "exynos_drm_crtc.h" |
| 19 | 20 | #include "exynos_drm_fb.h" |
| @@ -57,11 +58,12 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last) · 37 unmodified lines | ||
| 57 | 58 | } |
| 58 | 59 | |
| 59 | 60 | static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) |
| 60 | − | |
| 61 | 61 | { |
| 62 | 62 | struct drm_plane_state *state = &exynos_state->base; |
| 63 | − struct drm_crtc *crtc = exynos_state->base.crtc; | |
| 64 | − struct drm_display_mode *mode = &crtc->state->adjusted_mode; | |
| 63 | + struct drm_crtc *crtc = state->crtc; | |
| 64 | + struct drm_crtc_state *crtc_state = | |
| 65 | + drm_atomic_get_existing_crtc_state(state->state, crtc); | |
| 66 | + struct drm_display_mode *mode = &crtc_state->adjusted_mode; | |
| 65 | 67 | int crtc_x, crtc_y; |
| 66 | 68 | unsigned int crtc_w, crtc_h; |
| 67 | 69 | unsigned int src_x, src_y; |
| @@ -758,10 +758,10 @@ static int i915_drm_resume(struct drm_device *dev) · 757 unmodified lines | ||
| 758 | 758 | dev_priv->display.hpd_irq_setup(dev); |
| 759 | 759 | spin_unlock_irq(&dev_priv->irq_lock); |
| 760 | 760 | |
| 761 | − intel_display_resume(dev); | |
| 762 | − | |
| 763 | 761 | intel_dp_mst_resume(dev); |
| 764 | 762 | |
| 763 | + intel_display_resume(dev); | |
| 764 | + | |
| 765 | 765 | /* |
| 766 | 766 | * ... but also need to make sure that hotplug processing |
| 767 | 767 | * doesn't cause havoc. Like in the driver load code we don't |
| @@ -1829,7 +1829,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) · 1828 unmodified lines | ||
| 1829 | 1829 | /* IRQs are synced during runtime_suspend, we don't require a wakeref */ |
| 1830 | 1830 | disable_rpm_wakeref_asserts(dev_priv); |
| 1831 | 1831 | |
| 1832 | − for (;;) { | |
| 1832 | + do { | |
| 1833 | 1833 | master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; |
| 1834 | 1834 | iir = I915_READ(VLV_IIR); |
| 1835 | 1835 | |
| @@ -1857,7 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) · 21 unmodified lines | ||
| 1857 | 1857 | |
| 1858 | 1858 | I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL); |
| 1859 | 1859 | POSTING_READ(GEN8_MASTER_IRQ); |
| 1860 | − } | |
| 1860 | + } while (0); | |
| 1861 | 1861 | |
| 1862 | 1862 | enable_rpm_wakeref_asserts(dev_priv); |
| 1863 | 1863 | |
| @@ -506,6 +506,8 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, · 505 unmodified lines | ||
| 506 | 506 | struct intel_connector *intel_connector = to_intel_connector(connector); |
| 507 | 507 | struct drm_device *dev = connector->dev; |
| 508 | 508 | |
| 509 | + intel_connector->unregister(intel_connector); | |
| 510 | + | |
| 509 | 511 | /* need to nuke the connector */ |
| 510 | 512 | drm_modeset_lock_all(dev); |
| 511 | 513 | if (connector->state->crtc) { |
| @@ -519,11 +521,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, · 7 unmodified lines | ||
| 519 | 521 | |
| 520 | 522 | WARN(ret, "Disabling mst crtc failed with %i\n", ret); |
| 521 | 523 | } |
| 522 | − drm_modeset_unlock_all(dev); | |
| 523 | 524 | |
| 524 | − intel_connector->unregister(intel_connector); | |
| 525 | − | |
| 526 | − drm_modeset_lock_all(dev); | |
| 527 | 525 | intel_connector_remove_from_fbdev(intel_connector); |
| 528 | 526 | drm_connector_cleanup(connector); |
| 529 | 527 | drm_modeset_unlock_all(dev); |
| @@ -478,11 +478,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, · 477 unmodified lines | ||
| 478 | 478 | * and as part of the cleanup in the hw state restore we also redisable |
| 479 | 479 | * the vga plane. |
| 480 | 480 | */ |
| 481 | − if (!HAS_PCH_SPLIT(dev)) { | |
| 482 | − drm_modeset_lock_all(dev); | |
| 481 | + if (!HAS_PCH_SPLIT(dev)) | |
| 483 | 482 | intel_display_resume(dev); |
| 484 | − drm_modeset_unlock_all(dev); | |
| 485 | − } | |
| 486 | 483 | |
| 487 | 484 | dev_priv->modeset_restore = MODESET_DONE; |
| 488 | 485 | |
| @@ -375,10 +375,15 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc, · 374 unmodified lines | ||
| 375 | 375 | |
| 376 | 376 | qxl_bo_kunmap(user_bo); |
| 377 | 377 | |
| 378 | + qcrtc->cur_x += qcrtc->hot_spot_x - hot_x; | |
| 379 | + qcrtc->cur_y += qcrtc->hot_spot_y - hot_y; | |
| 380 | + qcrtc->hot_spot_x = hot_x; | |
| 381 | + qcrtc->hot_spot_y = hot_y; | |
| 382 | + | |
| 378 | 383 | cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); |
| 379 | 384 | cmd->type = QXL_CURSOR_SET; |
| 380 | − cmd->u.set.position.x = qcrtc->cur_x; | |
| 381 | − cmd->u.set.position.y = qcrtc->cur_y; | |
| 385 | + cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; | |
| 386 | + cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; | |
| 382 | 387 | |
| 383 | 388 | cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0); |
| 384 | 389 | |
| @@ -441,8 +446,8 @@ static int qxl_crtc_cursor_move(struct drm_crtc *crtc, · 56 unmodified lines | ||
| 441 | 446 | |
| 442 | 447 | cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release); |
| 443 | 448 | cmd->type = QXL_CURSOR_MOVE; |
| 444 | − cmd->u.position.x = qcrtc->cur_x; | |
| 445 | − cmd->u.position.y = qcrtc->cur_y; | |
| 449 | + cmd->u.position.x = qcrtc->cur_x + qcrtc->hot_spot_x; | |
| 450 | + cmd->u.position.y = qcrtc->cur_y + qcrtc->hot_spot_y; | |
| 446 | 451 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 447 | 452 | |
| 448 | 453 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); |
| @@ -135,6 +135,8 @@ struct qxl_crtc { · 134 unmodified lines | ||
| 135 | 135 | int index; |
| 136 | 136 | int cur_x; |
| 137 | 137 | int cur_y; |
| 138 | + int hot_spot_x; | |
| 139 | + int hot_spot_y; | |
| 138 | 140 | }; |
| 139 | 141 | |
| 140 | 142 | struct qxl_output { |
| @@ -109,6 +109,8 @@ · 108 unmodified lines | ||
| 109 | 109 | #define NI_DP_MSE_SAT2 0x7398 |
| 110 | 110 | |
| 111 | 111 | #define NI_DP_MSE_SAT_UPDATE 0x739c |
| 112 | +# define NI_DP_MSE_SAT_UPDATE_MASK 0x3 | |
| 113 | +# define NI_DP_MSE_16_MTP_KEEPOUT 0x100 | |
| 112 | 114 | |
| 113 | 115 | #define NI_DIG_BE_CNTL 0x7140 |
| 114 | 116 | # define NI_DIG_FE_SOURCE_SELECT(x) (((x) & 0x7f) << 8) |
| @@ -89,8 +89,16 @@ static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary, · 88 unmodified lines | ||
| 89 | 89 | WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1); |
| 90 | 90 | |
| 91 | 91 | do { |
| 92 | + unsigned value1, value2; | |
| 93 | + udelay(10); | |
| 92 | 94 | temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset); |
| 93 | − } while ((temp & 0x1) && retries++ < 10000); | |
| 95 | + | |
| 96 | + value1 = temp & NI_DP_MSE_SAT_UPDATE_MASK; | |
| 97 | + value2 = temp & NI_DP_MSE_16_MTP_KEEPOUT; | |
| 98 | + | |
| 99 | + if (!value1 && !value2) | |
| 100 | + break; | |
| 101 | + } while (retries++ < 50); | |
| 94 | 102 | |
| 95 | 103 | if (retries == 10000) |
| 96 | 104 | DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset); |
| @@ -150,7 +158,7 @@ static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn · 53 unmodified lines | ||
| 150 | 158 | return 0; |
| 151 | 159 | } |
| 152 | 160 | |
| 153 | −static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, uint32_t y) | |
| 161 | +static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, s64 avg_time_slots_per_mtp) | |
| 154 | 162 | { |
| 155 | 163 | struct drm_device *dev = mst->base.dev; |
| 156 | 164 | struct radeon_device *rdev = dev->dev_private; |
| @@ -158,6 +166,8 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui · 1 unmodified line | ||
| 158 | 166 | uint32_t val, temp; |
| 159 | 167 | uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe); |
| 160 | 168 | int retries = 0; |
| 169 | + uint32_t x = drm_fixp2int(avg_time_slots_per_mtp); | |
| 170 | + uint32_t y = drm_fixp2int_ceil((avg_time_slots_per_mtp - x) << 26); | |
| 161 | 171 | |
| 162 | 172 | val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y); |
| 163 | 173 | |
| @@ -165,6 +175,7 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui · 1 unmodified line | ||
| 165 | 175 | |
| 166 | 176 | do { |
| 167 | 177 | temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset); |
| 178 | + udelay(10); | |
| 168 | 179 | } while ((temp & 0x1) && (retries++ < 10000)); |
| 169 | 180 | |
| 170 | 181 | if (retries >= 10000) |
| @@ -246,14 +257,8 @@ radeon_dp_mst_connector_destroy(struct drm_connector *connector) · 75 unmodified lines | ||
| 246 | 257 | kfree(radeon_connector); |
| 247 | 258 | } |
| 248 | 259 | |
| 249 | −static int radeon_connector_dpms(struct drm_connector *connector, int mode) | |
| 250 | −{ | |
| 251 | − DRM_DEBUG_KMS("\n"); | |
| 252 | − return 0; | |
| 253 | −} | |
| 254 | − | |
| 255 | 260 | static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = { |
| 256 | − .dpms = radeon_connector_dpms, | |
| 261 | + .dpms = drm_helper_connector_dpms, | |
| 257 | 262 | .detect = radeon_dp_mst_detect, |
| 258 | 263 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 259 | 264 | .destroy = radeon_dp_mst_connector_destroy, |
| @@ -394,7 +399,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) · 134 unmodified lines | ||
| 394 | 399 | struct drm_crtc *crtc; |
| 395 | 400 | struct radeon_crtc *radeon_crtc; |
| 396 | 401 | int ret, slots; |
| 397 | − | |
| 402 | + s64 fixed_pbn, fixed_pbn_per_slot, avg_time_slots_per_mtp; | |
| 398 | 403 | if (!ASIC_IS_DCE5(rdev)) { |
| 399 | 404 | DRM_ERROR("got mst dpms on non-DCE5\n"); |
| 400 | 405 | return; |
| @@ -456,7 +461,11 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) · 55 unmodified lines | ||
| 456 | 461 | |
| 457 | 462 | mst_enc->enc_active = true; |
| 458 | 463 | radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary); |
| 459 | − radeon_dp_mst_set_vcp_size(radeon_encoder, slots, 0); | |
| 464 | + | |
| 465 | + fixed_pbn = drm_int2fixp(mst_enc->pbn); | |
| 466 | + fixed_pbn_per_slot = drm_int2fixp(radeon_connector->mst_port->mst_mgr.pbn_div); | |
| 467 | + avg_time_slots_per_mtp = drm_fixp_div(fixed_pbn, fixed_pbn_per_slot); | |
| 468 | + radeon_dp_mst_set_vcp_size(radeon_encoder, avg_time_slots_per_mtp); | |
| 460 | 469 | |
| 461 | 470 | atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0, |
| 462 | 471 | mst_enc->fe); |