History

Merge tag 'drm-intel-next-2023-09-29' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

drm/i915 feature pull for v6.7: Features and functionality: - Early Xe2 LPD / Lunarlake (LNL) display enabling (Lucas, Matt, Gustavo, Stanislav, Luca, Clint, Juha-Pekka, Balasubramani, Ravi) - Plenty of various DSC improvements and fixes (Ankit) - Add DSC PPS state readout and verification (Suraj) - Improve fastsets for VRR, LRR and M/N updates (Ville) - Use connector->ddc to create (non-DP MST) connector sysfs ddc symlinks (Ville) - Various DSB improvements, load LUTs using DSB (Ville) - Improve shared link bandwidth management, starting with FDI (Imre) - Optimize get param ioctl for PXP status (Alan) - Remove DG2 pre-production hardware workarounds (Matt) - Add more RPL P/U PCI IDs (Dnyaneshwar) - Add new DG2-G12 stepping (Swati) - Add PSR sink error status to debugfs (Jouni) - Add DP enhanced framing to crtc state checker (Ville) Refactoring and cleanups: - Simplify TileY/Tile4 tiling selftest enumeration (Matt) - Remove some unused power domain code (Gustavo) - Check stepping of display IP version rather than MTL platform (Matt) - DP audio compute config cleanups (Vinod) - SDVO cleanups and refactoring, more robust failure handling (Ville) - Color register definition and readout cleanups (Jani) - Reduce header interdependencies for frontbuffer tracking (Jani) - Continue replacing struct edid with struct drm_edid (Jani) - Use source physical address instead of EDID for CEC (Jani) - Clean up Type-C port lane count functions (Luca) - Clean up DSC PPS register definitions and readout (Jani) - Stop using GEM_BUG_ON()/GEM_WARN_ON() in display code (Jani) - Move more of the display probe to display code (Jani) - Remove redundant runtime suspended state flag (Jouni) - Move display info printing to display code (Balasubramani) - Frontbuffer tracking improvements (Jouni) - Add trailing newlines to debug logging (Jim Cromie) - Separate display workarounds from clock gating init (Matt) - Reduce dmesg log spamming for combo PHY, PLL state, FEC, DP MST (Ville, Imre) Fixes: - Fix hotplug poll detect loops via suspend/resume (Imre) - Fix hotplug detect for forced connectors (Imre) - Fix DSC first_line_bpg_offset calculation (Suraj) - Fix debug prints for SDP CRC16 (Arun) - Fix PXP runtime resume (Alan) - Fix cx0 PHY lane handling (Gustavo) - Fix frontbuffer tracking locking in debugfs (Juha-Pekka) - Fix SDVO detect on some models (Ville) - Fix SDP split configuration for DP MST (Vinod) - Fix AUX usage and reads for HDCP on DP MST (Suraj) - Fix PSR workaround (Jouni) - Fix redundant AUX power get/put in DP force (Imre) - Fix ICL DSI TCLK POST by letting hardware handle it (William) - Fix IRQ reset for XE LP+ (Gustavo) - Fix h/vsync_end instead of h/vtotal in VBT (Ville) - Fix C20 PHY msgbus timeout issues (Gustavo) - Fix pre-TGL FEC pipe A vs. DDI A mixup (Ville) - Fix FEC state readout for DP MST (Ville) DRM subsystem core changes: - Assume sink supports 8 bpc when DSC is supported (Ankit) - Add drm_edid_is_digital() helper (Jani) - Parse source physical address from EDID (Jani) - Add function to attach CEC without EDID (Jani) - Reorder connector sysfs/debugfs remove (Ville) - Register connector sysfs ddc symlink later (Ville) Media subsystem changes: - Add comments about CEC source physical address usage (Jani) Merges: - Backmerge drm-next to get v6.6-rc1 (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> # Conflicts: # drivers/gpu/drm/i915/i915_drv.h From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/87r0mhi7a6.fsf@intel.com

Dave Airlie committed 3 years ago

Commit 389af782 parents caacbdc 3570bd9142 files · +4550 −2464Browse files

Unified · Split

142 files
  1. drivers/gpu/drm/display/drm_dp_cec.c +20 −3
  2. drivers/gpu/drm/display/drm_dp_helper.c +6 −2
  3. drivers/gpu/drm/drm_connector.c +10 −1
  4. drivers/gpu/drm/drm_edid.c +20 −2
  5. drivers/gpu/drm/drm_internal.h +2 −0
  6. drivers/gpu/drm/drm_sysfs.c +15 −7
  7. drivers/gpu/drm/i915/Makefile +2 −0
  8. drivers/gpu/drm/i915/display/g4x_dp.c +8 −2
  9. drivers/gpu/drm/i915/display/g4x_hdmi.c +5 −1
  10. drivers/gpu/drm/i915/display/hsw_ips.c +1 −0
  11. drivers/gpu/drm/i915/display/i9xx_plane.c +1 −0
  12. drivers/gpu/drm/i915/display/icl_dsi.c +1 −12
  13. drivers/gpu/drm/i915/display/intel_atomic.c +2 −0
  14. drivers/gpu/drm/i915/display/intel_atomic_plane.c +11 −3
  15. drivers/gpu/drm/i915/display/intel_audio.c +3 −3
  16. drivers/gpu/drm/i915/display/intel_audio.h +1 −2
  17. drivers/gpu/drm/i915/display/intel_bios.c +17 −9
  18. drivers/gpu/drm/i915/display/intel_cdclk.c +86 −21
  19. drivers/gpu/drm/i915/display/intel_color.c +142 −12
  20. drivers/gpu/drm/i915/display/intel_color.h +2 −0
  21. drivers/gpu/drm/i915/display/intel_color_regs.h +286 −0
  22. drivers/gpu/drm/i915/display/intel_combo_phy.c +8 −9
  23. drivers/gpu/drm/i915/display/intel_connector.c +3 −3
  24. drivers/gpu/drm/i915/display/intel_connector.h +1 −1
  25. drivers/gpu/drm/i915/display/intel_crt.c +33 −31
  26. drivers/gpu/drm/i915/display/intel_crtc.c +76 −42
  27. drivers/gpu/drm/i915/display/intel_crtc.h +4 −2
  28. drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +3 −0
  29. drivers/gpu/drm/i915/display/intel_cx0_phy.c +107 −98
  30. drivers/gpu/drm/i915/display/intel_cx0_phy.h +8 −6
  31. drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +13 −0
  32. drivers/gpu/drm/i915/display/intel_ddi.c +20 −18
  33. drivers/gpu/drm/i915/display/intel_display.c +337 −139
  34. drivers/gpu/drm/i915/display/intel_display.h +4 −4
  35. drivers/gpu/drm/i915/display/intel_display_debugfs.c +4 −0
  36. drivers/gpu/drm/i915/display/intel_display_device.c +82 −16
  37. drivers/gpu/drm/i915/display/intel_display_device.h +28 −3
  38. drivers/gpu/drm/i915/display/intel_display_driver.c +8 −0
  39. drivers/gpu/drm/i915/display/intel_display_irq.c +3 −1
  40. drivers/gpu/drm/i915/display/intel_display_power.c +4 −6
  41. drivers/gpu/drm/i915/display/intel_display_power.h +0 −1
  42. drivers/gpu/drm/i915/display/intel_display_power_map.c +53 −10
  43. drivers/gpu/drm/i915/display/intel_display_power_well.c +49 −3
  44. drivers/gpu/drm/i915/display/intel_display_power_well.h +1 −0
  45. drivers/gpu/drm/i915/display/intel_display_types.h +40 −9
  46. drivers/gpu/drm/i915/display/intel_display_wa.c +48 −0
  47. drivers/gpu/drm/i915/display/intel_display_wa.h +13 −0
  48. drivers/gpu/drm/i915/display/intel_dmc.c +1 −1
  49. drivers/gpu/drm/i915/display/intel_dp.c +676 −201
  50. drivers/gpu/drm/i915/display/intel_dp.h +26 −8
  51. drivers/gpu/drm/i915/display/intel_dp_aux.c +29 −20
  52. drivers/gpu/drm/i915/display/intel_dp_aux_regs.h +44 −36
  53. drivers/gpu/drm/i915/display/intel_dp_hdcp.c +58 −29
  54. drivers/gpu/drm/i915/display/intel_dp_link_training.c +8 −6
  55. drivers/gpu/drm/i915/display/intel_dp_mst.c +97 −59
  56. drivers/gpu/drm/i915/display/intel_dpll.c +35 −19
  57. drivers/gpu/drm/i915/display/intel_dpt.c +1 −1
  58. drivers/gpu/drm/i915/display/intel_drrs.c +1 −0
  59. drivers/gpu/drm/i915/display/intel_dsb.c +188 −29
  60. drivers/gpu/drm/i915/display/intel_dsb.h +8 −1
  61. drivers/gpu/drm/i915/display/intel_dsb_regs.h +31 −0
  62. drivers/gpu/drm/i915/display/intel_dvo.c +5 −6
  63. drivers/gpu/drm/i915/display/intel_fb.c +58 −3
  64. drivers/gpu/drm/i915/display/intel_fb_pin.c +2 −1
  65. drivers/gpu/drm/i915/display/intel_fbc.c +12 −11
  66. drivers/gpu/drm/i915/display/intel_fbc.h +2 −0
  67. drivers/gpu/drm/i915/display/intel_fdi.c +149 −20
  68. drivers/gpu/drm/i915/display/intel_fdi.h +8 −0
  69. drivers/gpu/drm/i915/display/intel_frontbuffer.c +32 −2
  70. drivers/gpu/drm/i915/display/intel_frontbuffer.h +4 −0
  71. drivers/gpu/drm/i915/display/intel_gmbus.c +4 −1
  72. drivers/gpu/drm/i915/display/intel_hdcp.c +14 −19
  73. drivers/gpu/drm/i915/display/intel_hdmi.c +39 −82
  74. drivers/gpu/drm/i915/display/intel_hotplug.c +78 −7
  75. drivers/gpu/drm/i915/display/intel_hotplug_irq.c +22 −2
  76. drivers/gpu/drm/i915/display/intel_link_bw.c +212 −0
  77. drivers/gpu/drm/i915/display/intel_link_bw.h +37 −0
  78. drivers/gpu/drm/i915/display/intel_lspcon.c +7 −7
  79. drivers/gpu/drm/i915/display/intel_lvds.c +18 −15
  80. drivers/gpu/drm/i915/display/intel_overlay.c +2 −0
  81. drivers/gpu/drm/i915/display/intel_panel.c +4 −13
  82. drivers/gpu/drm/i915/display/intel_plane_initial.c +1 −0
  83. drivers/gpu/drm/i915/display/intel_pmdemand.c +1 −1
  84. drivers/gpu/drm/i915/display/intel_psr.c +37 −15
  85. drivers/gpu/drm/i915/display/intel_sdvo.c +196 −185
  86. drivers/gpu/drm/i915/display/intel_sdvo_regs.h +1 −1
  87. drivers/gpu/drm/i915/display/intel_sprite.c +1 −0
  88. drivers/gpu/drm/i915/display/intel_tc.c +50 −16
  89. drivers/gpu/drm/i915/display/intel_tc.h +1 −2
  90. drivers/gpu/drm/i915/display/intel_vblank.c +14 −0
  91. drivers/gpu/drm/i915/display/intel_vblank.h +1 −0
  92. drivers/gpu/drm/i915/display/intel_vdsc.c +287 −343
  93. drivers/gpu/drm/i915/display/intel_vdsc_regs.h +126 −271
  94. drivers/gpu/drm/i915/display/intel_vrr.c +16 −2
  95. drivers/gpu/drm/i915/display/intel_vrr.h +1 −0
  96. drivers/gpu/drm/i915/display/skl_universal_plane.c +2 −5
  97. drivers/gpu/drm/i915/display/skl_watermark.c +24 −8
  98. drivers/gpu/drm/i915/display/skl_watermark.h +2 −0
  99. drivers/gpu/drm/i915/gem/i915_gem_clflush.c +1 −2
  100. drivers/gpu/drm/i915/gem/i915_gem_domain.c +1 −1
  101. drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +2 −2
  102. drivers/gpu/drm/i915/gem/i915_gem_object.c +1 −0
  103. drivers/gpu/drm/i915/gem/i915_gem_object.h +0 −89
  104. drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h +103 −0
  105. drivers/gpu/drm/i915/gem/i915_gem_phys.c +1 −0
  106. drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +15 −24
  107. drivers/gpu/drm/i915/gt/gen8_ppgtt.c +18 −18
  108. drivers/gpu/drm/i915/gt/intel_gtt.h +2 −2
  109. drivers/gpu/drm/i915/i915_driver.c +5 −5
  110. drivers/gpu/drm/i915/i915_driver.h +2 −2
  111. drivers/gpu/drm/i915/i915_drv.h +2 −16
  112. drivers/gpu/drm/i915/i915_gem.c +1 −1
  113. drivers/gpu/drm/i915/i915_getparam.c +1 −1
  114. drivers/gpu/drm/i915/i915_gpu_error.c +2 −2
  115. drivers/gpu/drm/i915/i915_irq.c +2 −0
  116. drivers/gpu/drm/i915/i915_pci.c +0 −1
  117. drivers/gpu/drm/i915/i915_reg.h +4 −277
  118. drivers/gpu/drm/i915/i915_vma.c +1 −0
  119. drivers/gpu/drm/i915/i915_vma_resource.c +1 −1
  120. drivers/gpu/drm/i915/intel_clock_gating.c +2 −50
  121. drivers/gpu/drm/i915/intel_device_info.c +0 −14
  122. drivers/gpu/drm/i915/intel_device_info.h +0 −1
  123. drivers/gpu/drm/i915/intel_gvt_mmio_table.c +1 −0
  124. drivers/gpu/drm/i915/intel_runtime_pm.c +0 −1
  125. drivers/gpu/drm/i915/intel_runtime_pm.h +2 −2
  126. drivers/gpu/drm/i915/intel_step.c +1 −0
  127. drivers/gpu/drm/i915/pxp/intel_pxp.c +33 −7
  128. drivers/gpu/drm/i915/pxp/intel_pxp.h +1 −1
  129. drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c +4 −3
  130. drivers/gpu/drm/i915/pxp/intel_pxp_pm.c +17 −1
  131. drivers/gpu/drm/i915/pxp/intel_pxp_pm.h +3 −2
  132. drivers/gpu/drm/i915/pxp/intel_pxp_tee.c +4 −3
  133. drivers/gpu/drm/i915/pxp/intel_pxp_types.h +9 −0
  134. drivers/gpu/drm/i915/selftests/mock_gem_device.c +2 −0
  135. drivers/gpu/drm/i915/soc/intel_pch.c +9 −3
  136. drivers/gpu/drm/i915/soc/intel_pch.h +2 −0
  137. drivers/media/cec/core/cec-adap.c +5 −0
  138. drivers/media/cec/core/cec-notifier.c +5 −0
  139. include/drm/display/drm_dp_helper.h +6 −0
  140. include/drm/drm_connector.h +8 −0
  141. include/drm/drm_edid.h +1 −0
  142. include/drm/i915_pciids.h +6 −2
drivers/gpu/drm/display/drm_dp_cec.c+20−3
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <drm/display/drm_dp_helper.h>14#include <drm/display/drm_dp_helper.h>
15#include <drm/drm_connector.h>15#include <drm/drm_connector.h>
16#include <drm/drm_device.h>16#include <drm/drm_device.h>
17#include <drm/drm_edid.h>
17 18
18/*19/*
19 * Unfortunately it turns out that we have a chicken-and-egg situation20 * Unfortunately it turns out that we have a chicken-and-egg situation
@@ -297,7 +298,7 @@ static void drm_dp_cec_unregister_work(struct work_struct *work) · 277 unmodified lines
297 * were unchanged and just update the CEC physical address. Otherwise298 * were unchanged and just update the CEC physical address. Otherwise
298 * unregister the old CEC adapter and create a new one.299 * unregister the old CEC adapter and create a new one.
299 */300 */
300void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)301void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address)
301{302{
302 struct drm_connector *connector = aux->cec.connector;303 struct drm_connector *connector = aux->cec.connector;
303 u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |304 u32 cec_caps = CEC_CAP_DEFAULTS | CEC_CAP_NEEDS_HPD |
@@ -339,7 +340,7 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) · 35 unmodified lines
339 if (aux->cec.adap->capabilities == cec_caps &&340 if (aux->cec.adap->capabilities == cec_caps &&
340 aux->cec.adap->available_log_addrs == num_las) {341 aux->cec.adap->available_log_addrs == num_las) {
341 /* Unchanged, so just set the phys addr */342 /* Unchanged, so just set the phys addr */
342 cec_s_phys_addr_from_edid(aux->cec.adap, edid);343 cec_s_phys_addr(aux->cec.adap, source_physical_address, false);
343 goto unlock;344 goto unlock;
344 }345 }
345 /*346 /*
@@ -370,11 +371,27 @@ void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) · 24 unmodified lines
370 * from drm_dp_cec_register_connector() edid == NULL, so in371 * from drm_dp_cec_register_connector() edid == NULL, so in
371 * that case the phys addr is just invalidated.372 * that case the phys addr is just invalidated.
372 */373 */
373 cec_s_phys_addr_from_edid(aux->cec.adap, edid);374 cec_s_phys_addr(aux->cec.adap, source_physical_address, false);
374 }375 }
375unlock:376unlock:
376 mutex_unlock(&aux->cec.lock);377 mutex_unlock(&aux->cec.lock);
377}378}
379EXPORT_SYMBOL(drm_dp_cec_attach);
380
381/*
382 * Note: Prefer calling drm_dp_cec_attach() with
383 * connector->display_info.source_physical_address if possible.
384 */
385void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid)
386{
387 u16 pa = CEC_PHYS_ADDR_INVALID;
388
389 if (edid && edid->extensions)
390 pa = cec_get_edid_phys_addr((const u8 *)edid,
391 EDID_LENGTH * (edid->extensions + 1), NULL);
392
393 drm_dp_cec_attach(aux, pa);
394}
378EXPORT_SYMBOL(drm_dp_cec_set_edid);395EXPORT_SYMBOL(drm_dp_cec_set_edid);
379 396
380/*397/*
drivers/gpu/drm/display/drm_dp_helper.c+6−2
@@ -2449,12 +2449,16 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_S · 2448 unmodified lines
2449 int num_bpc = 0;2449 int num_bpc = 0;
2450 u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];2450 u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT];
2451 2451
2452 if (!drm_dp_sink_supports_dsc(dsc_dpcd))
2453 return 0;
2454
2452 if (color_depth & DP_DSC_12_BPC)2455 if (color_depth & DP_DSC_12_BPC)
2453 dsc_bpc[num_bpc++] = 12;2456 dsc_bpc[num_bpc++] = 12;
2454 if (color_depth & DP_DSC_10_BPC)2457 if (color_depth & DP_DSC_10_BPC)
2455 dsc_bpc[num_bpc++] = 10;2458 dsc_bpc[num_bpc++] = 10;
2456 if (color_depth & DP_DSC_8_BPC)2459
2457 dsc_bpc[num_bpc++] = 8;2460 /* A DP DSC Sink device shall support 8 bpc. */
2461 dsc_bpc[num_bpc++] = 8;
2458 2462
2459 return num_bpc;2463 return num_bpc;
2460}2464}
drivers/gpu/drm/drm_connector.c+10−1
@@ -631,6 +631,10 @@ int drm_connector_register(struct drm_connector *connector) · 630 unmodified lines
631 goto err_debugfs;631 goto err_debugfs;
632 }632 }
633 633
634 ret = drm_sysfs_connector_add_late(connector);
635 if (ret)
636 goto err_late_register;
637
634 drm_mode_object_register(connector->dev, &connector->base);638 drm_mode_object_register(connector->dev, &connector->base);
635 639
636 connector->registration_state = DRM_CONNECTOR_REGISTERED;640 connector->registration_state = DRM_CONNECTOR_REGISTERED;
@@ -647,6 +651,9 @@ int drm_connector_register(struct drm_connector *connector) · 10 unmodified lines
647 mutex_unlock(&connector_list_lock);651 mutex_unlock(&connector_list_lock);
648 goto unlock;652 goto unlock;
649 653
654err_late_register:
655 if (connector->funcs->early_unregister)
656 connector->funcs->early_unregister(connector);
650err_debugfs:657err_debugfs:
651 drm_debugfs_connector_remove(connector);658 drm_debugfs_connector_remove(connector);
652 drm_sysfs_connector_remove(connector);659 drm_sysfs_connector_remove(connector);
@@ -681,11 +688,13 @@ void drm_connector_unregister(struct drm_connector *connector) · 28 unmodified lines
681 connector->privacy_screen,688 connector->privacy_screen,
682 &connector->privacy_screen_notifier);689 &connector->privacy_screen_notifier);
683 690
691 drm_sysfs_connector_remove_early(connector);
692
684 if (connector->funcs->early_unregister)693 if (connector->funcs->early_unregister)
685 connector->funcs->early_unregister(connector);694 connector->funcs->early_unregister(connector);
686 695
687 drm_sysfs_connector_remove(connector);
688 drm_debugfs_connector_remove(connector);696 drm_debugfs_connector_remove(connector);
697 drm_sysfs_connector_remove(connector);
689 698
690 connector->registration_state = DRM_CONNECTOR_UNREGISTERED;699 connector->registration_state = DRM_CONNECTOR_UNREGISTERED;
691 mutex_unlock(&connector->mutex);700 mutex_unlock(&connector->mutex);
drivers/gpu/drm/drm_edid.c+20−2
@@ -29,6 +29,7 @@ · 28 unmodified lines
29 */29 */
30 30
31#include <linux/bitfield.h>31#include <linux/bitfield.h>
32#include <linux/cec.h>
32#include <linux/hdmi.h>33#include <linux/hdmi.h>
33#include <linux/i2c.h>34#include <linux/i2c.h>
34#include <linux/kernel.h>35#include <linux/kernel.h>
@@ -3110,7 +3111,7 @@ drm_monitor_supports_rb(const struct drm_edid *drm_edid) · 3075 unmodified lines
3110 return ret;3111 return ret;
3111 }3112 }
3112 3113
3113 return ((drm_edid->edid->input & DRM_EDID_INPUT_DIGITAL) != 0);3114 return drm_edid_is_digital(drm_edid);
3114}3115}
3115 3116
3116static void3117static void
@@ -6200,6 +6201,8 @@ drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db) · 3083 unmodified lines
6200 6201
6201 info->is_hdmi = true;6202 info->is_hdmi = true;
6202 6203
6204 info->source_physical_address = (db[4] << 8) | db[5];
6205
6203 if (len >= 6)6206 if (len >= 6)
6204 info->dvi_dual = db[6] & 1;6207 info->dvi_dual = db[6] & 1;
6205 if (len >= 7)6208 if (len >= 7)
@@ -6478,6 +6481,8 @@ static void drm_reset_display_info(struct drm_connector *connector) · 272 unmodified lines
6478 info->vics_len = 0;6481 info->vics_len = 0;
6479 6482
6480 info->quirks = 0;6483 info->quirks = 0;
6484
6485 info->source_physical_address = CEC_PHYS_ADDR_INVALID;
6481}6486}
6482 6487
6483static void update_displayid_info(struct drm_connector *connector,6488static void update_displayid_info(struct drm_connector *connector,
@@ -6527,7 +6532,7 @@ static void update_display_info(struct drm_connector *connector, · 43 unmodified lines
6527 if (edid->revision < 3)6532 if (edid->revision < 3)
6528 goto out;6533 goto out;
6529 6534
6530 if (!(edid->input & DRM_EDID_INPUT_DIGITAL))6535 if (!drm_edid_is_digital(drm_edid))
6531 goto out;6536 goto out;
6532 6537
6533 info->color_formats |= DRM_COLOR_FORMAT_RGB444;6538 info->color_formats |= DRM_COLOR_FORMAT_RGB444;
@@ -7343,3 +7348,16 @@ static void _drm_update_tile_info(struct drm_connector *connector, · 809 unmodified lines
7343 connector->tile_group = NULL;7348 connector->tile_group = NULL;
7344 }7349 }
7345}7350}
7351
7352/**
7353 * drm_edid_is_digital - is digital?
7354 * @drm_edid: The EDID
7355 *
7356 * Return true if input is digital.
7357 */
7358bool drm_edid_is_digital(const struct drm_edid *drm_edid)
7359{
7360 return drm_edid && drm_edid->edid &&
7361 drm_edid->edid->input & DRM_EDID_INPUT_DIGITAL;
7362}
7363EXPORT_SYMBOL(drm_edid_is_digital);
drivers/gpu/drm/drm_internal.h+2−0
@@ -153,6 +153,8 @@ int drm_sysfs_init(void); · 152 unmodified lines
153void drm_sysfs_destroy(void);153void drm_sysfs_destroy(void);
154struct device *drm_sysfs_minor_alloc(struct drm_minor *minor);154struct device *drm_sysfs_minor_alloc(struct drm_minor *minor);
155int drm_sysfs_connector_add(struct drm_connector *connector);155int drm_sysfs_connector_add(struct drm_connector *connector);
156int drm_sysfs_connector_add_late(struct drm_connector *connector);
157void drm_sysfs_connector_remove_early(struct drm_connector *connector);
156void drm_sysfs_connector_remove(struct drm_connector *connector);158void drm_sysfs_connector_remove(struct drm_connector *connector);
157 159
158void drm_sysfs_lease_event(struct drm_device *dev);160void drm_sysfs_lease_event(struct drm_device *dev);
drivers/gpu/drm/drm_sysfs.c+15−7
@@ -400,10 +400,6 @@ int drm_sysfs_connector_add(struct drm_connector *connector) · 399 unmodified lines
400 drm_err(dev, "failed to add component to create link to typec connector\n");400 drm_err(dev, "failed to add component to create link to typec connector\n");
401 }401 }
402 402
403 if (connector->ddc)
404 return sysfs_create_link(&connector->kdev->kobj,
405 &connector->ddc->dev.kobj, "ddc");
406
407 return 0;403 return 0;
408 404
409err_free:405err_free:
@@ -411,13 +407,25 @@ err_free: · 1 unmodified line
411 return r;407 return r;
412}408}
413 409
414void drm_sysfs_connector_remove(struct drm_connector *connector)410int drm_sysfs_connector_add_late(struct drm_connector *connector)
415{411{
416 if (!connector->kdev)412 if (connector->ddc)
417 return;413 return sysfs_create_link(&connector->kdev->kobj,
414 &connector->ddc->dev.kobj, "ddc");
415
416 return 0;
417}
418 418
419void drm_sysfs_connector_remove_early(struct drm_connector *connector)
420{
419 if (connector->ddc)421 if (connector->ddc)
420 sysfs_remove_link(&connector->kdev->kobj, "ddc");422 sysfs_remove_link(&connector->kdev->kobj, "ddc");
423}
424
425void drm_sysfs_connector_remove(struct drm_connector *connector)
426{
427 if (!connector->kdev)
428 return;
421 429
422 if (dev_fwnode(connector->kdev))430 if (dev_fwnode(connector->kdev))
423 component_del(connector->kdev, &typec_connector_ops);431 component_del(connector->kdev, &typec_connector_ops);
drivers/gpu/drm/i915/Makefile+2−0
@@ -248,6 +248,7 @@ i915-y += \ · 247 unmodified lines
248 display/intel_display_power_well.o \248 display/intel_display_power_well.o \
249 display/intel_display_reset.o \249 display/intel_display_reset.o \
250 display/intel_display_rps.o \250 display/intel_display_rps.o \
251 display/intel_display_wa.o \
251 display/intel_dmc.o \252 display/intel_dmc.o \
252 display/intel_dpio_phy.o \253 display/intel_dpio_phy.o \
253 display/intel_dpll.o \254 display/intel_dpll.o \
@@ -267,6 +268,7 @@ i915-y += \ · 13 unmodified lines
267 display/intel_hotplug.o \268 display/intel_hotplug.o \
268 display/intel_hotplug_irq.o \269 display/intel_hotplug_irq.o \
269 display/intel_hti.o \270 display/intel_hti.o \
271 display/intel_link_bw.o \
270 display/intel_load_detect.o \272 display/intel_load_detect.o \
271 display/intel_lpe_audio.o \273 display/intel_lpe_audio.o \
272 display/intel_modeset_lock.o \274 display/intel_modeset_lock.o \
drivers/gpu/drm/i915/display/g4x_dp.c+8−2
@@ -141,7 +141,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder, · 140 unmodified lines
141 141
142 intel_de_rmw(dev_priv, TRANS_DP_CTL(crtc->pipe),142 intel_de_rmw(dev_priv, TRANS_DP_CTL(crtc->pipe),
143 TRANS_DP_ENH_FRAMING,143 TRANS_DP_ENH_FRAMING,
144 drm_dp_enhanced_frame_cap(intel_dp->dpcd) ?144 pipe_config->enhanced_framing ?
145 TRANS_DP_ENH_FRAMING : 0);145 TRANS_DP_ENH_FRAMING : 0);
146 } else {146 } else {
147 if (IS_G4X(dev_priv) && pipe_config->limited_color_range)147 if (IS_G4X(dev_priv) && pipe_config->limited_color_range)
@@ -153,7 +153,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder, · 5 unmodified lines
153 intel_dp->DP |= DP_SYNC_VS_HIGH;153 intel_dp->DP |= DP_SYNC_VS_HIGH;
154 intel_dp->DP |= DP_LINK_TRAIN_OFF;154 intel_dp->DP |= DP_LINK_TRAIN_OFF;
155 155
156 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))156 if (pipe_config->enhanced_framing)
157 intel_dp->DP |= DP_ENHANCED_FRAMING;157 intel_dp->DP |= DP_ENHANCED_FRAMING;
158 158
159 if (IS_CHERRYVIEW(dev_priv))159 if (IS_CHERRYVIEW(dev_priv))
@@ -351,6 +351,9 @@ static void intel_dp_get_config(struct intel_encoder *encoder, · 191 unmodified lines
351 u32 trans_dp = intel_de_read(dev_priv,351 u32 trans_dp = intel_de_read(dev_priv,
352 TRANS_DP_CTL(crtc->pipe));352 TRANS_DP_CTL(crtc->pipe));
353 353
354 if (trans_dp & TRANS_DP_ENH_FRAMING)
355 pipe_config->enhanced_framing = true;
356
354 if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)357 if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH)
355 flags |= DRM_MODE_FLAG_PHSYNC;358 flags |= DRM_MODE_FLAG_PHSYNC;
356 else359 else
@@ -361,6 +364,9 @@ static void intel_dp_get_config(struct intel_encoder *encoder, · 4 unmodified lines
361 else364 else
362 flags |= DRM_MODE_FLAG_NVSYNC;365 flags |= DRM_MODE_FLAG_NVSYNC;
363 } else {366 } else {
367 if (tmp & DP_ENHANCED_FRAMING)
368 pipe_config->enhanced_framing = true;
369
364 if (tmp & DP_SYNC_HS_HIGH)370 if (tmp & DP_SYNC_HS_HIGH)
365 flags |= DRM_MODE_FLAG_PHSYNC;371 flags |= DRM_MODE_FLAG_PHSYNC;
366 else372 else
drivers/gpu/drm/i915/display/g4x_hdmi.c+5−1
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include "intel_display_types.h"16#include "intel_display_types.h"
17#include "intel_dp_aux.h"17#include "intel_dp_aux.h"
18#include "intel_dpio_phy.h"18#include "intel_dpio_phy.h"
19#include "intel_fdi.h"
19#include "intel_fifo_underrun.h"20#include "intel_fifo_underrun.h"
20#include "intel_hdmi.h"21#include "intel_hdmi.h"
21#include "intel_hotplug.h"22#include "intel_hotplug.h"
@@ -133,8 +134,11 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder, · 111 unmodified lines
133 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);134 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
134 struct drm_i915_private *i915 = to_i915(encoder->base.dev);135 struct drm_i915_private *i915 = to_i915(encoder->base.dev);
135 136
136 if (HAS_PCH_SPLIT(i915))137 if (HAS_PCH_SPLIT(i915)) {
137 crtc_state->has_pch_encoder = true;138 crtc_state->has_pch_encoder = true;
139 if (!intel_fdi_compute_pipe_bpp(crtc_state))
140 return -EINVAL;
141 }
138 142
139 if (IS_G4X(i915))143 if (IS_G4X(i915))
140 crtc_state->has_hdmi_sink = g4x_compute_has_hdmi_sink(state, crtc);144 crtc_state->has_hdmi_sink = g4x_compute_has_hdmi_sink(state, crtc);
drivers/gpu/drm/i915/display/hsw_ips.c+1−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#include "hsw_ips.h"6#include "hsw_ips.h"
7#include "i915_drv.h"7#include "i915_drv.h"
8#include "i915_reg.h"8#include "i915_reg.h"
9#include "intel_color_regs.h"
9#include "intel_de.h"10#include "intel_de.h"
10#include "intel_display_types.h"11#include "intel_display_types.h"
11#include "intel_pcode.h"12#include "intel_pcode.h"
drivers/gpu/drm/i915/display/i9xx_plane.c+1−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include "intel_display_types.h"17#include "intel_display_types.h"
18#include "intel_fb.h"18#include "intel_fb.h"
19#include "intel_fbc.h"19#include "intel_fbc.h"
20#include "intel_frontbuffer.h"
20#include "intel_sprite.h"21#include "intel_sprite.h"
21 22
22/* Primary plane formats for gen <= 3 */23/* Primary plane formats for gen <= 3 */
drivers/gpu/drm/i915/display/icl_dsi.c+1−12
@@ -1822,7 +1822,7 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi) · 1821 unmodified lines
1822 u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;1822 u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt;
1823 u32 ths_prepare_ns, tclk_trail_ns;1823 u32 ths_prepare_ns, tclk_trail_ns;
1824 u32 hs_zero_cnt;1824 u32 hs_zero_cnt;
1825 u32 tclk_pre_cnt, tclk_post_cnt;1825 u32 tclk_pre_cnt;
1826 1826
1827 tlpx_ns = intel_dsi_tlpx_ns(intel_dsi);1827 tlpx_ns = intel_dsi_tlpx_ns(intel_dsi);
1828 1828
@@ -1869,15 +1869,6 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi) · 40 unmodified lines
1869 tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX;1869 tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX;
1870 }1870 }
1871 1871
1872 /* tclk post count in escape clocks */
1873 tclk_post_cnt = DIV_ROUND_UP(mipi_config->tclk_post, tlpx_ns);
1874 if (tclk_post_cnt > ICL_TCLK_POST_CNT_MAX) {
1875 drm_dbg_kms(&dev_priv->drm,
1876 "tclk_post_cnt out of range (%d)\n",
1877 tclk_post_cnt);
1878 tclk_post_cnt = ICL_TCLK_POST_CNT_MAX;
1879 }
1880
1881 /* hs zero cnt in escape clocks */1872 /* hs zero cnt in escape clocks */
1882 hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero -1873 hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero -
1883 ths_prepare_ns, tlpx_ns);1874 ths_prepare_ns, tlpx_ns);
@@ -1903,8 +1894,6 @@ static void icl_dphy_param_init(struct intel_dsi *intel_dsi) · 19 unmodified lines
1903 CLK_ZERO(clk_zero_cnt) |1894 CLK_ZERO(clk_zero_cnt) |
1904 CLK_PRE_OVERRIDE |1895 CLK_PRE_OVERRIDE |
1905 CLK_PRE(tclk_pre_cnt) |1896 CLK_PRE(tclk_pre_cnt) |
1906 CLK_POST_OVERRIDE |
1907 CLK_POST(tclk_post_cnt) |
1908 CLK_TRAIL_OVERRIDE |1897 CLK_TRAIL_OVERRIDE |
1909 CLK_TRAIL(trail_cnt));1898 CLK_TRAIL(trail_cnt));
1910 1899
drivers/gpu/drm/i915/display/intel_atomic.c+2−0
@@ -259,6 +259,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc) · 258 unmodified lines
259 drm_property_blob_get(crtc_state->post_csc_lut);259 drm_property_blob_get(crtc_state->post_csc_lut);
260 260
261 crtc_state->update_pipe = false;261 crtc_state->update_pipe = false;
262 crtc_state->update_m_n = false;
263 crtc_state->update_lrr = false;
262 crtc_state->disable_lp_wm = false;264 crtc_state->disable_lp_wm = false;
263 crtc_state->disable_cxsr = false;265 crtc_state->disable_cxsr = false;
264 crtc_state->update_wm_pre = false;266 crtc_state->update_wm_pre = false;
drivers/gpu/drm/i915/display/intel_atomic_plane.c+11−3
@@ -214,9 +214,6 @@ intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, · 213 unmodified lines
214 int width, height;214 int width, height;
215 unsigned int rel_data_rate;215 unsigned int rel_data_rate;
216 216
217 if (plane->id == PLANE_CURSOR)
218 return 0;
219
220 if (!plane_state->uapi.visible)217 if (!plane_state->uapi.visible)
221 return 0;218 return 0;
222 219
@@ -244,6 +241,9 @@ intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, · 21 unmodified lines
244 241
245 rel_data_rate = width * height * fb->format->cpp[color_plane];242 rel_data_rate = width * height * fb->format->cpp[color_plane];
246 243
244 if (plane->id == PLANE_CURSOR)
245 return rel_data_rate;
246
247 return intel_adjusted_rate(&plane_state->uapi.src,247 return intel_adjusted_rate(&plane_state->uapi.src,
248 &plane_state->uapi.dst,248 &plane_state->uapi.dst,
249 rel_data_rate);249 rel_data_rate);
@@ -981,6 +981,14 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) · 731 unmodified lines
981 if (fb->format->format == DRM_FORMAT_RGB565 && rotated) {981 if (fb->format->format == DRM_FORMAT_RGB565 && rotated) {
982 hsub = 2;982 hsub = 2;
983 vsub = 2;983 vsub = 2;
984 } else if (DISPLAY_VER(i915) >= 20 &&
985 intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
986 /*
987 * This allows NV12 and P0xx formats to have odd size and/or odd
988 * source coordinates on DISPLAY_VER(i915) >= 20
989 */
990 hsub = 1;
991 vsub = 1;
984 } else {992 } else {
985 hsub = fb->format->hsub;993 hsub = fb->format->hsub;
986 vsub = fb->format->vsub;994 vsub = fb->format->vsub;
drivers/gpu/drm/i915/display/intel_audio.c+3−3
@@ -759,10 +759,10 @@ static void ibx_audio_codec_enable(struct intel_encoder *encoder, · 758 unmodified lines
759 mutex_unlock(&i915->display.audio.mutex);759 mutex_unlock(&i915->display.audio.mutex);
760}760}
761 761
762void intel_audio_sdp_split_update(struct intel_encoder *encoder,762void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state)
763 const struct intel_crtc_state *crtc_state)
764{763{
765 struct drm_i915_private *i915 = to_i915(encoder->base.dev);764 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
765 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
766 enum transcoder trans = crtc_state->cpu_transcoder;766 enum transcoder trans = crtc_state->cpu_transcoder;
767 767
768 if (HAS_DP20(i915))768 if (HAS_DP20(i915))
drivers/gpu/drm/i915/display/intel_audio.h+1−2
@@ -29,7 +29,6 @@ void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv); · 28 unmodified lines
29void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv);29void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv);
30void intel_audio_init(struct drm_i915_private *dev_priv);30void intel_audio_init(struct drm_i915_private *dev_priv);
31void intel_audio_deinit(struct drm_i915_private *dev_priv);31void intel_audio_deinit(struct drm_i915_private *dev_priv);
32void intel_audio_sdp_split_update(struct intel_encoder *encoder,32void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state);
33 const struct intel_crtc_state *crtc_state);
34 33
35#endif /* __INTEL_AUDIO_H__ */34#endif /* __INTEL_AUDIO_H__ */
drivers/gpu/drm/i915/display/intel_bios.c+17−9
@@ -521,7 +521,8 @@ static void init_bdb_blocks(struct drm_i915_private *i915, · 520 unmodified lines
521}521}
522 522
523static void523static void
524fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,524fill_detail_timing_data(struct drm_i915_private *i915,
525 struct drm_display_mode *panel_fixed_mode,
525 const struct lvds_dvo_timing *dvo_timing)526 const struct lvds_dvo_timing *dvo_timing)
526{527{
527 panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |528 panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
@@ -561,11 +562,17 @@ fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, · 33 unmodified lines
561 panel_fixed_mode->height_mm = (dvo_timing->vimage_hi << 8) |562 panel_fixed_mode->height_mm = (dvo_timing->vimage_hi << 8) |
562 dvo_timing->vimage_lo;563 dvo_timing->vimage_lo;
563 564
564 /* Some VBTs have bogus h/vtotal values */565 /* Some VBTs have bogus h/vsync_end values */
565 if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)566 if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) {
566 panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;567 drm_dbg_kms(&i915->drm, "reducing hsync_end %d->%d\n",
567 if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)568 panel_fixed_mode->hsync_end, panel_fixed_mode->htotal);
568 panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;569 panel_fixed_mode->hsync_end = panel_fixed_mode->htotal;
570 }
571 if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal) {
572 drm_dbg_kms(&i915->drm, "reducing vsync_end %d->%d\n",
573 panel_fixed_mode->vsync_end, panel_fixed_mode->vtotal);
574 panel_fixed_mode->vsync_end = panel_fixed_mode->vtotal;
575 }
569 576
570 drm_mode_set_name(panel_fixed_mode);577 drm_mode_set_name(panel_fixed_mode);
571}578}
@@ -849,7 +856,7 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915, · 277 unmodified lines
849 if (!panel_fixed_mode)856 if (!panel_fixed_mode)
850 return;857 return;
851 858
852 fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing);859 fill_detail_timing_data(i915, panel_fixed_mode, panel_dvo_timing);
853 860
854 panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;861 panel->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
855 862
@@ -1134,7 +1141,7 @@ parse_sdvo_panel_data(struct drm_i915_private *i915, · 278 unmodified lines
1134 if (!panel_fixed_mode)1141 if (!panel_fixed_mode)
1135 return;1142 return;
1136 1143
1137 fill_detail_timing_data(panel_fixed_mode, &dtds->dtds[index]);1144 fill_detail_timing_data(i915, panel_fixed_mode, &dtds->dtds[index]);
1138 1145
1139 panel->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode;1146 panel->vbt.sdvo_lvds_vbt_mode = panel_fixed_mode;
1140 1147
@@ -2194,7 +2201,8 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin) · 1053 unmodified lines
2194 const u8 *ddc_pin_map;2201 const u8 *ddc_pin_map;
2195 int i, n_entries;2202 int i, n_entries;
2196 2203
2197 if (HAS_PCH_MTP(i915) || IS_ALDERLAKE_P(i915)) {2204 if (INTEL_PCH_TYPE(i915) >= PCH_LNL || HAS_PCH_MTP(i915) ||
2205 IS_ALDERLAKE_P(i915)) {
2198 ddc_pin_map = adlp_ddc_pin_map;2206 ddc_pin_map = adlp_ddc_pin_map;
2199 n_entries = ARRAY_SIZE(adlp_ddc_pin_map);2207 n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
2200 } else if (IS_ALDERLAKE_S(i915)) {2208 } else if (IS_ALDERLAKE_S(i915)) {
drivers/gpu/drm/i915/display/intel_cdclk.c+86−21
@@ -32,6 +32,7 @@ · 31 unmodified lines
32#include "intel_cdclk.h"32#include "intel_cdclk.h"
33#include "intel_crtc.h"33#include "intel_crtc.h"
34#include "intel_de.h"34#include "intel_de.h"
35#include "intel_dp.h"
35#include "intel_display_types.h"36#include "intel_display_types.h"
36#include "intel_mchbar_regs.h"37#include "intel_mchbar_regs.h"
37#include "intel_pci_config.h"38#include "intel_pci_config.h"
@@ -1381,6 +1382,31 @@ static const struct intel_cdclk_vals mtl_cdclk_table[] = { · 1343 unmodified lines
1381 {}1382 {}
1382};1383};
1383 1384
1385static const struct intel_cdclk_vals lnl_cdclk_table[] = {
1386 { .refclk = 38400, .cdclk = 153600, .divider = 2, .ratio = 16, .waveform = 0xaaaa },
1387 { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 16, .waveform = 0xad5a },
1388 { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 16, .waveform = 0xb6b6 },
1389 { .refclk = 38400, .cdclk = 211200, .divider = 2, .ratio = 16, .waveform = 0xdbb6 },
1390 { .refclk = 38400, .cdclk = 230400, .divider = 2, .ratio = 16, .waveform = 0xeeee },
1391 { .refclk = 38400, .cdclk = 249600, .divider = 2, .ratio = 16, .waveform = 0xf7de },
1392 { .refclk = 38400, .cdclk = 268800, .divider = 2, .ratio = 16, .waveform = 0xfefe },
1393 { .refclk = 38400, .cdclk = 288000, .divider = 2, .ratio = 16, .waveform = 0xfffe },
1394 { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16, .waveform = 0xffff },
1395 { .refclk = 38400, .cdclk = 330000, .divider = 2, .ratio = 25, .waveform = 0xdbb6 },
1396 { .refclk = 38400, .cdclk = 360000, .divider = 2, .ratio = 25, .waveform = 0xeeee },
1397 { .refclk = 38400, .cdclk = 390000, .divider = 2, .ratio = 25, .waveform = 0xf7de },
1398 { .refclk = 38400, .cdclk = 420000, .divider = 2, .ratio = 25, .waveform = 0xfefe },
1399 { .refclk = 38400, .cdclk = 450000, .divider = 2, .ratio = 25, .waveform = 0xfffe },
1400 { .refclk = 38400, .cdclk = 480000, .divider = 2, .ratio = 25, .waveform = 0xffff },
1401 { .refclk = 38400, .cdclk = 487200, .divider = 2, .ratio = 29, .waveform = 0xfefe },
1402 { .refclk = 38400, .cdclk = 522000, .divider = 2, .ratio = 29, .waveform = 0xfffe },
1403 { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29, .waveform = 0xffff },
1404 { .refclk = 38400, .cdclk = 571200, .divider = 2, .ratio = 34, .waveform = 0xfefe },
1405 { .refclk = 38400, .cdclk = 612000, .divider = 2, .ratio = 34, .waveform = 0xfffe },
1406 { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34, .waveform = 0xffff },
1407 {}
1408};
1409
1384static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)1410static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
1385{1411{
1386 const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;1412 const struct intel_cdclk_vals *table = dev_priv->display.cdclk.table;
@@ -1840,9 +1866,10 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i91 · 453 unmodified lines
1840 1866
1841static bool pll_enable_wa_needed(struct drm_i915_private *dev_priv)1867static bool pll_enable_wa_needed(struct drm_i915_private *dev_priv)
1842{1868{
1843 return ((IS_DG2(dev_priv) || IS_METEORLAKE(dev_priv)) &&1869 return (DISPLAY_VER_FULL(dev_priv) == IP_VER(20, 0) ||
1844 dev_priv->display.cdclk.hw.vco > 0 &&1870 DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 0) ||
1845 HAS_CDCLK_SQUASH(dev_priv));1871 IS_DG2(dev_priv)) &&
1872 dev_priv->display.cdclk.hw.vco > 0;
1846}1873}
1847 1874
1848static void _bxt_set_cdclk(struct drm_i915_private *dev_priv,1875static void _bxt_set_cdclk(struct drm_i915_private *dev_priv,
@@ -1879,8 +1906,7 @@ static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, · 30 unmodified lines
1879 dg2_cdclk_squash_program(dev_priv, waveform);1906 dg2_cdclk_squash_program(dev_priv, waveform);
1880 1907
1881 val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) |1908 val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) |
1882 bxt_cdclk_cd2x_pipe(dev_priv, pipe) |1909 bxt_cdclk_cd2x_pipe(dev_priv, pipe);
1883 skl_cdclk_decimal(cdclk);
1884 1910
1885 /*1911 /*
1886 * Disable SSA Precharge when CD clock frequency < 500 MHz,1912 * Disable SSA Precharge when CD clock frequency < 500 MHz,
@@ -1889,6 +1915,12 @@ static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, · 2 unmodified lines
1889 if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&1915 if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
1890 cdclk >= 500000)1916 cdclk >= 500000)
1891 val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;1917 val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
1918
1919 if (DISPLAY_VER(dev_priv) >= 20)
1920 val |= MDCLK_SOURCE_SEL_CDCLK_PLL;
1921 else
1922 val |= skl_cdclk_decimal(cdclk);
1923
1892 intel_de_write(dev_priv, CDCLK_CTL, val);1924 intel_de_write(dev_priv, CDCLK_CTL, val);
1893 1925
1894 if (pipe != INVALID_PIPE)1926 if (pipe != INVALID_PIPE)
@@ -2533,6 +2565,48 @@ static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state) · 638 unmodified lines
2533 return min_cdclk;2565 return min_cdclk;
2534}2566}
2535 2567
2568static int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
2569{
2570 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2571 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2572 int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
2573 int min_cdclk = 0;
2574
2575 /*
2576 * When we decide to use only one VDSC engine, since
2577 * each VDSC operates with 1 ppc throughput, pixel clock
2578 * cannot be higher than the VDSC clock (cdclk)
2579 * If there 2 VDSC engines, then pixel clock can't be higher than
2580 * VDSC clock(cdclk) * 2 and so on.
2581 */
2582 min_cdclk = max_t(int, min_cdclk,
2583 DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances));
2584
2585 if (crtc_state->bigjoiner_pipes) {
2586 int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock);
2587
2588 /*
2589 * According to Bigjoiner bw check:
2590 * compressed_bpp <= PPC * CDCLK * Big joiner Interface bits / Pixel clock
2591 *
2592 * We have already computed compressed_bpp, so now compute the min CDCLK that
2593 * is required to support this compressed_bpp.
2594 *
2595 * => CDCLK >= compressed_bpp * Pixel clock / (PPC * Bigjoiner Interface bits)
2596 *
2597 * Since PPC = 2 with bigjoiner
2598 * => CDCLK >= compressed_bpp * Pixel clock / 2 * Bigjoiner Interface bits
2599 */
2600 int bigjoiner_interface_bits = DISPLAY_VER(i915) > 13 ? 36 : 24;
2601 int min_cdclk_bj = (crtc_state->dsc.compressed_bpp * pixel_clock) /
2602 (2 * bigjoiner_interface_bits);
2603
2604 min_cdclk = max(min_cdclk, min_cdclk_bj);
2605 }
2606
2607 return min_cdclk;
2608}
2609
2536int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)2610int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
2537{2611{
2538 struct drm_i915_private *dev_priv =2612 struct drm_i915_private *dev_priv =
@@ -2604,20 +2678,8 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) · 65 unmodified lines
2604 /* Account for additional needs from the planes */2678 /* Account for additional needs from the planes */
2605 min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);2679 min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
2606 2680
2607 /*2681 if (crtc_state->dsc.compression_enable)
2608 * When we decide to use only one VDSC engine, since2682 min_cdclk = max(min_cdclk, intel_vdsc_min_cdclk(crtc_state));
2609 * each VDSC operates with 1 ppc throughput, pixel clock
2610 * cannot be higher than the VDSC clock (cdclk)
2611 * If there 2 VDSC engines, then pixel clock can't be higher than
2612 * VDSC clock(cdclk) * 2 and so on.
2613 */
2614 if (crtc_state->dsc.compression_enable) {
2615 int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
2616
2617 min_cdclk = max_t(int, min_cdclk,
2618 DIV_ROUND_UP(crtc_state->pixel_rate,
2619 num_vdsc_instances));
2620 }
2621 2683
2622 /*2684 /*
2623 * HACK. Currently for TGL/DG2 platforms we calculate2685 * HACK. Currently for TGL/DG2 platforms we calculate
@@ -3108,7 +3170,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) · 484 unmodified lines
3108 } else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual,3170 } else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual,
3109 &new_cdclk_state->actual)) {3171 &new_cdclk_state->actual)) {
3110 /* All pipes must be switched off while we change the cdclk. */3172 /* All pipes must be switched off while we change the cdclk. */
3111 ret = intel_modeset_all_pipes(state, "CDCLK change");3173 ret = intel_modeset_all_pipes_late(state, "CDCLK change");
3112 if (ret)3174 if (ret)
3113 return ret;3175 return ret;
3114 3176
@@ -3559,7 +3621,10 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = { · 444 unmodified lines
3559 */3621 */
3560void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)3622void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
3561{3623{
3562 if (IS_METEORLAKE(dev_priv)) {3624 if (DISPLAY_VER(dev_priv) >= 20) {
3625 dev_priv->display.funcs.cdclk = &mtl_cdclk_funcs;
3626 dev_priv->display.cdclk.table = lnl_cdclk_table;
3627 } else if (DISPLAY_VER(dev_priv) >= 14) {
3563 dev_priv->display.funcs.cdclk = &mtl_cdclk_funcs;3628 dev_priv->display.funcs.cdclk = &mtl_cdclk_funcs;
3564 dev_priv->display.cdclk.table = mtl_cdclk_table;3629 dev_priv->display.cdclk.table = mtl_cdclk_table;
3565 } else if (IS_DG2(dev_priv)) {3630 } else if (IS_DG2(dev_priv)) {
drivers/gpu/drm/i915/display/intel_color.c+142−12
@@ -24,6 +24,7 @@ · 23 unmodified lines
24 24
25#include "i915_reg.h"25#include "i915_reg.h"
26#include "intel_color.h"26#include "intel_color.h"
27#include "intel_color_regs.h"
27#include "intel_de.h"28#include "intel_de.h"
28#include "intel_display_types.h"29#include "intel_display_types.h"
29#include "intel_dsb.h"30#include "intel_dsb.h"
@@ -75,6 +76,10 @@ struct intel_color_funcs { · 45 unmodified lines
75 * software state. Used by eg. the hardware state checker.76 * software state. Used by eg. the hardware state checker.
76 */77 */
77 void (*read_csc)(struct intel_crtc_state *crtc_state);78 void (*read_csc)(struct intel_crtc_state *crtc_state);
79 /*
80 * Read config other than LUTs and CSCs, before them. Optional.
81 */
82 void (*get_config)(struct intel_crtc_state *crtc_state);
78};83};
79 84
80#define CTM_COEFF_SIGN (1ULL << 63)85#define CTM_COEFF_SIGN (1ULL << 63)
@@ -1013,6 +1018,65 @@ static void hsw_color_commit_arm(const struct intel_crtc_state *crtc_state) · 932 unmodified lines
1013 crtc_state->csc_mode);1018 crtc_state->csc_mode);
1014}1019}
1015 1020
1021static u32 hsw_read_gamma_mode(struct intel_crtc *crtc)
1022{
1023 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1024
1025 return intel_de_read(i915, GAMMA_MODE(crtc->pipe));
1026}
1027
1028static u32 ilk_read_csc_mode(struct intel_crtc *crtc)
1029{
1030 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1031
1032 return intel_de_read(i915, PIPE_CSC_MODE(crtc->pipe));
1033}
1034
1035static void i9xx_get_config(struct intel_crtc_state *crtc_state)
1036{
1037 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1038 struct intel_plane *plane = to_intel_plane(crtc->base.primary);
1039 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1040 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
1041 u32 tmp;
1042
1043 tmp = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
1044
1045 if (tmp & DISP_PIPE_GAMMA_ENABLE)
1046 crtc_state->gamma_enable = true;
1047
1048 if (!HAS_GMCH(dev_priv) && tmp & DISP_PIPE_CSC_ENABLE)
1049 crtc_state->csc_enable = true;
1050}
1051
1052static void hsw_get_config(struct intel_crtc_state *crtc_state)
1053{
1054 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1055
1056 crtc_state->gamma_mode = hsw_read_gamma_mode(crtc);
1057 crtc_state->csc_mode = ilk_read_csc_mode(crtc);
1058
1059 i9xx_get_config(crtc_state);
1060}
1061
1062static void skl_get_config(struct intel_crtc_state *crtc_state)
1063{
1064 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1065 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1066 u32 tmp;
1067
1068 crtc_state->gamma_mode = hsw_read_gamma_mode(crtc);
1069 crtc_state->csc_mode = ilk_read_csc_mode(crtc);
1070
1071 tmp = intel_de_read(i915, SKL_BOTTOM_COLOR(crtc->pipe));
1072
1073 if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
1074 crtc_state->gamma_enable = true;
1075
1076 if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
1077 crtc_state->csc_enable = true;
1078}
1079
1016static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)1080static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
1017{1081{
1018 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);1082 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -1265,9 +1329,20 @@ static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state, · 246 unmodified lines
1265 1329
1266 lut = blob->data;1330 lut = blob->data;
1267 1331
1332 /*
1333 * DSB fails to correctly load the legacy LUT
1334 * unless we either write each entry twice,
1335 * or use non-posted writes
1336 */
1337 if (crtc_state->dsb)
1338 intel_dsb_nonpost_start(crtc_state->dsb);
1339
1268 for (i = 0; i < 256; i++)1340 for (i = 0; i < 256; i++)
1269 ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),1341 ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
1270 i9xx_lut_8(&lut[i]));1342 i9xx_lut_8(&lut[i]));
1343
1344 if (crtc_state->dsb)
1345 intel_dsb_nonpost_end(crtc_state->dsb);
1271}1346}
1272 1347
1273static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,1348static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,
@@ -1677,12 +1752,6 @@ static void icl_load_luts(const struct intel_crtc_state *crtc_state) · 403 unmodified lines
1677 MISSING_CASE(crtc_state->gamma_mode);1752 MISSING_CASE(crtc_state->gamma_mode);
1678 break;1753 break;
1679 }1754 }
1680
1681 if (crtc_state->dsb) {
1682 intel_dsb_finish(crtc_state->dsb);
1683 intel_dsb_commit(crtc_state->dsb, false);
1684 intel_dsb_wait(crtc_state->dsb);
1685 }
1686}1755}
1687 1756
1688static void vlv_load_luts(const struct intel_crtc_state *crtc_state)1757static void vlv_load_luts(const struct intel_crtc_state *crtc_state)
@@ -1789,6 +1858,9 @@ void intel_color_load_luts(const struct intel_crtc_state *crtc_state) · 100 unmodified lines
1789{1858{
1790 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);1859 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1791 1860
1861 if (crtc_state->dsb)
1862 return;
1863
1792 i915->display.funcs.color->load_luts(crtc_state);1864 i915->display.funcs.color->load_luts(crtc_state);
1793}1865}
1794 1866
@@ -1805,6 +1877,9 @@ void intel_color_commit_arm(const struct intel_crtc_state *crtc_state) · 10 unmodified lines
1805 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);1877 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1806 1878
1807 i915->display.funcs.color->color_commit_arm(crtc_state);1879 i915->display.funcs.color->color_commit_arm(crtc_state);
1880
1881 if (crtc_state->dsb)
1882 intel_dsb_commit(crtc_state->dsb, true);
1808}1883}
1809 1884
1810void intel_color_post_update(const struct intel_crtc_state *crtc_state)1885void intel_color_post_update(const struct intel_crtc_state *crtc_state)
@@ -1818,14 +1893,25 @@ void intel_color_post_update(const struct intel_crtc_state *crtc_state) · 7 unmodified lines
1818void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)1893void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)
1819{1894{
1820 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);1895 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1896 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1821 1897
1822 /* FIXME DSB has issues loading LUTs, disable it for now */1898 /* FIXME DSB has issues loading LUTs, disable it for now */
1823 return;1899 return;
1824 1900
1901 if (!crtc_state->hw.active ||
1902 intel_crtc_needs_modeset(crtc_state))
1903 return;
1904
1825 if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)1905 if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)
1826 return;1906 return;
1827 1907
1828 crtc_state->dsb = intel_dsb_prepare(crtc, 1024);1908 crtc_state->dsb = intel_dsb_prepare(crtc_state, 1024);
1909 if (!crtc_state->dsb)
1910 return;
1911
1912 i915->display.funcs.color->load_luts(crtc_state);
1913
1914 intel_dsb_finish(crtc_state->dsb);
1829}1915}
1830 1916
1831void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)1917void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)
@@ -1837,6 +1923,17 @@ void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state) · 5 unmodified lines
1837 crtc_state->dsb = NULL;1923 crtc_state->dsb = NULL;
1838}1924}
1839 1925
1926void intel_color_wait_commit(const struct intel_crtc_state *crtc_state)
1927{
1928 if (crtc_state->dsb)
1929 intel_dsb_wait(crtc_state->dsb);
1930}
1931
1932bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state)
1933{
1934 return crtc_state->dsb;
1935}
1936
1840static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)1937static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1841{1938{
1842 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);1939 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
@@ -1891,6 +1988,9 @@ void intel_color_get_config(struct intel_crtc_state *crtc_state) · 48 unmodified lines
1891{1988{
1892 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);1989 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1893 1990
1991 if (i915->display.funcs.color->get_config)
1992 i915->display.funcs.color->get_config(crtc_state);
1993
1894 i915->display.funcs.color->read_luts(crtc_state);1994 i915->display.funcs.color->read_luts(crtc_state);
1895 1995
1896 if (i915->display.funcs.color->read_csc)1996 if (i915->display.funcs.color->read_csc)
@@ -2865,16 +2965,16 @@ static int icl_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state) · 968 unmodified lines
2865 return 16;2965 return 16;
2866}2966}
2867 2967
2868static bool err_check(struct drm_color_lut *lut1,2968static bool err_check(const struct drm_color_lut *lut1,
2869 struct drm_color_lut *lut2, u32 err)2969 const struct drm_color_lut *lut2, u32 err)
2870{2970{
2871 return ((abs((long)lut2->red - lut1->red)) <= err) &&2971 return ((abs((long)lut2->red - lut1->red)) <= err) &&
2872 ((abs((long)lut2->blue - lut1->blue)) <= err) &&2972 ((abs((long)lut2->blue - lut1->blue)) <= err) &&
2873 ((abs((long)lut2->green - lut1->green)) <= err);2973 ((abs((long)lut2->green - lut1->green)) <= err);
2874}2974}
2875 2975
2876static bool intel_lut_entries_equal(struct drm_color_lut *lut1,2976static bool intel_lut_entries_equal(const struct drm_color_lut *lut1,
2877 struct drm_color_lut *lut2,2977 const struct drm_color_lut *lut2,
2878 int lut_size, u32 err)2978 int lut_size, u32 err)
2879{2979{
2880 int i;2980 int i;
@@ -2891,7 +2991,7 @@ static bool intel_lut_equal(const struct drm_property_blob *blob1, · 10 unmodified lines
2891 const struct drm_property_blob *blob2,2991 const struct drm_property_blob *blob2,
2892 int check_size, int precision)2992 int check_size, int precision)
2893{2993{
2894 struct drm_color_lut *lut1, *lut2;2994 const struct drm_color_lut *lut1, *lut2;
2895 int lut_size1, lut_size2;2995 int lut_size1, lut_size2;
2896 u32 err;2996 u32 err;
2897 2997
@@ -3204,6 +3304,16 @@ static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc) · 306 unmodified lines
3204 return blob;3304 return blob;
3205}3305}
3206 3306
3307static void chv_get_config(struct intel_crtc_state *crtc_state)
3308{
3309 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3310 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3311
3312 crtc_state->cgm_mode = intel_de_read(i915, CGM_PIPE_MODE(crtc->pipe));
3313
3314 i9xx_get_config(crtc_state);
3315}
3316
3207static void chv_read_luts(struct intel_crtc_state *crtc_state)3317static void chv_read_luts(struct intel_crtc_state *crtc_state)
3208{3318{
3209 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);3319 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -3267,6 +3377,15 @@ static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc) · 57 unmodified lines
3267 return blob;3377 return blob;
3268}3378}
3269 3379
3380static void ilk_get_config(struct intel_crtc_state *crtc_state)
3381{
3382 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3383
3384 crtc_state->csc_mode = ilk_read_csc_mode(crtc);
3385
3386 i9xx_get_config(crtc_state);
3387}
3388
3270static void ilk_read_luts(struct intel_crtc_state *crtc_state)3389static void ilk_read_luts(struct intel_crtc_state *crtc_state)
3271{3390{
3272 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);3391 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -3573,6 +3692,7 @@ static const struct intel_color_funcs chv_color_funcs = { · 300 unmodified lines
3573 .read_luts = chv_read_luts,3692 .read_luts = chv_read_luts,
3574 .lut_equal = chv_lut_equal,3693 .lut_equal = chv_lut_equal,
3575 .read_csc = chv_read_csc,3694 .read_csc = chv_read_csc,
3695 .get_config = chv_get_config,
3576};3696};
3577 3697
3578static const struct intel_color_funcs vlv_color_funcs = {3698static const struct intel_color_funcs vlv_color_funcs = {
@@ -3590,6 +3710,7 @@ static const struct intel_color_funcs i965_color_funcs = { · 11 unmodified lines
3590 .load_luts = i965_load_luts,3710 .load_luts = i965_load_luts,
3591 .read_luts = i965_read_luts,3711 .read_luts = i965_read_luts,
3592 .lut_equal = i965_lut_equal,3712 .lut_equal = i965_lut_equal,
3713 .get_config = i9xx_get_config,
3593};3714};
3594 3715
3595static const struct intel_color_funcs i9xx_color_funcs = {3716static const struct intel_color_funcs i9xx_color_funcs = {
@@ -3598,6 +3719,7 @@ static const struct intel_color_funcs i9xx_color_funcs = { · 2 unmodified lines
3598 .load_luts = i9xx_load_luts,3719 .load_luts = i9xx_load_luts,
3599 .read_luts = i9xx_read_luts,3720 .read_luts = i9xx_read_luts,
3600 .lut_equal = i9xx_lut_equal,3721 .lut_equal = i9xx_lut_equal,
3722 .get_config = i9xx_get_config,
3601};3723};
3602 3724
3603static const struct intel_color_funcs tgl_color_funcs = {3725static const struct intel_color_funcs tgl_color_funcs = {
@@ -3608,6 +3730,7 @@ static const struct intel_color_funcs tgl_color_funcs = { · 4 unmodified lines
3608 .read_luts = icl_read_luts,3730 .read_luts = icl_read_luts,
3609 .lut_equal = icl_lut_equal,3731 .lut_equal = icl_lut_equal,
3610 .read_csc = icl_read_csc,3732 .read_csc = icl_read_csc,
3733 .get_config = skl_get_config,
3611};3734};
3612 3735
3613static const struct intel_color_funcs icl_color_funcs = {3736static const struct intel_color_funcs icl_color_funcs = {
@@ -3619,6 +3742,7 @@ static const struct intel_color_funcs icl_color_funcs = { · 5 unmodified lines
3619 .read_luts = icl_read_luts,3742 .read_luts = icl_read_luts,
3620 .lut_equal = icl_lut_equal,3743 .lut_equal = icl_lut_equal,
3621 .read_csc = icl_read_csc,3744 .read_csc = icl_read_csc,
3745 .get_config = skl_get_config,
3622};3746};
3623 3747
3624static const struct intel_color_funcs glk_color_funcs = {3748static const struct intel_color_funcs glk_color_funcs = {
@@ -3629,6 +3753,7 @@ static const struct intel_color_funcs glk_color_funcs = { · 4 unmodified lines
3629 .read_luts = glk_read_luts,3753 .read_luts = glk_read_luts,
3630 .lut_equal = glk_lut_equal,3754 .lut_equal = glk_lut_equal,
3631 .read_csc = skl_read_csc,3755 .read_csc = skl_read_csc,
3756 .get_config = skl_get_config,
3632};3757};
3633 3758
3634static const struct intel_color_funcs skl_color_funcs = {3759static const struct intel_color_funcs skl_color_funcs = {
@@ -3639,6 +3764,7 @@ static const struct intel_color_funcs skl_color_funcs = { · 4 unmodified lines
3639 .read_luts = bdw_read_luts,3764 .read_luts = bdw_read_luts,
3640 .lut_equal = ivb_lut_equal,3765 .lut_equal = ivb_lut_equal,
3641 .read_csc = skl_read_csc,3766 .read_csc = skl_read_csc,
3767 .get_config = skl_get_config,
3642};3768};
3643 3769
3644static const struct intel_color_funcs bdw_color_funcs = {3770static const struct intel_color_funcs bdw_color_funcs = {
@@ -3649,6 +3775,7 @@ static const struct intel_color_funcs bdw_color_funcs = { · 4 unmodified lines
3649 .read_luts = bdw_read_luts,3775 .read_luts = bdw_read_luts,
3650 .lut_equal = ivb_lut_equal,3776 .lut_equal = ivb_lut_equal,
3651 .read_csc = ilk_read_csc,3777 .read_csc = ilk_read_csc,
3778 .get_config = hsw_get_config,
3652};3779};
3653 3780
3654static const struct intel_color_funcs hsw_color_funcs = {3781static const struct intel_color_funcs hsw_color_funcs = {
@@ -3659,6 +3786,7 @@ static const struct intel_color_funcs hsw_color_funcs = { · 4 unmodified lines
3659 .read_luts = ivb_read_luts,3786 .read_luts = ivb_read_luts,
3660 .lut_equal = ivb_lut_equal,3787 .lut_equal = ivb_lut_equal,
3661 .read_csc = ilk_read_csc,3788 .read_csc = ilk_read_csc,
3789 .get_config = hsw_get_config,
3662};3790};
3663 3791
3664static const struct intel_color_funcs ivb_color_funcs = {3792static const struct intel_color_funcs ivb_color_funcs = {
@@ -3669,6 +3797,7 @@ static const struct intel_color_funcs ivb_color_funcs = { · 4 unmodified lines
3669 .read_luts = ivb_read_luts,3797 .read_luts = ivb_read_luts,
3670 .lut_equal = ivb_lut_equal,3798 .lut_equal = ivb_lut_equal,
3671 .read_csc = ilk_read_csc,3799 .read_csc = ilk_read_csc,
3800 .get_config = ilk_get_config,
3672};3801};
3673 3802
3674static const struct intel_color_funcs ilk_color_funcs = {3803static const struct intel_color_funcs ilk_color_funcs = {
@@ -3679,6 +3808,7 @@ static const struct intel_color_funcs ilk_color_funcs = { · 4 unmodified lines
3679 .read_luts = ilk_read_luts,3808 .read_luts = ilk_read_luts,
3680 .lut_equal = ilk_lut_equal,3809 .lut_equal = ilk_lut_equal,
3681 .read_csc = ilk_read_csc,3810 .read_csc = ilk_read_csc,
3811 .get_config = ilk_get_config,
3682};3812};
3683 3813
3684void intel_color_crtc_init(struct intel_crtc *crtc)3814void intel_color_crtc_init(struct intel_crtc *crtc)
drivers/gpu/drm/i915/display/intel_color.h+2−0
@@ -19,6 +19,8 @@ void intel_color_crtc_init(struct intel_crtc *crtc); · 18 unmodified lines
19int intel_color_check(struct intel_crtc_state *crtc_state);19int intel_color_check(struct intel_crtc_state *crtc_state);
20void intel_color_prepare_commit(struct intel_crtc_state *crtc_state);20void intel_color_prepare_commit(struct intel_crtc_state *crtc_state);
21void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state);21void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state);
22bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state);
23void intel_color_wait_commit(const struct intel_crtc_state *crtc_state);
22void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state);24void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state);
23void intel_color_commit_arm(const struct intel_crtc_state *crtc_state);25void intel_color_commit_arm(const struct intel_crtc_state *crtc_state);
24void intel_color_post_update(const struct intel_crtc_state *crtc_state);26void intel_color_post_update(const struct intel_crtc_state *crtc_state);
drivers/gpu/drm/i915/display/intel_color_regs.h+286−0
@@ -0,0 +1,286 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#ifndef __INTEL_COLOR_REGS_H__
7#define __INTEL_COLOR_REGS_H__
8
9#include "intel_display_reg_defs.h"
10
11/* legacy palette */
12#define _LGC_PALETTE_A 0x4a000
13#define _LGC_PALETTE_B 0x4a800
14/* see PALETTE_* for the bits */
15#define LGC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + (i) * 4)
16
17/* ilk/snb precision palette */
18#define _PREC_PALETTE_A 0x4b000
19#define _PREC_PALETTE_B 0x4c000
20/* 10bit mode */
21#define PREC_PALETTE_10_RED_MASK REG_GENMASK(29, 20)
22#define PREC_PALETTE_10_GREEN_MASK REG_GENMASK(19, 10)
23#define PREC_PALETTE_10_BLUE_MASK REG_GENMASK(9, 0)
24/* 12.4 interpolated mode ldw */
25#define PREC_PALETTE_12P4_RED_LDW_MASK REG_GENMASK(29, 24)
26#define PREC_PALETTE_12P4_GREEN_LDW_MASK REG_GENMASK(19, 14)
27#define PREC_PALETTE_12P4_BLUE_LDW_MASK REG_GENMASK(9, 4)
28/* 12.4 interpolated mode udw */
29#define PREC_PALETTE_12P4_RED_UDW_MASK REG_GENMASK(29, 20)
30#define PREC_PALETTE_12P4_GREEN_UDW_MASK REG_GENMASK(19, 10)
31#define PREC_PALETTE_12P4_BLUE_UDW_MASK REG_GENMASK(9, 0)
32#define PREC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _PREC_PALETTE_A, _PREC_PALETTE_B) + (i) * 4)
33
34#define _PREC_PIPEAGCMAX 0x4d000
35#define _PREC_PIPEBGCMAX 0x4d010
36#define PREC_PIPEGCMAX(pipe, i) _MMIO(_PIPE(pipe, _PIPEAGCMAX, _PIPEBGCMAX) + (i) * 4) /* u1.16 */
37
38#define _GAMMA_MODE_A 0x4a480
39#define _GAMMA_MODE_B 0x4ac80
40#define GAMMA_MODE(pipe) _MMIO_PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B)
41#define PRE_CSC_GAMMA_ENABLE REG_BIT(31) /* icl+ */
42#define POST_CSC_GAMMA_ENABLE REG_BIT(30) /* icl+ */
43#define PALETTE_ANTICOL_DISABLE REG_BIT(15) /* skl+ */
44#define GAMMA_MODE_MODE_MASK REG_GENMASK(1, 0)
45#define GAMMA_MODE_MODE_8BIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 0)
46#define GAMMA_MODE_MODE_10BIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 1)
47#define GAMMA_MODE_MODE_12BIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 2)
48#define GAMMA_MODE_MODE_SPLIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 3) /* ivb-bdw */
49#define GAMMA_MODE_MODE_12BIT_MULTI_SEG REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 3) /* icl-tgl */
50
51/* pipe CSC */
52#define _PIPE_A_CSC_COEFF_RY_GY 0x49010
53#define _PIPE_A_CSC_COEFF_BY 0x49014
54#define _PIPE_A_CSC_COEFF_RU_GU 0x49018
55#define _PIPE_A_CSC_COEFF_BU 0x4901c
56#define _PIPE_A_CSC_COEFF_RV_GV 0x49020
57#define _PIPE_A_CSC_COEFF_BV 0x49024
58
59#define _PIPE_A_CSC_MODE 0x49028
60#define ICL_CSC_ENABLE (1 << 31) /* icl+ */
61#define ICL_OUTPUT_CSC_ENABLE (1 << 30) /* icl+ */
62#define CSC_BLACK_SCREEN_OFFSET (1 << 2) /* ilk/snb */
63#define CSC_POSITION_BEFORE_GAMMA (1 << 1) /* pre-glk */
64#define CSC_MODE_YUV_TO_RGB (1 << 0) /* ilk/snb */
65
66#define _PIPE_A_CSC_PREOFF_HI 0x49030
67#define _PIPE_A_CSC_PREOFF_ME 0x49034
68#define _PIPE_A_CSC_PREOFF_LO 0x49038
69#define _PIPE_A_CSC_POSTOFF_HI 0x49040
70#define _PIPE_A_CSC_POSTOFF_ME 0x49044
71#define _PIPE_A_CSC_POSTOFF_LO 0x49048
72
73#define _PIPE_B_CSC_COEFF_RY_GY 0x49110
74#define _PIPE_B_CSC_COEFF_BY 0x49114
75#define _PIPE_B_CSC_COEFF_RU_GU 0x49118
76#define _PIPE_B_CSC_COEFF_BU 0x4911c
77#define _PIPE_B_CSC_COEFF_RV_GV 0x49120
78#define _PIPE_B_CSC_COEFF_BV 0x49124
79#define _PIPE_B_CSC_MODE 0x49128
80#define _PIPE_B_CSC_PREOFF_HI 0x49130
81#define _PIPE_B_CSC_PREOFF_ME 0x49134
82#define _PIPE_B_CSC_PREOFF_LO 0x49138
83#define _PIPE_B_CSC_POSTOFF_HI 0x49140
84#define _PIPE_B_CSC_POSTOFF_ME 0x49144
85#define _PIPE_B_CSC_POSTOFF_LO 0x49148
86
87#define PIPE_CSC_COEFF_RY_GY(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY)
88#define PIPE_CSC_COEFF_BY(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY)
89#define PIPE_CSC_COEFF_RU_GU(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU)
90#define PIPE_CSC_COEFF_BU(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BU, _PIPE_B_CSC_COEFF_BU)
91#define PIPE_CSC_COEFF_RV_GV(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RV_GV, _PIPE_B_CSC_COEFF_RV_GV)
92#define PIPE_CSC_COEFF_BV(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BV, _PIPE_B_CSC_COEFF_BV)
93#define PIPE_CSC_MODE(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_MODE, _PIPE_B_CSC_MODE)
94#define PIPE_CSC_PREOFF_HI(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_HI, _PIPE_B_CSC_PREOFF_HI)
95#define PIPE_CSC_PREOFF_ME(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_ME, _PIPE_B_CSC_PREOFF_ME)
96#define PIPE_CSC_PREOFF_LO(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_LO, _PIPE_B_CSC_PREOFF_LO)
97#define PIPE_CSC_POSTOFF_HI(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_HI, _PIPE_B_CSC_POSTOFF_HI)
98#define PIPE_CSC_POSTOFF_ME(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
99#define PIPE_CSC_POSTOFF_LO(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
100
101/* Pipe Output CSC */
102#define _PIPE_A_OUTPUT_CSC_COEFF_RY_GY 0x49050
103#define _PIPE_A_OUTPUT_CSC_COEFF_BY 0x49054
104#define _PIPE_A_OUTPUT_CSC_COEFF_RU_GU 0x49058
105#define _PIPE_A_OUTPUT_CSC_COEFF_BU 0x4905c
106#define _PIPE_A_OUTPUT_CSC_COEFF_RV_GV 0x49060
107#define _PIPE_A_OUTPUT_CSC_COEFF_BV 0x49064
108#define _PIPE_A_OUTPUT_CSC_PREOFF_HI 0x49068
109#define _PIPE_A_OUTPUT_CSC_PREOFF_ME 0x4906c
110#define _PIPE_A_OUTPUT_CSC_PREOFF_LO 0x49070
111#define _PIPE_A_OUTPUT_CSC_POSTOFF_HI 0x49074
112#define _PIPE_A_OUTPUT_CSC_POSTOFF_ME 0x49078
113#define _PIPE_A_OUTPUT_CSC_POSTOFF_LO 0x4907c
114
115#define _PIPE_B_OUTPUT_CSC_COEFF_RY_GY 0x49150
116#define _PIPE_B_OUTPUT_CSC_COEFF_BY 0x49154
117#define _PIPE_B_OUTPUT_CSC_COEFF_RU_GU 0x49158
118#define _PIPE_B_OUTPUT_CSC_COEFF_BU 0x4915c
119#define _PIPE_B_OUTPUT_CSC_COEFF_RV_GV 0x49160
120#define _PIPE_B_OUTPUT_CSC_COEFF_BV 0x49164
121#define _PIPE_B_OUTPUT_CSC_PREOFF_HI 0x49168
122#define _PIPE_B_OUTPUT_CSC_PREOFF_ME 0x4916c
123#define _PIPE_B_OUTPUT_CSC_PREOFF_LO 0x49170
124#define _PIPE_B_OUTPUT_CSC_POSTOFF_HI 0x49174
125#define _PIPE_B_OUTPUT_CSC_POSTOFF_ME 0x49178
126#define _PIPE_B_OUTPUT_CSC_POSTOFF_LO 0x4917c
127
128#define PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe) _MMIO_PIPE(pipe,\
129 _PIPE_A_OUTPUT_CSC_COEFF_RY_GY,\
130 _PIPE_B_OUTPUT_CSC_COEFF_RY_GY)
131#define PIPE_CSC_OUTPUT_COEFF_BY(pipe) _MMIO_PIPE(pipe, \
132 _PIPE_A_OUTPUT_CSC_COEFF_BY, \
133 _PIPE_B_OUTPUT_CSC_COEFF_BY)
134#define PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe) _MMIO_PIPE(pipe, \
135 _PIPE_A_OUTPUT_CSC_COEFF_RU_GU, \
136 _PIPE_B_OUTPUT_CSC_COEFF_RU_GU)
137#define PIPE_CSC_OUTPUT_COEFF_BU(pipe) _MMIO_PIPE(pipe, \
138 _PIPE_A_OUTPUT_CSC_COEFF_BU, \
139 _PIPE_B_OUTPUT_CSC_COEFF_BU)
140#define PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe) _MMIO_PIPE(pipe, \
141 _PIPE_A_OUTPUT_CSC_COEFF_RV_GV, \
142 _PIPE_B_OUTPUT_CSC_COEFF_RV_GV)
143#define PIPE_CSC_OUTPUT_COEFF_BV(pipe) _MMIO_PIPE(pipe, \
144 _PIPE_A_OUTPUT_CSC_COEFF_BV, \
145 _PIPE_B_OUTPUT_CSC_COEFF_BV)
146#define PIPE_CSC_OUTPUT_PREOFF_HI(pipe) _MMIO_PIPE(pipe, \
147 _PIPE_A_OUTPUT_CSC_PREOFF_HI, \
148 _PIPE_B_OUTPUT_CSC_PREOFF_HI)
149#define PIPE_CSC_OUTPUT_PREOFF_ME(pipe) _MMIO_PIPE(pipe, \
150 _PIPE_A_OUTPUT_CSC_PREOFF_ME, \
151 _PIPE_B_OUTPUT_CSC_PREOFF_ME)
152#define PIPE_CSC_OUTPUT_PREOFF_LO(pipe) _MMIO_PIPE(pipe, \
153 _PIPE_A_OUTPUT_CSC_PREOFF_LO, \
154 _PIPE_B_OUTPUT_CSC_PREOFF_LO)
155#define PIPE_CSC_OUTPUT_POSTOFF_HI(pipe) _MMIO_PIPE(pipe, \
156 _PIPE_A_OUTPUT_CSC_POSTOFF_HI, \
157 _PIPE_B_OUTPUT_CSC_POSTOFF_HI)
158#define PIPE_CSC_OUTPUT_POSTOFF_ME(pipe) _MMIO_PIPE(pipe, \
159 _PIPE_A_OUTPUT_CSC_POSTOFF_ME, \
160 _PIPE_B_OUTPUT_CSC_POSTOFF_ME)
161#define PIPE_CSC_OUTPUT_POSTOFF_LO(pipe) _MMIO_PIPE(pipe, \
162 _PIPE_A_OUTPUT_CSC_POSTOFF_LO, \
163 _PIPE_B_OUTPUT_CSC_POSTOFF_LO)
164
165/* pipe degamma/gamma LUTs on IVB+ */
166#define _PAL_PREC_INDEX_A 0x4A400
167#define _PAL_PREC_INDEX_B 0x4AC00
168#define _PAL_PREC_INDEX_C 0x4B400
169#define PAL_PREC_SPLIT_MODE REG_BIT(31)
170#define PAL_PREC_AUTO_INCREMENT REG_BIT(15)
171#define PAL_PREC_INDEX_VALUE_MASK REG_GENMASK(9, 0)
172#define PAL_PREC_INDEX_VALUE(x) REG_FIELD_PREP(PAL_PREC_INDEX_VALUE_MASK, (x))
173#define _PAL_PREC_DATA_A 0x4A404
174#define _PAL_PREC_DATA_B 0x4AC04
175#define _PAL_PREC_DATA_C 0x4B404
176/* see PREC_PALETTE_* for the bits */
177#define _PAL_PREC_GC_MAX_A 0x4A410
178#define _PAL_PREC_GC_MAX_B 0x4AC10
179#define _PAL_PREC_GC_MAX_C 0x4B410
180#define _PAL_PREC_EXT_GC_MAX_A 0x4A420
181#define _PAL_PREC_EXT_GC_MAX_B 0x4AC20
182#define _PAL_PREC_EXT_GC_MAX_C 0x4B420
183#define _PAL_PREC_EXT2_GC_MAX_A 0x4A430
184#define _PAL_PREC_EXT2_GC_MAX_B 0x4AC30
185#define _PAL_PREC_EXT2_GC_MAX_C 0x4B430
186
187#define PREC_PAL_INDEX(pipe) _MMIO_PIPE(pipe, _PAL_PREC_INDEX_A, _PAL_PREC_INDEX_B)
188#define PREC_PAL_DATA(pipe) _MMIO_PIPE(pipe, _PAL_PREC_DATA_A, _PAL_PREC_DATA_B)
189#define PREC_PAL_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4) /* u1.16 */
190#define PREC_PAL_EXT_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4) /* u3.16 */
191#define PREC_PAL_EXT2_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT2_GC_MAX_A, _PAL_PREC_EXT2_GC_MAX_B) + (i) * 4) /* glk+, u3.16 */
192
193#define _PRE_CSC_GAMC_INDEX_A 0x4A484
194#define _PRE_CSC_GAMC_INDEX_B 0x4AC84
195#define _PRE_CSC_GAMC_INDEX_C 0x4B484
196#define PRE_CSC_GAMC_AUTO_INCREMENT REG_BIT(10)
197#define PRE_CSC_GAMC_INDEX_VALUE_MASK REG_GENMASK(7, 0)
198#define PRE_CSC_GAMC_INDEX_VALUE(x) REG_FIELD_PREP(PRE_CSC_GAMC_INDEX_VALUE_MASK, (x))
199#define _PRE_CSC_GAMC_DATA_A 0x4A488
200#define _PRE_CSC_GAMC_DATA_B 0x4AC88
201#define _PRE_CSC_GAMC_DATA_C 0x4B488
202
203#define PRE_CSC_GAMC_INDEX(pipe) _MMIO_PIPE(pipe, _PRE_CSC_GAMC_INDEX_A, _PRE_CSC_GAMC_INDEX_B)
204#define PRE_CSC_GAMC_DATA(pipe) _MMIO_PIPE(pipe, _PRE_CSC_GAMC_DATA_A, _PRE_CSC_GAMC_DATA_B)
205
206/* ICL Multi segmented gamma */
207#define _PAL_PREC_MULTI_SEG_INDEX_A 0x4A408
208#define _PAL_PREC_MULTI_SEG_INDEX_B 0x4AC08
209#define PAL_PREC_MULTI_SEG_AUTO_INCREMENT REG_BIT(15)
210#define PAL_PREC_MULTI_SEG_INDEX_VALUE_MASK REG_GENMASK(4, 0)
211#define PAL_PREC_MULTI_SEG_INDEX_VALUE(x) REG_FIELD_PREP(PAL_PREC_MULTI_SEG_INDEX_VALUE_MASK, (x))
212
213#define _PAL_PREC_MULTI_SEG_DATA_A 0x4A40C
214#define _PAL_PREC_MULTI_SEG_DATA_B 0x4AC0C
215/* see PREC_PALETTE_12P4_* for the bits */
216
217#define PREC_PAL_MULTI_SEG_INDEX(pipe) _MMIO_PIPE(pipe, \
218 _PAL_PREC_MULTI_SEG_INDEX_A, \
219 _PAL_PREC_MULTI_SEG_INDEX_B)
220#define PREC_PAL_MULTI_SEG_DATA(pipe) _MMIO_PIPE(pipe, \
221 _PAL_PREC_MULTI_SEG_DATA_A, \
222 _PAL_PREC_MULTI_SEG_DATA_B)
223
224#define _PIPE_A_WGC_C01_C00 0x600B0 /* s2.10 */
225#define _PIPE_A_WGC_C02 0x600B4 /* s2.10 */
226#define _PIPE_A_WGC_C11_C10 0x600B8 /* s2.10 */
227#define _PIPE_A_WGC_C12 0x600BC /* s2.10 */
228#define _PIPE_A_WGC_C21_C20 0x600C0 /* s2.10 */
229#define _PIPE_A_WGC_C22 0x600C4 /* s2.10 */
230
231#define PIPE_WGC_C01_C00(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C01_C00)
232#define PIPE_WGC_C02(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C02)
233#define PIPE_WGC_C11_C10(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C11_C10)
234#define PIPE_WGC_C12(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C12)
235#define PIPE_WGC_C21_C20(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C21_C20)
236#define PIPE_WGC_C22(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C22)
237
238/* pipe CSC & degamma/gamma LUTs on CHV */
239#define _CGM_PIPE_A_CSC_COEFF01 (VLV_DISPLAY_BASE + 0x67900)
240#define _CGM_PIPE_A_CSC_COEFF23 (VLV_DISPLAY_BASE + 0x67904)
241#define _CGM_PIPE_A_CSC_COEFF45 (VLV_DISPLAY_BASE + 0x67908)
242#define _CGM_PIPE_A_CSC_COEFF67 (VLV_DISPLAY_BASE + 0x6790C)
243#define _CGM_PIPE_A_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x67910)
244#define _CGM_PIPE_A_DEGAMMA (VLV_DISPLAY_BASE + 0x66000)
245/* cgm degamma ldw */
246#define CGM_PIPE_DEGAMMA_GREEN_LDW_MASK REG_GENMASK(29, 16)
247#define CGM_PIPE_DEGAMMA_BLUE_LDW_MASK REG_GENMASK(13, 0)
248/* cgm degamma udw */
249#define CGM_PIPE_DEGAMMA_RED_UDW_MASK REG_GENMASK(13, 0)
250#define _CGM_PIPE_A_GAMMA (VLV_DISPLAY_BASE + 0x67000)
251/* cgm gamma ldw */
252#define CGM_PIPE_GAMMA_GREEN_LDW_MASK REG_GENMASK(25, 16)
253#define CGM_PIPE_GAMMA_BLUE_LDW_MASK REG_GENMASK(9, 0)
254/* cgm gamma udw */
255#define CGM_PIPE_GAMMA_RED_UDW_MASK REG_GENMASK(9, 0)
256#define _CGM_PIPE_A_MODE (VLV_DISPLAY_BASE + 0x67A00)
257#define CGM_PIPE_MODE_GAMMA (1 << 2)
258#define CGM_PIPE_MODE_CSC (1 << 1)
259#define CGM_PIPE_MODE_DEGAMMA (1 << 0)
260
261#define _CGM_PIPE_B_CSC_COEFF01 (VLV_DISPLAY_BASE + 0x69900)
262#define _CGM_PIPE_B_CSC_COEFF23 (VLV_DISPLAY_BASE + 0x69904)
263#define _CGM_PIPE_B_CSC_COEFF45 (VLV_DISPLAY_BASE + 0x69908)
264#define _CGM_PIPE_B_CSC_COEFF67 (VLV_DISPLAY_BASE + 0x6990C)
265#define _CGM_PIPE_B_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x69910)
266#define _CGM_PIPE_B_DEGAMMA (VLV_DISPLAY_BASE + 0x68000)
267#define _CGM_PIPE_B_GAMMA (VLV_DISPLAY_BASE + 0x69000)
268#define _CGM_PIPE_B_MODE (VLV_DISPLAY_BASE + 0x69A00)
269
270#define CGM_PIPE_CSC_COEFF01(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF01, _CGM_PIPE_B_CSC_COEFF01)
271#define CGM_PIPE_CSC_COEFF23(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF23, _CGM_PIPE_B_CSC_COEFF23)
272#define CGM_PIPE_CSC_COEFF45(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF45, _CGM_PIPE_B_CSC_COEFF45)
273#define CGM_PIPE_CSC_COEFF67(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF67, _CGM_PIPE_B_CSC_COEFF67)
274#define CGM_PIPE_CSC_COEFF8(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF8, _CGM_PIPE_B_CSC_COEFF8)
275#define CGM_PIPE_DEGAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_DEGAMMA, _CGM_PIPE_B_DEGAMMA) + (i) * 8 + (w) * 4)
276#define CGM_PIPE_GAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_GAMMA, _CGM_PIPE_B_GAMMA) + (i) * 8 + (w) * 4)
277#define CGM_PIPE_MODE(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_MODE, _CGM_PIPE_B_MODE)
278
279/* Skylake+ pipe bottom (background) color */
280#define _SKL_BOTTOM_COLOR_A 0x70034
281#define _SKL_BOTTOM_COLOR_B 0x71034
282#define SKL_BOTTOM_COLOR_GAMMA_ENABLE REG_BIT(31)
283#define SKL_BOTTOM_COLOR_CSC_ENABLE REG_BIT(30)
284#define SKL_BOTTOM_COLOR(pipe) _MMIO_PIPE(pipe, _SKL_BOTTOM_COLOR_A, _SKL_BOTTOM_COLOR_B)
285
286#endif /* __INTEL_COLOR_REGS_H__ */
drivers/gpu/drm/i915/display/intel_combo_phy.c+8−9
@@ -114,10 +114,6 @@ static bool icl_verify_procmon_ref_values(struct drm_i915_private *dev_priv, · 113 unmodified lines
114 114
115 procmon = icl_get_procmon_ref_values(dev_priv, phy);115 procmon = icl_get_procmon_ref_values(dev_priv, phy);
116 116
117 drm_dbg_kms(&dev_priv->drm,
118 "Combo PHY %c Voltage/Process Info : %s\n",
119 phy_name(phy), procmon->name);
120
121 ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),117 ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
122 (0xff << 16) | 0xff, procmon->dw1);118 (0xff << 16) | 0xff, procmon->dw1);
123 ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),119 ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
@@ -312,14 +308,17 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv) · 188 unmodified lines
312 enum phy phy;308 enum phy phy;
313 309
314 for_each_combo_phy(dev_priv, phy) {310 for_each_combo_phy(dev_priv, phy) {
311 const struct icl_procmon *procmon;
315 u32 val;312 u32 val;
316 313
317 if (icl_combo_phy_verify_state(dev_priv, phy)) {314 if (icl_combo_phy_verify_state(dev_priv, phy))
318 drm_dbg(&dev_priv->drm,
319 "Combo PHY %c already enabled, won't reprogram it.\n",
320 phy_name(phy));
321 continue;315 continue;
322 }316
317 procmon = icl_get_procmon_ref_values(dev_priv, phy);
318
319 drm_dbg(&dev_priv->drm,
320 "Initializing combo PHY %c (Voltage/Process Info : %s)\n",
321 phy_name(phy), procmon->name);
323 322
324 if (!has_phy_misc(dev_priv, phy))323 if (!has_phy_misc(dev_priv, phy))
325 goto skip_phy_misc;324 goto skip_phy_misc;
drivers/gpu/drm/i915/display/intel_connector.c+3−3
@@ -192,17 +192,17 @@ int intel_connector_update_modes(struct drm_connector *connector, · 191 unmodified lines
192/**192/**
193 * intel_ddc_get_modes - get modelist from monitor193 * intel_ddc_get_modes - get modelist from monitor
194 * @connector: DRM connector device to use194 * @connector: DRM connector device to use
195 * @adapter: i2c adapter195 * @ddc: DDC bus i2c adapter
196 *196 *
197 * Fetch the EDID information from @connector using the DDC bus.197 * Fetch the EDID information from @connector using the DDC bus.
198 */198 */
199int intel_ddc_get_modes(struct drm_connector *connector,199int intel_ddc_get_modes(struct drm_connector *connector,
200 struct i2c_adapter *adapter)200 struct i2c_adapter *ddc)
201{201{
202 const struct drm_edid *drm_edid;202 const struct drm_edid *drm_edid;
203 int ret;203 int ret;
204 204
205 drm_edid = drm_edid_read_ddc(connector, adapter);205 drm_edid = drm_edid_read_ddc(connector, ddc);
206 if (!drm_edid)206 if (!drm_edid)
207 return 0;207 return 0;
208 208
drivers/gpu/drm/i915/display/intel_connector.h+1−1
@@ -26,7 +26,7 @@ bool intel_connector_get_hw_state(struct intel_connector *connector); · 25 unmodified lines
26enum pipe intel_connector_get_pipe(struct intel_connector *connector);26enum pipe intel_connector_get_pipe(struct intel_connector *connector);
27int intel_connector_update_modes(struct drm_connector *connector,27int intel_connector_update_modes(struct drm_connector *connector,
28 const struct drm_edid *drm_edid);28 const struct drm_edid *drm_edid);
29int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);29int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *ddc);
30void intel_attach_force_audio_property(struct drm_connector *connector);30void intel_attach_force_audio_property(struct drm_connector *connector);
31void intel_attach_broadcast_rgb_property(struct drm_connector *connector);31void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
32void intel_attach_aspect_ratio_property(struct drm_connector *connector);32void intel_attach_aspect_ratio_property(struct drm_connector *connector);
drivers/gpu/drm/i915/display/intel_crt.c+33−31
@@ -413,6 +413,9 @@ static int pch_crt_compute_config(struct intel_encoder *encoder, · 412 unmodified lines
413 return -EINVAL;413 return -EINVAL;
414 414
415 pipe_config->has_pch_encoder = true;415 pipe_config->has_pch_encoder = true;
416 if (!intel_fdi_compute_pipe_bpp(pipe_config))
417 return -EINVAL;
418
416 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;419 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
417 420
418 return 0;421 return 0;
@@ -435,10 +438,14 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder, · 16 unmodified lines
435 return -EINVAL;438 return -EINVAL;
436 439
437 pipe_config->has_pch_encoder = true;440 pipe_config->has_pch_encoder = true;
441 if (!intel_fdi_compute_pipe_bpp(pipe_config))
442 return -EINVAL;
443
438 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;444 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
439 445
440 /* LPT FDI RX only supports 8bpc. */446 /* LPT FDI RX only supports 8bpc. */
441 if (HAS_PCH_LPT(dev_priv)) {447 if (HAS_PCH_LPT(dev_priv)) {
448 /* TODO: Check crtc_state->max_link_bpp_x16 instead of bw_constrained */
442 if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {449 if (pipe_config->bw_constrained && pipe_config->pipe_bpp < 24) {
443 drm_dbg_kms(&dev_priv->drm,450 drm_dbg_kms(&dev_priv->drm,
444 "LPT only supports 24bpp\n");451 "LPT only supports 24bpp\n");
@@ -451,6 +458,8 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder, · 6 unmodified lines
451 /* FDI must always be 2.7 GHz */458 /* FDI must always be 2.7 GHz */
452 pipe_config->port_clock = 135000 * 2;459 pipe_config->port_clock = 135000 * 2;
453 460
461 pipe_config->enhanced_framing = true;
462
454 adjusted_mode->crtc_clock = lpt_iclkip(pipe_config);463 adjusted_mode->crtc_clock = lpt_iclkip(pipe_config);
455 464
456 return 0;465 return 0;
@@ -610,18 +619,18 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) · 153 unmodified lines
610}619}
611 620
612static const struct drm_edid *intel_crt_get_edid(struct drm_connector *connector,621static const struct drm_edid *intel_crt_get_edid(struct drm_connector *connector,
613 struct i2c_adapter *i2c)622 struct i2c_adapter *ddc)
614{623{
615 const struct drm_edid *drm_edid;624 const struct drm_edid *drm_edid;
616 625
617 drm_edid = drm_edid_read_ddc(connector, i2c);626 drm_edid = drm_edid_read_ddc(connector, ddc);
618 627
619 if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {628 if (!drm_edid && !intel_gmbus_is_forced_bit(ddc)) {
620 drm_dbg_kms(connector->dev,629 drm_dbg_kms(connector->dev,
621 "CRT GMBUS EDID read failed, retry using GPIO bit-banging\n");630 "CRT GMBUS EDID read failed, retry using GPIO bit-banging\n");
622 intel_gmbus_force_bit(i2c, true);631 intel_gmbus_force_bit(ddc, true);
623 drm_edid = drm_edid_read_ddc(connector, i2c);632 drm_edid = drm_edid_read_ddc(connector, ddc);
624 intel_gmbus_force_bit(i2c, false);633 intel_gmbus_force_bit(ddc, false);
625 }634 }
626 635
627 return drm_edid;636 return drm_edid;
@@ -629,12 +638,12 @@ static const struct drm_edid *intel_crt_get_edid(struct drm_connector *connector · 1 unmodified line
629 638
630/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */639/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */
631static int intel_crt_ddc_get_modes(struct drm_connector *connector,640static int intel_crt_ddc_get_modes(struct drm_connector *connector,
632 struct i2c_adapter *adapter)641 struct i2c_adapter *ddc)
633{642{
634 const struct drm_edid *drm_edid;643 const struct drm_edid *drm_edid;
635 int ret;644 int ret;
636 645
637 drm_edid = intel_crt_get_edid(connector, adapter);646 drm_edid = intel_crt_get_edid(connector, ddc);
638 if (!drm_edid)647 if (!drm_edid)
639 return 0;648 return 0;
640 649
@@ -650,28 +659,23 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) · 9 unmodified lines
650 struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));659 struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
651 struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev);660 struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev);
652 const struct drm_edid *drm_edid;661 const struct drm_edid *drm_edid;
653 struct i2c_adapter *i2c;
654 bool ret = false;662 bool ret = false;
655 663
656 i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->display.vbt.crt_ddc_pin);664 drm_edid = intel_crt_get_edid(connector, connector->ddc);
657 drm_edid = intel_crt_get_edid(connector, i2c);
658 665
659 if (drm_edid) {666 if (drm_edid) {
660 const struct edid *edid = drm_edid_raw(drm_edid);
661 bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
662
663 /*667 /*
664 * This may be a DVI-I connector with a shared DDC668 * This may be a DVI-I connector with a shared DDC
665 * link between analog and digital outputs, so we669 * link between analog and digital outputs, so we
666 * have to check the EDID input spec of the attached device.670 * have to check the EDID input spec of the attached device.
667 */671 */
668 if (!is_digital) {672 if (drm_edid_is_digital(drm_edid)) {
669 drm_dbg_kms(&dev_priv->drm,673 drm_dbg_kms(&dev_priv->drm,
670 "CRT detected via DDC:0x50 [EDID]\n");674 "CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
671 ret = true;
672 } else {675 } else {
673 drm_dbg_kms(&dev_priv->drm,676 drm_dbg_kms(&dev_priv->drm,
674 "CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");677 "CRT detected via DDC:0x50 [EDID]\n");
678 ret = true;
675 }679 }
676 } else {680 } else {
677 drm_dbg_kms(&dev_priv->drm,681 drm_dbg_kms(&dev_priv->drm,
@@ -907,12 +911,6 @@ load_detect: · 229 unmodified lines
907out:911out:
908 intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);912 intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
909 913
910 /*
911 * Make sure the refs for power wells enabled during detect are
912 * dropped to avoid a new detect cycle triggered by HPD polling.
913 */
914 intel_display_power_flush_work(dev_priv);
915
916 return status;914 return status;
917}915}
918 916
@@ -923,20 +921,19 @@ static int intel_crt_get_modes(struct drm_connector *connector) · 4 unmodified lines
923 struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));921 struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
924 struct intel_encoder *intel_encoder = &crt->base;922 struct intel_encoder *intel_encoder = &crt->base;
925 intel_wakeref_t wakeref;923 intel_wakeref_t wakeref;
926 struct i2c_adapter *i2c;924 struct i2c_adapter *ddc;
927 int ret;925 int ret;
928 926
929 wakeref = intel_display_power_get(dev_priv,927 wakeref = intel_display_power_get(dev_priv,
930 intel_encoder->power_domain);928 intel_encoder->power_domain);
931 929
932 i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->display.vbt.crt_ddc_pin);930 ret = intel_crt_ddc_get_modes(connector, connector->ddc);
933 ret = intel_crt_ddc_get_modes(connector, i2c);
934 if (ret || !IS_G4X(dev_priv))931 if (ret || !IS_G4X(dev_priv))
935 goto out;932 goto out;
936 933
937 /* Try to probe digital port for output in DVI-I -> VGA mode. */934 /* Try to probe digital port for output in DVI-I -> VGA mode. */
938 i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PIN_DPB);935 ddc = intel_gmbus_get_adapter(dev_priv, GMBUS_PIN_DPB);
939 ret = intel_crt_ddc_get_modes(connector, i2c);936 ret = intel_crt_ddc_get_modes(connector, ddc);
940 937
941out:938out:
942 intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);939 intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
@@ -994,6 +991,7 @@ void intel_crt_init(struct drm_i915_private *dev_priv) · 51 unmodified lines
994 struct intel_crt *crt;991 struct intel_crt *crt;
995 struct intel_connector *intel_connector;992 struct intel_connector *intel_connector;
996 i915_reg_t adpa_reg;993 i915_reg_t adpa_reg;
994 u8 ddc_pin;
997 u32 adpa;995 u32 adpa;
998 996
999 if (HAS_PCH_SPLIT(dev_priv))997 if (HAS_PCH_SPLIT(dev_priv))
@@ -1030,10 +1028,14 @@ void intel_crt_init(struct drm_i915_private *dev_priv) · 30 unmodified lines
1030 return;1028 return;
1031 }1029 }
1032 1030
1031 ddc_pin = dev_priv->display.vbt.crt_ddc_pin;
1032
1033 connector = &intel_connector->base;1033 connector = &intel_connector->base;
1034 crt->connector = intel_connector;1034 crt->connector = intel_connector;
1035 drm_connector_init(&dev_priv->drm, &intel_connector->base,1035 drm_connector_init_with_ddc(&dev_priv->drm, connector,
1036 &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);1036 &intel_crt_connector_funcs,
1037 DRM_MODE_CONNECTOR_VGA,
1038 intel_gmbus_get_adapter(dev_priv, ddc_pin));
1037 1039
1038 drm_encoder_init(&dev_priv->drm, &crt->base.base, &intel_crt_enc_funcs,1040 drm_encoder_init(&dev_priv->drm, &crt->base.base, &intel_crt_enc_funcs,
1039 DRM_MODE_ENCODER_DAC, "CRT");1041 DRM_MODE_ENCODER_DAC, "CRT");
drivers/gpu/drm/i915/display/intel_crtc.c+76−42
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include "intel_display_trace.h"24#include "intel_display_trace.h"
25#include "intel_display_types.h"25#include "intel_display_types.h"
26#include "intel_drrs.h"26#include "intel_drrs.h"
27#include "intel_dsb.h"
27#include "intel_dsi.h"28#include "intel_dsi.h"
28#include "intel_fifo_underrun.h"29#include "intel_fifo_underrun.h"
29#include "intel_pipe_crc.h"30#include "intel_pipe_crc.h"
@@ -175,6 +176,7 @@ void intel_crtc_state_reset(struct intel_crtc_state *crtc_state, · 145 unmodified lines
175 crtc_state->hsw_workaround_pipe = INVALID_PIPE;176 crtc_state->hsw_workaround_pipe = INVALID_PIPE;
176 crtc_state->scaler_state.scaler_id = -1;177 crtc_state->scaler_state.scaler_id = -1;
177 crtc_state->mst_master_transcoder = INVALID_TRANSCODER;178 crtc_state->mst_master_transcoder = INVALID_TRANSCODER;
179 crtc_state->max_link_bpp_x16 = INT_MAX;
178}180}
179 181
180static struct intel_crtc *intel_crtc_alloc(void)182static struct intel_crtc *intel_crtc_alloc(void)
@@ -394,7 +396,8 @@ static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_sta · 213 unmodified lines
394 return crtc_state->hw.active &&396 return crtc_state->hw.active &&
395 !intel_crtc_needs_modeset(crtc_state) &&397 !intel_crtc_needs_modeset(crtc_state) &&
396 !crtc_state->preload_luts &&398 !crtc_state->preload_luts &&
397 intel_crtc_needs_color_update(crtc_state);399 intel_crtc_needs_color_update(crtc_state) &&
400 !intel_color_uses_dsb(crtc_state);
398}401}
399 402
400static void intel_crtc_vblank_work(struct kthread_work *base)403static void intel_crtc_vblank_work(struct kthread_work *base)
@@ -468,9 +471,64 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) · 67 unmodified lines
468 return vblank_start;471 return vblank_start;
469}472}
470 473
474static void intel_crtc_vblank_evade_scanlines(struct intel_atomic_state *state,
475 struct intel_crtc *crtc,
476 int *min, int *max, int *vblank_start)
477{
478 const struct intel_crtc_state *old_crtc_state =
479 intel_atomic_get_old_crtc_state(state, crtc);
480 const struct intel_crtc_state *new_crtc_state =
481 intel_atomic_get_new_crtc_state(state, crtc);
482 const struct intel_crtc_state *crtc_state;
483 const struct drm_display_mode *adjusted_mode;
484
485 /*
486 * During fastsets/etc. the transcoder is still
487 * running with the old timings at this point.
488 *
489 * TODO: maybe just use the active timings here?
490 */
491 if (intel_crtc_needs_modeset(new_crtc_state))
492 crtc_state = new_crtc_state;
493 else
494 crtc_state = old_crtc_state;
495
496 adjusted_mode = &crtc_state->hw.adjusted_mode;
497
498 if (crtc->mode_flags & I915_MODE_FLAG_VRR) {
499 /* timing changes should happen with VRR disabled */
500 drm_WARN_ON(state->base.dev, intel_crtc_needs_modeset(new_crtc_state) ||
501 new_crtc_state->update_m_n || new_crtc_state->update_lrr);
502
503 if (intel_vrr_is_push_sent(crtc_state))
504 *vblank_start = intel_vrr_vmin_vblank_start(crtc_state);
505 else
506 *vblank_start = intel_vrr_vmax_vblank_start(crtc_state);
507 } else {
508 *vblank_start = intel_mode_vblank_start(adjusted_mode);
509 }
510
511 /* FIXME needs to be calibrated sensibly */
512 *min = *vblank_start - intel_usecs_to_scanlines(adjusted_mode,
513 VBLANK_EVASION_TIME_US);
514 *max = *vblank_start - 1;
515
516 /*
517 * M/N and TRANS_VTOTAL are double buffered on the transcoder's
518 * undelayed vblank, so with seamless M/N and LRR we must evade
519 * both vblanks.
520 *
521 * DSB execution waits for the transcoder's undelayed vblank,
522 * hence we must kick off the commit before that.
523 */
524 if (new_crtc_state->dsb || new_crtc_state->update_m_n || new_crtc_state->update_lrr)
525 *min -= adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
526}
527
471/**528/**
472 * intel_pipe_update_start() - start update of a set of display registers529 * intel_pipe_update_start() - start update of a set of display registers
473 * @new_crtc_state: the new crtc state530 * @state: the atomic state
531 * @crtc: the crtc
474 *532 *
475 * Mark the start of an update to pipe registers that should be updated533 * Mark the start of an update to pipe registers that should be updated
476 * atomically regarding vblank. If the next vblank will happens within534 * atomically regarding vblank. If the next vblank will happens within
@@ -480,11 +538,12 @@ static int intel_mode_vblank_start(const struct drm_display_mode *mode) · 3 unmodified lines
480 * until a subsequent call to intel_pipe_update_end(). That is done to538 * until a subsequent call to intel_pipe_update_end(). That is done to
481 * avoid random delays.539 * avoid random delays.
482 */540 */
483void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state)541void intel_pipe_update_start(struct intel_atomic_state *state,
542 struct intel_crtc *crtc)
484{543{
485 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
486 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);544 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
487 const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;545 struct intel_crtc_state *new_crtc_state =
546 intel_atomic_get_new_crtc_state(state, crtc);
488 long timeout = msecs_to_jiffies_timeout(1);547 long timeout = msecs_to_jiffies_timeout(1);
489 int scanline, min, max, vblank_start;548 int scanline, min, max, vblank_start;
490 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);549 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
@@ -500,27 +559,7 @@ void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) · 9 unmodified lines
500 if (intel_crtc_needs_vblank_work(new_crtc_state))559 if (intel_crtc_needs_vblank_work(new_crtc_state))
501 intel_crtc_vblank_work_init(new_crtc_state);560 intel_crtc_vblank_work_init(new_crtc_state);
502 561
503 if (new_crtc_state->vrr.enable) {562 intel_crtc_vblank_evade_scanlines(state, crtc, &min, &max, &vblank_start);
504 if (intel_vrr_is_push_sent(new_crtc_state))
505 vblank_start = intel_vrr_vmin_vblank_start(new_crtc_state);
506 else
507 vblank_start = intel_vrr_vmax_vblank_start(new_crtc_state);
508 } else {
509 vblank_start = intel_mode_vblank_start(adjusted_mode);
510 }
511
512 /* FIXME needs to be calibrated sensibly */
513 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
514 VBLANK_EVASION_TIME_US);
515 max = vblank_start - 1;
516
517 /*
518 * M/N is double buffered on the transcoder's undelayed vblank,
519 * so with seamless M/N we must evade both vblanks.
520 */
521 if (new_crtc_state->seamless_m_n && intel_crtc_needs_fastset(new_crtc_state))
522 min -= adjusted_mode->crtc_vblank_start - adjusted_mode->crtc_vdisplay;
523
524 if (min <= 0 || max <= 0)563 if (min <= 0 || max <= 0)
525 goto irq_disable;564 goto irq_disable;
526 565
@@ -631,25 +670,26 @@ static void dbg_vblank_evade(struct intel_crtc *crtc, ktime_t end) {} · 104 unmodified lines
631 670
632/**671/**
633 * intel_pipe_update_end() - end update of a set of display registers672 * intel_pipe_update_end() - end update of a set of display registers
634 * @new_crtc_state: the new crtc state673 * @state: the atomic state
674 * @crtc: the crtc
635 *675 *
636 * Mark the end of an update started with intel_pipe_update_start(). This676 * Mark the end of an update started with intel_pipe_update_start(). This
637 * re-enables interrupts and verifies the update was actually completed677 * re-enables interrupts and verifies the update was actually completed
638 * before a vblank.678 * before a vblank.
639 */679 */
640void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)680void intel_pipe_update_end(struct intel_atomic_state *state,
681 struct intel_crtc *crtc)
641{682{
642 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);683 struct intel_crtc_state *new_crtc_state =
684 intel_atomic_get_new_crtc_state(state, crtc);
643 enum pipe pipe = crtc->pipe;685 enum pipe pipe = crtc->pipe;
644 int scanline_end = intel_get_crtc_scanline(crtc);686 int scanline_end = intel_get_crtc_scanline(crtc);
645 u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);687 u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
646 ktime_t end_vbl_time = ktime_get();688 ktime_t end_vbl_time = ktime_get();
647 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);689 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
648 690
649 intel_psr_unlock(new_crtc_state);
650
651 if (new_crtc_state->do_async_flip)691 if (new_crtc_state->do_async_flip)
652 return;692 goto out;
653 693
654 trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);694 trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);
655 695
@@ -697,19 +737,10 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) · 41 unmodified lines
697 */737 */
698 intel_vrr_send_push(new_crtc_state);738 intel_vrr_send_push(new_crtc_state);
699 739
700 /*
701 * Seamless M/N update may need to update frame timings.
702 *
703 * FIXME Should be synchronized with the start of vblank somehow...
704 */
705 if (new_crtc_state->seamless_m_n && intel_crtc_needs_fastset(new_crtc_state))
706 intel_crtc_update_active_timings(new_crtc_state,
707 new_crtc_state->vrr.enable);
708
709 local_irq_enable();740 local_irq_enable();
710 741
711 if (intel_vgpu_active(dev_priv))742 if (intel_vgpu_active(dev_priv))
712 return;743 goto out;
713 744
714 if (crtc->debug.start_vbl_count &&745 if (crtc->debug.start_vbl_count &&
715 crtc->debug.start_vbl_count != end_vbl_count) {746 crtc->debug.start_vbl_count != end_vbl_count) {
@@ -724,4 +755,7 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) · 8 unmodified lines
724 }755 }
725 756
726 dbg_vblank_evade(crtc, end_vbl_time);757 dbg_vblank_evade(crtc, end_vbl_time);
758
759out:
760 intel_psr_unlock(new_crtc_state);
727}761}
drivers/gpu/drm/i915/display/intel_crtc.h+4−2
@@ -36,8 +36,10 @@ void intel_crtc_state_reset(struct intel_crtc_state *crtc_state, · 35 unmodified lines
36u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc);36u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc);
37void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state);37void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state);
38void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state);38void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state);
39void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state);39void intel_pipe_update_start(struct intel_atomic_state *state,
40void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state);40 struct intel_crtc *crtc);
41void intel_pipe_update_end(struct intel_atomic_state *state,
42 struct intel_crtc *crtc);
41void intel_wait_for_vblank_workers(struct intel_atomic_state *state);43void intel_wait_for_vblank_workers(struct intel_atomic_state *state);
42struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915);44struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915);
43struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,45struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915,
drivers/gpu/drm/i915/display/intel_crtc_state_dump.c+3−0
@@ -258,6 +258,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, · 257 unmodified lines
258 intel_dump_m_n_config(pipe_config, "dp m2_n2",258 intel_dump_m_n_config(pipe_config, "dp m2_n2",
259 pipe_config->lane_count,259 pipe_config->lane_count,
260 &pipe_config->dp_m2_n2);260 &pipe_config->dp_m2_n2);
261 drm_dbg_kms(&i915->drm, "fec: %s, enhanced framing: %s\n",
262 str_enabled_disabled(pipe_config->fec_enable),
263 str_enabled_disabled(pipe_config->enhanced_framing));
261 }264 }
262 265
263 drm_dbg_kms(&i915->drm, "framestart delay: %d, MSA timing delay: %d\n",266 drm_dbg_kms(&i915->drm, "framestart delay: %d, MSA timing delay: %d\n",
drivers/gpu/drm/i915/display/intel_cx0_phy.c+107−98
@@ -31,7 +31,7 @@ · 30 unmodified lines
31 31
32bool intel_is_c10phy(struct drm_i915_private *i915, enum phy phy)32bool intel_is_c10phy(struct drm_i915_private *i915, enum phy phy)
33{33{
34 if (IS_METEORLAKE(i915) && (phy < PHY_C))34 if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0) && phy < PHY_C)
35 return true;35 return true;
36 36
37 return false;37 return false;
@@ -46,6 +46,22 @@ static int lane_mask_to_lane(u8 lane_mask) · 8 unmodified lines
46 return ilog2(lane_mask);46 return ilog2(lane_mask);
47}47}
48 48
49static u8 intel_cx0_get_owned_lane_mask(struct drm_i915_private *i915,
50 struct intel_encoder *encoder)
51{
52 struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
53
54 if (!intel_tc_port_in_dp_alt_mode(dig_port))
55 return INTEL_CX0_BOTH_LANES;
56
57 /*
58 * In DP-alt with pin assignment D, only PHY lane 0 is owned
59 * by display and lane 1 is owned by USB.
60 */
61 return intel_tc_port_max_lane_count(dig_port) > 2
62 ? INTEL_CX0_BOTH_LANES : INTEL_CX0_LANE0;
63}
64
49static void65static void
50assert_dc_off(struct drm_i915_private *i915)66assert_dc_off(struct drm_i915_private *i915)
51{67{
@@ -55,19 +71,38 @@ assert_dc_off(struct drm_i915_private *i915) · 3 unmodified lines
55 drm_WARN_ON(&i915->drm, !enabled);71 drm_WARN_ON(&i915->drm, !enabled);
56}72}
57 73
74static void intel_cx0_program_msgbus_timer(struct intel_encoder *encoder)
75{
76 int lane;
77 struct drm_i915_private *i915 = to_i915(encoder->base.dev);
78
79 for_each_cx0_lane_in_mask(INTEL_CX0_BOTH_LANES, lane)
80 intel_de_rmw(i915,
81 XELPDP_PORT_MSGBUS_TIMER(encoder->port, lane),
82 XELPDP_PORT_MSGBUS_TIMER_VAL_MASK,
83 XELPDP_PORT_MSGBUS_TIMER_VAL);
84}
85
58/*86/*
59 * Prepare HW for CX0 phy transactions.87 * Prepare HW for CX0 phy transactions.
60 *88 *
61 * It is required that PSR and DC5/6 are disabled before any CX0 message89 * It is required that PSR and DC5/6 are disabled before any CX0 message
62 * bus transaction is executed.90 * bus transaction is executed.
91 *
92 * We also do the msgbus timer programming here to ensure that the timer
93 * is already programmed before any access to the msgbus.
63 */94 */
64static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *encoder)95static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *encoder)
65{96{
97 intel_wakeref_t wakeref;
66 struct drm_i915_private *i915 = to_i915(encoder->base.dev);98 struct drm_i915_private *i915 = to_i915(encoder->base.dev);
67 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);99 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
68 100
69 intel_psr_pause(intel_dp);101 intel_psr_pause(intel_dp);
70 return intel_display_power_get(i915, POWER_DOMAIN_DC_OFF);102 wakeref = intel_display_power_get(i915, POWER_DOMAIN_DC_OFF);
103 intel_cx0_program_msgbus_timer(encoder);
104
105 return wakeref;
71}106}
72 107
73static void intel_cx0_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref)108static void intel_cx0_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref)
@@ -116,6 +151,13 @@ static int intel_cx0_wait_for_ack(struct drm_i915_private *i915, enum port port, · 42 unmodified lines
116 XELPDP_MSGBUS_TIMEOUT_SLOW, val)) {151 XELPDP_MSGBUS_TIMEOUT_SLOW, val)) {
117 drm_dbg_kms(&i915->drm, "PHY %c Timeout waiting for message ACK. Status: 0x%x\n",152 drm_dbg_kms(&i915->drm, "PHY %c Timeout waiting for message ACK. Status: 0x%x\n",
118 phy_name(phy), *val);153 phy_name(phy), *val);
154
155 if (!(intel_de_read(i915, XELPDP_PORT_MSGBUS_TIMER(port, lane)) &
156 XELPDP_PORT_MSGBUS_TIMER_TIMED_OUT))
157 drm_dbg_kms(&i915->drm,
158 "PHY %c Hardware did not detect a timeout\n",
159 phy_name(phy));
160
119 intel_cx0_bus_reset(i915, port, lane);161 intel_cx0_bus_reset(i915, port, lane);
120 return -ETIMEDOUT;162 return -ETIMEDOUT;
121 }163 }
@@ -359,6 +401,7 @@ void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, · 237 unmodified lines
359 struct drm_i915_private *i915 = to_i915(encoder->base.dev);401 struct drm_i915_private *i915 = to_i915(encoder->base.dev);
360 const struct intel_ddi_buf_trans *trans;402 const struct intel_ddi_buf_trans *trans;
361 enum phy phy = intel_port_to_phy(i915, encoder->port);403 enum phy phy = intel_port_to_phy(i915, encoder->port);
404 u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(i915, encoder);
362 intel_wakeref_t wakeref;405 intel_wakeref_t wakeref;
363 int n_entries, ln;406 int n_entries, ln;
364 407
@@ -371,13 +414,13 @@ void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, · 6 unmodified lines
371 }414 }
372 415
373 if (intel_is_c10phy(i915, phy)) {416 if (intel_is_c10phy(i915, phy)) {
374 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),417 intel_cx0_rmw(i915, encoder->port, owned_lane_mask, PHY_C10_VDR_CONTROL(1),
375 0, C10_VDR_CTRL_MSGBUS_ACCESS, MB_WRITE_COMMITTED);418 0, C10_VDR_CTRL_MSGBUS_ACCESS, MB_WRITE_COMMITTED);
376 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CMN(3),419 intel_cx0_rmw(i915, encoder->port, owned_lane_mask, PHY_C10_VDR_CMN(3),
377 C10_CMN3_TXVBOOST_MASK,420 C10_CMN3_TXVBOOST_MASK,
378 C10_CMN3_TXVBOOST(intel_c10_get_tx_vboost_lvl(crtc_state)),421 C10_CMN3_TXVBOOST(intel_c10_get_tx_vboost_lvl(crtc_state)),
379 MB_WRITE_UNCOMMITTED);422 MB_WRITE_UNCOMMITTED);
380 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_TX(1),423 intel_cx0_rmw(i915, encoder->port, owned_lane_mask, PHY_C10_VDR_TX(1),
381 C10_TX1_TERMCTL_MASK,424 C10_TX1_TERMCTL_MASK,
382 C10_TX1_TERMCTL(intel_c10_get_tx_term_ctl(crtc_state)),425 C10_TX1_TERMCTL(intel_c10_get_tx_term_ctl(crtc_state)),
383 MB_WRITE_COMMITTED);426 MB_WRITE_COMMITTED);
@@ -385,32 +428,34 @@ void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, · 1 unmodified line
385 428
386 for (ln = 0; ln < crtc_state->lane_count; ln++) {429 for (ln = 0; ln < crtc_state->lane_count; ln++) {
387 int level = intel_ddi_level(encoder, crtc_state, ln);430 int level = intel_ddi_level(encoder, crtc_state, ln);
388 int lane, tx;431 int lane = ln / 2;
432 int tx = ln % 2;
433 u8 lane_mask = lane == 0 ? INTEL_CX0_LANE0 : INTEL_CX0_LANE1;
389 434
390 lane = ln / 2;435 if (!(lane_mask & owned_lane_mask))
391 tx = ln % 2;436 continue;
392 437
393 intel_cx0_rmw(i915, encoder->port, BIT(lane), PHY_CX0_VDROVRD_CTL(lane, tx, 0),438 intel_cx0_rmw(i915, encoder->port, lane_mask, PHY_CX0_VDROVRD_CTL(lane, tx, 0),
394 C10_PHY_OVRD_LEVEL_MASK,439 C10_PHY_OVRD_LEVEL_MASK,
395 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.pre_cursor),440 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.pre_cursor),
396 MB_WRITE_COMMITTED);441 MB_WRITE_COMMITTED);
397 intel_cx0_rmw(i915, encoder->port, BIT(lane), PHY_CX0_VDROVRD_CTL(lane, tx, 1),442 intel_cx0_rmw(i915, encoder->port, lane_mask, PHY_CX0_VDROVRD_CTL(lane, tx, 1),
398 C10_PHY_OVRD_LEVEL_MASK,443 C10_PHY_OVRD_LEVEL_MASK,
399 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.vswing),444 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.vswing),
400 MB_WRITE_COMMITTED);445 MB_WRITE_COMMITTED);
401 intel_cx0_rmw(i915, encoder->port, BIT(lane), PHY_CX0_VDROVRD_CTL(lane, tx, 2),446 intel_cx0_rmw(i915, encoder->port, lane_mask, PHY_CX0_VDROVRD_CTL(lane, tx, 2),
402 C10_PHY_OVRD_LEVEL_MASK,447 C10_PHY_OVRD_LEVEL_MASK,
403 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.post_cursor),448 C10_PHY_OVRD_LEVEL(trans->entries[level].snps.post_cursor),
404 MB_WRITE_COMMITTED);449 MB_WRITE_COMMITTED);
405 }450 }
406 451
407 /* Write Override enables in 0xD71 */452 /* Write Override enables in 0xD71 */
408 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_OVRD,453 intel_cx0_rmw(i915, encoder->port, owned_lane_mask, PHY_C10_VDR_OVRD,
409 0, PHY_C10_VDR_OVRD_TX1 | PHY_C10_VDR_OVRD_TX2,454 0, PHY_C10_VDR_OVRD_TX1 | PHY_C10_VDR_OVRD_TX2,
410 MB_WRITE_COMMITTED);455 MB_WRITE_COMMITTED);
411 456
412 if (intel_is_c10phy(i915, phy))457 if (intel_is_c10phy(i915, phy))
413 intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),458 intel_cx0_rmw(i915, encoder->port, owned_lane_mask, PHY_C10_VDR_CONTROL(1),
414 0, C10_VDR_CTRL_UPDATE_CFG, MB_WRITE_COMMITTED);459 0, C10_VDR_CTRL_UPDATE_CFG, MB_WRITE_COMMITTED);
415 460
416 intel_cx0_phy_transaction_end(encoder, wakeref);461 intel_cx0_phy_transaction_end(encoder, wakeref);
@@ -2534,17 +2579,15 @@ static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, · 2117 unmodified lines
2534{2579{
2535 enum port port = encoder->port;2580 enum port port = encoder->port;
2536 enum phy phy = intel_port_to_phy(i915, port);2581 enum phy phy = intel_port_to_phy(i915, port);
2537 bool both_lanes = intel_tc_port_fia_max_lane_count(enc_to_dig_port(encoder)) > 2;2582 u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(i915, encoder);
2538 u8 lane_mask = lane_reversal ? INTEL_CX0_LANE1 :2583 u8 lane_mask = lane_reversal ? INTEL_CX0_LANE1 : INTEL_CX0_LANE0;
2539 INTEL_CX0_LANE0;2584 u32 lane_pipe_reset = owned_lane_mask == INTEL_CX0_BOTH_LANES
2540 u32 lane_pipe_reset = both_lanes ?2585 ? XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1)
2541 XELPDP_LANE_PIPE_RESET(0) |2586 : XELPDP_LANE_PIPE_RESET(0);
2542 XELPDP_LANE_PIPE_RESET(1) :2587 u32 lane_phy_current_status = owned_lane_mask == INTEL_CX0_BOTH_LANES
2543 XELPDP_LANE_PIPE_RESET(0);2588 ? (XELPDP_LANE_PHY_CURRENT_STATUS(0) |
2544 u32 lane_phy_current_status = both_lanes ?2589 XELPDP_LANE_PHY_CURRENT_STATUS(1))
2545 XELPDP_LANE_PHY_CURRENT_STATUS(0) |2590 : XELPDP_LANE_PHY_CURRENT_STATUS(0);
2546 XELPDP_LANE_PHY_CURRENT_STATUS(1) :
2547 XELPDP_LANE_PHY_CURRENT_STATUS(0);
2548 2591
2549 if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL1(port),2592 if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL1(port),
2550 XELPDP_PORT_BUF_SOC_PHY_READY,2593 XELPDP_PORT_BUF_SOC_PHY_READY,
@@ -2564,15 +2607,11 @@ static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, · 13 unmodified lines
2564 phy_name(phy), XELPDP_PORT_RESET_START_TIMEOUT_US);2607 phy_name(phy), XELPDP_PORT_RESET_START_TIMEOUT_US);
2565 2608
2566 intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(port),2609 intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(port),
2567 intel_cx0_get_pclk_refclk_request(both_lanes ?2610 intel_cx0_get_pclk_refclk_request(owned_lane_mask),
2568 INTEL_CX0_BOTH_LANES :
2569 INTEL_CX0_LANE0),
2570 intel_cx0_get_pclk_refclk_request(lane_mask));2611 intel_cx0_get_pclk_refclk_request(lane_mask));
2571 2612
2572 if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(port),2613 if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(port),
2573 intel_cx0_get_pclk_refclk_ack(both_lanes ?2614 intel_cx0_get_pclk_refclk_ack(owned_lane_mask),
2574 INTEL_CX0_BOTH_LANES :
2575 INTEL_CX0_LANE0),
2576 intel_cx0_get_pclk_refclk_ack(lane_mask),2615 intel_cx0_get_pclk_refclk_ack(lane_mask),
2577 XELPDP_REFCLK_ENABLE_TIMEOUT_US, 0, NULL))2616 XELPDP_REFCLK_ENABLE_TIMEOUT_US, 0, NULL))
2578 drm_warn(&i915->drm, "PHY %c failed to request refclk after %dus.\n",2617 drm_warn(&i915->drm, "PHY %c failed to request refclk after %dus.\n",
@@ -2594,79 +2633,43 @@ static void intel_cx0_program_phy_lane(struct drm_i915_private *i915, · 15 unmodified lines
2594 struct intel_encoder *encoder, int lane_count,2633 struct intel_encoder *encoder, int lane_count,
2595 bool lane_reversal)2634 bool lane_reversal)
2596{2635{
2597 u8 l0t1, l0t2, l1t1, l1t2;2636 int i;
2637 u8 disables;
2598 bool dp_alt_mode = intel_tc_port_in_dp_alt_mode(enc_to_dig_port(encoder));2638 bool dp_alt_mode = intel_tc_port_in_dp_alt_mode(enc_to_dig_port(encoder));
2639 u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(i915, encoder);
2599 enum port port = encoder->port;2640 enum port port = encoder->port;
2600 2641
2601 if (intel_is_c10phy(i915, intel_port_to_phy(i915, port)))2642 if (intel_is_c10phy(i915, intel_port_to_phy(i915, port)))
2602 intel_cx0_rmw(i915, port, INTEL_CX0_BOTH_LANES,2643 intel_cx0_rmw(i915, port, owned_lane_mask,
2603 PHY_C10_VDR_CONTROL(1), 0,2644 PHY_C10_VDR_CONTROL(1), 0,
2604 C10_VDR_CTRL_MSGBUS_ACCESS,2645 C10_VDR_CTRL_MSGBUS_ACCESS,
2605 MB_WRITE_COMMITTED);2646 MB_WRITE_COMMITTED);
2606 2647
2607 /* TODO: DP-alt MFD case where only one PHY lane should be programmed. */2648 if (lane_reversal)
2608 l0t1 = intel_cx0_read(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(1, 2));2649 disables = REG_GENMASK8(3, 0) >> lane_count;
2609 l0t2 = intel_cx0_read(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(2, 2));2650 else
2610 l1t1 = intel_cx0_read(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(1, 2));2651 disables = REG_GENMASK8(3, 0) << lane_count;
2611 l1t2 = intel_cx0_read(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(2, 2));2652
2612 2653 if (dp_alt_mode && lane_count == 1) {
2613 l0t1 |= CONTROL2_DISABLE_SINGLE_TX;2654 disables &= ~REG_GENMASK8(1, 0);
2614 l0t2 |= CONTROL2_DISABLE_SINGLE_TX;2655 disables |= REG_FIELD_PREP8(REG_GENMASK8(1, 0), 0x1);
2615 l1t1 |= CONTROL2_DISABLE_SINGLE_TX;
2616 l1t2 |= CONTROL2_DISABLE_SINGLE_TX;
2617
2618 if (lane_reversal) {
2619 switch (lane_count) {
2620 case 4:
2621 l0t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
2622 fallthrough;
2623 case 3:
2624 l0t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
2625 fallthrough;
2626 case 2:
2627 l1t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
2628 fallthrough;
2629 case 1:
2630 l1t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
2631 break;
2632 default:
2633 MISSING_CASE(lane_count);
2634 }
2635 } else {
2636 switch (lane_count) {
2637 case 4:
2638 l1t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
2639 fallthrough;
2640 case 3:
2641 l1t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
2642 fallthrough;
2643 case 2:
2644 l0t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
2645 l0t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
2646 break;
2647 case 1:
2648 if (dp_alt_mode)
2649 l0t2 &= ~CONTROL2_DISABLE_SINGLE_TX;
2650 else
2651 l0t1 &= ~CONTROL2_DISABLE_SINGLE_TX;
2652 break;
2653 default:
2654 MISSING_CASE(lane_count);
2655 }
2656 }2656 }
2657 2657
2658 /* disable MLs */2658 for (i = 0; i < 4; i++) {
2659 intel_cx0_write(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(1, 2),2659 int tx = i % 2 + 1;
2660 l0t1, MB_WRITE_COMMITTED);2660 u8 lane_mask = i < 2 ? INTEL_CX0_LANE0 : INTEL_CX0_LANE1;
2661 intel_cx0_write(i915, port, INTEL_CX0_LANE0, PHY_CX0_TX_CONTROL(2, 2),2661
2662 l0t2, MB_WRITE_COMMITTED);2662 if (!(owned_lane_mask & lane_mask))
2663 intel_cx0_write(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(1, 2),2663 continue;
2664 l1t1, MB_WRITE_COMMITTED);2664
2665 intel_cx0_write(i915, port, INTEL_CX0_LANE1, PHY_CX0_TX_CONTROL(2, 2),2665 intel_cx0_rmw(i915, port, lane_mask, PHY_CX0_TX_CONTROL(tx, 2),
2666 l1t2, MB_WRITE_COMMITTED);2666 CONTROL2_DISABLE_SINGLE_TX,
2667 disables & BIT(i) ? CONTROL2_DISABLE_SINGLE_TX : 0,
2668 MB_WRITE_COMMITTED);
2669 }
2667 2670
2668 if (intel_is_c10phy(i915, intel_port_to_phy(i915, port)))2671 if (intel_is_c10phy(i915, intel_port_to_phy(i915, port)))
2669 intel_cx0_rmw(i915, port, INTEL_CX0_BOTH_LANES,2672 intel_cx0_rmw(i915, port, owned_lane_mask,
2670 PHY_C10_VDR_CONTROL(1), 0,2673 PHY_C10_VDR_CONTROL(1), 0,
2671 C10_VDR_CTRL_UPDATE_CFG,2674 C10_VDR_CTRL_UPDATE_CFG,
2672 MB_WRITE_COMMITTED);2675 MB_WRITE_COMMITTED);
@@ -2721,39 +2724,45 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder, · 48 unmodified lines
2721 intel_cx0_powerdown_change_sequence(i915, encoder->port, INTEL_CX0_BOTH_LANES,2724 intel_cx0_powerdown_change_sequence(i915, encoder->port, INTEL_CX0_BOTH_LANES,
2722 CX0_P2_STATE_READY);2725 CX0_P2_STATE_READY);
2723 2726
2724 /* 4. Program PHY internal PLL internal registers. */2727 /*
2728 * 4. Program PORT_MSGBUS_TIMER register's Message Bus Timer field to 0xA000.
2729 * (This is done inside intel_cx0_phy_transaction_begin(), since we would need
2730 * the right timer thresholds for readouts too.)
2731 */
2732
2733 /* 5. Program PHY internal PLL internal registers. */
2725 if (intel_is_c10phy(i915, phy))2734 if (intel_is_c10phy(i915, phy))
2726 intel_c10_pll_program(i915, crtc_state, encoder);2735 intel_c10_pll_program(i915, crtc_state, encoder);
2727 else2736 else
2728 intel_c20_pll_program(i915, crtc_state, encoder);2737 intel_c20_pll_program(i915, crtc_state, encoder);
2729 2738
2730 /*2739 /*
2731 * 5. Program the enabled and disabled owned PHY lane2740 * 6. Program the enabled and disabled owned PHY lane
2732 * transmitters over message bus2741 * transmitters over message bus
2733 */2742 */
2734 intel_cx0_program_phy_lane(i915, encoder, crtc_state->lane_count, lane_reversal);2743 intel_cx0_program_phy_lane(i915, encoder, crtc_state->lane_count, lane_reversal);
2735 2744
2736 /*2745 /*
2737 * 6. Follow the Display Voltage Frequency Switching - Sequence2746 * 7. Follow the Display Voltage Frequency Switching - Sequence
2738 * Before Frequency Change. We handle this step in bxt_set_cdclk().2747 * Before Frequency Change. We handle this step in bxt_set_cdclk().
2739 */2748 */
2740 2749
2741 /*2750 /*
2742 * 7. Program DDI_CLK_VALFREQ to match intended DDI2751 * 8. Program DDI_CLK_VALFREQ to match intended DDI
2743 * clock frequency.2752 * clock frequency.
2744 */2753 */
2745 intel_de_write(i915, DDI_CLK_VALFREQ(encoder->port),2754 intel_de_write(i915, DDI_CLK_VALFREQ(encoder->port),
2746 crtc_state->port_clock);2755 crtc_state->port_clock);
2747 2756
2748 /*2757 /*
2749 * 8. Set PORT_CLOCK_CTL register PCLK PLL Request2758 * 9. Set PORT_CLOCK_CTL register PCLK PLL Request
2750 * LN<Lane for maxPCLK> to "1" to enable PLL.2759 * LN<Lane for maxPCLK> to "1" to enable PLL.
2751 */2760 */
2752 intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),2761 intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
2753 intel_cx0_get_pclk_pll_request(INTEL_CX0_BOTH_LANES),2762 intel_cx0_get_pclk_pll_request(INTEL_CX0_BOTH_LANES),
2754 intel_cx0_get_pclk_pll_request(maxpclk_lane));2763 intel_cx0_get_pclk_pll_request(maxpclk_lane));
2755 2764
2756 /* 9. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK> == "1". */2765 /* 10. Poll on PORT_CLOCK_CTL PCLK PLL Ack LN<Lane for maxPCLK> == "1". */
2757 if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),2766 if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(encoder->port),
2758 intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES),2767 intel_cx0_get_pclk_pll_ack(INTEL_CX0_BOTH_LANES),
2759 intel_cx0_get_pclk_pll_ack(maxpclk_lane),2768 intel_cx0_get_pclk_pll_ack(maxpclk_lane),
@@ -2762,7 +2771,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder, · 2 unmodified lines
2762 phy_name(phy), XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US);2771 phy_name(phy), XELPDP_PCLK_PLL_ENABLE_TIMEOUT_US);
2763 2772
2764 /*2773 /*
2765 * 10. Follow the Display Voltage Frequency Switching Sequence After2774 * 11. Follow the Display Voltage Frequency Switching Sequence After
2766 * Frequency Change. We handle this step in bxt_set_cdclk().2775 * Frequency Change. We handle this step in bxt_set_cdclk().
2767 */2776 */
2768 2777
drivers/gpu/drm/i915/display/intel_cx0_phy.h+8−6
@@ -10,14 +10,15 @@ · 9 unmodified lines
10#include <linux/bitfield.h>10#include <linux/bitfield.h>
11#include <linux/bits.h>11#include <linux/bits.h>
12 12
13#include "i915_drv.h"
14#include "intel_display_types.h"
15
16struct drm_i915_private;
17struct intel_encoder;
18struct intel_crtc_state;
19enum icl_port_dpll_id;13enum icl_port_dpll_id;
20enum phy;14enum phy;
15struct drm_i915_private;
16struct intel_atomic_state;
17struct intel_c10pll_state;
18struct intel_c20pll_state;
19struct intel_crtc_state;
20struct intel_encoder;
21struct intel_hdmi;
21 22
22bool intel_is_c10phy(struct drm_i915_private *dev_priv, enum phy phy);23bool intel_is_c10phy(struct drm_i915_private *dev_priv, enum phy phy);
23void intel_mtl_pll_enable(struct intel_encoder *encoder,24void intel_mtl_pll_enable(struct intel_encoder *encoder,
@@ -44,4 +45,5 @@ void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder, · 20 unmodified lines
44 const struct intel_crtc_state *crtc_state);45 const struct intel_crtc_state *crtc_state);
45int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);46int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);
46int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder);47int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder);
48
47#endif /* __INTEL_CX0_PHY_H__ */49#endif /* __INTEL_CX0_PHY_H__ */
drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h+13−0
@@ -110,6 +110,19 @@ · 109 unmodified lines
110#define CX0_P4PG_STATE_DISABLE 0xC110#define CX0_P4PG_STATE_DISABLE 0xC
111#define CX0_P2_STATE_RESET 0x2111#define CX0_P2_STATE_RESET 0x2
112 112
113#define _XELPDP_PORT_MSGBUS_TIMER_LN0_A 0x640d8
114#define _XELPDP_PORT_MSGBUS_TIMER_LN0_B 0x641d8
115#define _XELPDP_PORT_MSGBUS_TIMER_LN0_USBC1 0x16f258
116#define _XELPDP_PORT_MSGBUS_TIMER_LN0_USBC2 0x16f458
117#define XELPDP_PORT_MSGBUS_TIMER(port, lane) _MMIO(_PICK_EVEN_2RANGES(port, PORT_TC1, \
118 _XELPDP_PORT_MSGBUS_TIMER_LN0_A, \
119 _XELPDP_PORT_MSGBUS_TIMER_LN0_B, \
120 _XELPDP_PORT_MSGBUS_TIMER_LN0_USBC1, \
121 _XELPDP_PORT_MSGBUS_TIMER_LN0_USBC2) + (lane) * 4)
122#define XELPDP_PORT_MSGBUS_TIMER_TIMED_OUT REG_BIT(31)
123#define XELPDP_PORT_MSGBUS_TIMER_VAL_MASK REG_GENMASK(23, 0)
124#define XELPDP_PORT_MSGBUS_TIMER_VAL REG_FIELD_PREP(XELPDP_PORT_MSGBUS_TIMER_VAL_MASK, 0xa000)
125
113#define _XELPDP_PORT_CLOCK_CTL_A 0x640E0126#define _XELPDP_PORT_CLOCK_CTL_A 0x640E0
114#define _XELPDP_PORT_CLOCK_CTL_B 0x641E0127#define _XELPDP_PORT_CLOCK_CTL_B 0x641E0
115#define _XELPDP_PORT_CLOCK_CTL_USBC1 0x16F260128#define _XELPDP_PORT_CLOCK_CTL_USBC1 0x16F260
drivers/gpu/drm/i915/display/intel_ddi.c+20−18
@@ -3248,7 +3248,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state, · 3247 unmodified lines
3248 intel_ddi_enable_transcoder_func(encoder, crtc_state);3248 intel_ddi_enable_transcoder_func(encoder, crtc_state);
3249 3249
3250 /* Enable/Disable DP2.0 SDP split config before transcoder */3250 /* Enable/Disable DP2.0 SDP split config before transcoder */
3251 intel_audio_sdp_split_update(encoder, crtc_state);3251 intel_audio_sdp_split_update(crtc_state);
3252 3252
3253 intel_enable_transcoder(crtc_state);3253 intel_enable_transcoder(crtc_state);
3254 3254
@@ -3432,7 +3432,7 @@ static void mtl_ddi_prepare_link_retrain(struct intel_dp *intel_dp, · 177 unmodified lines
3432 dp_tp_ctl |= DP_TP_CTL_MODE_MST;3432 dp_tp_ctl |= DP_TP_CTL_MODE_MST;
3433 } else {3433 } else {
3434 dp_tp_ctl |= DP_TP_CTL_MODE_SST;3434 dp_tp_ctl |= DP_TP_CTL_MODE_SST;
3435 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))3435 if (crtc_state->enhanced_framing)
3436 dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;3436 dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3437 }3437 }
3438 intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);3438 intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
@@ -3489,7 +3489,7 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, · 50 unmodified lines
3489 dp_tp_ctl |= DP_TP_CTL_MODE_MST;3489 dp_tp_ctl |= DP_TP_CTL_MODE_MST;
3490 } else {3490 } else {
3491 dp_tp_ctl |= DP_TP_CTL_MODE_SST;3491 dp_tp_ctl |= DP_TP_CTL_MODE_SST;
3492 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))3492 if (crtc_state->enhanced_framing)
3493 dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;3493 dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3494 }3494 }
3495 intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);3495 intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
@@ -3724,17 +3724,14 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, · 228 unmodified lines
3724 intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder,3724 intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder,
3725 &pipe_config->dp_m2_n2);3725 &pipe_config->dp_m2_n2);
3726 3726
3727 if (DISPLAY_VER(dev_priv) >= 11) {3727 pipe_config->enhanced_framing =
3728 i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config);3728 intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, pipe_config)) &
3729 DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3729 3730
3731 if (DISPLAY_VER(dev_priv) >= 11)
3730 pipe_config->fec_enable =3732 pipe_config->fec_enable =
3731 intel_de_read(dev_priv, dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;3733 intel_de_read(dev_priv,
3732 3734 dp_tp_ctl_reg(encoder, pipe_config)) & DP_TP_CTL_FEC_ENABLE;
3733 drm_dbg_kms(&dev_priv->drm,
3734 "[ENCODER:%d:%s] Fec status: %u\n",
3735 encoder->base.base.id, encoder->base.name,
3736 pipe_config->fec_enable);
3737 }
3738 3735
3739 if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp))3736 if (dig_port->lspcon.active && intel_dp_has_hdmi_sink(&dig_port->dp))
3740 pipe_config->infoframes.enable |=3737 pipe_config->infoframes.enable |=
@@ -3747,6 +3744,9 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, · 6 unmodified lines
3747 if (!HAS_DP20(dev_priv)) {3744 if (!HAS_DP20(dev_priv)) {
3748 /* FDI */3745 /* FDI */
3749 pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);3746 pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
3747 pipe_config->enhanced_framing =
3748 intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, pipe_config)) &
3749 DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3750 break;3750 break;
3751 }3751 }
3752 fallthrough; /* 128b/132b */3752 fallthrough; /* 128b/132b */
@@ -3762,6 +3762,11 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, · 9 unmodified lines
3762 intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,3762 intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
3763 &pipe_config->dp_m_n);3763 &pipe_config->dp_m_n);
3764 3764
3765 if (DISPLAY_VER(dev_priv) >= 11)
3766 pipe_config->fec_enable =
3767 intel_de_read(dev_priv,
3768 dp_tp_ctl_reg(encoder, pipe_config)) & DP_TP_CTL_FEC_ENABLE;
3769
3765 pipe_config->infoframes.enable |=3770 pipe_config->infoframes.enable |=
3766 intel_hdmi_infoframes_enabled(encoder, pipe_config);3771 intel_hdmi_infoframes_enabled(encoder, pipe_config);
3767 break;3772 break;
@@ -3857,11 +3862,9 @@ static void mtl_ddi_get_config(struct intel_encoder *encoder, · 89 unmodified lines
3857 crtc_state->port_clock = intel_mtl_tbt_calc_port_clock(encoder);3862 crtc_state->port_clock = intel_mtl_tbt_calc_port_clock(encoder);
3858 } else if (intel_is_c10phy(i915, phy)) {3863 } else if (intel_is_c10phy(i915, phy)) {
3859 intel_c10pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c10);3864 intel_c10pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c10);
3860 intel_c10pll_dump_hw_state(i915, &crtc_state->cx0pll_state.c10);
3861 crtc_state->port_clock = intel_c10pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c10);3865 crtc_state->port_clock = intel_c10pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c10);
3862 } else {3866 } else {
3863 intel_c20pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c20);3867 intel_c20pll_readout_hw_state(encoder, &crtc_state->cx0pll_state.c20);
3864 intel_c20pll_dump_hw_state(i915, &crtc_state->cx0pll_state.c20);
3865 crtc_state->port_clock = intel_c20pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c20);3868 crtc_state->port_clock = intel_c20pll_calc_port_clock(encoder, &crtc_state->cx0pll_state.c20);
3866 }3869 }
3867 3870
@@ -4173,7 +4176,7 @@ static int intel_ddi_compute_config_late(struct intel_encoder *encoder, · 305 unmodified lines
4173 struct drm_connector *connector = conn_state->connector;4176 struct drm_connector *connector = conn_state->connector;
4174 u8 port_sync_transcoders = 0;4177 u8 port_sync_transcoders = 0;
4175 4178
4176 drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]",4179 drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]\n",
4177 encoder->base.base.id, encoder->base.name,4180 encoder->base.base.id, encoder->base.name,
4178 crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name);4181 crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name);
4179 4182
@@ -4323,8 +4326,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, · 143 unmodified lines
4323 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);4326 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
4324 struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);4327 struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);
4325 struct intel_connector *connector = hdmi->attached_connector;4328 struct intel_connector *connector = hdmi->attached_connector;
4326 struct i2c_adapter *adapter =4329 struct i2c_adapter *ddc = connector->base.ddc;
4327 intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
4328 struct drm_connector_state *conn_state;4330 struct drm_connector_state *conn_state;
4329 struct intel_crtc_state *crtc_state;4331 struct intel_crtc_state *crtc_state;
4330 struct intel_crtc *crtc;4332 struct intel_crtc *crtc;
@@ -4365,7 +4367,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, · 34 unmodified lines
4365 !try_wait_for_completion(&conn_state->commit->hw_done))4367 !try_wait_for_completion(&conn_state->commit->hw_done))
4366 return 0;4368 return 0;
4367 4369
4368 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);4370 ret = drm_scdc_readb(ddc, SCDC_TMDS_CONFIG, &config);
4369 if (ret < 0) {4371 if (ret < 0) {
4370 drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n",4372 drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n",
4371 connector->base.base.id, connector->base.name, ret);4373 connector->base.base.id, connector->base.name, ret);
drivers/gpu/drm/i915/display/intel_display.c+337−139
@@ -77,6 +77,7 @@ · 76 unmodified lines
77#include "intel_dpll_mgr.h"77#include "intel_dpll_mgr.h"
78#include "intel_dpt.h"78#include "intel_dpt.h"
79#include "intel_drrs.h"79#include "intel_drrs.h"
80#include "intel_dsb.h"
80#include "intel_dsi.h"81#include "intel_dsi.h"
81#include "intel_dvo.h"82#include "intel_dvo.h"
82#include "intel_fb.h"83#include "intel_fb.h"
@@ -87,6 +88,7 @@ · 4 unmodified lines
87#include "intel_frontbuffer.h"88#include "intel_frontbuffer.h"
88#include "intel_hdmi.h"89#include "intel_hdmi.h"
89#include "intel_hotplug.h"90#include "intel_hotplug.h"
91#include "intel_link_bw.h"
90#include "intel_lvds.h"92#include "intel_lvds.h"
91#include "intel_lvds_regs.h"93#include "intel_lvds_regs.h"
92#include "intel_modeset_setup.h"94#include "intel_modeset_setup.h"
@@ -726,7 +728,7 @@ static void icl_set_pipe_chicken(const struct intel_crtc_state *crtc_state) · 633 unmodified lines
726 tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP;728 tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP;
727 729
728 /* Wa_14010547955:dg2 */730 /* Wa_14010547955:dg2 */
729 if (IS_DG2_DISPLAY_STEP(dev_priv, STEP_B0, STEP_FOREVER))731 if (IS_DG2(dev_priv))
730 tmp |= DG2_RENDER_CCSTAG_4_3_EN;732 tmp |= DG2_RENDER_CCSTAG_4_3_EN;
731 733
732 intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp);734 intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp);
@@ -913,16 +915,32 @@ static bool planes_disabling(const struct intel_crtc_state *old_crtc_state, · 180 unmodified lines
913 return is_disabling(active_planes, old_crtc_state, new_crtc_state);915 return is_disabling(active_planes, old_crtc_state, new_crtc_state);
914}916}
915 917
918static bool vrr_params_changed(const struct intel_crtc_state *old_crtc_state,
919 const struct intel_crtc_state *new_crtc_state)
920{
921 return old_crtc_state->vrr.flipline != new_crtc_state->vrr.flipline ||
922 old_crtc_state->vrr.vmin != new_crtc_state->vrr.vmin ||
923 old_crtc_state->vrr.vmax != new_crtc_state->vrr.vmax ||
924 old_crtc_state->vrr.guardband != new_crtc_state->vrr.guardband ||
925 old_crtc_state->vrr.pipeline_full != new_crtc_state->vrr.pipeline_full;
926}
927
916static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,928static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state,
917 const struct intel_crtc_state *new_crtc_state)929 const struct intel_crtc_state *new_crtc_state)
918{930{
919 return is_enabling(vrr.enable, old_crtc_state, new_crtc_state);931 return is_enabling(vrr.enable, old_crtc_state, new_crtc_state) ||
932 (new_crtc_state->vrr.enable &&
933 (new_crtc_state->update_m_n || new_crtc_state->update_lrr ||
934 vrr_params_changed(old_crtc_state, new_crtc_state)));
920}935}
921 936
922static bool vrr_disabling(const struct intel_crtc_state *old_crtc_state,937static bool vrr_disabling(const struct intel_crtc_state *old_crtc_state,
923 const struct intel_crtc_state *new_crtc_state)938 const struct intel_crtc_state *new_crtc_state)
924{939{
925 return is_disabling(vrr.enable, old_crtc_state, new_crtc_state);940 return is_disabling(vrr.enable, old_crtc_state, new_crtc_state) ||
941 (old_crtc_state->vrr.enable &&
942 (new_crtc_state->update_m_n || new_crtc_state->update_lrr ||
943 vrr_params_changed(old_crtc_state, new_crtc_state)));
926}944}
927 945
928#undef is_disabling946#undef is_disabling
@@ -1767,7 +1785,7 @@ bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy) · 838 unmodified lines
1767 if (IS_DG2(dev_priv))1785 if (IS_DG2(dev_priv))
1768 /* DG2's "TC1" output uses a SNPS PHY */1786 /* DG2's "TC1" output uses a SNPS PHY */
1769 return false;1787 return false;
1770 else if (IS_ALDERLAKE_P(dev_priv) || IS_METEORLAKE(dev_priv))1788 else if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER_FULL(dev_priv) == IP_VER(14, 0))
1771 return phy >= PHY_F && phy <= PHY_I;1789 return phy >= PHY_F && phy <= PHY_I;
1772 else if (IS_TIGERLAKE(dev_priv))1790 else if (IS_TIGERLAKE(dev_priv))
1773 return phy >= PHY_D && phy <= PHY_I;1791 return phy >= PHY_D && phy <= PHY_I;
@@ -2570,6 +2588,37 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta · 796 unmodified lines
2570 VTOTAL(crtc_vtotal - 1));2588 VTOTAL(crtc_vtotal - 1));
2571}2589}
2572 2590
2591static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state)
2592{
2593 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2594 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2595 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
2596 const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
2597 u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start, crtc_vblank_end;
2598
2599 crtc_vdisplay = adjusted_mode->crtc_vdisplay;
2600 crtc_vtotal = adjusted_mode->crtc_vtotal;
2601 crtc_vblank_start = adjusted_mode->crtc_vblank_start;
2602 crtc_vblank_end = adjusted_mode->crtc_vblank_end;
2603
2604 drm_WARN_ON(&dev_priv->drm, adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE);
2605
2606 /*
2607 * The hardware actually ignores TRANS_VBLANK.VBLANK_END in DP mode.
2608 * But let's write it anyway to keep the state checker happy.
2609 */
2610 intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder),
2611 VBLANK_START(crtc_vblank_start - 1) |
2612 VBLANK_END(crtc_vblank_end - 1));
2613 /*
2614 * The double buffer latch point for TRANS_VTOTAL
2615 * is the transcoder's undelayed vblank.
2616 */
2617 intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder),
2618 VACTIVE(crtc_vdisplay - 1) |
2619 VTOTAL(crtc_vtotal - 1));
2620}
2621
2573static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)2622static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
2574{2623{
2575 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);2624 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -2869,24 +2918,6 @@ bdw_get_pipe_misc_output_format(struct intel_crtc *crtc) · 293 unmodified lines
2869 }2918 }
2870}2919}
2871 2920
2872static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state)
2873{
2874 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2875 struct intel_plane *plane = to_intel_plane(crtc->base.primary);
2876 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
2877 enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
2878 u32 tmp;
2879
2880 tmp = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
2881
2882 if (tmp & DISP_PIPE_GAMMA_ENABLE)
2883 crtc_state->gamma_enable = true;
2884
2885 if (!HAS_GMCH(dev_priv) &&
2886 tmp & DISP_PIPE_CSC_ENABLE)
2887 crtc_state->csc_enable = true;
2888}
2889
2890static bool i9xx_get_pipe_config(struct intel_crtc *crtc,2921static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
2891 struct intel_crtc_state *pipe_config)2922 struct intel_crtc_state *pipe_config)
2892{2923{
@@ -2942,11 +2973,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, · 49 unmodified lines
2942 (tmp & TRANSCONF_WGC_ENABLE))2973 (tmp & TRANSCONF_WGC_ENABLE))
2943 pipe_config->wgc_enable = true;2974 pipe_config->wgc_enable = true;
2944 2975
2945 if (IS_CHERRYVIEW(dev_priv))
2946 pipe_config->cgm_mode = intel_de_read(dev_priv,
2947 CGM_PIPE_MODE(crtc->pipe));
2948
2949 i9xx_get_pipe_color_config(pipe_config);
2950 intel_color_get_config(pipe_config);2976 intel_color_get_config(pipe_config);
2951 2977
2952 if (DISPLAY_VER(dev_priv) < 4)2978 if (DISPLAY_VER(dev_priv) < 4)
@@ -3344,10 +3370,6 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, · 391 unmodified lines
3344 3370
3345 pipe_config->msa_timing_delay = REG_FIELD_GET(TRANSCONF_MSA_TIMING_DELAY_MASK, tmp);3371 pipe_config->msa_timing_delay = REG_FIELD_GET(TRANSCONF_MSA_TIMING_DELAY_MASK, tmp);
3346 3372
3347 pipe_config->csc_mode = intel_de_read(dev_priv,
3348 PIPE_CSC_MODE(crtc->pipe));
3349
3350 i9xx_get_pipe_color_config(pipe_config);
3351 intel_color_get_config(pipe_config);3373 intel_color_get_config(pipe_config);
3352 3374
3353 pipe_config->pixel_multiplier = 1;3375 pipe_config->pixel_multiplier = 1;
@@ -3738,24 +3760,6 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, · 384 unmodified lines
3738 3760
3739 pipe_config->sink_format = pipe_config->output_format;3761 pipe_config->sink_format = pipe_config->output_format;
3740 3762
3741 pipe_config->gamma_mode = intel_de_read(dev_priv,
3742 GAMMA_MODE(crtc->pipe));
3743
3744 pipe_config->csc_mode = intel_de_read(dev_priv,
3745 PIPE_CSC_MODE(crtc->pipe));
3746
3747 if (DISPLAY_VER(dev_priv) >= 9) {
3748 tmp = intel_de_read(dev_priv, SKL_BOTTOM_COLOR(crtc->pipe));
3749
3750 if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE)
3751 pipe_config->gamma_enable = true;
3752
3753 if (tmp & SKL_BOTTOM_COLOR_CSC_ENABLE)
3754 pipe_config->csc_enable = true;
3755 } else {
3756 i9xx_get_pipe_color_config(pipe_config);
3757 }
3758
3759 intel_color_get_config(pipe_config);3763 intel_color_get_config(pipe_config);
3760 3764
3761 tmp = intel_de_read(dev_priv, WM_LINETIME(crtc->pipe));3765 tmp = intel_de_read(dev_priv, WM_LINETIME(crtc->pipe));
@@ -4641,7 +4645,8 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state, · 879 unmodified lines
4641 4645
4642static int4646static int
4643intel_modeset_pipe_config(struct intel_atomic_state *state,4647intel_modeset_pipe_config(struct intel_atomic_state *state,
4644 struct intel_crtc *crtc)4648 struct intel_crtc *crtc,
4649 const struct intel_link_bw_limits *limits)
4645{4650{
4646 struct drm_i915_private *i915 = to_i915(crtc->base.dev);4651 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
4647 struct intel_crtc_state *crtc_state =4652 struct intel_crtc_state *crtc_state =
@@ -4650,7 +4655,6 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, · 2 unmodified lines
4650 struct drm_connector_state *connector_state;4655 struct drm_connector_state *connector_state;
4651 int pipe_src_w, pipe_src_h;4656 int pipe_src_w, pipe_src_h;
4652 int base_bpp, ret, i;4657 int base_bpp, ret, i;
4653 bool retry = true;
4654 4658
4655 crtc_state->cpu_transcoder = (enum transcoder) crtc->pipe;4659 crtc_state->cpu_transcoder = (enum transcoder) crtc->pipe;
4656 4660
@@ -4673,6 +4677,16 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, · 16 unmodified lines
4673 if (ret)4677 if (ret)
4674 return ret;4678 return ret;
4675 4679
4680 crtc_state->max_link_bpp_x16 = limits->max_bpp_x16[crtc->pipe];
4681
4682 if (crtc_state->pipe_bpp > to_bpp_int(crtc_state->max_link_bpp_x16)) {
4683 drm_dbg_kms(&i915->drm,
4684 "[CRTC:%d:%s] Link bpp limited to " BPP_X16_FMT "\n",
4685 crtc->base.base.id, crtc->base.name,
4686 BPP_X16_ARGS(crtc_state->max_link_bpp_x16));
4687 crtc_state->bw_constrained = true;
4688 }
4689
4676 base_bpp = crtc_state->pipe_bpp;4690 base_bpp = crtc_state->pipe_bpp;
4677 4691
4678 /*4692 /*
@@ -4714,7 +4728,6 @@ intel_modeset_pipe_config(struct intel_atomic_state *state, · 35 unmodified lines
4714 crtc_state->output_types |= BIT(encoder->type);4728 crtc_state->output_types |= BIT(encoder->type);
4715 }4729 }
4716 4730
4717encoder_retry:
4718 /* Ensure the port clock defaults are reset when retrying. */4731 /* Ensure the port clock defaults are reset when retrying. */
4719 crtc_state->port_clock = 0;4732 crtc_state->port_clock = 0;
4720 crtc_state->pixel_multiplier = 1;4733 crtc_state->pixel_multiplier = 1;
@@ -4754,17 +4767,6 @@ encoder_retry: · 33 unmodified lines
4754 ret = intel_crtc_compute_config(state, crtc);4767 ret = intel_crtc_compute_config(state, crtc);
4755 if (ret == -EDEADLK)4768 if (ret == -EDEADLK)
4756 return ret;4769 return ret;
4757 if (ret == -EAGAIN) {
4758 if (drm_WARN(&i915->drm, !retry,
4759 "[CRTC:%d:%s] loop in pipe configuration computation\n",
4760 crtc->base.base.id, crtc->base.name))
4761 return -EINVAL;
4762
4763 drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] bw constrained, retrying\n",
4764 crtc->base.base.id, crtc->base.name);
4765 retry = false;
4766 goto encoder_retry;
4767 }
4768 if (ret < 0) {4770 if (ret < 0) {
4769 drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] config failure: %d\n",4771 drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] config failure: %d\n",
4770 crtc->base.base.id, crtc->base.name, ret);4772 crtc->base.base.id, crtc->base.name, ret);
@@ -5111,11 +5113,13 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, · 340 unmodified lines
5111 PIPE_CONF_CHECK_I(name.crtc_hsync_start); \5113 PIPE_CONF_CHECK_I(name.crtc_hsync_start); \
5112 PIPE_CONF_CHECK_I(name.crtc_hsync_end); \5114 PIPE_CONF_CHECK_I(name.crtc_hsync_end); \
5113 PIPE_CONF_CHECK_I(name.crtc_vdisplay); \5115 PIPE_CONF_CHECK_I(name.crtc_vdisplay); \
5114 PIPE_CONF_CHECK_I(name.crtc_vtotal); \
5115 PIPE_CONF_CHECK_I(name.crtc_vblank_start); \5116 PIPE_CONF_CHECK_I(name.crtc_vblank_start); \
5116 PIPE_CONF_CHECK_I(name.crtc_vblank_end); \
5117 PIPE_CONF_CHECK_I(name.crtc_vsync_start); \5117 PIPE_CONF_CHECK_I(name.crtc_vsync_start); \
5118 PIPE_CONF_CHECK_I(name.crtc_vsync_end); \5118 PIPE_CONF_CHECK_I(name.crtc_vsync_end); \
5119 if (!fastset || !pipe_config->update_lrr) { \
5120 PIPE_CONF_CHECK_I(name.crtc_vtotal); \
5121 PIPE_CONF_CHECK_I(name.crtc_vblank_end); \
5122 } \
5119} while (0)5123} while (0)
5120 5124
5121#define PIPE_CONF_CHECK_RECT(name) do { \5125#define PIPE_CONF_CHECK_RECT(name) do { \
@@ -5215,7 +5219,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, · 93 unmodified lines
5215 PIPE_CONF_CHECK_X(lane_lat_optim_mask);5219 PIPE_CONF_CHECK_X(lane_lat_optim_mask);
5216 5220
5217 if (HAS_DOUBLE_BUFFERED_M_N(dev_priv)) {5221 if (HAS_DOUBLE_BUFFERED_M_N(dev_priv)) {
5218 if (!fastset || !pipe_config->seamless_m_n)5222 if (!fastset || !pipe_config->update_m_n)
5219 PIPE_CONF_CHECK_M_N(dp_m_n);5223 PIPE_CONF_CHECK_M_N(dp_m_n);
5220 } else {5224 } else {
5221 PIPE_CONF_CHECK_M_N(dp_m_n);5225 PIPE_CONF_CHECK_M_N(dp_m_n);
@@ -5255,6 +5259,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, · 33 unmodified lines
5255 PIPE_CONF_CHECK_BOOL(hdmi_scrambling);5259 PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
5256 PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);5260 PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
5257 PIPE_CONF_CHECK_BOOL(has_infoframe);5261 PIPE_CONF_CHECK_BOOL(has_infoframe);
5262 PIPE_CONF_CHECK_BOOL(enhanced_framing);
5258 PIPE_CONF_CHECK_BOOL(fec_enable);5263 PIPE_CONF_CHECK_BOOL(fec_enable);
5259 5264
5260 PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);5265 PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
@@ -5352,7 +5357,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, · 91 unmodified lines
5352 if (IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) >= 5)5357 if (IS_G4X(dev_priv) || DISPLAY_VER(dev_priv) >= 5)
5353 PIPE_CONF_CHECK_I(pipe_bpp);5358 PIPE_CONF_CHECK_I(pipe_bpp);
5354 5359
5355 if (!fastset || !pipe_config->seamless_m_n) {5360 if (!fastset || !pipe_config->update_m_n) {
5356 PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_clock);5361 PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_clock);
5357 PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_clock);5362 PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_clock);
5358 }5363 }
@@ -5377,6 +5382,37 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, · 18 unmodified lines
5377 PIPE_CONF_CHECK_I(master_transcoder);5382 PIPE_CONF_CHECK_I(master_transcoder);
5378 PIPE_CONF_CHECK_X(bigjoiner_pipes);5383 PIPE_CONF_CHECK_X(bigjoiner_pipes);
5379 5384
5385 PIPE_CONF_CHECK_BOOL(dsc.config.block_pred_enable);
5386 PIPE_CONF_CHECK_BOOL(dsc.config.convert_rgb);
5387 PIPE_CONF_CHECK_BOOL(dsc.config.simple_422);
5388 PIPE_CONF_CHECK_BOOL(dsc.config.native_422);
5389 PIPE_CONF_CHECK_BOOL(dsc.config.native_420);
5390 PIPE_CONF_CHECK_BOOL(dsc.config.vbr_enable);
5391 PIPE_CONF_CHECK_I(dsc.config.line_buf_depth);
5392 PIPE_CONF_CHECK_I(dsc.config.bits_per_component);
5393 PIPE_CONF_CHECK_I(dsc.config.pic_width);
5394 PIPE_CONF_CHECK_I(dsc.config.pic_height);
5395 PIPE_CONF_CHECK_I(dsc.config.slice_width);
5396 PIPE_CONF_CHECK_I(dsc.config.slice_height);
5397 PIPE_CONF_CHECK_I(dsc.config.initial_dec_delay);
5398 PIPE_CONF_CHECK_I(dsc.config.initial_xmit_delay);
5399 PIPE_CONF_CHECK_I(dsc.config.scale_decrement_interval);
5400 PIPE_CONF_CHECK_I(dsc.config.scale_increment_interval);
5401 PIPE_CONF_CHECK_I(dsc.config.initial_scale_value);
5402 PIPE_CONF_CHECK_I(dsc.config.first_line_bpg_offset);
5403 PIPE_CONF_CHECK_I(dsc.config.flatness_min_qp);
5404 PIPE_CONF_CHECK_I(dsc.config.flatness_max_qp);
5405 PIPE_CONF_CHECK_I(dsc.config.slice_bpg_offset);
5406 PIPE_CONF_CHECK_I(dsc.config.nfl_bpg_offset);
5407 PIPE_CONF_CHECK_I(dsc.config.initial_offset);
5408 PIPE_CONF_CHECK_I(dsc.config.final_offset);
5409 PIPE_CONF_CHECK_I(dsc.config.rc_model_size);
5410 PIPE_CONF_CHECK_I(dsc.config.rc_quant_incr_limit0);
5411 PIPE_CONF_CHECK_I(dsc.config.rc_quant_incr_limit1);
5412 PIPE_CONF_CHECK_I(dsc.config.slice_chunk_size);
5413 PIPE_CONF_CHECK_I(dsc.config.second_line_bpg_offset);
5414 PIPE_CONF_CHECK_I(dsc.config.nsl_bpg_offset);
5415
5380 PIPE_CONF_CHECK_I(dsc.compression_enable);5416 PIPE_CONF_CHECK_I(dsc.compression_enable);
5381 PIPE_CONF_CHECK_I(dsc.dsc_split);5417 PIPE_CONF_CHECK_I(dsc.dsc_split);
5382 PIPE_CONF_CHECK_I(dsc.compressed_bpp);5418 PIPE_CONF_CHECK_I(dsc.compressed_bpp);
@@ -5385,13 +5421,14 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, · 2 unmodified lines
5385 PIPE_CONF_CHECK_I(splitter.link_count);5421 PIPE_CONF_CHECK_I(splitter.link_count);
5386 PIPE_CONF_CHECK_I(splitter.pixel_overlap);5422 PIPE_CONF_CHECK_I(splitter.pixel_overlap);
5387 5423
5388 if (!fastset)5424 if (!fastset) {
5389 PIPE_CONF_CHECK_BOOL(vrr.enable);5425 PIPE_CONF_CHECK_BOOL(vrr.enable);
5390 PIPE_CONF_CHECK_I(vrr.vmin);5426 PIPE_CONF_CHECK_I(vrr.vmin);
5391 PIPE_CONF_CHECK_I(vrr.vmax);5427 PIPE_CONF_CHECK_I(vrr.vmax);
5392 PIPE_CONF_CHECK_I(vrr.flipline);5428 PIPE_CONF_CHECK_I(vrr.flipline);
5393 PIPE_CONF_CHECK_I(vrr.pipeline_full);5429 PIPE_CONF_CHECK_I(vrr.pipeline_full);
5394 PIPE_CONF_CHECK_I(vrr.guardband);5430 PIPE_CONF_CHECK_I(vrr.guardband);
5431 }
5395 5432
5396#undef PIPE_CONF_CHECK_X5433#undef PIPE_CONF_CHECK_X
5397#undef PIPE_CONF_CHECK_I5434#undef PIPE_CONF_CHECK_I
@@ -5420,17 +5457,54 @@ intel_verify_planes(struct intel_atomic_state *state) · 22 unmodified lines
5420 plane_state->uapi.visible);5457 plane_state->uapi.visible);
5421}5458}
5422 5459
5423int intel_modeset_all_pipes(struct intel_atomic_state *state,5460static int intel_modeset_pipe(struct intel_atomic_state *state,
5424 const char *reason)5461 struct intel_crtc_state *crtc_state,
5462 const char *reason)
5425{5463{
5426 struct drm_i915_private *dev_priv = to_i915(state->base.dev);5464 struct drm_i915_private *i915 = to_i915(state->base.dev);
5465 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
5466 int ret;
5467
5468 drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Full modeset due to %s\n",
5469 crtc->base.base.id, crtc->base.name, reason);
5470
5471 ret = drm_atomic_add_affected_connectors(&state->base,
5472 &crtc->base);
5473 if (ret)
5474 return ret;
5475
5476 ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);
5477 if (ret)
5478 return ret;
5479
5480 ret = intel_atomic_add_affected_planes(state, crtc);
5481 if (ret)
5482 return ret;
5483
5484 crtc_state->uapi.mode_changed = true;
5485
5486 return 0;
5487}
5488
5489/**
5490 * intel_modeset_pipes_in_mask_early - force a full modeset on a set of pipes
5491 * @state: intel atomic state
5492 * @reason: the reason for the full modeset
5493 * @mask: mask of pipes to modeset
5494 *
5495 * Add pipes in @mask to @state and force a full modeset on the enabled ones
5496 * due to the description in @reason.
5497 * This function can be called only before new plane states are computed.
5498 *
5499 * Returns 0 in case of success, negative error code otherwise.
5500 */
5501int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
5502 const char *reason, u8 mask)
5503{
5504 struct drm_i915_private *i915 = to_i915(state->base.dev);
5427 struct intel_crtc *crtc;5505 struct intel_crtc *crtc;
5428 5506
5429 /*5507 for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, mask) {
5430 * Add all pipes to the state, and force
5431 * a modeset on all the active ones.
5432 */
5433 for_each_intel_crtc(&dev_priv->drm, crtc) {
5434 struct intel_crtc_state *crtc_state;5508 struct intel_crtc_state *crtc_state;
5435 int ret;5509 int ret;
5436 5510
@@ -5438,29 +5512,54 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state, · 1 unmodified line
5438 if (IS_ERR(crtc_state))5512 if (IS_ERR(crtc_state))
5439 return PTR_ERR(crtc_state);5513 return PTR_ERR(crtc_state);
5440 5514
5441 if (!crtc_state->hw.active ||5515 if (!crtc_state->hw.enable ||
5442 intel_crtc_needs_modeset(crtc_state))5516 intel_crtc_needs_modeset(crtc_state))
5443 continue;5517 continue;
5444 5518
5445 drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s] Full modeset due to %s\n",5519 ret = intel_modeset_pipe(state, crtc_state, reason);
5446 crtc->base.base.id, crtc->base.name, reason);
5447
5448 crtc_state->uapi.mode_changed = true;
5449 crtc_state->update_pipe = false;
5450
5451 ret = drm_atomic_add_affected_connectors(&state->base,
5452 &crtc->base);
5453 if (ret)5520 if (ret)
5454 return ret;5521 return ret;
5522 }
5455 5523
5456 ret = intel_dp_mst_add_topology_state_for_crtc(state, crtc);5524 return 0;
5457 if (ret)5525}
5458 return ret;
5459 5526
5460 ret = intel_atomic_add_affected_planes(state, crtc);5527/**
5528 * intel_modeset_all_pipes_late - force a full modeset on all pipes
5529 * @state: intel atomic state
5530 * @reason: the reason for the full modeset
5531 *
5532 * Add all pipes to @state and force a full modeset on the active ones due to
5533 * the description in @reason.
5534 * This function can be called only after new plane states are computed already.
5535 *
5536 * Returns 0 in case of success, negative error code otherwise.
5537 */
5538int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
5539 const char *reason)
5540{
5541 struct drm_i915_private *dev_priv = to_i915(state->base.dev);
5542 struct intel_crtc *crtc;
5543
5544 for_each_intel_crtc(&dev_priv->drm, crtc) {
5545 struct intel_crtc_state *crtc_state;
5546 int ret;
5547
5548 crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
5549 if (IS_ERR(crtc_state))
5550 return PTR_ERR(crtc_state);
5551
5552 if (!crtc_state->hw.active ||
5553 intel_crtc_needs_modeset(crtc_state))
5554 continue;
5555
5556 ret = intel_modeset_pipe(state, crtc_state, reason);
5461 if (ret)5557 if (ret)
5462 return ret;5558 return ret;
5463 5559
5560 crtc_state->update_pipe = false;
5561 crtc_state->update_m_n = false;
5562 crtc_state->update_lrr = false;
5464 crtc_state->update_planes |= crtc_state->active_planes;5563 crtc_state->update_planes |= crtc_state->active_planes;
5465 crtc_state->async_flip_planes = 0;5564 crtc_state->async_flip_planes = 0;
5466 crtc_state->do_async_flip = false;5565 crtc_state->do_async_flip = false;
@@ -5564,13 +5663,25 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta · 97 unmodified lines
5564{5663{
5565 struct drm_i915_private *i915 = to_i915(old_crtc_state->uapi.crtc->dev);5664 struct drm_i915_private *i915 = to_i915(old_crtc_state->uapi.crtc->dev);
5566 5665
5567 if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true)) {5666 /* only allow LRR when the timings stay within the VRR range */
5667 if (old_crtc_state->vrr.in_range != new_crtc_state->vrr.in_range)
5668 new_crtc_state->update_lrr = false;
5669
5670 if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true))
5568 drm_dbg_kms(&i915->drm, "fastset requirement not met, forcing full modeset\n");5671 drm_dbg_kms(&i915->drm, "fastset requirement not met, forcing full modeset\n");
5672 else
5673 new_crtc_state->uapi.mode_changed = false;
5569 5674
5570 return;5675 if (intel_crtc_needs_modeset(new_crtc_state) ||
5571 }5676 intel_compare_link_m_n(&old_crtc_state->dp_m_n,
5677 &new_crtc_state->dp_m_n))
5678 new_crtc_state->update_m_n = false;
5679
5680 if (intel_crtc_needs_modeset(new_crtc_state) ||
5681 (old_crtc_state->hw.adjusted_mode.crtc_vtotal == new_crtc_state->hw.adjusted_mode.crtc_vtotal &&
5682 old_crtc_state->hw.adjusted_mode.crtc_vblank_end == new_crtc_state->hw.adjusted_mode.crtc_vblank_end))
5683 new_crtc_state->update_lrr = false;
5572 5684
5573 new_crtc_state->uapi.mode_changed = false;
5574 if (!intel_crtc_needs_modeset(new_crtc_state))5685 if (!intel_crtc_needs_modeset(new_crtc_state))
5575 new_crtc_state->update_pipe = true;5686 new_crtc_state->update_pipe = true;
5576}5687}
@@ -6171,6 +6282,101 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state) · 594 unmodified lines
6171 return 0;6282 return 0;
6172}6283}
6173 6284
6285static int intel_atomic_check_config(struct intel_atomic_state *state,
6286 struct intel_link_bw_limits *limits,
6287 enum pipe *failed_pipe)
6288{
6289 struct drm_i915_private *i915 = to_i915(state->base.dev);
6290 struct intel_crtc_state *new_crtc_state;
6291 struct intel_crtc *crtc;
6292 int ret;
6293 int i;
6294
6295 *failed_pipe = INVALID_PIPE;
6296
6297 ret = intel_bigjoiner_add_affected_crtcs(state);
6298 if (ret)
6299 return ret;
6300
6301 ret = intel_fdi_add_affected_crtcs(state);
6302 if (ret)
6303 return ret;
6304
6305 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
6306 if (!intel_crtc_needs_modeset(new_crtc_state)) {
6307 if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
6308 copy_bigjoiner_crtc_state_nomodeset(state, crtc);
6309 else
6310 intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
6311 continue;
6312 }
6313
6314 if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
6315 drm_WARN_ON(&i915->drm, new_crtc_state->uapi.enable);
6316 continue;
6317 }
6318
6319 ret = intel_crtc_prepare_cleared_state(state, crtc);
6320 if (ret)
6321 break;
6322
6323 if (!new_crtc_state->hw.enable)
6324 continue;
6325
6326 ret = intel_modeset_pipe_config(state, crtc, limits);
6327 if (ret)
6328 break;
6329
6330 ret = intel_atomic_check_bigjoiner(state, crtc);
6331 if (ret)
6332 break;
6333 }
6334
6335 if (ret)
6336 *failed_pipe = crtc->pipe;
6337
6338 return ret;
6339}
6340
6341static int intel_atomic_check_config_and_link(struct intel_atomic_state *state)
6342{
6343 struct drm_i915_private *i915 = to_i915(state->base.dev);
6344 struct intel_link_bw_limits new_limits;
6345 struct intel_link_bw_limits old_limits;
6346 int ret;
6347
6348 intel_link_bw_init_limits(i915, &new_limits);
6349 old_limits = new_limits;
6350
6351 while (true) {
6352 enum pipe failed_pipe;
6353
6354 ret = intel_atomic_check_config(state, &new_limits,
6355 &failed_pipe);
6356 if (ret) {
6357 /*
6358 * The bpp limit for a pipe is below the minimum it supports, set the
6359 * limit to the minimum and recalculate the config.
6360 */
6361 if (ret == -EINVAL &&
6362 intel_link_bw_set_bpp_limit_for_pipe(state,
6363 &old_limits,
6364 &new_limits,
6365 failed_pipe))
6366 continue;
6367
6368 break;
6369 }
6370
6371 old_limits = new_limits;
6372
6373 ret = intel_link_bw_atomic_check(state, &new_limits);
6374 if (ret != -EAGAIN)
6375 break;
6376 }
6377
6378 return ret;
6379}
6174/**6380/**
6175 * intel_atomic_check - validate state object6381 * intel_atomic_check - validate state object
6176 * @dev: drm device6382 * @dev: drm device
@@ -6215,41 +6421,10 @@ int intel_atomic_check(struct drm_device *dev, · 38 unmodified lines
6215 return ret;6421 return ret;
6216 }6422 }
6217 6423
6218 ret = intel_bigjoiner_add_affected_crtcs(state);6424 ret = intel_atomic_check_config_and_link(state);
6219 if (ret)6425 if (ret)
6220 goto fail;6426 goto fail;
6221 6427
6222 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
6223 new_crtc_state, i) {
6224 if (!intel_crtc_needs_modeset(new_crtc_state)) {
6225 if (intel_crtc_is_bigjoiner_slave(new_crtc_state))
6226 copy_bigjoiner_crtc_state_nomodeset(state, crtc);
6227 else
6228 intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc);
6229 continue;
6230 }
6231
6232 if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
6233 drm_WARN_ON(&dev_priv->drm, new_crtc_state->uapi.enable);
6234 continue;
6235 }
6236
6237 ret = intel_crtc_prepare_cleared_state(state, crtc);
6238 if (ret)
6239 goto fail;
6240
6241 if (!new_crtc_state->hw.enable)
6242 continue;
6243
6244 ret = intel_modeset_pipe_config(state, crtc);
6245 if (ret)
6246 goto fail;
6247
6248 ret = intel_atomic_check_bigjoiner(state, crtc);
6249 if (ret)
6250 goto fail;
6251 }
6252
6253 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,6428 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
6254 new_crtc_state, i) {6429 new_crtc_state, i) {
6255 if (!intel_crtc_needs_modeset(new_crtc_state))6430 if (!intel_crtc_needs_modeset(new_crtc_state))
@@ -6285,6 +6460,8 @@ int intel_atomic_check(struct drm_device *dev, · 29 unmodified lines
6285 if (intel_cpu_transcoders_need_modeset(state, BIT(master))) {6460 if (intel_cpu_transcoders_need_modeset(state, BIT(master))) {
6286 new_crtc_state->uapi.mode_changed = true;6461 new_crtc_state->uapi.mode_changed = true;
6287 new_crtc_state->update_pipe = false;6462 new_crtc_state->update_pipe = false;
6463 new_crtc_state->update_m_n = false;
6464 new_crtc_state->update_lrr = false;
6288 }6465 }
6289 }6466 }
6290 6467
@@ -6297,6 +6474,8 @@ int intel_atomic_check(struct drm_device *dev, · 6 unmodified lines
6297 if (intel_cpu_transcoders_need_modeset(state, trans)) {6474 if (intel_cpu_transcoders_need_modeset(state, trans)) {
6298 new_crtc_state->uapi.mode_changed = true;6475 new_crtc_state->uapi.mode_changed = true;
6299 new_crtc_state->update_pipe = false;6476 new_crtc_state->update_pipe = false;
6477 new_crtc_state->update_m_n = false;
6478 new_crtc_state->update_lrr = false;
6300 }6479 }
6301 }6480 }
6302 6481
@@ -6304,6 +6483,8 @@ int intel_atomic_check(struct drm_device *dev, · 1 unmodified line
6304 if (intel_pipes_need_modeset(state, new_crtc_state->bigjoiner_pipes)) {6483 if (intel_pipes_need_modeset(state, new_crtc_state->bigjoiner_pipes)) {
6305 new_crtc_state->uapi.mode_changed = true;6484 new_crtc_state->uapi.mode_changed = true;
6306 new_crtc_state->update_pipe = false;6485 new_crtc_state->update_pipe = false;
6486 new_crtc_state->update_m_n = false;
6487 new_crtc_state->update_lrr = false;
6307 }6488 }
6308 }6489 }
6309 }6490 }
@@ -6482,9 +6663,12 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, · 172 unmodified lines
6482 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))6663 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
6483 hsw_set_linetime_wm(new_crtc_state);6664 hsw_set_linetime_wm(new_crtc_state);
6484 6665
6485 if (new_crtc_state->seamless_m_n)6666 if (new_crtc_state->update_m_n)
6486 intel_cpu_transcoder_set_m1_n1(crtc, new_crtc_state->cpu_transcoder,6667 intel_cpu_transcoder_set_m1_n1(crtc, new_crtc_state->cpu_transcoder,
6487 &new_crtc_state->dp_m_n);6668 &new_crtc_state->dp_m_n);
6669
6670 if (new_crtc_state->update_lrr)
6671 intel_set_transcoder_timings_lrr(new_crtc_state);
6488}6672}
6489 6673
6490static void commit_pipe_pre_planes(struct intel_atomic_state *state,6674static void commit_pipe_pre_planes(struct intel_atomic_state *state,
@@ -6521,6 +6705,8 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state, · 30 unmodified lines
6521 struct intel_crtc *crtc)6705 struct intel_crtc *crtc)
6522{6706{
6523 struct drm_i915_private *dev_priv = to_i915(state->base.dev);6707 struct drm_i915_private *dev_priv = to_i915(state->base.dev);
6708 const struct intel_crtc_state *old_crtc_state =
6709 intel_atomic_get_old_crtc_state(state, crtc);
6524 const struct intel_crtc_state *new_crtc_state =6710 const struct intel_crtc_state *new_crtc_state =
6525 intel_atomic_get_new_crtc_state(state, crtc);6711 intel_atomic_get_new_crtc_state(state, crtc);
6526 6712
@@ -6532,6 +6718,9 @@ static void commit_pipe_post_planes(struct intel_atomic_state *state, · 5 unmodified lines
6532 if (DISPLAY_VER(dev_priv) >= 9 &&6718 if (DISPLAY_VER(dev_priv) >= 9 &&
6533 !intel_crtc_needs_modeset(new_crtc_state))6719 !intel_crtc_needs_modeset(new_crtc_state))
6534 skl_detach_scalers(new_crtc_state);6720 skl_detach_scalers(new_crtc_state);
6721
6722 if (vrr_enabling(old_crtc_state, new_crtc_state))
6723 intel_vrr_enable(new_crtc_state);
6535}6724}
6536 6725
6537static void intel_enable_crtc(struct intel_atomic_state *state,6726static void intel_enable_crtc(struct intel_atomic_state *state,
@@ -6572,12 +6761,6 @@ static void intel_update_crtc(struct intel_atomic_state *state, · 34 unmodified lines
6572 intel_dpt_configure(crtc);6761 intel_dpt_configure(crtc);
6573 }6762 }
6574 6763
6575 if (vrr_enabling(old_crtc_state, new_crtc_state)) {
6576 intel_vrr_enable(new_crtc_state);
6577 intel_crtc_update_active_timings(new_crtc_state,
6578 new_crtc_state->vrr.enable);
6579 }
6580
6581 if (!modeset) {6764 if (!modeset) {
6582 if (new_crtc_state->preload_luts &&6765 if (new_crtc_state->preload_luts &&
6583 intel_crtc_needs_color_update(new_crtc_state))6766 intel_crtc_needs_color_update(new_crtc_state))
@@ -6591,6 +6774,9 @@ static void intel_update_crtc(struct intel_atomic_state *state, · 7 unmodified lines
6591 if (DISPLAY_VER(i915) >= 11 &&6774 if (DISPLAY_VER(i915) >= 11 &&
6592 intel_crtc_needs_fastset(new_crtc_state))6775 intel_crtc_needs_fastset(new_crtc_state))
6593 icl_set_pipe_chicken(new_crtc_state);6776 icl_set_pipe_chicken(new_crtc_state);
6777
6778 if (vrr_params_changed(old_crtc_state, new_crtc_state))
6779 intel_vrr_set_transcoder_timings(new_crtc_state);
6594 }6780 }
6595 6781
6596 intel_fbc_update(state, crtc);6782 intel_fbc_update(state, crtc);
@@ -6604,7 +6790,7 @@ static void intel_update_crtc(struct intel_atomic_state *state, · 7 unmodified lines
6604 intel_crtc_planes_update_noarm(state, crtc);6790 intel_crtc_planes_update_noarm(state, crtc);
6605 6791
6606 /* Perform vblank evasion around commit operation */6792 /* Perform vblank evasion around commit operation */
6607 intel_pipe_update_start(new_crtc_state);6793 intel_pipe_update_start(state, crtc);
6608 6794
6609 commit_pipe_pre_planes(state, crtc);6795 commit_pipe_pre_planes(state, crtc);
6610 6796
@@ -6612,7 +6798,17 @@ static void intel_update_crtc(struct intel_atomic_state *state, · 1 unmodified line
6612 6798
6613 commit_pipe_post_planes(state, crtc);6799 commit_pipe_post_planes(state, crtc);
6614 6800
6615 intel_pipe_update_end(new_crtc_state);6801 intel_pipe_update_end(state, crtc);
6802
6803 /*
6804 * VRR/Seamless M/N update may need to update frame timings.
6805 *
6806 * FIXME Should be synchronized with the start of vblank somehow...
6807 */
6808 if (vrr_enabling(old_crtc_state, new_crtc_state) ||
6809 new_crtc_state->update_m_n || new_crtc_state->update_lrr)
6810 intel_crtc_update_active_timings(new_crtc_state,
6811 new_crtc_state->vrr.enable);
6616 6812
6617 /*6813 /*
6618 * We usually enable FIFO underrun interrupts as part of the6814 * We usually enable FIFO underrun interrupts as part of the
@@ -7072,6 +7268,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) · 453 unmodified lines
7072 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {7268 for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
7073 if (new_crtc_state->do_async_flip)7269 if (new_crtc_state->do_async_flip)
7074 intel_crtc_disable_flip_done(state, crtc);7270 intel_crtc_disable_flip_done(state, crtc);
7271
7272 intel_color_wait_commit(new_crtc_state);
7075 }7273 }
7076 7274
7077 /*7275 /*
drivers/gpu/drm/i915/display/intel_display.h+4−4
@@ -190,8 +190,6 @@ enum aux_ch { · 189 unmodified lines
190 AUX_CH_E_XELPD,190 AUX_CH_E_XELPD,
191};191};
192 192
193#define aux_ch_name(a) ((a) + 'A')
194
195enum phy {193enum phy {
196 PHY_NONE = -1,194 PHY_NONE = -1,
197 195
@@ -513,8 +511,10 @@ void intel_plane_fixup_bitmasks(struct intel_crtc_state *crtc_state); · 315 unmodified lines
513void intel_update_watermarks(struct drm_i915_private *i915);511void intel_update_watermarks(struct drm_i915_private *i915);
514 512
515/* modesetting */513/* modesetting */
516int intel_modeset_all_pipes(struct intel_atomic_state *state,514int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state,
517 const char *reason);515 const char *reason, u8 pipe_mask);
516int intel_modeset_all_pipes_late(struct intel_atomic_state *state,
517 const char *reason);
518void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,518void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
519 struct intel_power_domain_mask *old_domains);519 struct intel_power_domain_mask *old_domains);
520void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,520void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,
drivers/gpu/drm/i915/display/intel_display_debugfs.c+4−0
@@ -43,12 +43,16 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) · 42 unmodified lines
43{43{
44 struct drm_i915_private *dev_priv = node_to_i915(m->private);44 struct drm_i915_private *dev_priv = node_to_i915(m->private);
45 45
46 spin_lock(&dev_priv->display.fb_tracking.lock);
47
46 seq_printf(m, "FB tracking busy bits: 0x%08x\n",48 seq_printf(m, "FB tracking busy bits: 0x%08x\n",
47 dev_priv->display.fb_tracking.busy_bits);49 dev_priv->display.fb_tracking.busy_bits);
48 50
49 seq_printf(m, "FB tracking flip bits: 0x%08x\n",51 seq_printf(m, "FB tracking flip bits: 0x%08x\n",
50 dev_priv->display.fb_tracking.flip_bits);52 dev_priv->display.fb_tracking.flip_bits);
51 53
54 spin_unlock(&dev_priv->display.fb_tracking.lock);
55
52 return 0;56 return 0;
53}57}
54 58
drivers/gpu/drm/i915/display/intel_display_device.c+82−16
@@ -710,18 +710,61 @@ static const struct intel_display_device_info xe_hpd_display = { · 709 unmodified lines
710 BIT(PORT_TC1),710 BIT(PORT_TC1),
711};711};
712 712
713#define XE_LPDP_FEATURES \
714 .abox_mask = GENMASK(1, 0), \
715 .color = { \
716 .degamma_lut_size = 129, .gamma_lut_size = 1024, \
717 .degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING | \
718 DRM_COLOR_LUT_EQUAL_CHANNELS, \
719 }, \
720 .dbuf.size = 4096, \
721 .dbuf.slice_mask = BIT(DBUF_S1) | BIT(DBUF_S2) | BIT(DBUF_S3) | \
722 BIT(DBUF_S4), \
723 .has_cdclk_crawl = 1, \
724 .has_cdclk_squash = 1, \
725 .has_ddi = 1, \
726 .has_dp_mst = 1, \
727 .has_dsb = 1, \
728 .has_fpga_dbg = 1, \
729 .has_hotplug = 1, \
730 .has_ipc = 1, \
731 .has_psr = 1, \
732 .pipe_offsets = { \
733 [TRANSCODER_A] = PIPE_A_OFFSET, \
734 [TRANSCODER_B] = PIPE_B_OFFSET, \
735 [TRANSCODER_C] = PIPE_C_OFFSET, \
736 [TRANSCODER_D] = PIPE_D_OFFSET, \
737 }, \
738 .trans_offsets = { \
739 [TRANSCODER_A] = TRANSCODER_A_OFFSET, \
740 [TRANSCODER_B] = TRANSCODER_B_OFFSET, \
741 [TRANSCODER_C] = TRANSCODER_C_OFFSET, \
742 [TRANSCODER_D] = TRANSCODER_D_OFFSET, \
743 }, \
744 TGL_CURSOR_OFFSETS, \
745 \
746 .__runtime_defaults.cpu_transcoder_mask = \
747 BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | \
748 BIT(TRANSCODER_C) | BIT(TRANSCODER_D), \
749 .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B), \
750 .__runtime_defaults.has_dmc = 1, \
751 .__runtime_defaults.has_dsc = 1, \
752 .__runtime_defaults.has_hdcp = 1, \
753 .__runtime_defaults.pipe_mask = \
754 BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D), \
755 .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) | \
756 BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4)
757
713static const struct intel_display_device_info xe_lpdp_display = {758static const struct intel_display_device_info xe_lpdp_display = {
714 XE_LPD_FEATURES,759 XE_LPDP_FEATURES,
715 .has_cdclk_crawl = 1,760};
716 .has_cdclk_squash = 1,
717 761
718 .__runtime_defaults.ip.ver = 14,762static const struct intel_display_device_info xe2_lpd_display = {
719 .__runtime_defaults.fbc_mask = BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B),763 XE_LPDP_FEATURES,
720 .__runtime_defaults.cpu_transcoder_mask =764
721 BIT(TRANSCODER_A) | BIT(TRANSCODER_B) |765 .__runtime_defaults.fbc_mask =
722 BIT(TRANSCODER_C) | BIT(TRANSCODER_D),766 BIT(INTEL_FBC_A) | BIT(INTEL_FBC_B) |
723 .__runtime_defaults.port_mask = BIT(PORT_A) | BIT(PORT_B) |767 BIT(INTEL_FBC_C) | BIT(INTEL_FBC_D),
724 BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
725};768};
726 769
727/*770/*
@@ -803,6 +846,7 @@ static const struct { · 75 unmodified lines
803 const struct intel_display_device_info *display;846 const struct intel_display_device_info *display;
804} gmdid_display_map[] = {847} gmdid_display_map[] = {
805 { 14, 0, &xe_lpdp_display },848 { 14, 0, &xe_lpdp_display },
849 { 20, 0, &xe2_lpd_display },
806};850};
807 851
808static const struct intel_display_device_info *852static const struct intel_display_device_info *
@@ -850,16 +894,12 @@ probe_gmdid_display(struct drm_i915_private *i915, u16 *ver, u16 *rel, u16 *step · 41 unmodified lines
850 return &no_display;894 return &no_display;
851}895}
852 896
853const struct intel_display_device_info *897static const struct intel_display_device_info *
854intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid,898probe_display(struct drm_i915_private *i915)
855 u16 *gmdid_ver, u16 *gmdid_rel, u16 *gmdid_step)
856{899{
857 struct pci_dev *pdev = to_pci_dev(i915->drm.dev);900 struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
858 int i;901 int i;
859 902
860 if (has_gmdid)
861 return probe_gmdid_display(i915, gmdid_ver, gmdid_rel, gmdid_step);
862
863 if (has_no_display(pdev)) {903 if (has_no_display(pdev)) {
864 drm_dbg_kms(&i915->drm, "Device doesn't have display\n");904 drm_dbg_kms(&i915->drm, "Device doesn't have display\n");
865 return &no_display;905 return &no_display;
@@ -876,6 +916,29 @@ intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid, · 10 unmodified lines
876 return &no_display;916 return &no_display;
877}917}
878 918
919void intel_display_device_probe(struct drm_i915_private *i915)
920{
921 const struct intel_display_device_info *info;
922 u16 ver, rel, step;
923
924 if (HAS_GMD_ID(i915))
925 info = probe_gmdid_display(i915, &ver, &rel, &step);
926 else
927 info = probe_display(i915);
928
929 i915->display.info.__device_info = info;
930
931 memcpy(DISPLAY_RUNTIME_INFO(i915),
932 &DISPLAY_INFO(i915)->__runtime_defaults,
933 sizeof(*DISPLAY_RUNTIME_INFO(i915)));
934
935 if (HAS_GMD_ID(i915)) {
936 DISPLAY_RUNTIME_INFO(i915)->ip.ver = ver;
937 DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
938 DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
939 }
940}
941
879void intel_display_device_info_runtime_init(struct drm_i915_private *i915)942void intel_display_device_info_runtime_init(struct drm_i915_private *i915)
880{943{
881 struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);944 struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(i915);
@@ -970,16 +1033,19 @@ void intel_display_device_info_runtime_init(struct drm_i915_private *i915) · 88 unmodified lines
970 if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {1033 if (dfsm & SKL_DFSM_PIPE_B_DISABLE) {
971 display_runtime->pipe_mask &= ~BIT(PIPE_B);1034 display_runtime->pipe_mask &= ~BIT(PIPE_B);
972 display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);1035 display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_B);
1036 display_runtime->fbc_mask &= ~BIT(INTEL_FBC_B);
973 }1037 }
974 if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {1038 if (dfsm & SKL_DFSM_PIPE_C_DISABLE) {
975 display_runtime->pipe_mask &= ~BIT(PIPE_C);1039 display_runtime->pipe_mask &= ~BIT(PIPE_C);
976 display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);1040 display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_C);
1041 display_runtime->fbc_mask &= ~BIT(INTEL_FBC_C);
977 }1042 }
978 1043
979 if (DISPLAY_VER(i915) >= 12 &&1044 if (DISPLAY_VER(i915) >= 12 &&
980 (dfsm & TGL_DFSM_PIPE_D_DISABLE)) {1045 (dfsm & TGL_DFSM_PIPE_D_DISABLE)) {
981 display_runtime->pipe_mask &= ~BIT(PIPE_D);1046 display_runtime->pipe_mask &= ~BIT(PIPE_D);
982 display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);1047 display_runtime->cpu_transcoder_mask &= ~BIT(TRANSCODER_D);
1048 display_runtime->fbc_mask &= ~BIT(INTEL_FBC_D);
983 }1049 }
984 1050
985 if (!display_runtime->pipe_mask)1051 if (!display_runtime->pipe_mask)
drivers/gpu/drm/i915/display/intel_display_device.h+28−3
@@ -32,6 +32,7 @@ struct drm_printer; · 31 unmodified lines
32 func(overlay_needs_physical); \32 func(overlay_needs_physical); \
33 func(supports_tv);33 func(supports_tv);
34 34
35#define HAS_4TILE(i915) (IS_DG2(i915) || DISPLAY_VER(i915) >= 14)
35#define HAS_ASYNC_FLIPS(i915) (DISPLAY_VER(i915) >= 5)36#define HAS_ASYNC_FLIPS(i915) (DISPLAY_VER(i915) >= 5)
36#define HAS_CDCLK_CRAWL(i915) (DISPLAY_INFO(i915)->has_cdclk_crawl)37#define HAS_CDCLK_CRAWL(i915) (DISPLAY_INFO(i915)->has_cdclk_crawl)
37#define HAS_CDCLK_SQUASH(i915) (DISPLAY_INFO(i915)->has_cdclk_squash)38#define HAS_CDCLK_SQUASH(i915) (DISPLAY_INFO(i915)->has_cdclk_squash)
@@ -55,6 +56,7 @@ struct drm_printer; · 17 unmodified lines
55#define HAS_HW_SAGV_WM(i915) (DISPLAY_VER(i915) >= 13 && !IS_DGFX(i915))56#define HAS_HW_SAGV_WM(i915) (DISPLAY_VER(i915) >= 13 && !IS_DGFX(i915))
56#define HAS_IPC(i915) (DISPLAY_INFO(i915)->has_ipc)57#define HAS_IPC(i915) (DISPLAY_INFO(i915)->has_ipc)
57#define HAS_IPS(i915) (IS_HASWELL_ULT(i915) || IS_BROADWELL(i915))58#define HAS_IPS(i915) (IS_HASWELL_ULT(i915) || IS_BROADWELL(i915))
59#define HAS_LRR(i915) (DISPLAY_VER(i915) >= 12)
58#define HAS_LSPCON(i915) (IS_DISPLAY_VER(i915, 9, 10))60#define HAS_LSPCON(i915) (IS_DISPLAY_VER(i915, 9, 10))
59#define HAS_MBUS_JOINING(i915) (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)61#define HAS_MBUS_JOINING(i915) (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14)
60#define HAS_MSO(i915) (DISPLAY_VER(i915) >= 12)62#define HAS_MSO(i915) (DISPLAY_VER(i915) >= 12)
@@ -71,6 +73,31 @@ struct drm_printer; · 10 unmodified lines
71#define OVERLAY_NEEDS_PHYSICAL(i915) (DISPLAY_INFO(i915)->overlay_needs_physical)73#define OVERLAY_NEEDS_PHYSICAL(i915) (DISPLAY_INFO(i915)->overlay_needs_physical)
72#define SUPPORTS_TV(i915) (DISPLAY_INFO(i915)->supports_tv)74#define SUPPORTS_TV(i915) (DISPLAY_INFO(i915)->supports_tv)
73 75
76/* Check that device has a display IP version within the specific range. */
77#define IS_DISPLAY_IP_RANGE(__i915, from, until) ( \
78 BUILD_BUG_ON_ZERO((from) < IP_VER(2, 0)) + \
79 (DISPLAY_VER_FULL(__i915) >= (from) && \
80 DISPLAY_VER_FULL(__i915) <= (until)))
81
82/*
83 * Check if a device has a specific IP version as well as a stepping within the
84 * specified range [from, until). The lower bound is inclusive, the upper
85 * bound is exclusive. The most common use-case of this macro is for checking
86 * bounds for workarounds, which usually have a stepping ("from") at which the
87 * hardware issue is first present and another stepping ("until") at which a
88 * hardware fix is present and the software workaround is no longer necessary.
89 * E.g.,
90 *
91 * IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_B2)
92 * IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_C0, STEP_FOREVER)
93 *
94 * "STEP_FOREVER" can be passed as "until" for workarounds that have no upper
95 * stepping bound for the specified IP version.
96 */
97#define IS_DISPLAY_IP_STEP(__i915, ipver, from, until) \
98 (IS_DISPLAY_IP_RANGE((__i915), (ipver), (ipver)) && \
99 IS_DISPLAY_STEP((__i915), (from), (until)))
100
74struct intel_display_runtime_info {101struct intel_display_runtime_info {
75 struct {102 struct {
76 u16 ver;103 u16 ver;
@@ -123,9 +150,7 @@ struct intel_display_device_info { · 46 unmodified lines
123 } color;150 } color;
124};151};
125 152
126const struct intel_display_device_info *153void intel_display_device_probe(struct drm_i915_private *i915);
127intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid,
128 u16 *ver, u16 *rel, u16 *step);
129void intel_display_device_info_runtime_init(struct drm_i915_private *i915);154void intel_display_device_info_runtime_init(struct drm_i915_private *i915);
130 155
131void intel_display_device_info_print(const struct intel_display_device_info *info,156void intel_display_device_info_print(const struct intel_display_device_info *info,
drivers/gpu/drm/i915/display/intel_display_driver.c+8−0
@@ -31,6 +31,7 @@ · 30 unmodified lines
31#include "intel_display_irq.h"31#include "intel_display_irq.h"
32#include "intel_display_power.h"32#include "intel_display_power.h"
33#include "intel_display_types.h"33#include "intel_display_types.h"
34#include "intel_display_wa.h"
34#include "intel_dkl_phy.h"35#include "intel_dkl_phy.h"
35#include "intel_dmc.h"36#include "intel_dmc.h"
36#include "intel_dp.h"37#include "intel_dp.h"
@@ -88,6 +89,8 @@ void intel_display_driver_init_hw(struct drm_i915_private *i915) · 51 unmodified lines
88 intel_update_cdclk(i915);89 intel_update_cdclk(i915);
89 intel_cdclk_dump_config(i915, &i915->display.cdclk.hw, "Current CDCLK");90 intel_cdclk_dump_config(i915, &i915->display.cdclk.hw, "Current CDCLK");
90 cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw;91 cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw;
92
93 intel_display_wa_apply(i915);
91}94}
92 95
93static const struct drm_mode_config_funcs intel_mode_funcs = {96static const struct drm_mode_config_funcs intel_mode_funcs = {
@@ -377,6 +380,8 @@ int intel_display_driver_probe(struct drm_i915_private *i915) · 283 unmodified lines
377 380
378void intel_display_driver_register(struct drm_i915_private *i915)381void intel_display_driver_register(struct drm_i915_private *i915)
379{382{
383 struct drm_printer p = drm_debug_printer("i915 display info:");
384
380 if (!HAS_DISPLAY(i915))385 if (!HAS_DISPLAY(i915))
381 return;386 return;
382 387
@@ -404,6 +409,9 @@ void intel_display_driver_register(struct drm_i915_private *i915) · 21 unmodified lines
404 * fbdev->async_cookie.409 * fbdev->async_cookie.
405 */410 */
406 drm_kms_helper_poll_init(&i915->drm);411 drm_kms_helper_poll_init(&i915->drm);
412
413 intel_display_device_info_print(DISPLAY_INFO(i915),
414 DISPLAY_RUNTIME_INFO(i915), &p);
407}415}
408 416
409/* part #1: call before irq uninstall */417/* part #1: call before irq uninstall */
drivers/gpu/drm/i915/display/intel_display_irq.c+3−1
@@ -792,7 +792,9 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) · 791 unmodified lines
792{792{
793 u32 mask;793 u32 mask;
794 794
795 if (DISPLAY_VER(dev_priv) >= 14)795 if (DISPLAY_VER(dev_priv) >= 20)
796 return 0;
797 else if (DISPLAY_VER(dev_priv) >= 14)
796 return TGL_DE_PORT_AUX_DDIA |798 return TGL_DE_PORT_AUX_DDIA |
797 TGL_DE_PORT_AUX_DDIB;799 TGL_DE_PORT_AUX_DDIB;
798 else if (DISPLAY_VER(dev_priv) >= 13)800 else if (DISPLAY_VER(dev_priv) >= 13)
drivers/gpu/drm/i915/display/intel_display_power.c+4−6
@@ -186,8 +186,6 @@ intel_display_power_domain_str(enum intel_display_power_domain domain) · 185 unmodified lines
186 return "GMBUS";186 return "GMBUS";
187 case POWER_DOMAIN_INIT:187 case POWER_DOMAIN_INIT:
188 return "INIT";188 return "INIT";
189 case POWER_DOMAIN_MODESET:
190 return "MODESET";
191 case POWER_DOMAIN_GT_IRQ:189 case POWER_DOMAIN_GT_IRQ:
192 return "GT_IRQ";190 return "GT_IRQ";
193 case POWER_DOMAIN_DC_OFF:191 case POWER_DOMAIN_DC_OFF:
@@ -218,7 +216,7 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, · 24 unmodified lines
218 struct i915_power_well *power_well;216 struct i915_power_well *power_well;
219 bool is_enabled;217 bool is_enabled;
220 218
221 if (dev_priv->runtime_pm.suspended)219 if (pm_runtime_suspended(dev_priv->drm.dev))
222 return false;220 return false;
223 221
224 is_enabled = true;222 is_enabled = true;
@@ -338,8 +336,6 @@ unlock: · 113 unmodified lines
338 mutex_unlock(&power_domains->lock);336 mutex_unlock(&power_domains->lock);
339}337}
340 338
341#define POWER_DOMAIN_MASK (GENMASK_ULL(POWER_DOMAIN_NUM - 1, 0))
342
343static void __async_put_domains_mask(struct i915_power_domains *power_domains,339static void __async_put_domains_mask(struct i915_power_domains *power_domains,
344 struct intel_power_domain_mask *mask)340 struct intel_power_domain_mask *mask)
345{341{
@@ -947,7 +943,9 @@ static u32 get_allowed_dc_mask(const struct drm_i915_private *dev_priv, · 601 unmodified lines
947 if (!HAS_DISPLAY(dev_priv))943 if (!HAS_DISPLAY(dev_priv))
948 return 0;944 return 0;
949 945
950 if (IS_DG2(dev_priv))946 if (DISPLAY_VER(dev_priv) >= 20)
947 max_dc = 2;
948 else if (IS_DG2(dev_priv))
951 max_dc = 1;949 max_dc = 1;
952 else if (IS_DG1(dev_priv))950 else if (IS_DG1(dev_priv))
953 max_dc = 3;951 max_dc = 3;
drivers/gpu/drm/i915/display/intel_display_power.h+0−1
@@ -108,7 +108,6 @@ enum intel_display_power_domain { · 107 unmodified lines
108 POWER_DOMAIN_AUX_TBT6,108 POWER_DOMAIN_AUX_TBT6,
109 109
110 POWER_DOMAIN_GMBUS,110 POWER_DOMAIN_GMBUS,
111 POWER_DOMAIN_MODESET,
112 POWER_DOMAIN_GT_IRQ,111 POWER_DOMAIN_GT_IRQ,
113 POWER_DOMAIN_DC_OFF,112 POWER_DOMAIN_DC_OFF,
114 POWER_DOMAIN_TC_COLD_OFF,113 POWER_DOMAIN_TC_COLD_OFF,
drivers/gpu/drm/i915/display/intel_display_power_map.c+53−10
@@ -332,7 +332,6 @@ I915_DECL_PW_DOMAINS(skl_pwdoms_pw_2, · 331 unmodified lines
332I915_DECL_PW_DOMAINS(skl_pwdoms_dc_off,332I915_DECL_PW_DOMAINS(skl_pwdoms_dc_off,
333 SKL_PW_2_POWER_DOMAINS,333 SKL_PW_2_POWER_DOMAINS,
334 POWER_DOMAIN_AUX_A,334 POWER_DOMAIN_AUX_A,
335 POWER_DOMAIN_MODESET,
336 POWER_DOMAIN_GT_IRQ,335 POWER_DOMAIN_GT_IRQ,
337 POWER_DOMAIN_DC_OFF,336 POWER_DOMAIN_DC_OFF,
338 POWER_DOMAIN_INIT);337 POWER_DOMAIN_INIT);
@@ -437,7 +436,6 @@ I915_DECL_PW_DOMAINS(bxt_pwdoms_dc_off, · 98 unmodified lines
437 BXT_PW_2_POWER_DOMAINS,436 BXT_PW_2_POWER_DOMAINS,
438 POWER_DOMAIN_AUX_A,437 POWER_DOMAIN_AUX_A,
439 POWER_DOMAIN_GMBUS,438 POWER_DOMAIN_GMBUS,
440 POWER_DOMAIN_MODESET,
441 POWER_DOMAIN_GT_IRQ,439 POWER_DOMAIN_GT_IRQ,
442 POWER_DOMAIN_DC_OFF,440 POWER_DOMAIN_DC_OFF,
443 POWER_DOMAIN_INIT);441 POWER_DOMAIN_INIT);
@@ -519,7 +517,6 @@ I915_DECL_PW_DOMAINS(glk_pwdoms_dc_off, · 75 unmodified lines
519 GLK_PW_2_POWER_DOMAINS,517 GLK_PW_2_POWER_DOMAINS,
520 POWER_DOMAIN_AUX_A,518 POWER_DOMAIN_AUX_A,
521 POWER_DOMAIN_GMBUS,519 POWER_DOMAIN_GMBUS,
522 POWER_DOMAIN_MODESET,
523 POWER_DOMAIN_GT_IRQ,520 POWER_DOMAIN_GT_IRQ,
524 POWER_DOMAIN_DC_OFF,521 POWER_DOMAIN_DC_OFF,
525 POWER_DOMAIN_INIT);522 POWER_DOMAIN_INIT);
@@ -685,7 +682,6 @@ I915_DECL_PW_DOMAINS(icl_pwdoms_pw_2, · 159 unmodified lines
685I915_DECL_PW_DOMAINS(icl_pwdoms_dc_off,682I915_DECL_PW_DOMAINS(icl_pwdoms_dc_off,
686 ICL_PW_2_POWER_DOMAINS,683 ICL_PW_2_POWER_DOMAINS,
687 POWER_DOMAIN_AUX_A,684 POWER_DOMAIN_AUX_A,
688 POWER_DOMAIN_MODESET,
689 POWER_DOMAIN_DC_OFF,685 POWER_DOMAIN_DC_OFF,
690 POWER_DOMAIN_INIT);686 POWER_DOMAIN_INIT);
691 687
@@ -861,7 +857,6 @@ I915_DECL_PW_DOMAINS(tgl_pwdoms_dc_off, · 169 unmodified lines
861 POWER_DOMAIN_AUX_A,857 POWER_DOMAIN_AUX_A,
862 POWER_DOMAIN_AUX_B,858 POWER_DOMAIN_AUX_B,
863 POWER_DOMAIN_AUX_C,859 POWER_DOMAIN_AUX_C,
864 POWER_DOMAIN_MODESET,
865 POWER_DOMAIN_DC_OFF,860 POWER_DOMAIN_DC_OFF,
866 POWER_DOMAIN_INIT);861 POWER_DOMAIN_INIT);
867 862
@@ -1058,7 +1053,6 @@ I915_DECL_PW_DOMAINS(rkl_pwdoms_dc_off, · 190 unmodified lines
1058 RKL_PW_3_POWER_DOMAINS,1053 RKL_PW_3_POWER_DOMAINS,
1059 POWER_DOMAIN_AUX_A,1054 POWER_DOMAIN_AUX_A,
1060 POWER_DOMAIN_AUX_B,1055 POWER_DOMAIN_AUX_B,
1061 POWER_DOMAIN_MODESET,
1062 POWER_DOMAIN_DC_OFF,1056 POWER_DOMAIN_DC_OFF,
1063 POWER_DOMAIN_INIT);1057 POWER_DOMAIN_INIT);
1064 1058
@@ -1141,7 +1135,6 @@ I915_DECL_PW_DOMAINS(dg1_pwdoms_dc_off, · 76 unmodified lines
1141 POWER_DOMAIN_AUDIO_MMIO,1135 POWER_DOMAIN_AUDIO_MMIO,
1142 POWER_DOMAIN_AUX_A,1136 POWER_DOMAIN_AUX_A,
1143 POWER_DOMAIN_AUX_B,1137 POWER_DOMAIN_AUX_B,
1144 POWER_DOMAIN_MODESET,
1145 POWER_DOMAIN_DC_OFF,1138 POWER_DOMAIN_DC_OFF,
1146 POWER_DOMAIN_INIT);1139 POWER_DOMAIN_INIT);
1147 1140
@@ -1311,7 +1304,6 @@ I915_DECL_PW_DOMAINS(xelpd_pwdoms_dc_off, · 163 unmodified lines
1311 POWER_DOMAIN_AUDIO_MMIO,1304 POWER_DOMAIN_AUDIO_MMIO,
1312 POWER_DOMAIN_AUX_A,1305 POWER_DOMAIN_AUX_A,
1313 POWER_DOMAIN_AUX_B,1306 POWER_DOMAIN_AUX_B,
1314 POWER_DOMAIN_MODESET,
1315 POWER_DOMAIN_DC_OFF,1307 POWER_DOMAIN_DC_OFF,
1316 POWER_DOMAIN_INIT);1308 POWER_DOMAIN_INIT);
1317 1309
@@ -1426,7 +1418,6 @@ I915_DECL_PW_DOMAINS(xehpd_pwdoms_dc_off, · 108 unmodified lines
1426 POWER_DOMAIN_AUDIO_MMIO,1418 POWER_DOMAIN_AUDIO_MMIO,
1427 POWER_DOMAIN_AUX_A,1419 POWER_DOMAIN_AUX_A,
1428 POWER_DOMAIN_AUX_B,1420 POWER_DOMAIN_AUX_B,
1429 POWER_DOMAIN_MODESET,
1430 POWER_DOMAIN_DC_OFF,1421 POWER_DOMAIN_DC_OFF,
1431 POWER_DOMAIN_INIT);1422 POWER_DOMAIN_INIT);
1432 1423
@@ -1545,6 +1536,56 @@ static const struct i915_power_well_desc_list xelpdp_power_wells[] = { · 112 unmodified lines
1545 I915_PW_DESCRIPTORS(xelpdp_power_wells_main),1536 I915_PW_DESCRIPTORS(xelpdp_power_wells_main),
1546};1537};
1547 1538
1539I915_DECL_PW_DOMAINS(xe2lpd_pwdoms_pica_tc,
1540 POWER_DOMAIN_PORT_DDI_LANES_TC1,
1541 POWER_DOMAIN_PORT_DDI_LANES_TC2,
1542 POWER_DOMAIN_PORT_DDI_LANES_TC3,
1543 POWER_DOMAIN_PORT_DDI_LANES_TC4,
1544 POWER_DOMAIN_AUX_USBC1,
1545 POWER_DOMAIN_AUX_USBC2,
1546 POWER_DOMAIN_AUX_USBC3,
1547 POWER_DOMAIN_AUX_USBC4,
1548 POWER_DOMAIN_AUX_TBT1,
1549 POWER_DOMAIN_AUX_TBT2,
1550 POWER_DOMAIN_AUX_TBT3,
1551 POWER_DOMAIN_AUX_TBT4,
1552 POWER_DOMAIN_INIT);
1553
1554static const struct i915_power_well_desc xe2lpd_power_wells_pica[] = {
1555 {
1556 .instances = &I915_PW_INSTANCES(I915_PW("PICA_TC",
1557 &xe2lpd_pwdoms_pica_tc,
1558 .id = DISP_PW_ID_NONE),
1559 ),
1560 .ops = &xe2lpd_pica_power_well_ops,
1561 },
1562};
1563
1564I915_DECL_PW_DOMAINS(xe2lpd_pwdoms_dc_off,
1565 POWER_DOMAIN_DC_OFF,
1566 XELPD_PW_C_POWER_DOMAINS,
1567 XELPD_PW_D_POWER_DOMAINS,
1568 POWER_DOMAIN_AUDIO_MMIO,
1569 POWER_DOMAIN_INIT);
1570
1571static const struct i915_power_well_desc xe2lpd_power_wells_dcoff[] = {
1572 {
1573 .instances = &I915_PW_INSTANCES(
1574 I915_PW("DC_off", &xe2lpd_pwdoms_dc_off,
1575 .id = SKL_DISP_DC_OFF),
1576 ),
1577 .ops = &gen9_dc_off_power_well_ops,
1578 },
1579};
1580
1581static const struct i915_power_well_desc_list xe2lpd_power_wells[] = {
1582 I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
1583 I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
1584 I915_PW_DESCRIPTORS(xe2lpd_power_wells_dcoff),
1585 I915_PW_DESCRIPTORS(xelpdp_power_wells_main),
1586 I915_PW_DESCRIPTORS(xe2lpd_power_wells_pica),
1587};
1588
1548static void init_power_well_domains(const struct i915_power_well_instance *inst,1589static void init_power_well_domains(const struct i915_power_well_instance *inst,
1549 struct i915_power_well *power_well)1590 struct i915_power_well *power_well)
1550{1591{
@@ -1652,7 +1693,9 @@ int intel_display_power_map_init(struct i915_power_domains *power_domains) · 101 unmodified lines
1652 return 0;1693 return 0;
1653 }1694 }
1654 1695
1655 if (DISPLAY_VER(i915) >= 14)1696 if (DISPLAY_VER(i915) >= 20)
1697 return set_power_wells(power_domains, xe2lpd_power_wells);
1698 else if (DISPLAY_VER(i915) >= 14)
1656 return set_power_wells(power_domains, xelpdp_power_wells);1699 return set_power_wells(power_domains, xelpdp_power_wells);
1657 else if (IS_DG2(i915))1700 else if (IS_DG2(i915))
1658 return set_power_wells(power_domains, xehpd_power_wells);1701 return set_power_wells(power_domains, xehpd_power_wells);
drivers/gpu/drm/i915/display/intel_display_power_well.c+49−3
@@ -1794,8 +1794,13 @@ static void xelpdp_aux_power_well_enable(struct drm_i915_private *dev_priv, · 1793 unmodified lines
1794 struct i915_power_well *power_well)1794 struct i915_power_well *power_well)
1795{1795{
1796 enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;1796 enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
1797 enum phy phy = icl_aux_pw_to_phy(dev_priv, power_well);
1798
1799 if (intel_phy_is_tc(dev_priv, phy))
1800 icl_tc_port_assert_ref_held(dev_priv, power_well,
1801 aux_ch_to_digital_port(dev_priv, aux_ch));
1797 1802
1798 intel_de_rmw(dev_priv, XELPDP_DP_AUX_CH_CTL(aux_ch),1803 intel_de_rmw(dev_priv, XELPDP_DP_AUX_CH_CTL(dev_priv, aux_ch),
1799 XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,1804 XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
1800 XELPDP_DP_AUX_CH_CTL_POWER_REQUEST);1805 XELPDP_DP_AUX_CH_CTL_POWER_REQUEST);
1801 1806
@@ -1813,7 +1818,7 @@ static void xelpdp_aux_power_well_disable(struct drm_i915_private *dev_priv, · 11 unmodified lines
1813{1818{
1814 enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;1819 enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
1815 1820
1816 intel_de_rmw(dev_priv, XELPDP_DP_AUX_CH_CTL(aux_ch),1821 intel_de_rmw(dev_priv, XELPDP_DP_AUX_CH_CTL(dev_priv, aux_ch),
1817 XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,1822 XELPDP_DP_AUX_CH_CTL_POWER_REQUEST,
1818 0);1823 0);
1819 usleep_range(10, 30);1824 usleep_range(10, 30);
@@ -1824,10 +1829,44 @@ static bool xelpdp_aux_power_well_enabled(struct drm_i915_private *dev_priv, · 4 unmodified lines
1824{1829{
1825 enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;1830 enum aux_ch aux_ch = i915_power_well_instance(power_well)->xelpdp.aux_ch;
1826 1831
1827 return intel_de_read(dev_priv, XELPDP_DP_AUX_CH_CTL(aux_ch)) &1832 return intel_de_read(dev_priv, XELPDP_DP_AUX_CH_CTL(dev_priv, aux_ch)) &
1828 XELPDP_DP_AUX_CH_CTL_POWER_STATUS;1833 XELPDP_DP_AUX_CH_CTL_POWER_STATUS;
1829}1834}
1830 1835
1836static void xe2lpd_pica_power_well_enable(struct drm_i915_private *dev_priv,
1837 struct i915_power_well *power_well)
1838{
1839 intel_de_write(dev_priv, XE2LPD_PICA_PW_CTL,
1840 XE2LPD_PICA_CTL_POWER_REQUEST);
1841
1842 if (intel_de_wait_for_set(dev_priv, XE2LPD_PICA_PW_CTL,
1843 XE2LPD_PICA_CTL_POWER_STATUS, 1)) {
1844 drm_dbg_kms(&dev_priv->drm, "pica power well enable timeout\n");
1845
1846 drm_WARN(&dev_priv->drm, 1, "Power well PICA timeout when enabled");
1847 }
1848}
1849
1850static void xe2lpd_pica_power_well_disable(struct drm_i915_private *dev_priv,
1851 struct i915_power_well *power_well)
1852{
1853 intel_de_write(dev_priv, XE2LPD_PICA_PW_CTL, 0);
1854
1855 if (intel_de_wait_for_clear(dev_priv, XE2LPD_PICA_PW_CTL,
1856 XE2LPD_PICA_CTL_POWER_STATUS, 1)) {
1857 drm_dbg_kms(&dev_priv->drm, "pica power well disable timeout\n");
1858
1859 drm_WARN(&dev_priv->drm, 1, "Power well PICA timeout when disabled");
1860 }
1861}
1862
1863static bool xe2lpd_pica_power_well_enabled(struct drm_i915_private *dev_priv,
1864 struct i915_power_well *power_well)
1865{
1866 return intel_de_read(dev_priv, XE2LPD_PICA_PW_CTL) &
1867 XE2LPD_PICA_CTL_POWER_STATUS;
1868}
1869
1831const struct i915_power_well_ops i9xx_always_on_power_well_ops = {1870const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
1832 .sync_hw = i9xx_power_well_sync_hw_noop,1871 .sync_hw = i9xx_power_well_sync_hw_noop,
1833 .enable = i9xx_always_on_power_well_noop,1872 .enable = i9xx_always_on_power_well_noop,
@@ -1947,3 +1986,10 @@ const struct i915_power_well_ops xelpdp_aux_power_well_ops = { · 113 unmodified lines
1947 .disable = xelpdp_aux_power_well_disable,1986 .disable = xelpdp_aux_power_well_disable,
1948 .is_enabled = xelpdp_aux_power_well_enabled,1987 .is_enabled = xelpdp_aux_power_well_enabled,
1949};1988};
1989
1990const struct i915_power_well_ops xe2lpd_pica_power_well_ops = {
1991 .sync_hw = i9xx_power_well_sync_hw_noop,
1992 .enable = xe2lpd_pica_power_well_enable,
1993 .disable = xe2lpd_pica_power_well_disable,
1994 .is_enabled = xe2lpd_pica_power_well_enabled,
1995};
drivers/gpu/drm/i915/display/intel_display_power_well.h+1−0
@@ -176,5 +176,6 @@ extern const struct i915_power_well_ops icl_aux_power_well_ops; · 175 unmodified lines
176extern const struct i915_power_well_ops icl_ddi_power_well_ops;176extern const struct i915_power_well_ops icl_ddi_power_well_ops;
177extern const struct i915_power_well_ops tgl_tc_cold_off_ops;177extern const struct i915_power_well_ops tgl_tc_cold_off_ops;
178extern const struct i915_power_well_ops xelpdp_aux_power_well_ops;178extern const struct i915_power_well_ops xelpdp_aux_power_well_ops;
179extern const struct i915_power_well_ops xe2lpd_pica_power_well_ops;
179 180
180#endif181#endif
drivers/gpu/drm/i915/display/intel_display_types.h+40−9
@@ -500,15 +500,15 @@ struct intel_hdcp_shim { · 499 unmodified lines
500 enum hdcp_wired_protocol protocol;500 enum hdcp_wired_protocol protocol;
501 501
502 /* Detects whether sink is HDCP2.2 capable */502 /* Detects whether sink is HDCP2.2 capable */
503 int (*hdcp_2_2_capable)(struct intel_digital_port *dig_port,503 int (*hdcp_2_2_capable)(struct intel_connector *connector,
504 bool *capable);504 bool *capable);
505 505
506 /* Write HDCP2.2 messages */506 /* Write HDCP2.2 messages */
507 int (*write_2_2_msg)(struct intel_digital_port *dig_port,507 int (*write_2_2_msg)(struct intel_connector *connector,
508 void *buf, size_t size);508 void *buf, size_t size);
509 509
510 /* Read HDCP2.2 messages */510 /* Read HDCP2.2 messages */
511 int (*read_2_2_msg)(struct intel_digital_port *dig_port,511 int (*read_2_2_msg)(struct intel_connector *connector,
512 u8 msg_id, void *buf, size_t size);512 u8 msg_id, void *buf, size_t size);
513 513
514 /*514 /*
@@ -516,7 +516,7 @@ struct intel_hdcp_shim { · 1 unmodified line
516 * type to Receivers. In DP HDCP2.2 Stream type is one of the input to516 * type to Receivers. In DP HDCP2.2 Stream type is one of the input to
517 * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI.517 * the HDCP2.2 Cipher for En/De-Cryption. Not applicable for HDMI.
518 */518 */
519 int (*config_stream_type)(struct intel_digital_port *dig_port,519 int (*config_stream_type)(struct intel_connector *connector,
520 bool is_repeater, u8 type);520 bool is_repeater, u8 type);
521 521
522 /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */522 /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */
@@ -1083,6 +1083,8 @@ struct intel_crtc_state { · 560 unmodified lines
1083 1083
1084 unsigned fb_bits; /* framebuffers to flip */1084 unsigned fb_bits; /* framebuffers to flip */
1085 bool update_pipe; /* can a fast modeset be performed? */1085 bool update_pipe; /* can a fast modeset be performed? */
1086 bool update_m_n; /* update M/N seamlessly during fastset? */
1087 bool update_lrr; /* update TRANS_VTOTAL/etc. during fastset? */
1086 bool disable_cxsr;1088 bool disable_cxsr;
1087 bool update_wm_pre, update_wm_post; /* watermarks are updated */1089 bool update_wm_pre, update_wm_post; /* watermarks are updated */
1088 bool fifo_changed; /* FIFO split is changed */1090 bool fifo_changed; /* FIFO split is changed */
@@ -1189,13 +1191,13 @@ struct intel_crtc_state { · 100 unmodified lines
1189 u32 ctrl, div;1191 u32 ctrl, div;
1190 } dsi_pll;1192 } dsi_pll;
1191 1193
1192 int pipe_bpp;1194 int max_link_bpp_x16; /* in 1/16 bpp units */
1195 int pipe_bpp; /* in 1 bpp units */
1193 struct intel_link_m_n dp_m_n;1196 struct intel_link_m_n dp_m_n;
1194 1197
1195 /* m2_n2 for eDP downclock */1198 /* m2_n2 for eDP downclock */
1196 struct intel_link_m_n dp_m2_n2;1199 struct intel_link_m_n dp_m2_n2;
1197 bool has_drrs;1200 bool has_drrs;
1198 bool seamless_m_n;
1199 1201
1200 /* PSR is supported but might not be enabled due the lack of enabled planes */1202 /* PSR is supported but might not be enabled due the lack of enabled planes */
1201 bool has_psr;1203 bool has_psr;
@@ -1362,7 +1364,14 @@ struct intel_crtc_state { · 160 unmodified lines
1362 u16 linetime;1364 u16 linetime;
1363 u16 ips_linetime;1365 u16 ips_linetime;
1364 1366
1365 /* Forward Error correction State */1367 bool enhanced_framing;
1368
1369 /*
1370 * Forward Error Correction.
1371 *
1372 * Note: This will be false for 128b/132b, which will always have FEC
1373 * enabled automatically.
1374 */
1366 bool fec_enable;1375 bool fec_enable;
1367 1376
1368 bool sdp_split_enable;1377 bool sdp_split_enable;
@@ -1383,7 +1392,7 @@ struct intel_crtc_state { · 14 unmodified lines
1383 1392
1384 /* Variable Refresh Rate state */1393 /* Variable Refresh Rate state */
1385 struct {1394 struct {
1386 bool enable;1395 bool enable, in_range;
1387 u8 pipeline_full;1396 u8 pipeline_full;
1388 u16 flipline, vmin, vmax, guardband;1397 u16 flipline, vmin, vmax, guardband;
1389 } vrr;1398 } vrr;
@@ -1581,7 +1590,6 @@ struct intel_watermark_params { · 191 unmodified lines
1581 1590
1582struct intel_hdmi {1591struct intel_hdmi {
1583 i915_reg_t hdmi_reg;1592 i915_reg_t hdmi_reg;
1584 int ddc_bus;
1585 struct {1593 struct {
1586 enum drm_dp_dual_mode_type type;1594 enum drm_dp_dual_mode_type type;
1587 int max_tmds_clock;1595 int max_tmds_clock;
@@ -2108,4 +2116,27 @@ to_intel_frontbuffer(struct drm_framebuffer *fb) · 520 unmodified lines
2108 return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL;2116 return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL;
2109}2117}
2110 2118
2119static inline int to_bpp_int(int bpp_x16)
2120{
2121 return bpp_x16 >> 4;
2122}
2123
2124static inline int to_bpp_frac(int bpp_x16)
2125{
2126 return bpp_x16 & 0xf;
2127}
2128
2129#define BPP_X16_FMT "%d.%04d"
2130#define BPP_X16_ARGS(bpp_x16) to_bpp_int(bpp_x16), (to_bpp_frac(bpp_x16) * 625)
2131
2132static inline int to_bpp_int_roundup(int bpp_x16)
2133{
2134 return (bpp_x16 + 0xf) >> 4;
2135}
2136
2137static inline int to_bpp_x16(int bpp)
2138{
2139 return bpp << 4;
2140}
2141
2111#endif /* __INTEL_DISPLAY_TYPES_H__ */2142#endif /* __INTEL_DISPLAY_TYPES_H__ */
drivers/gpu/drm/i915/display/intel_display_wa.c+48−0
@@ -0,0 +1,48 @@
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#include "i915_drv.h"
7#include "i915_reg.h"
8#include "intel_de.h"
9#include "intel_display_wa.h"
10
11static void gen11_display_wa_apply(struct drm_i915_private *i915)
12{
13 /* Wa_1409120013 */
14 intel_de_write(i915, ILK_DPFC_CHICKEN(INTEL_FBC_A),
15 DPFC_CHICKEN_COMP_DUMMY_PIXEL);
16
17 /* Wa_14010594013 */
18 intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, 0, ICL_DELAY_PMRSP);
19}
20
21static void xe_d_display_wa_apply(struct drm_i915_private *i915)
22{
23 /* Wa_1409120013 */
24 intel_de_write(i915, ILK_DPFC_CHICKEN(INTEL_FBC_A),
25 DPFC_CHICKEN_COMP_DUMMY_PIXEL);
26
27 /* Wa_14013723622 */
28 intel_de_rmw(i915, CLKREQ_POLICY, CLKREQ_POLICY_MEM_UP_OVRD, 0);
29}
30
31static void adlp_display_wa_apply(struct drm_i915_private *i915)
32{
33 /* Wa_22011091694:adlp */
34 intel_de_rmw(i915, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS);
35
36 /* Bspec/49189 Initialize Sequence */
37 intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0);
38}
39
40void intel_display_wa_apply(struct drm_i915_private *i915)
41{
42 if (IS_ALDERLAKE_P(i915))
43 adlp_display_wa_apply(i915);
44 else if (DISPLAY_VER(i915) == 12)
45 xe_d_display_wa_apply(i915);
46 else if (DISPLAY_VER(i915) == 11)
47 gen11_display_wa_apply(i915);
48}
drivers/gpu/drm/i915/display/intel_display_wa.h+13−0
@@ -0,0 +1,13 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#ifndef __INTEL_DISPLAY_WA_H__
7#define __INTEL_DISPLAY_WA_H__
8
9struct drm_i915_private;
10
11void intel_display_wa_apply(struct drm_i915_private *i915);
12
13#endif
drivers/gpu/drm/i915/display/intel_dmc.c+1−1
@@ -998,7 +998,7 @@ void intel_dmc_init(struct drm_i915_private *i915) · 997 unmodified lines
998 998
999 INIT_WORK(&dmc->work, dmc_load_work_fn);999 INIT_WORK(&dmc->work, dmc_load_work_fn);
1000 1000
1001 if (IS_METEORLAKE(i915)) {1001 if (DISPLAY_VER_FULL(i915) == IP_VER(14, 0)) {
1002 dmc->fw_path = MTL_DMC_PATH;1002 dmc->fw_path = MTL_DMC_PATH;
1003 dmc->max_fw_size = XELPDP_DMC_MAX_FW_SIZE;1003 dmc->max_fw_size = XELPDP_DMC_MAX_FW_SIZE;
1004 } else if (IS_DG2(i915)) {1004 } else if (IS_DG2(i915)) {
drivers/gpu/drm/i915/display/intel_dp.c+676−201
@@ -306,13 +306,13 @@ static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp) · 305 unmodified lines
306 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);306 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
307 int source_max = intel_dp_max_source_lane_count(dig_port);307 int source_max = intel_dp_max_source_lane_count(dig_port);
308 int sink_max = intel_dp->max_sink_lane_count;308 int sink_max = intel_dp->max_sink_lane_count;
309 int fia_max = intel_tc_port_fia_max_lane_count(dig_port);309 int lane_max = intel_tc_port_max_lane_count(dig_port);
310 int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);310 int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);
311 311
312 if (lttpr_max)312 if (lttpr_max)
313 sink_max = min(sink_max, lttpr_max);313 sink_max = min(sink_max, lttpr_max);
314 314
315 return min3(source_max, sink_max, fia_max);315 return min3(source_max, sink_max, lane_max);
316}316}
317 317
318int intel_dp_max_lane_count(struct intel_dp *intel_dp)318int intel_dp_max_lane_count(struct intel_dp *intel_dp)
@@ -740,14 +740,41 @@ u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, u32 p · 421 unmodified lines
740 return bits_per_pixel;740 return bits_per_pixel;
741}741}
742 742
743u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,743static
744 u32 link_clock, u32 lane_count,744u32 get_max_compressed_bpp_with_joiner(struct drm_i915_private *i915,
745 u32 mode_clock, u32 mode_hdisplay,745 u32 mode_clock, u32 mode_hdisplay,
746 bool bigjoiner,746 bool bigjoiner)
747 u32 pipe_bpp,747{
748 u32 timeslots)748 u32 max_bpp_small_joiner_ram;
749
750 /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
751 max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) / mode_hdisplay;
752
753 if (bigjoiner) {
754 int bigjoiner_interface_bits = DISPLAY_VER(i915) >= 14 ? 36 : 24;
755 /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */
756 int ppc = 2;
757 u32 max_bpp_bigjoiner =
758 i915->display.cdclk.max_cdclk_freq * ppc * bigjoiner_interface_bits /
759 intel_dp_mode_to_fec_clock(mode_clock);
760
761 max_bpp_small_joiner_ram *= 2;
762
763 return min(max_bpp_small_joiner_ram, max_bpp_bigjoiner);
764 }
765
766 return max_bpp_small_joiner_ram;
767}
768
769u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
770 u32 link_clock, u32 lane_count,
771 u32 mode_clock, u32 mode_hdisplay,
772 bool bigjoiner,
773 enum intel_output_format output_format,
774 u32 pipe_bpp,
775 u32 timeslots)
749{776{
750 u32 bits_per_pixel, max_bpp_small_joiner_ram;777 u32 bits_per_pixel, joiner_max_bpp;
751 778
752 /*779 /*
753 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*780 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
@@ -768,40 +795,32 @@ u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, · 14 unmodified lines
768 bits_per_pixel = ((link_clock * lane_count) * timeslots) /795 bits_per_pixel = ((link_clock * lane_count) * timeslots) /
769 (intel_dp_mode_to_fec_clock(mode_clock) * 8);796 (intel_dp_mode_to_fec_clock(mode_clock) * 8);
770 797
798 /* Bandwidth required for 420 is half, that of 444 format */
799 if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
800 bits_per_pixel *= 2;
801
802 /*
803 * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum
804 * supported PPS value can be 63.9375 and with the further
805 * mention that for 420, 422 formats, bpp should be programmed double
806 * the target bpp restricting our target bpp to be 31.9375 at max.
807 */
808 if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
809 bits_per_pixel = min_t(u32, bits_per_pixel, 31);
810
771 drm_dbg_kms(&i915->drm, "Max link bpp is %u for %u timeslots "811 drm_dbg_kms(&i915->drm, "Max link bpp is %u for %u timeslots "
772 "total bw %u pixel clock %u\n",812 "total bw %u pixel clock %u\n",
773 bits_per_pixel, timeslots,813 bits_per_pixel, timeslots,
774 (link_clock * lane_count * 8),814 (link_clock * lane_count * 8),
775 intel_dp_mode_to_fec_clock(mode_clock));815 intel_dp_mode_to_fec_clock(mode_clock));
776 816
777 /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */817 joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, mode_clock,
778 max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /818 mode_hdisplay, bigjoiner);
779 mode_hdisplay;819 bits_per_pixel = min(bits_per_pixel, joiner_max_bpp);
780
781 if (bigjoiner)
782 max_bpp_small_joiner_ram *= 2;
783
784 /*
785 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
786 * check, output bpp from small joiner RAM check)
787 */
788 bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
789
790 if (bigjoiner) {
791 u32 max_bpp_bigjoiner =
792 i915->display.cdclk.max_cdclk_freq * 48 /
793 intel_dp_mode_to_fec_clock(mode_clock);
794
795 bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
796 }
797 820
798 bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp);821 bits_per_pixel = intel_dp_dsc_nearest_valid_bpp(i915, bits_per_pixel, pipe_bpp);
799 822
800 /*823 return bits_per_pixel;
801 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
802 * fractional part is 0
803 */
804 return bits_per_pixel << 4;
805}824}
806 825
807u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,826u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
@@ -916,16 +935,42 @@ dfp_can_convert_from_ycbcr444(struct intel_dp *intel_dp, · 108 unmodified lines
916 return false;935 return false;
917}936}
918 937
938static bool
939dfp_can_convert(struct intel_dp *intel_dp,
940 enum intel_output_format output_format,
941 enum intel_output_format sink_format)
942{
943 switch (output_format) {
944 case INTEL_OUTPUT_FORMAT_RGB:
945 return dfp_can_convert_from_rgb(intel_dp, sink_format);
946 case INTEL_OUTPUT_FORMAT_YCBCR444:
947 return dfp_can_convert_from_ycbcr444(intel_dp, sink_format);
948 default:
949 MISSING_CASE(output_format);
950 return false;
951 }
952
953 return false;
954}
955
919static enum intel_output_format956static enum intel_output_format
920intel_dp_output_format(struct intel_connector *connector,957intel_dp_output_format(struct intel_connector *connector,
921 enum intel_output_format sink_format)958 enum intel_output_format sink_format)
922{959{
923 struct intel_dp *intel_dp = intel_attached_dp(connector);960 struct intel_dp *intel_dp = intel_attached_dp(connector);
924 struct drm_i915_private *i915 = dp_to_i915(intel_dp);961 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
962 enum intel_output_format force_dsc_output_format =
963 intel_dp->force_dsc_output_format;
925 enum intel_output_format output_format;964 enum intel_output_format output_format;
965 if (force_dsc_output_format) {
966 if (source_can_output(intel_dp, force_dsc_output_format) &&
967 (!drm_dp_is_branch(intel_dp->dpcd) ||
968 sink_format != force_dsc_output_format ||
969 dfp_can_convert(intel_dp, force_dsc_output_format, sink_format)))
970 return force_dsc_output_format;
926 971
927 if (intel_dp->force_dsc_output_format)972 drm_dbg_kms(&i915->drm, "Cannot force DSC output format\n");
928 return intel_dp->force_dsc_output_format;973 }
929 974
930 if (sink_format == INTEL_OUTPUT_FORMAT_RGB ||975 if (sink_format == INTEL_OUTPUT_FORMAT_RGB ||
931 dfp_can_convert_from_rgb(intel_dp, sink_format))976 dfp_can_convert_from_rgb(intel_dp, sink_format))
@@ -951,7 +996,7 @@ int intel_dp_min_bpp(enum intel_output_format output_format) · 19 unmodified lines
951 return 8 * 3;996 return 8 * 3;
952}997}
953 998
954static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)999int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
955{1000{
956 /*1001 /*
957 * bpp value was assumed to RGB format. And YCbCr 4:2:0 output1002 * bpp value was assumed to RGB format. And YCbCr 4:2:0 output
@@ -1122,7 +1167,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, · 164 unmodified lines
1122 int target_clock = mode->clock;1167 int target_clock = mode->clock;
1123 int max_rate, mode_rate, max_lanes, max_link_clock;1168 int max_rate, mode_rate, max_lanes, max_link_clock;
1124 int max_dotclk = dev_priv->max_dotclk_freq;1169 int max_dotclk = dev_priv->max_dotclk_freq;
1125 u16 dsc_max_output_bpp = 0;1170 u16 dsc_max_compressed_bpp = 0;
1126 u8 dsc_slice_count = 0;1171 u8 dsc_slice_count = 0;
1127 enum drm_mode_status status;1172 enum drm_mode_status status;
1128 bool dsc = false, bigjoiner = false;1173 bool dsc = false, bigjoiner = false;
@@ -1161,31 +1206,37 @@ intel_dp_mode_valid(struct drm_connector *_connector, · 32 unmodified lines
1161 1206
1162 if (HAS_DSC(dev_priv) &&1207 if (HAS_DSC(dev_priv) &&
1163 drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {1208 drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
1209 enum intel_output_format sink_format, output_format;
1210 int pipe_bpp;
1211
1212 sink_format = intel_dp_sink_format(connector, mode);
1213 output_format = intel_dp_output_format(connector, sink_format);
1164 /*1214 /*
1165 * TBD pass the connector BPC,1215 * TBD pass the connector BPC,
1166 * for now U8_MAX so that max BPC on that platform would be picked1216 * for now U8_MAX so that max BPC on that platform would be picked
1167 */1217 */
1168 int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);1218 pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
1169 1219
1170 /*1220 /*
1171 * Output bpp is stored in 6.4 format so right shift by 4 to get the1221 * Output bpp is stored in 6.4 format so right shift by 4 to get the
1172 * integer value since we support only integer values of bpp.1222 * integer value since we support only integer values of bpp.
1173 */1223 */
1174 if (intel_dp_is_edp(intel_dp)) {1224 if (intel_dp_is_edp(intel_dp)) {
1175 dsc_max_output_bpp =1225 dsc_max_compressed_bpp =
1176 drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4;1226 drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4;
1177 dsc_slice_count =1227 dsc_slice_count =
1178 drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,1228 drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
1179 true);1229 true);
1180 } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {1230 } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
1181 dsc_max_output_bpp =1231 dsc_max_compressed_bpp =
1182 intel_dp_dsc_get_output_bpp(dev_priv,1232 intel_dp_dsc_get_max_compressed_bpp(dev_priv,
1183 max_link_clock,1233 max_link_clock,
1184 max_lanes,1234 max_lanes,
1185 target_clock,1235 target_clock,
1186 mode->hdisplay,1236 mode->hdisplay,
1187 bigjoiner,1237 bigjoiner,
1188 pipe_bpp, 64) >> 4;1238 output_format,
1239 pipe_bpp, 64);
1189 dsc_slice_count =1240 dsc_slice_count =
1190 intel_dp_dsc_get_slice_count(intel_dp,1241 intel_dp_dsc_get_slice_count(intel_dp,
1191 target_clock,1242 target_clock,
@@ -1193,7 +1244,7 @@ intel_dp_mode_valid(struct drm_connector *_connector, · 1 unmodified line
1193 bigjoiner);1244 bigjoiner);
1194 }1245 }
1195 1246
1196 dsc = dsc_max_output_bpp && dsc_slice_count;1247 dsc = dsc_max_compressed_bpp && dsc_slice_count;
1197 }1248 }
1198 1249
1199 /*1250 /*
@@ -1306,13 +1357,13 @@ bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp) · 106 unmodified lines
1306static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,1357static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,
1307 const struct intel_crtc_state *pipe_config)1358 const struct intel_crtc_state *pipe_config)
1308{1359{
1360 struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
1309 struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);1361 struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
1310 1362
1311 /* On TGL, FEC is supported on all Pipes */
1312 if (DISPLAY_VER(dev_priv) >= 12)1363 if (DISPLAY_VER(dev_priv) >= 12)
1313 return true;1364 return true;
1314 1365
1315 if (DISPLAY_VER(dev_priv) == 11 && pipe_config->cpu_transcoder != TRANSCODER_A)1366 if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A)
1316 return true;1367 return true;
1317 1368
1318 return false;1369 return false;
@@ -1419,7 +1470,7 @@ intel_dp_adjust_compliance_config(struct intel_dp *intel_dp, · 100 unmodified lines
1419 if (intel_dp->compliance.test_data.bpc != 0) {1470 if (intel_dp->compliance.test_data.bpc != 0) {
1420 int bpp = 3 * intel_dp->compliance.test_data.bpc;1471 int bpp = 3 * intel_dp->compliance.test_data.bpc;
1421 1472
1422 limits->min_bpp = limits->max_bpp = bpp;1473 limits->pipe.min_bpp = limits->pipe.max_bpp = bpp;
1423 pipe_config->dither_force_disable = bpp == 6 * 3;1474 pipe_config->dither_force_disable = bpp == 6 * 3;
1424 1475
1425 drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp);1476 drm_dbg_kms(&i915->drm, "Setting pipe_bpp to %d\n", bpp);
@@ -1481,10 +1532,12 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, · 55 unmodified lines
1481 int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, conn_state);1532 int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, conn_state);
1482 int mode_rate, link_rate, link_avail;1533 int mode_rate, link_rate, link_avail;
1483 1534
1484 for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) {1535 for (bpp = to_bpp_int(limits->link.max_bpp_x16);
1485 int output_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp);1536 bpp >= to_bpp_int(limits->link.min_bpp_x16);
1537 bpp -= 2 * 3) {
1538 int link_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp);
1486 1539
1487 mode_rate = intel_dp_link_required(clock, output_bpp);1540 mode_rate = intel_dp_link_required(clock, link_bpp);
1488 1541
1489 for (i = 0; i < intel_dp->num_common_rates; i++) {1542 for (i = 0; i < intel_dp->num_common_rates; i++) {
1490 link_rate = intel_dp_common_rate(intel_dp, i);1543 link_rate = intel_dp_common_rate(intel_dp, i);
@@ -1512,18 +1565,31 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, · 21 unmodified lines
1512 return -EINVAL;1565 return -EINVAL;
1513}1566}
1514 1567
1515int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)1568static
1569u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private *i915)
1570{
1571 /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */
1572 if (DISPLAY_VER(i915) >= 12)
1573 return 12;
1574 if (DISPLAY_VER(i915) == 11)
1575 return 10;
1576
1577 return 0;
1578}
1579
1580int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
1516{1581{
1517 struct drm_i915_private *i915 = dp_to_i915(intel_dp);1582 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
1518 int i, num_bpc;1583 int i, num_bpc;
1519 u8 dsc_bpc[3] = {0};1584 u8 dsc_bpc[3] = {0};
1520 u8 dsc_max_bpc;1585 u8 dsc_max_bpc;
1521 1586
1522 /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */1587 dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(i915);
1523 if (DISPLAY_VER(i915) >= 12)1588
1524 dsc_max_bpc = min_t(u8, 12, max_req_bpc);1589 if (!dsc_max_bpc)
1525 else1590 return dsc_max_bpc;
1526 dsc_max_bpc = min_t(u8, 10, max_req_bpc);1591
1592 dsc_max_bpc = min_t(u8, dsc_max_bpc, max_req_bpc);
1527 1593
1528 num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,1594 num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
1529 dsc_bpc);1595 dsc_bpc);
@@ -1651,6 +1717,387 @@ static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp, · 121 unmodified lines
1651 return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format);1717 return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format);
1652}1718}
1653 1719
1720static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
1721 u32 lane_count, u32 mode_clock,
1722 enum intel_output_format output_format,
1723 int timeslots)
1724{
1725 u32 available_bw, required_bw;
1726
1727 available_bw = (link_clock * lane_count * timeslots) / 8;
1728 required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock));
1729
1730 return available_bw > required_bw;
1731}
1732
1733static int dsc_compute_link_config(struct intel_dp *intel_dp,
1734 struct intel_crtc_state *pipe_config,
1735 struct link_config_limits *limits,
1736 u16 compressed_bpp,
1737 int timeslots)
1738{
1739 const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
1740 int link_rate, lane_count;
1741 int i;
1742
1743 for (i = 0; i < intel_dp->num_common_rates; i++) {
1744 link_rate = intel_dp_common_rate(intel_dp, i);
1745 if (link_rate < limits->min_rate || link_rate > limits->max_rate)
1746 continue;
1747
1748 for (lane_count = limits->min_lane_count;
1749 lane_count <= limits->max_lane_count;
1750 lane_count <<= 1) {
1751 if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate, lane_count,
1752 adjusted_mode->clock,
1753 pipe_config->output_format,
1754 timeslots))
1755 continue;
1756
1757 pipe_config->lane_count = lane_count;
1758 pipe_config->port_clock = link_rate;
1759
1760 return 0;
1761 }
1762 }
1763
1764 return -EINVAL;
1765}
1766
1767static
1768u16 intel_dp_dsc_max_sink_compressed_bppx16(struct intel_dp *intel_dp,
1769 struct intel_crtc_state *pipe_config,
1770 int bpc)
1771{
1772 u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
1773
1774 if (max_bppx16)
1775 return max_bppx16;
1776 /*
1777 * If support not given in DPCD 67h, 68h use the Maximum Allowed bit rate
1778 * values as given in spec Table 2-157 DP v2.0
1779 */
1780 switch (pipe_config->output_format) {
1781 case INTEL_OUTPUT_FORMAT_RGB:
1782 case INTEL_OUTPUT_FORMAT_YCBCR444:
1783 return (3 * bpc) << 4;
1784 case INTEL_OUTPUT_FORMAT_YCBCR420:
1785 return (3 * (bpc / 2)) << 4;
1786 default:
1787 MISSING_CASE(pipe_config->output_format);
1788 break;
1789 }
1790
1791 return 0;
1792}
1793
1794static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
1795{
1796 /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */
1797 switch (pipe_config->output_format) {
1798 case INTEL_OUTPUT_FORMAT_RGB:
1799 case INTEL_OUTPUT_FORMAT_YCBCR444:
1800 return 8;
1801 case INTEL_OUTPUT_FORMAT_YCBCR420:
1802 return 6;
1803 default:
1804 MISSING_CASE(pipe_config->output_format);
1805 break;
1806 }
1807
1808 return 0;
1809}
1810
1811static int dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
1812 struct intel_crtc_state *pipe_config,
1813 int bpc)
1814{
1815 return intel_dp_dsc_max_sink_compressed_bppx16(intel_dp,
1816 pipe_config, bpc) >> 4;
1817}
1818
1819static int dsc_src_min_compressed_bpp(void)
1820{
1821 /* Min Compressed bpp supported by source is 8 */
1822 return 8;
1823}
1824
1825static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp)
1826{
1827 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
1828
1829 /*
1830 * Max Compressed bpp for Gen 13+ is 27bpp.
1831 * For earlier platform is 23bpp. (Bspec:49259).
1832 */
1833 if (DISPLAY_VER(i915) <= 12)
1834 return 23;
1835 else
1836 return 27;
1837}
1838
1839/*
1840 * From a list of valid compressed bpps try different compressed bpp and find a
1841 * suitable link configuration that can support it.
1842 */
1843static int
1844icl_dsc_compute_link_config(struct intel_dp *intel_dp,
1845 struct intel_crtc_state *pipe_config,
1846 struct link_config_limits *limits,
1847 int dsc_max_bpp,
1848 int dsc_min_bpp,
1849 int pipe_bpp,
1850 int timeslots)
1851{
1852 int i, ret;
1853
1854 /* Compressed BPP should be less than the Input DSC bpp */
1855 dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
1856
1857 for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) {
1858 if (valid_dsc_bpp[i] < dsc_min_bpp ||
1859 valid_dsc_bpp[i] > dsc_max_bpp)
1860 break;
1861
1862 ret = dsc_compute_link_config(intel_dp,
1863 pipe_config,
1864 limits,
1865 valid_dsc_bpp[i],
1866 timeslots);
1867 if (ret == 0) {
1868 pipe_config->dsc.compressed_bpp = valid_dsc_bpp[i];
1869 return 0;
1870 }
1871 }
1872
1873 return -EINVAL;
1874}
1875
1876/*
1877 * From XE_LPD onwards we supports compression bpps in steps of 1 up to
1878 * uncompressed bpp-1. So we start from max compressed bpp and see if any
1879 * link configuration is able to support that compressed bpp, if not we
1880 * step down and check for lower compressed bpp.
1881 */
1882static int
1883xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
1884 struct intel_crtc_state *pipe_config,
1885 struct link_config_limits *limits,
1886 int dsc_max_bpp,
1887 int dsc_min_bpp,
1888 int pipe_bpp,
1889 int timeslots)
1890{
1891 u16 compressed_bpp;
1892 int ret;
1893
1894 /* Compressed BPP should be less than the Input DSC bpp */
1895 dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
1896
1897 for (compressed_bpp = dsc_max_bpp;
1898 compressed_bpp >= dsc_min_bpp;
1899 compressed_bpp--) {
1900 ret = dsc_compute_link_config(intel_dp,
1901 pipe_config,
1902 limits,
1903 compressed_bpp,
1904 timeslots);
1905 if (ret == 0) {
1906 pipe_config->dsc.compressed_bpp = compressed_bpp;
1907 return 0;
1908 }
1909 }
1910 return -EINVAL;
1911}
1912
1913static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
1914 struct intel_crtc_state *pipe_config,
1915 struct link_config_limits *limits,
1916 int pipe_bpp,
1917 int timeslots)
1918{
1919 const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
1920 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
1921 int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
1922 int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
1923 int dsc_joiner_max_bpp;
1924
1925 dsc_src_min_bpp = dsc_src_min_compressed_bpp();
1926 dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
1927 dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
1928 dsc_min_bpp = max(dsc_min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16));
1929
1930 dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
1931 dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, pipe_bpp / 3);
1932 dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp;
1933
1934 dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, adjusted_mode->clock,
1935 adjusted_mode->hdisplay,
1936 pipe_config->bigjoiner_pipes);
1937 dsc_max_bpp = min(dsc_max_bpp, dsc_joiner_max_bpp);
1938 dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
1939
1940 if (DISPLAY_VER(i915) >= 13)
1941 return xelpd_dsc_compute_link_config(intel_dp, pipe_config, limits,
1942 dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
1943 return icl_dsc_compute_link_config(intel_dp, pipe_config, limits,
1944 dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
1945}
1946
1947static
1948u8 intel_dp_dsc_min_src_input_bpc(struct drm_i915_private *i915)
1949{
1950 /* Min DSC Input BPC for ICL+ is 8 */
1951 return HAS_DSC(i915) ? 8 : 0;
1952}
1953
1954static
1955bool is_dsc_pipe_bpp_sufficient(struct drm_i915_private *i915,
1956 struct drm_connector_state *conn_state,
1957 struct link_config_limits *limits,
1958 int pipe_bpp)
1959{
1960 u8 dsc_max_bpc, dsc_min_bpc, dsc_max_pipe_bpp, dsc_min_pipe_bpp;
1961
1962 dsc_max_bpc = min(intel_dp_dsc_max_src_input_bpc(i915), conn_state->max_requested_bpc);
1963 dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
1964
1965 dsc_max_pipe_bpp = min(dsc_max_bpc * 3, limits->pipe.max_bpp);
1966 dsc_min_pipe_bpp = max(dsc_min_bpc * 3, limits->pipe.min_bpp);
1967
1968 return pipe_bpp >= dsc_min_pipe_bpp &&
1969 pipe_bpp <= dsc_max_pipe_bpp;
1970}
1971
1972static
1973int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
1974 struct drm_connector_state *conn_state,
1975 struct link_config_limits *limits)
1976{
1977 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
1978 int forced_bpp;
1979
1980 if (!intel_dp->force_dsc_bpc)
1981 return 0;
1982
1983 forced_bpp = intel_dp->force_dsc_bpc * 3;
1984
1985 if (is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, forced_bpp)) {
1986 drm_dbg_kms(&i915->drm, "Input DSC BPC forced to %d\n", intel_dp->force_dsc_bpc);
1987 return forced_bpp;
1988 }
1989
1990 drm_dbg_kms(&i915->drm, "Cannot force DSC BPC:%d, due to DSC BPC limits\n",
1991 intel_dp->force_dsc_bpc);
1992
1993 return 0;
1994}
1995
1996static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
1997 struct intel_crtc_state *pipe_config,
1998 struct drm_connector_state *conn_state,
1999 struct link_config_limits *limits,
2000 int timeslots)
2001{
2002 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
2003 u8 max_req_bpc = conn_state->max_requested_bpc;
2004 u8 dsc_max_bpc, dsc_max_bpp;
2005 u8 dsc_min_bpc, dsc_min_bpp;
2006 u8 dsc_bpc[3] = {0};
2007 int forced_bpp, pipe_bpp;
2008 int num_bpc, i, ret;
2009
2010 forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
2011
2012 if (forced_bpp) {
2013 ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
2014 limits, forced_bpp, timeslots);
2015 if (ret == 0) {
2016 pipe_config->pipe_bpp = forced_bpp;
2017 return 0;
2018 }
2019 }
2020
2021 dsc_max_bpc = intel_dp_dsc_min_src_input_bpc(i915);
2022 if (!dsc_max_bpc)
2023 return -EINVAL;
2024
2025 dsc_max_bpc = min_t(u8, dsc_max_bpc, max_req_bpc);
2026 dsc_max_bpp = min(dsc_max_bpc * 3, limits->pipe.max_bpp);
2027
2028 dsc_min_bpc = intel_dp_dsc_min_src_input_bpc(i915);
2029 dsc_min_bpp = max(dsc_min_bpc * 3, limits->pipe.min_bpp);
2030
2031 /*
2032 * Get the maximum DSC bpc that will be supported by any valid
2033 * link configuration and compressed bpp.
2034 */
2035 num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, dsc_bpc);
2036 for (i = 0; i < num_bpc; i++) {
2037 pipe_bpp = dsc_bpc[i] * 3;
2038 if (pipe_bpp < dsc_min_bpp)
2039 break;
2040 if (pipe_bpp > dsc_max_bpp)
2041 continue;
2042 ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
2043 limits, pipe_bpp, timeslots);
2044 if (ret == 0) {
2045 pipe_config->pipe_bpp = pipe_bpp;
2046 return 0;
2047 }
2048 }
2049
2050 return -EINVAL;
2051}
2052
2053static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
2054 struct intel_crtc_state *pipe_config,
2055 struct drm_connector_state *conn_state,
2056 struct link_config_limits *limits)
2057{
2058 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
2059 int pipe_bpp, forced_bpp;
2060 int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
2061 int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
2062
2063 forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
2064
2065 if (forced_bpp) {
2066 pipe_bpp = forced_bpp;
2067 } else {
2068 int max_bpc = min(limits->pipe.max_bpp / 3, (int)conn_state->max_requested_bpc);
2069
2070 /* For eDP use max bpp that can be supported with DSC. */
2071 pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, max_bpc);
2072 if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, pipe_bpp)) {
2073 drm_dbg_kms(&i915->drm,
2074 "Computed BPC is not in DSC BPC limits\n");
2075 return -EINVAL;
2076 }
2077 }
2078 pipe_config->port_clock = limits->max_rate;
2079 pipe_config->lane_count = limits->max_lane_count;
2080
2081 dsc_src_min_bpp = dsc_src_min_compressed_bpp();
2082 dsc_sink_min_bpp = dsc_sink_min_compressed_bpp(pipe_config);
2083 dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp);
2084 dsc_min_bpp = max(dsc_min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16));
2085
2086 dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
2087 dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, pipe_bpp / 3);
2088 dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp;
2089 dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
2090
2091 /* Compressed BPP should be less than the Input DSC bpp */
2092 dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
2093
2094 pipe_config->dsc.compressed_bpp = max(dsc_min_bpp, dsc_max_bpp);
2095
2096 pipe_config->pipe_bpp = pipe_bpp;
2097
2098 return 0;
2099}
2100
1654int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,2101int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
1655 struct intel_crtc_state *pipe_config,2102 struct intel_crtc_state *pipe_config,
1656 struct drm_connector_state *conn_state,2103 struct drm_connector_state *conn_state,
@@ -1662,7 +2109,6 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, · 5 unmodified lines
1662 struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);2109 struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
1663 const struct drm_display_mode *adjusted_mode =2110 const struct drm_display_mode *adjusted_mode =
1664 &pipe_config->hw.adjusted_mode;2111 &pipe_config->hw.adjusted_mode;
1665 int pipe_bpp;
1666 int ret;2112 int ret;
1667 2113
1668 pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&2114 pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
@@ -1674,36 +2120,28 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, · 5 unmodified lines
1674 if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))2120 if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
1675 return -EINVAL;2121 return -EINVAL;
1676 2122
1677 if (compute_pipe_bpp)
1678 pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc);
1679 else
1680 pipe_bpp = pipe_config->pipe_bpp;
1681
1682 if (intel_dp->force_dsc_bpc) {
1683 pipe_bpp = intel_dp->force_dsc_bpc * 3;
1684 drm_dbg_kms(&dev_priv->drm, "Input DSC BPP forced to %d", pipe_bpp);
1685 }
1686
1687 /* Min Input BPC for ICL+ is 8 */
1688 if (pipe_bpp < 8 * 3) {
1689 drm_dbg_kms(&dev_priv->drm,
1690 "No DSC support for less than 8bpc\n");
1691 return -EINVAL;
1692 }
1693
1694 /*2123 /*
1695 * For now enable DSC for max bpp, max link rate, max lane count.2124 * compute pipe bpp is set to false for DP MST DSC case
1696 * Optimize this later for the minimum possible link rate/lane count2125 * and compressed_bpp is calculated same time once
1697 * with DSC enabled for the requested mode.2126 * vpci timeslots are allocated, because overall bpp
2127 * calculation procedure is bit different for MST case.
1698 */2128 */
1699 pipe_config->pipe_bpp = pipe_bpp;2129 if (compute_pipe_bpp) {
1700 pipe_config->port_clock = limits->max_rate;2130 if (intel_dp_is_edp(intel_dp))
1701 pipe_config->lane_count = limits->max_lane_count;2131 ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
2132 conn_state, limits);
2133 else
2134 ret = intel_dp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
2135 conn_state, limits, timeslots);
2136 if (ret) {
2137 drm_dbg_kms(&dev_priv->drm,
2138 "No Valid pipe bpp for given mode ret = %d\n", ret);
2139 return ret;
2140 }
2141 }
1702 2142
2143 /* Calculate Slice count */
1703 if (intel_dp_is_edp(intel_dp)) {2144 if (intel_dp_is_edp(intel_dp)) {
1704 pipe_config->dsc.compressed_bpp =
1705 min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
1706 pipe_config->pipe_bpp);
1707 pipe_config->dsc.slice_count =2145 pipe_config->dsc.slice_count =
1708 drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,2146 drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
1709 true);2147 true);
@@ -1713,34 +2151,8 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, · 3 unmodified lines
1713 return -EINVAL;2151 return -EINVAL;
1714 }2152 }
1715 } else {2153 } else {
1716 u16 dsc_max_output_bpp = 0;
1717 u8 dsc_dp_slice_count;2154 u8 dsc_dp_slice_count;
1718 2155
1719 if (compute_pipe_bpp) {
1720 dsc_max_output_bpp =
1721 intel_dp_dsc_get_output_bpp(dev_priv,
1722 pipe_config->port_clock,
1723 pipe_config->lane_count,
1724 adjusted_mode->crtc_clock,
1725 adjusted_mode->crtc_hdisplay,
1726 pipe_config->bigjoiner_pipes,
1727 pipe_bpp,
1728 timeslots);
1729 /*
1730 * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum
1731 * supported PPS value can be 63.9375 and with the further
1732 * mention that bpp should be programmed double the target bpp
1733 * restricting our target bpp to be 31.9375 at max
1734 */
1735 if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
1736 dsc_max_output_bpp = min_t(u16, dsc_max_output_bpp, 31 << 4);
1737
1738 if (!dsc_max_output_bpp) {
1739 drm_dbg_kms(&dev_priv->drm,
1740 "Compressed BPP not supported\n");
1741 return -EINVAL;
1742 }
1743 }
1744 dsc_dp_slice_count =2156 dsc_dp_slice_count =
1745 intel_dp_dsc_get_slice_count(intel_dp,2157 intel_dp_dsc_get_slice_count(intel_dp,
1746 adjusted_mode->crtc_clock,2158 adjusted_mode->crtc_clock,
@@ -1752,21 +2164,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, · 5 unmodified lines
1752 return -EINVAL;2164 return -EINVAL;
1753 }2165 }
1754 2166
1755 /*
1756 * compute pipe bpp is set to false for DP MST DSC case
1757 * and compressed_bpp is calculated same time once
1758 * vpci timeslots are allocated, because overall bpp
1759 * calculation procedure is bit different for MST case.
1760 */
1761 if (compute_pipe_bpp) {
1762 pipe_config->dsc.compressed_bpp = min_t(u16,
1763 dsc_max_output_bpp >> 4,
1764 pipe_config->pipe_bpp);
1765 }
1766 pipe_config->dsc.slice_count = dsc_dp_slice_count;2167 pipe_config->dsc.slice_count = dsc_dp_slice_count;
1767 drm_dbg_kms(&dev_priv->drm, "DSC: compressed bpp %d slice count %d\n",
1768 pipe_config->dsc.compressed_bpp,
1769 pipe_config->dsc.slice_count);
1770 }2168 }
1771 /*2169 /*
1772 * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate2170 * VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
@@ -1796,29 +2194,82 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, · 23 unmodified lines
1796 return 0;2194 return 0;
1797}2195}
1798 2196
1799static int2197/**
1800intel_dp_compute_link_config(struct intel_encoder *encoder,2198 * intel_dp_compute_config_link_bpp_limits - compute output link bpp limits
1801 struct intel_crtc_state *pipe_config,2199 * @intel_dp: intel DP
1802 struct drm_connector_state *conn_state,2200 * @crtc_state: crtc state
1803 bool respect_downstream_limits)2201 * @dsc: DSC compression mode
2202 * @limits: link configuration limits
2203 *
2204 * Calculates the output link min, max bpp values in @limits based on the
2205 * pipe bpp range, @crtc_state and @dsc mode.
2206 *
2207 * Returns %true in case of success.
2208 */
2209bool
2210intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
2211 const struct intel_crtc_state *crtc_state,
2212 bool dsc,
2213 struct link_config_limits *limits)
1804{2214{
1805 struct drm_i915_private *i915 = to_i915(encoder->base.dev);2215 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1806 struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
1807 const struct drm_display_mode *adjusted_mode =2216 const struct drm_display_mode *adjusted_mode =
1808 &pipe_config->hw.adjusted_mode;2217 &crtc_state->hw.adjusted_mode;
1809 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);2218 const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1810 struct link_config_limits limits;2219 const struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
1811 bool joiner_needs_dsc = false;2220 int max_link_bpp_x16;
1812 int ret;2221
2222 max_link_bpp_x16 = min(crtc_state->max_link_bpp_x16,
2223 to_bpp_x16(limits->pipe.max_bpp));
2224
2225 if (!dsc) {
2226 max_link_bpp_x16 = rounddown(max_link_bpp_x16, to_bpp_x16(2 * 3));
2227
2228 if (max_link_bpp_x16 < to_bpp_x16(limits->pipe.min_bpp))
2229 return false;
2230
2231 limits->link.min_bpp_x16 = to_bpp_x16(limits->pipe.min_bpp);
2232 } else {
2233 /*
2234 * TODO: set the DSC link limits already here, atm these are
2235 * initialized only later in intel_edp_dsc_compute_pipe_bpp() /
2236 * intel_dp_dsc_compute_pipe_bpp()
2237 */
2238 limits->link.min_bpp_x16 = 0;
2239 }
2240
2241 limits->link.max_bpp_x16 = max_link_bpp_x16;
2242
2243 drm_dbg_kms(&i915->drm,
2244 "[ENCODER:%d:%s][CRTC:%d:%s] DP link limits: pixel clock %d kHz DSC %s max lanes %d max rate %d max pipe_bpp %d max link_bpp " BPP_X16_FMT "\n",
2245 encoder->base.base.id, encoder->base.name,
2246 crtc->base.base.id, crtc->base.name,
2247 adjusted_mode->crtc_clock,
2248 dsc ? "on" : "off",
2249 limits->max_lane_count,
2250 limits->max_rate,
2251 limits->pipe.max_bpp,
2252 BPP_X16_ARGS(limits->link.max_bpp_x16));
1813 2253
1814 limits.min_rate = intel_dp_common_rate(intel_dp, 0);2254 return true;
1815 limits.max_rate = intel_dp_max_link_rate(intel_dp);2255}
2256
2257static bool
2258intel_dp_compute_config_limits(struct intel_dp *intel_dp,
2259 struct intel_crtc_state *crtc_state,
2260 bool respect_downstream_limits,
2261 bool dsc,
2262 struct link_config_limits *limits)
2263{
2264 limits->min_rate = intel_dp_common_rate(intel_dp, 0);
2265 limits->max_rate = intel_dp_max_link_rate(intel_dp);
1816 2266
1817 limits.min_lane_count = 1;2267 limits->min_lane_count = 1;
1818 limits.max_lane_count = intel_dp_max_lane_count(intel_dp);2268 limits->max_lane_count = intel_dp_max_lane_count(intel_dp);
1819 2269
1820 limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format);2270 limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format);
1821 limits.max_bpp = intel_dp_max_bpp(intel_dp, pipe_config, respect_downstream_limits);2271 limits->pipe.max_bpp = intel_dp_max_bpp(intel_dp, crtc_state,
2272 respect_downstream_limits);
1822 2273
1823 if (intel_dp->use_max_params) {2274 if (intel_dp->use_max_params) {
1824 /*2275 /*
@@ -1829,16 +2280,33 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, · 4 unmodified lines
1829 * configuration, and typically on older panels these2280 * configuration, and typically on older panels these
1830 * values correspond to the native resolution of the panel.2281 * values correspond to the native resolution of the panel.
1831 */2282 */
1832 limits.min_lane_count = limits.max_lane_count;2283 limits->min_lane_count = limits->max_lane_count;
1833 limits.min_rate = limits.max_rate;2284 limits->min_rate = limits->max_rate;
1834 }2285 }
1835 2286
1836 intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);2287 intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
1837 2288
1838 drm_dbg_kms(&i915->drm, "DP link computation with max lane count %i "2289 return intel_dp_compute_config_link_bpp_limits(intel_dp,
1839 "max rate %d max bpp %d pixel clock %iKHz\n",2290 crtc_state,
1840 limits.max_lane_count, limits.max_rate,2291 dsc,
1841 limits.max_bpp, adjusted_mode->crtc_clock);2292 limits);
2293}
2294
2295static int
2296intel_dp_compute_link_config(struct intel_encoder *encoder,
2297 struct intel_crtc_state *pipe_config,
2298 struct drm_connector_state *conn_state,
2299 bool respect_downstream_limits)
2300{
2301 struct drm_i915_private *i915 = to_i915(encoder->base.dev);
2302 struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
2303 const struct drm_display_mode *adjusted_mode =
2304 &pipe_config->hw.adjusted_mode;
2305 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2306 struct link_config_limits limits;
2307 bool joiner_needs_dsc = false;
2308 bool dsc_needed;
2309 int ret = 0;
1842 2310
1843 if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay,2311 if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay,
1844 adjusted_mode->crtc_clock))2312 adjusted_mode->crtc_clock))
@@ -1851,16 +2319,34 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, · 6 unmodified lines
1851 */2319 */
1852 joiner_needs_dsc = DISPLAY_VER(i915) < 13 && pipe_config->bigjoiner_pipes;2320 joiner_needs_dsc = DISPLAY_VER(i915) < 13 && pipe_config->bigjoiner_pipes;
1853 2321
1854 /*2322 dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
1855 * Optimize for slow and wide for everything, because there are some2323 !intel_dp_compute_config_limits(intel_dp, pipe_config,
1856 * eDP 1.3 and 1.4 panels don't work well with fast and narrow.2324 respect_downstream_limits,
1857 */2325 false,
1858 ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config, conn_state, &limits);2326 &limits);
2327
2328 if (!dsc_needed) {
2329 /*
2330 * Optimize for slow and wide for everything, because there are some
2331 * eDP 1.3 and 1.4 panels don't work well with fast and narrow.
2332 */
2333 ret = intel_dp_compute_link_config_wide(intel_dp, pipe_config,
2334 conn_state, &limits);
2335 if (ret)
2336 dsc_needed = true;
2337 }
1859 2338
1860 if (ret || joiner_needs_dsc || intel_dp->force_dsc_en) {2339 if (dsc_needed) {
1861 drm_dbg_kms(&i915->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",2340 drm_dbg_kms(&i915->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",
1862 str_yes_no(ret), str_yes_no(joiner_needs_dsc),2341 str_yes_no(ret), str_yes_no(joiner_needs_dsc),
1863 str_yes_no(intel_dp->force_dsc_en));2342 str_yes_no(intel_dp->force_dsc_en));
2343
2344 if (!intel_dp_compute_config_limits(intel_dp, pipe_config,
2345 respect_downstream_limits,
2346 true,
2347 &limits))
2348 return -EINVAL;
2349
1864 ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,2350 ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
1865 conn_state, &limits, 64, true);2351 conn_state, &limits, 64, true);
1866 if (ret < 0)2352 if (ret < 0)
@@ -2136,7 +2622,7 @@ static bool can_enable_drrs(struct intel_connector *connector, · 269 unmodified lines
2136static void2622static void
2137intel_dp_drrs_compute_config(struct intel_connector *connector,2623intel_dp_drrs_compute_config(struct intel_connector *connector,
2138 struct intel_crtc_state *pipe_config,2624 struct intel_crtc_state *pipe_config,
2139 int output_bpp)2625 int link_bpp)
2140{2626{
2141 struct drm_i915_private *i915 = to_i915(connector->base.dev);2627 struct drm_i915_private *i915 = to_i915(connector->base.dev);
2142 const struct drm_display_mode *downclock_mode =2628 const struct drm_display_mode *downclock_mode =
@@ -2144,7 +2630,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, · 1 unmodified line
2144 int pixel_clock;2630 int pixel_clock;
2145 2631
2146 if (has_seamless_m_n(connector))2632 if (has_seamless_m_n(connector))
2147 pipe_config->seamless_m_n = true;2633 pipe_config->update_m_n = true;
2148 2634
2149 if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {2635 if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
2150 if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))2636 if (intel_cpu_transcoder_has_m2_n2(i915, pipe_config->cpu_transcoder))
@@ -2161,7 +2647,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, · 10 unmodified lines
2161 if (pipe_config->splitter.enable)2647 if (pipe_config->splitter.enable)
2162 pixel_clock /= pipe_config->splitter.link_count;2648 pixel_clock /= pipe_config->splitter.link_count;
2163 2649
2164 intel_link_compute_m_n(output_bpp, pipe_config->lane_count, pixel_clock,2650 intel_link_compute_m_n(link_bpp, pipe_config->lane_count, pixel_clock,
2165 pipe_config->port_clock, &pipe_config->dp_m2_n2,2651 pipe_config->port_clock, &pipe_config->dp_m2_n2,
2166 pipe_config->fec_enable);2652 pipe_config->fec_enable);
2167 2653
@@ -2171,15 +2657,17 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, · 3 unmodified lines
2171}2657}
2172 2658
2173static bool intel_dp_has_audio(struct intel_encoder *encoder,2659static bool intel_dp_has_audio(struct intel_encoder *encoder,
2660 struct intel_crtc_state *crtc_state,
2174 const struct drm_connector_state *conn_state)2661 const struct drm_connector_state *conn_state)
2175{2662{
2176 struct drm_i915_private *i915 = to_i915(encoder->base.dev);2663 struct drm_i915_private *i915 = to_i915(encoder->base.dev);
2177 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2178 struct intel_connector *connector = intel_dp->attached_connector;
2179 const struct intel_digital_connector_state *intel_conn_state =2664 const struct intel_digital_connector_state *intel_conn_state =
2180 to_intel_digital_connector_state(conn_state);2665 to_intel_digital_connector_state(conn_state);
2666 struct intel_connector *connector =
2667 to_intel_connector(conn_state->connector);
2181 2668
2182 if (!intel_dp_port_has_audio(i915, encoder->port))2669 if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST) &&
2670 !intel_dp_port_has_audio(i915, encoder->port))
2183 return false;2671 return false;
2184 2672
2185 if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)2673 if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
@@ -2232,7 +2720,7 @@ intel_dp_compute_output_format(struct intel_encoder *encoder, · 46 unmodified lines
2232 return ret;2720 return ret;
2233}2721}
2234 2722
2235static void2723void
2236intel_dp_audio_compute_config(struct intel_encoder *encoder,2724intel_dp_audio_compute_config(struct intel_encoder *encoder,
2237 struct intel_crtc_state *pipe_config,2725 struct intel_crtc_state *pipe_config,
2238 struct drm_connector_state *conn_state)2726 struct drm_connector_state *conn_state)
@@ -2240,9 +2728,12 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder, · 1 unmodified line
2240 struct drm_i915_private *i915 = to_i915(encoder->base.dev);2728 struct drm_i915_private *i915 = to_i915(encoder->base.dev);
2241 struct drm_connector *connector = conn_state->connector;2729 struct drm_connector *connector = conn_state->connector;
2242 2730
2243 pipe_config->sdp_split_enable =2731 pipe_config->has_audio =
2244 intel_dp_has_audio(encoder, conn_state) &&2732 intel_dp_has_audio(encoder, pipe_config, conn_state) &&
2245 intel_dp_is_uhbr(pipe_config);2733 intel_audio_compute_config(encoder, pipe_config, conn_state);
2734
2735 pipe_config->sdp_split_enable = pipe_config->has_audio &&
2736 intel_dp_is_uhbr(pipe_config);
2246 2737
2247 drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] SDP split enable: %s\n",2738 drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] SDP split enable: %s\n",
2248 connector->base.id, connector->name,2739 connector->base.id, connector->name,
@@ -2259,15 +2750,11 @@ intel_dp_compute_config(struct intel_encoder *encoder, · 10 unmodified lines
2259 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);2750 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2260 const struct drm_display_mode *fixed_mode;2751 const struct drm_display_mode *fixed_mode;
2261 struct intel_connector *connector = intel_dp->attached_connector;2752 struct intel_connector *connector = intel_dp->attached_connector;
2262 int ret = 0, output_bpp;2753 int ret = 0, link_bpp;
2263 2754
2264 if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != PORT_A)2755 if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != PORT_A)
2265 pipe_config->has_pch_encoder = true;2756 pipe_config->has_pch_encoder = true;
2266 2757
2267 pipe_config->has_audio =
2268 intel_dp_has_audio(encoder, conn_state) &&
2269 intel_audio_compute_config(encoder, pipe_config, conn_state);
2270
2271 fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode);2758 fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode);
2272 if (intel_dp_is_edp(intel_dp) && fixed_mode) {2759 if (intel_dp_is_edp(intel_dp) && fixed_mode) {
2273 ret = intel_panel_compute_config(connector, adjusted_mode);2760 ret = intel_panel_compute_config(connector, adjusted_mode);
@@ -2308,11 +2795,14 @@ intel_dp_compute_config(struct intel_encoder *encoder, · 34 unmodified lines
2308 pipe_config->limited_color_range =2795 pipe_config->limited_color_range =
2309 intel_dp_limited_color_range(pipe_config, conn_state);2796 intel_dp_limited_color_range(pipe_config, conn_state);
2310 2797
2798 pipe_config->enhanced_framing =
2799 drm_dp_enhanced_frame_cap(intel_dp->dpcd);
2800
2311 if (pipe_config->dsc.compression_enable)2801 if (pipe_config->dsc.compression_enable)
2312 output_bpp = pipe_config->dsc.compressed_bpp;2802 link_bpp = pipe_config->dsc.compressed_bpp;
2313 else2803 else
2314 output_bpp = intel_dp_output_bpp(pipe_config->output_format,2804 link_bpp = intel_dp_output_bpp(pipe_config->output_format,
2315 pipe_config->pipe_bpp);2805 pipe_config->pipe_bpp);
2316 2806
2317 if (intel_dp->mso_link_count) {2807 if (intel_dp->mso_link_count) {
2318 int n = intel_dp->mso_link_count;2808 int n = intel_dp->mso_link_count;
@@ -2336,7 +2826,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, · 17 unmodified lines
2336 2826
2337 intel_dp_audio_compute_config(encoder, pipe_config, conn_state);2827 intel_dp_audio_compute_config(encoder, pipe_config, conn_state);
2338 2828
2339 intel_link_compute_m_n(output_bpp,2829 intel_link_compute_m_n(link_bpp,
2340 pipe_config->lane_count,2830 pipe_config->lane_count,
2341 adjusted_mode->crtc_clock,2831 adjusted_mode->crtc_clock,
2342 pipe_config->port_clock,2832 pipe_config->port_clock,
@@ -2352,7 +2842,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, · 9 unmodified lines
2352 2842
2353 intel_vrr_compute_config(pipe_config, conn_state);2843 intel_vrr_compute_config(pipe_config, conn_state);
2354 intel_psr_compute_config(intel_dp, pipe_config, conn_state);2844 intel_psr_compute_config(intel_dp, pipe_config, conn_state);
2355 intel_dp_drrs_compute_config(connector, pipe_config, output_bpp);2845 intel_dp_drrs_compute_config(connector, pipe_config, link_bpp);
2356 intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);2846 intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
2357 intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);2847 intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state);
2358 2848
@@ -4808,7 +5298,6 @@ intel_dp_set_edid(struct intel_dp *intel_dp) · 2449 unmodified lines
4808 struct drm_i915_private *i915 = dp_to_i915(intel_dp);5298 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
4809 struct intel_connector *connector = intel_dp->attached_connector;5299 struct intel_connector *connector = intel_dp->attached_connector;
4810 const struct drm_edid *drm_edid;5300 const struct drm_edid *drm_edid;
4811 const struct edid *edid;
4812 bool vrr_capable;5301 bool vrr_capable;
4813 5302
4814 intel_dp_unset_edid(intel_dp);5303 intel_dp_unset_edid(intel_dp);
@@ -4826,10 +5315,8 @@ intel_dp_set_edid(struct intel_dp *intel_dp) · 11 unmodified lines
4826 intel_dp_update_dfp(intel_dp, drm_edid);5315 intel_dp_update_dfp(intel_dp, drm_edid);
4827 intel_dp_update_420(intel_dp);5316 intel_dp_update_420(intel_dp);
4828 5317
4829 /* FIXME: Get rid of drm_edid_raw() */5318 drm_dp_cec_attach(&intel_dp->aux,
4830 edid = drm_edid_raw(drm_edid);5319 connector->base.display_info.source_physical_address);
4831
4832 drm_dp_cec_set_edid(&intel_dp->aux, edid);
4833}5320}
4834 5321
4835static void5322static void
@@ -4957,12 +5444,6 @@ out: · 121 unmodified lines
4957 if (status != connector_status_connected && !intel_dp->is_mst)5444 if (status != connector_status_connected && !intel_dp->is_mst)
4958 intel_dp_unset_edid(intel_dp);5445 intel_dp_unset_edid(intel_dp);
4959 5446
4960 /*
4961 * Make sure the refs for power wells enabled during detect are
4962 * dropped to avoid a new detect cycle triggered by HPD polling.
4963 */
4964 intel_display_power_flush_work(dev_priv);
4965
4966 if (!intel_dp_is_edp(intel_dp))5447 if (!intel_dp_is_edp(intel_dp))
4967 drm_dp_set_subconnector_property(connector,5448 drm_dp_set_subconnector_property(connector,
4968 status,5449 status,
@@ -4978,9 +5459,6 @@ intel_dp_force(struct drm_connector *connector) · 9 unmodified lines
4978 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);5459 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
4979 struct intel_encoder *intel_encoder = &dig_port->base;5460 struct intel_encoder *intel_encoder = &dig_port->base;
4980 struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);5461 struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
4981 enum intel_display_power_domain aux_domain =
4982 intel_aux_power_domain(dig_port);
4983 intel_wakeref_t wakeref;
4984 5462
4985 drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",5463 drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
4986 connector->base.id, connector->name);5464 connector->base.id, connector->name);
@@ -4989,11 +5467,7 @@ intel_dp_force(struct drm_connector *connector) · 2 unmodified lines
4989 if (connector->status != connector_status_connected)5467 if (connector->status != connector_status_connected)
4990 return;5468 return;
4991 5469
4992 wakeref = intel_display_power_get(dev_priv, aux_domain);
4993
4994 intel_dp_set_edid(intel_dp);5470 intel_dp_set_edid(intel_dp);
4995
4996 intel_display_power_put(dev_priv, aux_domain, wakeref);
4997}5471}
4998 5472
4999static int intel_dp_get_modes(struct drm_connector *connector)5473static int intel_dp_get_modes(struct drm_connector *connector)
@@ -5533,7 +6007,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, · 533 unmodified lines
5533 }6007 }
5534 6008
5535 mutex_lock(&dev_priv->drm.mode_config.mutex);6009 mutex_lock(&dev_priv->drm.mode_config.mutex);
5536 drm_edid = drm_edid_read_ddc(connector, &intel_dp->aux.ddc);6010 drm_edid = drm_edid_read_ddc(connector, connector->ddc);
5537 if (!drm_edid) {6011 if (!drm_edid) {
5538 /* Fallback to EDID from ACPI OpRegion, if any */6012 /* Fallback to EDID from ACPI OpRegion, if any */
5539 drm_edid = intel_opregion_get_edid(intel_connector);6013 drm_edid = intel_opregion_get_edid(intel_connector);
@@ -5672,12 +6146,15 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, · 132 unmodified lines
5672 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))6146 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
5673 intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);6147 intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
5674 6148
6149 intel_dp_aux_init(intel_dp);
6150
5675 drm_dbg_kms(&dev_priv->drm,6151 drm_dbg_kms(&dev_priv->drm,
5676 "Adding %s connector on [ENCODER:%d:%s]\n",6152 "Adding %s connector on [ENCODER:%d:%s]\n",
5677 type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",6153 type == DRM_MODE_CONNECTOR_eDP ? "eDP" : "DP",
5678 intel_encoder->base.base.id, intel_encoder->base.name);6154 intel_encoder->base.base.id, intel_encoder->base.name);
5679 6155
5680 drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);6156 drm_connector_init_with_ddc(dev, connector, &intel_dp_connector_funcs,
6157 type, &intel_dp->aux.ddc);
5681 drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);6158 drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
5682 6159
5683 if (!HAS_GMCH(dev_priv) && DISPLAY_VER(dev_priv) < 12)6160 if (!HAS_GMCH(dev_priv) && DISPLAY_VER(dev_priv) < 12)
@@ -5685,8 +6162,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, · 1 unmodified line
5685 6162
5686 intel_connector->polled = DRM_CONNECTOR_POLL_HPD;6163 intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
5687 6164
5688 intel_dp_aux_init(intel_dp);
5689
5690 intel_connector_attach_encoder(intel_connector, intel_encoder);6165 intel_connector_attach_encoder(intel_connector, intel_encoder);
5691 6166
5692 if (HAS_DDI(dev_priv))6167 if (HAS_DDI(dev_priv))
drivers/gpu/drm/i915/display/intel_dp.h+26−8
@@ -26,7 +26,14 @@ struct intel_encoder; · 25 unmodified lines
26struct link_config_limits {26struct link_config_limits {
27 int min_rate, max_rate;27 int min_rate, max_rate;
28 int min_lane_count, max_lane_count;28 int min_lane_count, max_lane_count;
29 int min_bpp, max_bpp;29 struct {
30 /* Uncompressed DSC input or link output bpp in 1 bpp units */
31 int min_bpp, max_bpp;
32 } pipe;
33 struct {
34 /* Compressed or uncompressed link output bpp in 1/16 bpp units */
35 int min_bpp_x16, max_bpp_x16;
36 } link;
30};37};
31 38
32void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);39void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp);
@@ -65,6 +72,9 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, · 32 unmodified lines
65 struct link_config_limits *limits,72 struct link_config_limits *limits,
66 int timeslots,73 int timeslots,
67 bool recompute_pipe_bpp);74 bool recompute_pipe_bpp);
75void intel_dp_audio_compute_config(struct intel_encoder *encoder,
76 struct intel_crtc_state *pipe_config,
77 struct drm_connector_state *conn_state);
68bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp);78bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp);
69bool intel_dp_is_edp(struct intel_dp *intel_dp);79bool intel_dp_is_edp(struct intel_dp *intel_dp);
70bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);80bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state);
@@ -106,13 +116,14 @@ void intel_read_dp_sdp(struct intel_encoder *encoder, · 35 unmodified lines
106 struct intel_crtc_state *crtc_state,116 struct intel_crtc_state *crtc_state,
107 unsigned int type);117 unsigned int type);
108bool intel_digital_port_connected(struct intel_encoder *encoder);118bool intel_digital_port_connected(struct intel_encoder *encoder);
109int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);119int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
110u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,120u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
111 u32 link_clock, u32 lane_count,121 u32 link_clock, u32 lane_count,
112 u32 mode_clock, u32 mode_hdisplay,122 u32 mode_clock, u32 mode_hdisplay,
113 bool bigjoiner,123 bool bigjoiner,
114 u32 pipe_bpp,124 enum intel_output_format output_format,
115 u32 timeslots);125 u32 pipe_bpp,
126 u32 timeslots);
116u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,127u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
117 int mode_clock, int mode_hdisplay,128 int mode_clock, int mode_hdisplay,
118 bool bigjoiner);129 bool bigjoiner);
@@ -143,5 +154,12 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp, · 24 unmodified lines
143void intel_dp_phy_test(struct intel_encoder *encoder);154void intel_dp_phy_test(struct intel_encoder *encoder);
144 155
145void intel_dp_wait_source_oui(struct intel_dp *intel_dp);156void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
157int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
158
159bool
160intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
161 const struct intel_crtc_state *crtc_state,
162 bool dsc,
163 struct link_config_limits *limits);
146 164
147#endif /* __INTEL_DP_H__ */165#endif /* __INTEL_DP_H__ */
drivers/gpu/drm/i915/display/intel_dp_aux.c+29−20
@@ -14,6 +14,21 @@ · 13 unmodified lines
14#include "intel_pps.h"14#include "intel_pps.h"
15#include "intel_tc.h"15#include "intel_tc.h"
16 16
17#define AUX_CH_NAME_BUFSIZE 6
18
19static const char *aux_ch_name(struct drm_i915_private *i915,
20 char *buf, int size, enum aux_ch aux_ch)
21{
22 if (DISPLAY_VER(i915) >= 13 && aux_ch >= AUX_CH_D_XELPD)
23 snprintf(buf, size, "%c", 'A' + aux_ch - AUX_CH_D_XELPD + AUX_CH_D);
24 else if (DISPLAY_VER(i915) >= 12 && aux_ch >= AUX_CH_USBC1)
25 snprintf(buf, size, "USBC%c", '1' + aux_ch - AUX_CH_USBC1);
26 else
27 snprintf(buf, size, "%c", 'A' + aux_ch);
28
29 return buf;
30}
31
17u32 intel_dp_aux_pack(const u8 *src, int src_bytes)32u32 intel_dp_aux_pack(const u8 *src, int src_bytes)
18{33{
19 int i;34 int i;
@@ -687,10 +702,10 @@ static i915_reg_t xelpdp_aux_ctl_reg(struct intel_dp *intel_dp) · 667 unmodified lines
687 case AUX_CH_USBC2:702 case AUX_CH_USBC2:
688 case AUX_CH_USBC3:703 case AUX_CH_USBC3:
689 case AUX_CH_USBC4:704 case AUX_CH_USBC4:
690 return XELPDP_DP_AUX_CH_CTL(aux_ch);705 return XELPDP_DP_AUX_CH_CTL(dev_priv, aux_ch);
691 default:706 default:
692 MISSING_CASE(aux_ch);707 MISSING_CASE(aux_ch);
693 return XELPDP_DP_AUX_CH_CTL(AUX_CH_A);708 return XELPDP_DP_AUX_CH_CTL(dev_priv, AUX_CH_A);
694 }709 }
695}710}
696 711
@@ -707,10 +722,10 @@ static i915_reg_t xelpdp_aux_data_reg(struct intel_dp *intel_dp, int index) · 10 unmodified lines
707 case AUX_CH_USBC2:722 case AUX_CH_USBC2:
708 case AUX_CH_USBC3:723 case AUX_CH_USBC3:
709 case AUX_CH_USBC4:724 case AUX_CH_USBC4:
710 return XELPDP_DP_AUX_CH_DATA(aux_ch, index);725 return XELPDP_DP_AUX_CH_DATA(dev_priv, aux_ch, index);
711 default:726 default:
712 MISSING_CASE(aux_ch);727 MISSING_CASE(aux_ch);
713 return XELPDP_DP_AUX_CH_DATA(AUX_CH_A, index);728 return XELPDP_DP_AUX_CH_DATA(dev_priv, AUX_CH_A, index);
714 }729 }
715}730}
716 731
@@ -728,6 +743,7 @@ void intel_dp_aux_init(struct intel_dp *intel_dp) · 11 unmodified lines
728 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);743 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
729 struct intel_encoder *encoder = &dig_port->base;744 struct intel_encoder *encoder = &dig_port->base;
730 enum aux_ch aux_ch = dig_port->aux_ch;745 enum aux_ch aux_ch = dig_port->aux_ch;
746 char buf[AUX_CH_NAME_BUFSIZE];
731 747
732 if (DISPLAY_VER(dev_priv) >= 14) {748 if (DISPLAY_VER(dev_priv) >= 14) {
733 intel_dp->aux_ch_ctl_reg = xelpdp_aux_ctl_reg;749 intel_dp->aux_ch_ctl_reg = xelpdp_aux_ctl_reg;
@@ -764,18 +780,9 @@ void intel_dp_aux_init(struct intel_dp *intel_dp) · 30 unmodified lines
764 drm_dp_aux_init(&intel_dp->aux);780 drm_dp_aux_init(&intel_dp->aux);
765 781
766 /* Failure to allocate our preferred name is not critical */782 /* Failure to allocate our preferred name is not critical */
767 if (DISPLAY_VER(dev_priv) >= 13 && aux_ch >= AUX_CH_D_XELPD)783 intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX %s/%s",
768 intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX %c/%s",784 aux_ch_name(dev_priv, buf, sizeof(buf), aux_ch),
769 aux_ch_name(aux_ch - AUX_CH_D_XELPD + AUX_CH_D),785 encoder->base.name);
770 encoder->base.name);
771 else if (DISPLAY_VER(dev_priv) >= 12 && aux_ch >= AUX_CH_USBC1)
772 intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX USBC%c/%s",
773 aux_ch - AUX_CH_USBC1 + '1',
774 encoder->base.name);
775 else
776 intel_dp->aux.name = kasprintf(GFP_KERNEL, "AUX %c/%s",
777 aux_ch_name(aux_ch),
778 encoder->base.name);
779 786
780 intel_dp->aux.transfer = intel_dp_aux_transfer;787 intel_dp->aux.transfer = intel_dp_aux_transfer;
781 cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE);788 cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE);
@@ -819,6 +826,7 @@ enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder) · 37 unmodified lines
819 struct intel_encoder *other;826 struct intel_encoder *other;
820 const char *source;827 const char *source;
821 enum aux_ch aux_ch;828 enum aux_ch aux_ch;
829 char buf[AUX_CH_NAME_BUFSIZE];
822 830
823 aux_ch = intel_bios_dp_aux_ch(encoder->devdata);831 aux_ch = intel_bios_dp_aux_ch(encoder->devdata);
824 source = "VBT";832 source = "VBT";
@@ -836,16 +844,17 @@ enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder) · 11 unmodified lines
836 other = get_encoder_by_aux_ch(encoder, aux_ch);844 other = get_encoder_by_aux_ch(encoder, aux_ch);
837 if (other) {845 if (other) {
838 drm_dbg_kms(&i915->drm,846 drm_dbg_kms(&i915->drm,
839 "[ENCODER:%d:%s] AUX CH %c already claimed by [ENCODER:%d:%s]\n",847 "[ENCODER:%d:%s] AUX CH %s already claimed by [ENCODER:%d:%s]\n",
840 encoder->base.base.id, encoder->base.name, aux_ch_name(aux_ch),848 encoder->base.base.id, encoder->base.name,
849 aux_ch_name(i915, buf, sizeof(buf), aux_ch),
841 other->base.base.id, other->base.name);850 other->base.base.id, other->base.name);
842 return AUX_CH_NONE;851 return AUX_CH_NONE;
843 }852 }
844 853
845 drm_dbg_kms(&i915->drm,854 drm_dbg_kms(&i915->drm,
846 "[ENCODER:%d:%s] Using AUX CH %c (%s)\n",855 "[ENCODER:%d:%s] Using AUX CH %s (%s)\n",
847 encoder->base.base.id, encoder->base.name,856 encoder->base.base.id, encoder->base.name,
848 aux_ch_name(aux_ch), source);857 aux_ch_name(i915, buf, sizeof(buf), aux_ch), source);
849 858
850 return aux_ch;859 return aux_ch;
851}860}
drivers/gpu/drm/i915/display/intel_dp_aux_regs.h+44−36
@@ -13,48 +13,34 @@ · 12 unmodified lines
13 * packet size supported is 20 bytes in each direction, hence the 5 fixed data13 * packet size supported is 20 bytes in each direction, hence the 5 fixed data
14 * registers14 * registers
15 */15 */
16#define _DPA_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64010)
17#define _DPA_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64014)
18 16
19#define _DPB_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64110)17/*
20#define _DPB_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64114)18 * Wrapper macro to convert from aux_ch to the index used in some of the
21 19 * registers.
22#define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL)20 */
23#define DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */21#define __xe2lpd_aux_ch_idx(aux_ch) \
24 22 (aux_ch >= AUX_CH_USBC1 ? aux_ch : AUX_CH_USBC4 + 1 + (aux_ch) - AUX_CH_A)
25#define _XELPDP_USBC1_AUX_CH_CTL 0x16F210
26#define _XELPDP_USBC2_AUX_CH_CTL 0x16F410
27#define _XELPDP_USBC3_AUX_CH_CTL 0x16F610
28#define _XELPDP_USBC4_AUX_CH_CTL 0x16F810
29
30#define XELPDP_DP_AUX_CH_CTL(aux_ch) _MMIO(_PICK(aux_ch, \
31 _DPA_AUX_CH_CTL, \
32 _DPB_AUX_CH_CTL, \
33 0, /* port/aux_ch C is non-existent */ \
34 _XELPDP_USBC1_AUX_CH_CTL, \
35 _XELPDP_USBC2_AUX_CH_CTL, \
36 _XELPDP_USBC3_AUX_CH_CTL, \
37 _XELPDP_USBC4_AUX_CH_CTL))
38
39#define _XELPDP_USBC1_AUX_CH_DATA1 0x16F214
40#define _XELPDP_USBC2_AUX_CH_DATA1 0x16F414
41#define _XELPDP_USBC3_AUX_CH_DATA1 0x16F614
42#define _XELPDP_USBC4_AUX_CH_DATA1 0x16F814
43
44#define XELPDP_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PICK(aux_ch, \
45 _DPA_AUX_CH_DATA1, \
46 _DPB_AUX_CH_DATA1, \
47 0, /* port/aux_ch C is non-existent */ \
48 _XELPDP_USBC1_AUX_CH_DATA1, \
49 _XELPDP_USBC2_AUX_CH_DATA1, \
50 _XELPDP_USBC3_AUX_CH_DATA1, \
51 _XELPDP_USBC4_AUX_CH_DATA1) + (i) * 4)
52 23
24/* TODO: Remove implicit dev_priv */
25#define _DPA_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64010)
26#define _DPB_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64110)
27#define _XELPDP_USBC1_AUX_CH_CTL 0x16f210
28#define _XELPDP_USBC2_AUX_CH_CTL 0x16f410
29#define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, \
30 _DPB_AUX_CH_CTL)
31#define _XELPDP_DP_AUX_CH_CTL(aux_ch) \
32 _MMIO(_PICK_EVEN_2RANGES(aux_ch, AUX_CH_USBC1, \
33 _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL, \
34 _XELPDP_USBC1_AUX_CH_CTL, \
35 _XELPDP_USBC2_AUX_CH_CTL))
36#define XELPDP_DP_AUX_CH_CTL(i915__, aux_ch) \
37 (DISPLAY_VER(i915__) >= 20 ? \
38 _XELPDP_DP_AUX_CH_CTL(__xe2lpd_aux_ch_idx(aux_ch)) : \
39 _XELPDP_DP_AUX_CH_CTL(aux_ch))
53#define DP_AUX_CH_CTL_SEND_BUSY REG_BIT(31)40#define DP_AUX_CH_CTL_SEND_BUSY REG_BIT(31)
54#define DP_AUX_CH_CTL_DONE REG_BIT(30)41#define DP_AUX_CH_CTL_DONE REG_BIT(30)
55#define DP_AUX_CH_CTL_INTERRUPT REG_BIT(29)42#define DP_AUX_CH_CTL_INTERRUPT REG_BIT(29)
56#define DP_AUX_CH_CTL_TIME_OUT_ERROR REG_BIT(28)43#define DP_AUX_CH_CTL_TIME_OUT_ERROR REG_BIT(28)
57
58#define DP_AUX_CH_CTL_TIME_OUT_MASK REG_GENMASK(27, 26)44#define DP_AUX_CH_CTL_TIME_OUT_MASK REG_GENMASK(27, 26)
59#define DP_AUX_CH_CTL_TIME_OUT_400us REG_FIELD_PREP(DP_AUX_CH_CTL_TIME_OUT_MASK, 0)45#define DP_AUX_CH_CTL_TIME_OUT_400us REG_FIELD_PREP(DP_AUX_CH_CTL_TIME_OUT_MASK, 0)
60#define DP_AUX_CH_CTL_TIME_OUT_600us REG_FIELD_PREP(DP_AUX_CH_CTL_TIME_OUT_MASK, 1)46#define DP_AUX_CH_CTL_TIME_OUT_600us REG_FIELD_PREP(DP_AUX_CH_CTL_TIME_OUT_MASK, 1)
@@ -83,4 +69,26 @@ · 22 unmodified lines
83#define DP_AUX_CH_CTL_SYNC_PULSE_SKL_MASK REG_GENMASK(4, 0) /* skl+ */69#define DP_AUX_CH_CTL_SYNC_PULSE_SKL_MASK REG_GENMASK(4, 0) /* skl+ */
84#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) REG_FIELD_PREP(DP_AUX_CH_CTL_SYNC_PULSE_SKL_MASK, (c) - 1)70#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) REG_FIELD_PREP(DP_AUX_CH_CTL_SYNC_PULSE_SKL_MASK, (c) - 1)
85 71
72/* TODO: Remove implicit dev_priv */
73#define _DPA_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64014)
74#define _DPB_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64114)
75#define _XELPDP_USBC1_AUX_CH_DATA1 0x16f214
76#define _XELPDP_USBC2_AUX_CH_DATA1 0x16f414
77#define DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, \
78 _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
79#define _XELPDP_DP_AUX_CH_DATA(aux_ch, i) \
80 _MMIO(_PICK_EVEN_2RANGES(aux_ch, AUX_CH_USBC1, \
81 _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1, \
82 _XELPDP_USBC1_AUX_CH_DATA1, \
83 _XELPDP_USBC2_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
84#define XELPDP_DP_AUX_CH_DATA(i915__, aux_ch, i) \
85 (DISPLAY_VER(i915__) >= 20 ? \
86 _XELPDP_DP_AUX_CH_DATA(__xe2lpd_aux_ch_idx(aux_ch), i) : \
87 _XELPDP_DP_AUX_CH_DATA(aux_ch, i))
88
89/* PICA Power Well Control */
90#define XE2LPD_PICA_PW_CTL _MMIO(0x16fe04)
91#define XE2LPD_PICA_CTL_POWER_REQUEST REG_BIT(31)
92#define XE2LPD_PICA_CTL_POWER_STATUS REG_BIT(30)
93
86#endif /* __INTEL_DP_AUX_REGS_H__ */94#endif /* __INTEL_DP_AUX_REGS_H__ */
drivers/gpu/drm/i915/display/intel_dp_hdcp.c+58−29
@@ -330,14 +330,26 @@ static const struct hdcp2_dp_msg_data hdcp2_dp_msg_data[] = { · 329 unmodified lines
330 0, 0 },330 0, 0 },
331};331};
332 332
333static struct drm_dp_aux *
334intel_dp_hdcp_get_aux(struct intel_connector *connector)
335{
336 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
337
338 if (intel_encoder_is_mst(connector->encoder))
339 return &connector->port->aux;
340 else
341 return &dig_port->dp.aux;
342}
343
333static int344static int
334intel_dp_hdcp2_read_rx_status(struct intel_digital_port *dig_port,345intel_dp_hdcp2_read_rx_status(struct intel_connector *connector,
335 u8 *rx_status)346 u8 *rx_status)
336{347{
337 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);348 struct drm_i915_private *i915 = to_i915(connector->base.dev);
349 struct drm_dp_aux *aux = intel_dp_hdcp_get_aux(connector);
338 ssize_t ret;350 ssize_t ret;
339 351
340 ret = drm_dp_dpcd_read(&dig_port->dp.aux,352 ret = drm_dp_dpcd_read(aux,
341 DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,353 DP_HDCP_2_2_REG_RXSTATUS_OFFSET, rx_status,
342 HDCP_2_2_DP_RXSTATUS_LEN);354 HDCP_2_2_DP_RXSTATUS_LEN);
343 if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {355 if (ret != HDCP_2_2_DP_RXSTATUS_LEN) {
@@ -350,14 +362,14 @@ intel_dp_hdcp2_read_rx_status(struct intel_digital_port *dig_port, · 6 unmodified lines
350}362}
351 363
352static364static
353int hdcp2_detect_msg_availability(struct intel_digital_port *dig_port,365int hdcp2_detect_msg_availability(struct intel_connector *connector,
354 u8 msg_id, bool *msg_ready)366 u8 msg_id, bool *msg_ready)
355{367{
356 u8 rx_status;368 u8 rx_status;
357 int ret;369 int ret;
358 370
359 *msg_ready = false;371 *msg_ready = false;
360 ret = intel_dp_hdcp2_read_rx_status(dig_port, &rx_status);372 ret = intel_dp_hdcp2_read_rx_status(connector, &rx_status);
361 if (ret < 0)373 if (ret < 0)
362 return ret;374 return ret;
363 375
@@ -383,12 +395,11 @@ int hdcp2_detect_msg_availability(struct intel_digital_port *dig_port, · 19 unmodified lines
383}395}
384 396
385static ssize_t397static ssize_t
386intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *dig_port,398intel_dp_hdcp2_wait_for_msg(struct intel_connector *connector,
387 const struct hdcp2_dp_msg_data *hdcp2_msg_data)399 const struct hdcp2_dp_msg_data *hdcp2_msg_data)
388{400{
389 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);401 struct drm_i915_private *i915 = to_i915(connector->base.dev);
390 struct intel_dp *dp = &dig_port->dp;402 struct intel_hdcp *hdcp = &connector->hdcp;
391 struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;
392 u8 msg_id = hdcp2_msg_data->msg_id;403 u8 msg_id = hdcp2_msg_data->msg_id;
393 int ret, timeout;404 int ret, timeout;
394 bool msg_ready = false;405 bool msg_ready = false;
@@ -411,8 +422,8 @@ intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *dig_port, · 16 unmodified lines
411 * the timeout at wait for CP_IRQ.422 * the timeout at wait for CP_IRQ.
412 */423 */
413 intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);424 intel_dp_hdcp_wait_for_cp_irq(hdcp, timeout);
414 ret = hdcp2_detect_msg_availability(dig_port,425 ret = hdcp2_detect_msg_availability(connector, msg_id,
415 msg_id, &msg_ready);426 &msg_ready);
416 if (!msg_ready)427 if (!msg_ready)
417 ret = -ETIMEDOUT;428 ret = -ETIMEDOUT;
418 }429 }
@@ -437,13 +448,14 @@ static const struct hdcp2_dp_msg_data *get_hdcp2_dp_msg_data(u8 msg_id) · 18 unmodified lines
437}448}
438 449
439static450static
440int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port,451int intel_dp_hdcp2_write_msg(struct intel_connector *connector,
441 void *buf, size_t size)452 void *buf, size_t size)
442{453{
443 unsigned int offset;454 unsigned int offset;
444 u8 *byte = buf;455 u8 *byte = buf;
445 ssize_t ret, bytes_to_write, len;456 ssize_t ret, bytes_to_write, len;
446 const struct hdcp2_dp_msg_data *hdcp2_msg_data;457 const struct hdcp2_dp_msg_data *hdcp2_msg_data;
458 struct drm_dp_aux *aux;
447 459
448 hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);460 hdcp2_msg_data = get_hdcp2_dp_msg_data(*byte);
449 if (!hdcp2_msg_data)461 if (!hdcp2_msg_data)
@@ -451,6 +463,8 @@ int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port, · 1 unmodified line
451 463
452 offset = hdcp2_msg_data->offset;464 offset = hdcp2_msg_data->offset;
453 465
466 aux = intel_dp_hdcp_get_aux(connector);
467
454 /* No msg_id in DP HDCP2.2 msgs */468 /* No msg_id in DP HDCP2.2 msgs */
455 bytes_to_write = size - 1;469 bytes_to_write = size - 1;
456 byte++;470 byte++;
@@ -459,7 +473,7 @@ int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port, · 2 unmodified lines
459 len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?473 len = bytes_to_write > DP_AUX_MAX_PAYLOAD_BYTES ?
460 DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;474 DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_write;
461 475
462 ret = drm_dp_dpcd_write(&dig_port->dp.aux,476 ret = drm_dp_dpcd_write(aux,
463 offset, (void *)byte, len);477 offset, (void *)byte, len);
464 if (ret < 0)478 if (ret < 0)
465 return ret;479 return ret;
@@ -473,12 +487,14 @@ int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port, · 7 unmodified lines
473}487}
474 488
475static489static
476ssize_t get_receiver_id_list_rx_info(struct intel_digital_port *dig_port, u32 *dev_cnt, u8 *byte)490ssize_t get_receiver_id_list_rx_info(struct intel_connector *connector,
491 u32 *dev_cnt, u8 *byte)
477{492{
493 struct drm_dp_aux *aux = intel_dp_hdcp_get_aux(connector);
478 ssize_t ret;494 ssize_t ret;
479 u8 *rx_info = byte;495 u8 *rx_info = byte;
480 496
481 ret = drm_dp_dpcd_read(&dig_port->dp.aux,497 ret = drm_dp_dpcd_read(aux,
482 DP_HDCP_2_2_REG_RXINFO_OFFSET,498 DP_HDCP_2_2_REG_RXINFO_OFFSET,
483 (void *)rx_info, HDCP_2_2_RXINFO_LEN);499 (void *)rx_info, HDCP_2_2_RXINFO_LEN);
484 if (ret != HDCP_2_2_RXINFO_LEN)500 if (ret != HDCP_2_2_RXINFO_LEN)
@@ -494,12 +510,13 @@ ssize_t get_receiver_id_list_rx_info(struct intel_digital_port *dig_port, u32 *d · 9 unmodified lines
494}510}
495 511
496static512static
497int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port,513int intel_dp_hdcp2_read_msg(struct intel_connector *connector,
498 u8 msg_id, void *buf, size_t size)514 u8 msg_id, void *buf, size_t size)
499{515{
516 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
500 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);517 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
501 struct intel_dp *dp = &dig_port->dp;518 struct intel_hdcp *hdcp = &connector->hdcp;
502 struct intel_hdcp *hdcp = &dp->attached_connector->hdcp;519 struct drm_dp_aux *aux;
503 unsigned int offset;520 unsigned int offset;
504 u8 *byte = buf;521 u8 *byte = buf;
505 ssize_t ret, bytes_to_recv, len;522 ssize_t ret, bytes_to_recv, len;
@@ -513,7 +530,9 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, · 7 unmodified lines
513 return -EINVAL;530 return -EINVAL;
514 offset = hdcp2_msg_data->offset;531 offset = hdcp2_msg_data->offset;
515 532
516 ret = intel_dp_hdcp2_wait_for_msg(dig_port, hdcp2_msg_data);533 aux = intel_dp_hdcp_get_aux(connector);
534
535 ret = intel_dp_hdcp2_wait_for_msg(connector, hdcp2_msg_data);
517 if (ret < 0)536 if (ret < 0)
518 return ret;537 return ret;
519 538
@@ -523,7 +542,7 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, · 3 unmodified lines
523 byte++;542 byte++;
524 543
525 if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {544 if (msg_id == HDCP_2_2_REP_SEND_RECVID_LIST) {
526 ret = get_receiver_id_list_rx_info(dig_port, &dev_cnt, byte);545 ret = get_receiver_id_list_rx_info(connector, &dev_cnt, byte);
527 if (ret < 0)546 if (ret < 0)
528 return ret;547 return ret;
529 548
@@ -541,11 +560,17 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, · 11 unmodified lines
541 DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;560 DP_AUX_MAX_PAYLOAD_BYTES : bytes_to_recv;
542 561
543 /* Entire msg read timeout since initiate of msg read */562 /* Entire msg read timeout since initiate of msg read */
544 if (bytes_to_recv == size - 1 && hdcp2_msg_data->msg_read_timeout > 0)563 if (bytes_to_recv == size - 1 && hdcp2_msg_data->msg_read_timeout > 0) {
545 msg_end = ktime_add_ms(ktime_get_raw(),564 if (intel_encoder_is_mst(connector->encoder))
546 hdcp2_msg_data->msg_read_timeout);565 msg_end = ktime_add_ms(ktime_get_raw(),
566 hdcp2_msg_data->msg_read_timeout *
567 connector->port->parent->num_ports);
568 else
569 msg_end = ktime_add_ms(ktime_get_raw(),
570 hdcp2_msg_data->msg_read_timeout);
571 }
547 572
548 ret = drm_dp_dpcd_read(&dig_port->dp.aux, offset,573 ret = drm_dp_dpcd_read(aux, offset,
549 (void *)byte, len);574 (void *)byte, len);
550 if (ret < 0) {575 if (ret < 0) {
551 drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",576 drm_dbg_kms(&i915->drm, "msg_id %d, ret %zd\n",
@@ -574,7 +599,7 @@ int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, · 22 unmodified lines
574}599}
575 600
576static601static
577int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *dig_port,602int intel_dp_hdcp2_config_stream_type(struct intel_connector *connector,
578 bool is_repeater, u8 content_type)603 bool is_repeater, u8 content_type)
579{604{
580 int ret;605 int ret;
@@ -593,7 +618,7 @@ int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *dig_port, · 12 unmodified lines
593 stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;618 stream_type_msg.msg_id = HDCP_2_2_ERRATA_DP_STREAM_TYPE;
594 stream_type_msg.stream_type = content_type;619 stream_type_msg.stream_type = content_type;
595 620
596 ret = intel_dp_hdcp2_write_msg(dig_port, &stream_type_msg,621 ret = intel_dp_hdcp2_write_msg(connector, &stream_type_msg,
597 sizeof(stream_type_msg));622 sizeof(stream_type_msg));
598 623
599 return ret < 0 ? ret : 0;624 return ret < 0 ? ret : 0;
@@ -607,7 +632,8 @@ int intel_dp_hdcp2_check_link(struct intel_digital_port *dig_port, · 7 unmodified lines
607 u8 rx_status;632 u8 rx_status;
608 int ret;633 int ret;
609 634
610 ret = intel_dp_hdcp2_read_rx_status(dig_port, &rx_status);635 ret = intel_dp_hdcp2_read_rx_status(connector,
636 &rx_status);
611 if (ret)637 if (ret)
612 return ret;638 return ret;
613 639
@@ -622,14 +648,17 @@ int intel_dp_hdcp2_check_link(struct intel_digital_port *dig_port, · 8 unmodified lines
622}648}
623 649
624static650static
625int intel_dp_hdcp2_capable(struct intel_digital_port *dig_port,651int intel_dp_hdcp2_capable(struct intel_connector *connector,
626 bool *capable)652 bool *capable)
627{653{
654 struct drm_dp_aux *aux;
628 u8 rx_caps[3];655 u8 rx_caps[3];
629 int ret;656 int ret;
630 657
658 aux = intel_dp_hdcp_get_aux(connector);
659
631 *capable = false;660 *capable = false;
632 ret = drm_dp_dpcd_read(&dig_port->dp.aux,661 ret = drm_dp_dpcd_read(aux,
633 DP_HDCP_2_2_REG_RX_CAPS_OFFSET,662 DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
634 rx_caps, HDCP_2_2_RXCAPS_LEN);663 rx_caps, HDCP_2_2_RXCAPS_LEN);
635 if (ret != HDCP_2_2_RXCAPS_LEN)664 if (ret != HDCP_2_2_RXCAPS_LEN)
drivers/gpu/drm/i915/display/intel_dp_link_training.c+8−6
@@ -655,7 +655,7 @@ intel_dp_update_link_bw_set(struct intel_dp *intel_dp, · 654 unmodified lines
655 /* Write the link configuration data */655 /* Write the link configuration data */
656 link_config[0] = link_bw;656 link_config[0] = link_bw;
657 link_config[1] = crtc_state->lane_count;657 link_config[1] = crtc_state->lane_count;
658 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))658 if (crtc_state->enhanced_framing)
659 link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;659 link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
660 drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);660 drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2);
661 661
@@ -1390,11 +1390,13 @@ void intel_dp_128b132b_sdp_crc16(struct intel_dp *intel_dp, · 728 unmodified lines
1390 * Default value of bit 31 is '0' hence discarding the write1390 * Default value of bit 31 is '0' hence discarding the write
1391 * TODO: Corrective actions on SDP corruption yet to be defined1391 * TODO: Corrective actions on SDP corruption yet to be defined
1392 */1392 */
1393 if (intel_dp_is_uhbr(crtc_state))1393 if (!intel_dp_is_uhbr(crtc_state))
1394 /* DP v2.0 SCR on SDP CRC16 for 128b/132b Link Layer */1394 return;
1395 drm_dp_dpcd_writeb(&intel_dp->aux,1395
1396 DP_SDP_ERROR_DETECTION_CONFIGURATION,1396 /* DP v2.0 SCR on SDP CRC16 for 128b/132b Link Layer */
1397 DP_SDP_CRC16_128B132B_EN);1397 drm_dp_dpcd_writeb(&intel_dp->aux,
1398 DP_SDP_ERROR_DETECTION_CONFIGURATION,
1399 DP_SDP_CRC16_128B132B_EN);
1398 1400
1399 lt_dbg(intel_dp, DP_PHY_DPRX, "DP2.0 SDP CRC16 for 128b/132b enabled\n");1401 lt_dbg(intel_dp, DP_PHY_DPRX, "DP2.0 SDP CRC16 for 128b/132b enabled\n");
1400}1402}
drivers/gpu/drm/i915/display/intel_dp_mst.c+97−59
@@ -155,15 +155,24 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, · 154 unmodified lines
155 const struct drm_display_mode *adjusted_mode =155 const struct drm_display_mode *adjusted_mode =
156 &crtc_state->hw.adjusted_mode;156 &crtc_state->hw.adjusted_mode;
157 int slots = -EINVAL;157 int slots = -EINVAL;
158 int link_bpp;
158 159
159 slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, limits->max_bpp,160 /*
160 limits->min_bpp, limits,161 * FIXME: allocate the BW according to link_bpp, which in the case of
162 * YUV420 is only half of the pipe bpp value.
163 */
164 slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state,
165 to_bpp_int(limits->link.max_bpp_x16),
166 to_bpp_int(limits->link.min_bpp_x16),
167 limits,
161 conn_state, 2 * 3, false);168 conn_state, 2 * 3, false);
162 169
163 if (slots < 0)170 if (slots < 0)
164 return slots;171 return slots;
165 172
166 intel_link_compute_m_n(crtc_state->pipe_bpp,173 link_bpp = intel_dp_output_bpp(crtc_state->output_format, crtc_state->pipe_bpp);
174
175 intel_link_compute_m_n(link_bpp,
167 crtc_state->lane_count,176 crtc_state->lane_count,
168 adjusted_mode->crtc_clock,177 adjusted_mode->crtc_clock,
169 crtc_state->port_clock,178 crtc_state->port_clock,
@@ -200,8 +209,8 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, · 30 unmodified lines
200 else209 else
201 dsc_max_bpc = min_t(u8, 10, conn_state->max_requested_bpc);210 dsc_max_bpc = min_t(u8, 10, conn_state->max_requested_bpc);
202 211
203 max_bpp = min_t(u8, dsc_max_bpc * 3, limits->max_bpp);212 max_bpp = min_t(u8, dsc_max_bpc * 3, limits->pipe.max_bpp);
204 min_bpp = limits->min_bpp;213 min_bpp = limits->pipe.min_bpp;
205 214
206 num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,215 num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
207 dsc_bpc);216 dsc_bpc);
@@ -228,6 +237,9 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, · 20 unmodified lines
228 if (max_bpp > sink_max_bpp)237 if (max_bpp > sink_max_bpp)
229 max_bpp = sink_max_bpp;238 max_bpp = sink_max_bpp;
230 239
240 min_bpp = max(min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16));
241 max_bpp = min(max_bpp, to_bpp_int(limits->link.max_bpp_x16));
242
231 slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, max_bpp,243 slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, max_bpp,
232 min_bpp, limits,244 min_bpp, limits,
233 conn_state, 2 * 3, true);245 conn_state, 2 * 3, true);
@@ -290,17 +302,39 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, · 56 unmodified lines
290 return 0;302 return 0;
291}303}
292 304
293static bool intel_dp_mst_has_audio(const struct drm_connector_state *conn_state)305static bool
306intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp,
307 struct intel_crtc_state *crtc_state,
308 bool dsc,
309 struct link_config_limits *limits)
294{310{
295 const struct intel_digital_connector_state *intel_conn_state =311 /*
296 to_intel_digital_connector_state(conn_state);312 * for MST we always configure max link bw - the spec doesn't
297 struct intel_connector *connector =313 * seem to suggest we should do otherwise.
298 to_intel_connector(conn_state->connector);314 */
315 limits->min_rate = limits->max_rate =
316 intel_dp_max_link_rate(intel_dp);
299 317
300 if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)318 limits->min_lane_count = limits->max_lane_count =
301 return connector->base.display_info.has_audio;319 intel_dp_max_lane_count(intel_dp);
302 else320
303 return intel_conn_state->force_audio == HDMI_AUDIO_ON;321 limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format);
322 /*
323 * FIXME: If all the streams can't fit into the link with
324 * their current pipe_bpp we should reduce pipe_bpp across
325 * the board until things start to fit. Until then we
326 * limit to <= 8bpc since that's what was hardcoded for all
327 * MST streams previously. This hack should be removed once
328 * we have the proper retry logic in place.
329 */
330 limits->pipe.max_bpp = min(crtc_state->pipe_bpp, 24);
331
332 intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
333
334 return intel_dp_compute_config_link_bpp_limits(intel_dp,
335 crtc_state,
336 dsc,
337 limits);
304}338}
305 339
306static int intel_dp_mst_compute_config(struct intel_encoder *encoder,340static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
@@ -313,7 +347,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, · 6 unmodified lines
313 const struct drm_display_mode *adjusted_mode =347 const struct drm_display_mode *adjusted_mode =
314 &pipe_config->hw.adjusted_mode;348 &pipe_config->hw.adjusted_mode;
315 struct link_config_limits limits;349 struct link_config_limits limits;
316 int ret;350 bool dsc_needed;
351 int ret = 0;
317 352
318 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)353 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
319 return -EINVAL;354 return -EINVAL;
@@ -322,42 +357,40 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, · 2 unmodified lines
322 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;357 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
323 pipe_config->has_pch_encoder = false;358 pipe_config->has_pch_encoder = false;
324 359
325 pipe_config->has_audio =360 dsc_needed = intel_dp->force_dsc_en ||
326 intel_dp_mst_has_audio(conn_state) &&361 !intel_dp_mst_compute_config_limits(intel_dp,
327 intel_audio_compute_config(encoder, pipe_config, conn_state);362 pipe_config,
363 false,
364 &limits);
328 365
329 /*366 if (!dsc_needed) {
330 * for MST we always configure max link bw - the spec doesn't367 ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
331 * seem to suggest we should do otherwise.368 conn_state, &limits);
332 */
333 limits.min_rate =
334 limits.max_rate = intel_dp_max_link_rate(intel_dp);
335 369
336 limits.min_lane_count =370 if (ret == -EDEADLK)
337 limits.max_lane_count = intel_dp_max_lane_count(intel_dp);371 return ret;
338
339 limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format);
340 /*
341 * FIXME: If all the streams can't fit into the link with
342 * their current pipe_bpp we should reduce pipe_bpp across
343 * the board until things start to fit. Until then we
344 * limit to <= 8bpc since that's what was hardcoded for all
345 * MST streams previously. This hack should be removed once
346 * we have the proper retry logic in place.
347 */
348 limits.max_bpp = min(pipe_config->pipe_bpp, 24);
349
350 intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
351
352 ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
353 conn_state, &limits);
354 372
355 if (ret == -EDEADLK)373 if (ret)
356 return ret;374 dsc_needed = true;
375 }
357 376
358 /* enable compression if the mode doesn't fit available BW */377 /* enable compression if the mode doesn't fit available BW */
359 drm_dbg_kms(&dev_priv->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en);378 if (dsc_needed) {
360 if (ret || intel_dp->force_dsc_en) {379 drm_dbg_kms(&dev_priv->drm, "Try DSC (fallback=%s, force=%s)\n",
380 str_yes_no(ret),
381 str_yes_no(intel_dp->force_dsc_en));
382
383 if (!intel_dp_mst_compute_config_limits(intel_dp,
384 pipe_config,
385 true,
386 &limits))
387 return -EINVAL;
388
389 /*
390 * FIXME: As bpc is hardcoded to 8, as mentioned above,
391 * WARN and ignore the debug flag force_dsc_bpc for now.
392 */
393 drm_WARN(&dev_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force BPC for MST\n");
361 /*394 /*
362 * Try to get at least some timeslots and then see, if395 * Try to get at least some timeslots and then see, if
363 * we can fit there with DSC.396 * we can fit there with DSC.
@@ -388,6 +421,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, · 24 unmodified lines
388 pipe_config->lane_lat_optim_mask =421 pipe_config->lane_lat_optim_mask =
389 bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);422 bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
390 423
424 intel_dp_audio_compute_config(encoder, pipe_config, conn_state);
425
391 intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);426 intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
392 427
393 return 0;428 return 0;
@@ -733,8 +768,8 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, · 339 unmodified lines
733 ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state,768 ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state,
734 drm_atomic_get_mst_payload_state(mst_state, connector->port));769 drm_atomic_get_mst_payload_state(mst_state, connector->port));
735 if (ret < 0)770 if (ret < 0)
736 drm_err(&dev_priv->drm, "Failed to create MST payload for %s: %d\n",771 drm_dbg_kms(&dev_priv->drm, "Failed to create MST payload for %s: %d\n",
737 connector->base.name, ret);772 connector->base.name, ret);
738 773
739 /*774 /*
740 * Before Gen 12 this is not done as part of775 * Before Gen 12 this is not done as part of
@@ -798,6 +833,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, · 57 unmodified lines
798 intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0,833 intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0,
799 FECSTALL_DIS_DPTSTREAM_DPTTG);834 FECSTALL_DIS_DPTSTREAM_DPTTG);
800 835
836 intel_audio_sdp_split_update(pipe_config);
837
801 intel_enable_transcoder(pipe_config);838 intel_enable_transcoder(pipe_config);
802 839
803 intel_crtc_vblank_on(pipe_config);840 intel_crtc_vblank_on(pipe_config);
@@ -918,7 +955,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, · 114 unmodified lines
918 int max_rate, mode_rate, max_lanes, max_link_clock;955 int max_rate, mode_rate, max_lanes, max_link_clock;
919 int ret;956 int ret;
920 bool dsc = false, bigjoiner = false;957 bool dsc = false, bigjoiner = false;
921 u16 dsc_max_output_bpp = 0;958 u16 dsc_max_compressed_bpp = 0;
922 u8 dsc_slice_count = 0;959 u8 dsc_slice_count = 0;
923 int target_clock = mode->clock;960 int target_clock = mode->clock;
924 961
@@ -969,17 +1006,18 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, · 44 unmodified lines
969 * TBD pass the connector BPC,1006 * TBD pass the connector BPC,
970 * for now U8_MAX so that max BPC on that platform would be picked1007 * for now U8_MAX so that max BPC on that platform would be picked
971 */1008 */
972 int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX);1009 int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
973 1010
974 if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {1011 if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
975 dsc_max_output_bpp =1012 dsc_max_compressed_bpp =
976 intel_dp_dsc_get_output_bpp(dev_priv,1013 intel_dp_dsc_get_max_compressed_bpp(dev_priv,
977 max_link_clock,1014 max_link_clock,
978 max_lanes,1015 max_lanes,
979 target_clock,1016 target_clock,
980 mode->hdisplay,1017 mode->hdisplay,
981 bigjoiner,1018 bigjoiner,
982 pipe_bpp, 64) >> 4;1019 INTEL_OUTPUT_FORMAT_RGB,
1020 pipe_bpp, 64);
983 dsc_slice_count =1021 dsc_slice_count =
984 intel_dp_dsc_get_slice_count(intel_dp,1022 intel_dp_dsc_get_slice_count(intel_dp,
985 target_clock,1023 target_clock,
@@ -987,7 +1025,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, · 1 unmodified line
987 bigjoiner);1025 bigjoiner);
988 }1026 }
989 1027
990 dsc = dsc_max_output_bpp && dsc_slice_count;1028 dsc = dsc_max_compressed_bpp && dsc_slice_count;
991 }1029 }
992 1030
993 /*1031 /*
drivers/gpu/drm/i915/display/intel_dpll.c+35−19
@@ -314,10 +314,11 @@ int pnv_calc_dpll_params(int refclk, struct dpll *clock) · 313 unmodified lines
314{314{
315 clock->m = clock->m2 + 2;315 clock->m = clock->m2 + 2;
316 clock->p = clock->p1 * clock->p2;316 clock->p = clock->p1 * clock->p2;
317 if (WARN_ON(clock->n == 0 || clock->p == 0))317
318 return 0;318 clock->vco = clock->n == 0 ? 0 :
319 clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);319 DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
320 clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);320 clock->dot = clock->p == 0 ? 0 :
321 DIV_ROUND_CLOSEST(clock->vco, clock->p);
321 322
322 return clock->dot;323 return clock->dot;
323}324}
@@ -331,10 +332,11 @@ int i9xx_calc_dpll_params(int refclk, struct dpll *clock) · 7 unmodified lines
331{332{
332 clock->m = i9xx_dpll_compute_m(clock);333 clock->m = i9xx_dpll_compute_m(clock);
333 clock->p = clock->p1 * clock->p2;334 clock->p = clock->p1 * clock->p2;
334 if (WARN_ON(clock->n + 2 == 0 || clock->p == 0))335
335 return 0;336 clock->vco = clock->n + 2 == 0 ? 0 :
336 clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);337 DIV_ROUND_CLOSEST(refclk * clock->m, clock->n + 2);
337 clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);338 clock->dot = clock->p == 0 ? 0 :
339 DIV_ROUND_CLOSEST(clock->vco, clock->p);
338 340
339 return clock->dot;341 return clock->dot;
340}342}
@@ -343,10 +345,11 @@ int vlv_calc_dpll_params(int refclk, struct dpll *clock) · 2 unmodified lines
343{345{
344 clock->m = clock->m1 * clock->m2;346 clock->m = clock->m1 * clock->m2;
345 clock->p = clock->p1 * clock->p2 * 5;347 clock->p = clock->p1 * clock->p2 * 5;
346 if (WARN_ON(clock->n == 0 || clock->p == 0))348
347 return 0;349 clock->vco = clock->n == 0 ? 0 :
348 clock->vco = DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);350 DIV_ROUND_CLOSEST(refclk * clock->m, clock->n);
349 clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);351 clock->dot = clock->p == 0 ? 0 :
352 DIV_ROUND_CLOSEST(clock->vco, clock->p);
350 353
351 return clock->dot;354 return clock->dot;
352}355}
@@ -355,11 +358,11 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock) · 2 unmodified lines
355{358{
356 clock->m = clock->m1 * clock->m2;359 clock->m = clock->m1 * clock->m2;
357 clock->p = clock->p1 * clock->p2 * 5;360 clock->p = clock->p1 * clock->p2 * 5;
358 if (WARN_ON(clock->n == 0 || clock->p == 0))361
359 return 0;362 clock->vco = clock->n == 0 ? 0 :
360 clock->vco = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, clock->m),363 DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, clock->m), clock->n << 22);
361 clock->n << 22);364 clock->dot = clock->p == 0 ? 0 :
362 clock->dot = DIV_ROUND_CLOSEST(clock->vco, clock->p);365 DIV_ROUND_CLOSEST(clock->vco, clock->p);
363 366
364 return clock->dot;367 return clock->dot;
365}368}
@@ -1179,6 +1182,8 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state, · 813 unmodified lines
1179 refclk, NULL, &crtc_state->dpll))1182 refclk, NULL, &crtc_state->dpll))
1180 return -EINVAL;1183 return -EINVAL;
1181 1184
1185 i9xx_calc_dpll_params(refclk, &crtc_state->dpll);
1186
1182 ilk_compute_dpll(crtc_state, &crtc_state->dpll,1187 ilk_compute_dpll(crtc_state, &crtc_state->dpll,
1183 &crtc_state->dpll);1188 &crtc_state->dpll);
1184 1189
@@ -1253,6 +1258,8 @@ static int chv_crtc_compute_clock(struct intel_atomic_state *state, · 68 unmodified lines
1253 refclk, NULL, &crtc_state->dpll))1258 refclk, NULL, &crtc_state->dpll))
1254 return -EINVAL;1259 return -EINVAL;
1255 1260
1261 chv_calc_dpll_params(refclk, &crtc_state->dpll);
1262
1256 chv_compute_dpll(crtc_state);1263 chv_compute_dpll(crtc_state);
1257 1264
1258 /* FIXME this is a mess */1265 /* FIXME this is a mess */
@@ -1275,9 +1282,10 @@ static int vlv_crtc_compute_clock(struct intel_atomic_state *state, · 16 unmodified lines
1275 1282
1276 if (!crtc_state->clock_set &&1283 if (!crtc_state->clock_set &&
1277 !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,1284 !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock,
1278 refclk, NULL, &crtc_state->dpll)) {1285 refclk, NULL, &crtc_state->dpll))
1279 return -EINVAL;1286 return -EINVAL;
1280 }1287
1288 vlv_calc_dpll_params(refclk, &crtc_state->dpll);
1281 1289
1282 vlv_compute_dpll(crtc_state);1290 vlv_compute_dpll(crtc_state);
1283 1291
@@ -1327,6 +1335,8 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state, · 43 unmodified lines
1327 refclk, NULL, &crtc_state->dpll))1335 refclk, NULL, &crtc_state->dpll))
1328 return -EINVAL;1336 return -EINVAL;
1329 1337
1338 i9xx_calc_dpll_params(refclk, &crtc_state->dpll);
1339
1330 i9xx_compute_dpll(crtc_state, &crtc_state->dpll,1340 i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
1331 &crtc_state->dpll);1341 &crtc_state->dpll);
1332 1342
@@ -1365,6 +1375,8 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state, · 32 unmodified lines
1365 refclk, NULL, &crtc_state->dpll))1375 refclk, NULL, &crtc_state->dpll))
1366 return -EINVAL;1376 return -EINVAL;
1367 1377
1378 pnv_calc_dpll_params(refclk, &crtc_state->dpll);
1379
1368 i9xx_compute_dpll(crtc_state, &crtc_state->dpll,1380 i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
1369 &crtc_state->dpll);1381 &crtc_state->dpll);
1370 1382
@@ -1401,6 +1413,8 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state, · 30 unmodified lines
1401 refclk, NULL, &crtc_state->dpll))1413 refclk, NULL, &crtc_state->dpll))
1402 return -EINVAL;1414 return -EINVAL;
1403 1415
1416 i9xx_calc_dpll_params(refclk, &crtc_state->dpll);
1417
1404 i9xx_compute_dpll(crtc_state, &crtc_state->dpll,1418 i9xx_compute_dpll(crtc_state, &crtc_state->dpll,
1405 &crtc_state->dpll);1419 &crtc_state->dpll);
1406 1420
@@ -1441,6 +1455,8 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state, · 34 unmodified lines
1441 refclk, NULL, &crtc_state->dpll))1455 refclk, NULL, &crtc_state->dpll))
1442 return -EINVAL;1456 return -EINVAL;
1443 1457
1458 i9xx_calc_dpll_params(refclk, &crtc_state->dpll);
1459
1444 i8xx_compute_dpll(crtc_state, &crtc_state->dpll,1460 i8xx_compute_dpll(crtc_state, &crtc_state->dpll,
1445 &crtc_state->dpll);1461 &crtc_state->dpll);
1446 1462
drivers/gpu/drm/i915/display/intel_dpt.c+1−1
@@ -29,7 +29,7 @@ static inline struct i915_dpt * · 28 unmodified lines
29i915_vm_to_dpt(struct i915_address_space *vm)29i915_vm_to_dpt(struct i915_address_space *vm)
30{30{
31 BUILD_BUG_ON(offsetof(struct i915_dpt, vm));31 BUILD_BUG_ON(offsetof(struct i915_dpt, vm));
32 GEM_BUG_ON(!i915_is_dpt(vm));32 drm_WARN_ON(&vm->i915->drm, !i915_is_dpt(vm));
33 return container_of(vm, struct i915_dpt, vm);33 return container_of(vm, struct i915_dpt, vm);
34}34}
35 35
drivers/gpu/drm/i915/display/intel_drrs.c+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include "intel_de.h"9#include "intel_de.h"
10#include "intel_display_types.h"10#include "intel_display_types.h"
11#include "intel_drrs.h"11#include "intel_drrs.h"
12#include "intel_frontbuffer.h"
12#include "intel_panel.h"13#include "intel_panel.h"
13 14
14/**15/**
drivers/gpu/drm/i915/display/intel_dsb.c+188−29
@@ -7,11 +7,16 @@ · 6 unmodified lines
7#include "gem/i915_gem_internal.h"7#include "gem/i915_gem_internal.h"
8 8
9#include "i915_drv.h"9#include "i915_drv.h"
10#include "i915_irq.h"
10#include "i915_reg.h"11#include "i915_reg.h"
12#include "intel_crtc.h"
11#include "intel_de.h"13#include "intel_de.h"
12#include "intel_display_types.h"14#include "intel_display_types.h"
13#include "intel_dsb.h"15#include "intel_dsb.h"
14#include "intel_dsb_regs.h"16#include "intel_dsb_regs.h"
17#include "intel_vblank.h"
18#include "intel_vrr.h"
19#include "skl_watermark.h"
15 20
16struct i915_vma;21struct i915_vma;
17 22
@@ -47,6 +52,8 @@ struct intel_dsb { · 29 unmodified lines
47 * register.52 * register.
48 */53 */
49 unsigned int ins_start_offset;54 unsigned int ins_start_offset;
55
56 int dewake_scanline;
50};57};
51 58
52/**59/**
@@ -70,17 +77,21 @@ struct intel_dsb { · 17 unmodified lines
70#define DSB_OPCODE_SHIFT 2477#define DSB_OPCODE_SHIFT 24
71#define DSB_OPCODE_NOOP 0x078#define DSB_OPCODE_NOOP 0x0
72#define DSB_OPCODE_MMIO_WRITE 0x179#define DSB_OPCODE_MMIO_WRITE 0x1
80#define DSB_BYTE_EN 0xf
81#define DSB_BYTE_EN_SHIFT 20
82#define DSB_REG_VALUE_MASK 0xfffff
73#define DSB_OPCODE_WAIT_USEC 0x283#define DSB_OPCODE_WAIT_USEC 0x2
74#define DSB_OPCODE_WAIT_LINES 0x384#define DSB_OPCODE_WAIT_SCANLINE 0x3
75#define DSB_OPCODE_WAIT_VBLANKS 0x485#define DSB_OPCODE_WAIT_VBLANKS 0x4
76#define DSB_OPCODE_WAIT_DSL_IN 0x586#define DSB_OPCODE_WAIT_DSL_IN 0x5
77#define DSB_OPCODE_WAIT_DSL_OUT 0x687#define DSB_OPCODE_WAIT_DSL_OUT 0x6
88#define DSB_SCANLINE_UPPER_SHIFT 20
89#define DSB_SCANLINE_LOWER_SHIFT 0
78#define DSB_OPCODE_INTERRUPT 0x790#define DSB_OPCODE_INTERRUPT 0x7
79#define DSB_OPCODE_INDEXED_WRITE 0x991#define DSB_OPCODE_INDEXED_WRITE 0x9
92/* see DSB_REG_VALUE_MASK */
80#define DSB_OPCODE_POLL 0xA93#define DSB_OPCODE_POLL 0xA
81#define DSB_BYTE_EN 0xF94/* see DSB_REG_VALUE_MASK */
82#define DSB_BYTE_EN_SHIFT 20
83#define DSB_REG_VALUE_MASK 0xfffff
84 95
85static bool assert_dsb_has_room(struct intel_dsb *dsb)96static bool assert_dsb_has_room(struct intel_dsb *dsb)
86{97{
@@ -93,10 +104,26 @@ static bool assert_dsb_has_room(struct intel_dsb *dsb) · 6 unmodified lines
93 crtc->base.base.id, crtc->base.name, dsb->id);104 crtc->base.base.id, crtc->base.name, dsb->id);
94}105}
95 106
107static void intel_dsb_dump(struct intel_dsb *dsb)
108{
109 struct intel_crtc *crtc = dsb->crtc;
110 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
111 const u32 *buf = dsb->cmd_buf;
112 int i;
113
114 drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] DSB %d commands {\n",
115 crtc->base.base.id, crtc->base.name, dsb->id);
116 for (i = 0; i < ALIGN(dsb->free_pos, 64 / 4); i += 4)
117 drm_dbg_kms(&i915->drm,
118 " 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
119 i * 4, buf[i], buf[i+1], buf[i+2], buf[i+3]);
120 drm_dbg_kms(&i915->drm, "}\n");
121}
122
96static bool is_dsb_busy(struct drm_i915_private *i915, enum pipe pipe,123static bool is_dsb_busy(struct drm_i915_private *i915, enum pipe pipe,
97 enum dsb_id id)124 enum dsb_id id)
98{125{
99 return intel_de_read(i915, DSB_CTRL(pipe, id)) & DSB_STATUS_BUSY;126 return intel_de_read_fw(i915, DSB_CTRL(pipe, id)) & DSB_STATUS_BUSY;
100}127}
101 128
102static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw)129static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw)
@@ -121,7 +148,15 @@ static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb, · 18 unmodified lines
121 const u32 *buf = dsb->cmd_buf;148 const u32 *buf = dsb->cmd_buf;
122 u32 prev_opcode, prev_reg;149 u32 prev_opcode, prev_reg;
123 150
124 prev_opcode = buf[dsb->ins_start_offset + 1] >> DSB_OPCODE_SHIFT;151 /*
152 * Nothing emitted yet? Must check before looking
153 * at the actual data since i915_gem_object_create_internal()
154 * does *not* give you zeroed memory!
155 */
156 if (dsb->free_pos == 0)
157 return false;
158
159 prev_opcode = buf[dsb->ins_start_offset + 1] & ~DSB_REG_VALUE_MASK;
125 prev_reg = buf[dsb->ins_start_offset + 1] & DSB_REG_VALUE_MASK;160 prev_reg = buf[dsb->ins_start_offset + 1] & DSB_REG_VALUE_MASK;
126 161
127 return prev_opcode == opcode && prev_reg == i915_mmio_reg_offset(reg);162 return prev_opcode == opcode && prev_reg == i915_mmio_reg_offset(reg);
@@ -129,12 +164,18 @@ static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb, · 1 unmodified line
129 164
130static bool intel_dsb_prev_ins_is_mmio_write(struct intel_dsb *dsb, i915_reg_t reg)165static bool intel_dsb_prev_ins_is_mmio_write(struct intel_dsb *dsb, i915_reg_t reg)
131{166{
132 return intel_dsb_prev_ins_is_write(dsb, DSB_OPCODE_MMIO_WRITE, reg);167 /* only full byte-enables can be converted to indexed writes */
168 return intel_dsb_prev_ins_is_write(dsb,
169 DSB_OPCODE_MMIO_WRITE << DSB_OPCODE_SHIFT |
170 DSB_BYTE_EN << DSB_BYTE_EN_SHIFT,
171 reg);
133}172}
134 173
135static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_t reg)174static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_t reg)
136{175{
137 return intel_dsb_prev_ins_is_write(dsb, DSB_OPCODE_INDEXED_WRITE, reg);176 return intel_dsb_prev_ins_is_write(dsb,
177 DSB_OPCODE_INDEXED_WRITE << DSB_OPCODE_SHIFT,
178 reg);
138}179}
139 180
140/**181/**
@@ -200,6 +241,53 @@ void intel_dsb_reg_write(struct intel_dsb *dsb, · 59 unmodified lines
200 }241 }
201}242}
202 243
244static u32 intel_dsb_mask_to_byte_en(u32 mask)
245{
246 return (!!(mask & 0xff000000) << 3 |
247 !!(mask & 0x00ff0000) << 2 |
248 !!(mask & 0x0000ff00) << 1 |
249 !!(mask & 0x000000ff) << 0);
250}
251
252/* Note: mask implemented via byte enables! */
253void intel_dsb_reg_write_masked(struct intel_dsb *dsb,
254 i915_reg_t reg, u32 mask, u32 val)
255{
256 intel_dsb_emit(dsb, val,
257 (DSB_OPCODE_MMIO_WRITE << DSB_OPCODE_SHIFT) |
258 (intel_dsb_mask_to_byte_en(mask) << DSB_BYTE_EN_SHIFT) |
259 i915_mmio_reg_offset(reg));
260}
261
262void intel_dsb_noop(struct intel_dsb *dsb, int count)
263{
264 int i;
265
266 for (i = 0; i < count; i++)
267 intel_dsb_emit(dsb, 0,
268 DSB_OPCODE_NOOP << DSB_OPCODE_SHIFT);
269}
270
271void intel_dsb_nonpost_start(struct intel_dsb *dsb)
272{
273 struct intel_crtc *crtc = dsb->crtc;
274 enum pipe pipe = crtc->pipe;
275
276 intel_dsb_reg_write_masked(dsb, DSB_CTRL(pipe, dsb->id),
277 DSB_NON_POSTED, DSB_NON_POSTED);
278 intel_dsb_noop(dsb, 4);
279}
280
281void intel_dsb_nonpost_end(struct intel_dsb *dsb)
282{
283 struct intel_crtc *crtc = dsb->crtc;
284 enum pipe pipe = crtc->pipe;
285
286 intel_dsb_reg_write_masked(dsb, DSB_CTRL(pipe, dsb->id),
287 DSB_NON_POSTED, 0);
288 intel_dsb_noop(dsb, 4);
289}
290
203static void intel_dsb_align_tail(struct intel_dsb *dsb)291static void intel_dsb_align_tail(struct intel_dsb *dsb)
204{292{
205 u32 aligned_tail, tail;293 u32 aligned_tail, tail;
@@ -216,17 +304,40 @@ static void intel_dsb_align_tail(struct intel_dsb *dsb) · 10 unmodified lines
216 304
217void intel_dsb_finish(struct intel_dsb *dsb)305void intel_dsb_finish(struct intel_dsb *dsb)
218{306{
307 struct intel_crtc *crtc = dsb->crtc;
308
309 /*
310 * DSB_FORCE_DEWAKE remains active even after DSB is
311 * disabled, so make sure to clear it (if set during
312 * intel_dsb_commit()).
313 */
314 intel_dsb_reg_write_masked(dsb, DSB_PMCTRL_2(crtc->pipe, dsb->id),
315 DSB_FORCE_DEWAKE, 0);
316
219 intel_dsb_align_tail(dsb);317 intel_dsb_align_tail(dsb);
220}318}
221 319
222/**320static int intel_dsb_dewake_scanline(const struct intel_crtc_state *crtc_state)
223 * intel_dsb_commit() - Trigger workload execution of DSB.321{
224 * @dsb: DSB context322 struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
225 * @wait_for_vblank: wait for vblank before executing323 const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
226 *324 unsigned int latency = skl_watermark_max_latency(i915);
227 * This function is used to do actual write to hardware using DSB.325 int vblank_start;
228 */326
229void intel_dsb_commit(struct intel_dsb *dsb, bool wait_for_vblank)327 if (crtc_state->vrr.enable) {
328 vblank_start = intel_vrr_vmin_vblank_start(crtc_state);
329 } else {
330 vblank_start = adjusted_mode->crtc_vblank_start;
331
332 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
333 vblank_start = DIV_ROUND_UP(vblank_start, 2);
334 }
335
336 return max(0, vblank_start - intel_usecs_to_scanlines(adjusted_mode, latency));
337}
338
339static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
340 unsigned int dewake_scanline)
230{341{
231 struct intel_crtc *crtc = dsb->crtc;342 struct intel_crtc *crtc = dsb->crtc;
232 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);343 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -243,13 +354,48 @@ void intel_dsb_commit(struct intel_dsb *dsb, bool wait_for_vblank) · 10 unmodified lines
243 return;354 return;
244 }355 }
245 356
246 intel_de_write(dev_priv, DSB_CTRL(pipe, dsb->id),357 intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id),
247 (wait_for_vblank ? DSB_WAIT_FOR_VBLANK : 0) |358 ctrl | DSB_ENABLE);
248 DSB_ENABLE);359
249 intel_de_write(dev_priv, DSB_HEAD(pipe, dsb->id),360 intel_de_write_fw(dev_priv, DSB_HEAD(pipe, dsb->id),
250 i915_ggtt_offset(dsb->vma));361 i915_ggtt_offset(dsb->vma));
251 intel_de_write(dev_priv, DSB_TAIL(pipe, dsb->id),362
252 i915_ggtt_offset(dsb->vma) + tail);363 if (dewake_scanline >= 0) {
364 int diff, hw_dewake_scanline;
365
366 hw_dewake_scanline = intel_crtc_scanline_to_hw(crtc, dewake_scanline);
367
368 intel_de_write_fw(dev_priv, DSB_PMCTRL(pipe, dsb->id),
369 DSB_ENABLE_DEWAKE |
370 DSB_SCANLINE_FOR_DEWAKE(hw_dewake_scanline));
371
372 /*
373 * Force DEwake immediately if we're already past
374 * or close to racing past the target scanline.
375 */
376 diff = dewake_scanline - intel_get_crtc_scanline(crtc);
377 intel_de_write_fw(dev_priv, DSB_PMCTRL_2(pipe, dsb->id),
378 (diff >= 0 && diff < 5 ? DSB_FORCE_DEWAKE : 0) |
379 DSB_BLOCK_DEWAKE_EXTENSION);
380 }
381
382 intel_de_write_fw(dev_priv, DSB_TAIL(pipe, dsb->id),
383 i915_ggtt_offset(dsb->vma) + tail);
384}
385
386/**
387 * intel_dsb_commit() - Trigger workload execution of DSB.
388 * @dsb: DSB context
389 * @wait_for_vblank: wait for vblank before executing
390 *
391 * This function is used to do actual write to hardware using DSB.
392 */
393void intel_dsb_commit(struct intel_dsb *dsb,
394 bool wait_for_vblank)
395{
396 _intel_dsb_commit(dsb,
397 wait_for_vblank ? DSB_WAIT_FOR_VBLANK : 0,
398 wait_for_vblank ? dsb->dewake_scanline : -1);
253}399}
254 400
255void intel_dsb_wait(struct intel_dsb *dsb)401void intel_dsb_wait(struct intel_dsb *dsb)
@@ -258,20 +404,31 @@ void intel_dsb_wait(struct intel_dsb *dsb) · 2 unmodified lines
258 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);404 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
259 enum pipe pipe = crtc->pipe;405 enum pipe pipe = crtc->pipe;
260 406
261 if (wait_for(!is_dsb_busy(dev_priv, pipe, dsb->id), 1))407 if (wait_for(!is_dsb_busy(dev_priv, pipe, dsb->id), 1)) {
408 u32 offset = i915_ggtt_offset(dsb->vma);
409
410 intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id),
411 DSB_ENABLE | DSB_HALT);
412
262 drm_err(&dev_priv->drm,413 drm_err(&dev_priv->drm,
263 "[CRTC:%d:%s] DSB %d timed out waiting for idle\n",414 "[CRTC:%d:%s] DSB %d timed out waiting for idle (current head=0x%x, head=0x%x, tail=0x%x)\n",
264 crtc->base.base.id, crtc->base.name, dsb->id);415 crtc->base.base.id, crtc->base.name, dsb->id,
416 intel_de_read_fw(dev_priv, DSB_CURRENT_HEAD(pipe, dsb->id)) - offset,
417 intel_de_read_fw(dev_priv, DSB_HEAD(pipe, dsb->id)) - offset,
418 intel_de_read_fw(dev_priv, DSB_TAIL(pipe, dsb->id)) - offset);
419
420 intel_dsb_dump(dsb);
421 }
265 422
266 /* Attempt to reset it */423 /* Attempt to reset it */
267 dsb->free_pos = 0;424 dsb->free_pos = 0;
268 dsb->ins_start_offset = 0;425 dsb->ins_start_offset = 0;
269 intel_de_write(dev_priv, DSB_CTRL(pipe, dsb->id), 0);426 intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id), 0);
270}427}
271 428
272/**429/**
273 * intel_dsb_prepare() - Allocate, pin and map the DSB command buffer.430 * intel_dsb_prepare() - Allocate, pin and map the DSB command buffer.
274 * @crtc: the CRTC431 * @crtc_state: the CRTC state
275 * @max_cmds: number of commands we need to fit into command buffer432 * @max_cmds: number of commands we need to fit into command buffer
276 *433 *
277 * This function prepare the command buffer which is used to store dsb434 * This function prepare the command buffer which is used to store dsb
@@ -280,9 +437,10 @@ void intel_dsb_wait(struct intel_dsb *dsb) · 2 unmodified lines
280 * Returns:437 * Returns:
281 * DSB context, NULL on failure438 * DSB context, NULL on failure
282 */439 */
283struct intel_dsb *intel_dsb_prepare(struct intel_crtc *crtc,440struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
284 unsigned int max_cmds)441 unsigned int max_cmds)
285{442{
443 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
286 struct drm_i915_private *i915 = to_i915(crtc->base.dev);444 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
287 struct drm_i915_gem_object *obj;445 struct drm_i915_gem_object *obj;
288 intel_wakeref_t wakeref;446 intel_wakeref_t wakeref;
@@ -328,6 +486,7 @@ struct intel_dsb *intel_dsb_prepare(struct intel_crtc *crtc, · 39 unmodified lines
328 dsb->size = size / 4; /* in dwords */486 dsb->size = size / 4; /* in dwords */
329 dsb->free_pos = 0;487 dsb->free_pos = 0;
330 dsb->ins_start_offset = 0;488 dsb->ins_start_offset = 0;
489 dsb->dewake_scanline = intel_dsb_dewake_scanline(crtc_state);
331 490
332 return dsb;491 return dsb;
333 492
drivers/gpu/drm/i915/display/intel_dsb.h+8−1
@@ -11,14 +11,21 @@ · 10 unmodified lines
11#include "i915_reg_defs.h"11#include "i915_reg_defs.h"
12 12
13struct intel_crtc;13struct intel_crtc;
14struct intel_crtc_state;
14struct intel_dsb;15struct intel_dsb;
15 16
16struct intel_dsb *intel_dsb_prepare(struct intel_crtc *crtc,17struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
17 unsigned int max_cmds);18 unsigned int max_cmds);
18void intel_dsb_finish(struct intel_dsb *dsb);19void intel_dsb_finish(struct intel_dsb *dsb);
19void intel_dsb_cleanup(struct intel_dsb *dsb);20void intel_dsb_cleanup(struct intel_dsb *dsb);
20void intel_dsb_reg_write(struct intel_dsb *dsb,21void intel_dsb_reg_write(struct intel_dsb *dsb,
21 i915_reg_t reg, u32 val);22 i915_reg_t reg, u32 val);
23void intel_dsb_reg_write_masked(struct intel_dsb *dsb,
24 i915_reg_t reg, u32 mask, u32 val);
25void intel_dsb_noop(struct intel_dsb *dsb, int count);
26void intel_dsb_nonpost_start(struct intel_dsb *dsb);
27void intel_dsb_nonpost_end(struct intel_dsb *dsb);
28
22void intel_dsb_commit(struct intel_dsb *dsb,29void intel_dsb_commit(struct intel_dsb *dsb,
23 bool wait_for_vblank);30 bool wait_for_vblank);
24void intel_dsb_wait(struct intel_dsb *dsb);31void intel_dsb_wait(struct intel_dsb *dsb);
drivers/gpu/drm/i915/display/intel_dsb_regs.h+31−0
@@ -37,6 +37,19 @@ · 36 unmodified lines
37#define DSB_DEBUG(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x14)37#define DSB_DEBUG(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x14)
38#define DSB_POLLMASK(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x1c)38#define DSB_POLLMASK(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x1c)
39#define DSB_STATUS(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x24)39#define DSB_STATUS(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x24)
40#define DSB_HP_IDLE_STATUS REG_BIT(31)
41#define DSB_DEWAKE_STATUS REG_BIT(30)
42#define DSB_REQARB_SM_STATE_MASK REG_GENMASK(29, 27)
43#define DSB_SAFE_WINDOW_LIVE REG_BIT(26)
44#define DSB_VTDFAULT_ARB_SM_STATE_MASK REG_GENMASK(25, 23)
45#define DSB_TLBTRANS_SM_STATE_MASK REG_GENMASK(21, 20)
46#define DSB_SAFE_WINDOW REG_BIT(19)
47#define DSB_POINTERS_SM_STATE_MASK REG_GENMASK(18, 17)
48#define DSB_BUSY_ON_DELAYED_VBLANK REG_BIT(16)
49#define DSB_MMIO_ARB_SM_STATE_MASK REG_GENMASK(15, 13)
50#define DSB_MMIO_INST_SM_STATE_MASK REG_GENMASK(11, 7)
51#define DSB_RESET_SM_STATE_MASK REG_GENMASK(5, 4)
52#define DSB_RUN_SM_STATE_MASK REG_GENMASK(2, 0)
40#define DSB_INTERRUPT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x28)53#define DSB_INTERRUPT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x28)
41#define DSB_ATS_FAULT_INT_EN REG_BIT(20)54#define DSB_ATS_FAULT_INT_EN REG_BIT(20)
42#define DSB_GTT_FAULT_INT_EN REG_BIT(19)55#define DSB_GTT_FAULT_INT_EN REG_BIT(19)
@@ -58,10 +71,28 @@ · 15 unmodified lines
58#define DSB_RM_READY_TIMEOUT_VALUE(x) REG_FIELD_PREP(DSB_RM_READY_TIMEOUT_VALUE, (x)) /* usec */71#define DSB_RM_READY_TIMEOUT_VALUE(x) REG_FIELD_PREP(DSB_RM_READY_TIMEOUT_VALUE, (x)) /* usec */
59#define DSB_RMTIMEOUTREG_CAPTURE(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x34)72#define DSB_RMTIMEOUTREG_CAPTURE(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x34)
60#define DSB_PMCTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x38)73#define DSB_PMCTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x38)
74#define DSB_ENABLE_DEWAKE REG_BIT(31)
75#define DSB_SCANLINE_FOR_DEWAKE_MASK REG_GENMASK(30, 0)
76#define DSB_SCANLINE_FOR_DEWAKE(x) REG_FIELD_PREP(DSB_SCANLINE_FOR_DEWAKE_MASK, (x))
61#define DSB_PMCTRL_2(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x3c)77#define DSB_PMCTRL_2(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x3c)
78#define DSB_MMIOGEN_DEWAKE_DIS REG_BIT(31)
79#define DSB_FORCE_DEWAKE REG_BIT(23)
80#define DSB_BLOCK_DEWAKE_EXTENSION REG_BIT(15)
81#define DSB_OVERRIDE_DC5_DC6_OK REG_BIT(7)
62#define DSB_PF_LN_LOWER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x40)82#define DSB_PF_LN_LOWER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x40)
63#define DSB_PF_LN_UPPER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x44)83#define DSB_PF_LN_UPPER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x44)
64#define DSB_BUFRPT_CNT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x48)84#define DSB_BUFRPT_CNT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x48)
65#define DSB_CHICKEN(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0xf0)85#define DSB_CHICKEN(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0xf0)
86#define DSB_FORCE_DMA_SYNC_RESET REG_BIT(31)
87#define DSB_FORCE_VTD_ENGIE_RESET REG_BIT(30)
88#define DSB_DISABLE_IPC_DEMOTE REG_BIT(29)
89#define DSB_SKIP_WAITS_EN REG_BIT(23)
90#define DSB_EXTEND_HP_IDLE REG_BIT(16)
91#define DSB_CTRL_WAIT_SAFE_WINDOW REG_BIT(15)
92#define DSB_CTRL_NO_WAIT_VBLANK REG_BIT(14)
93#define DSB_INST_WAIT_SAFE_WINDOW REG_BIT(7)
94#define DSB_INST_NO_WAIT_VBLANK REG_BIT(6)
95#define DSB_MMIOGEN_DEWAKE_DIS_CHICKEN REG_BIT(2)
96#define DSB_DISABLE_MMIO_COUNT_FOR_INDEXED REG_BIT(0)
66 97
67#endif /* __INTEL_DSB_REGS_H__ */98#endif /* __INTEL_DSB_REGS_H__ */
drivers/gpu/drm/i915/display/intel_dvo.c+5−6
@@ -328,7 +328,6 @@ intel_dvo_detect(struct drm_connector *_connector, bool force) · 327 unmodified lines
328static int intel_dvo_get_modes(struct drm_connector *_connector)328static int intel_dvo_get_modes(struct drm_connector *_connector)
329{329{
330 struct intel_connector *connector = to_intel_connector(_connector);330 struct intel_connector *connector = to_intel_connector(_connector);
331 struct drm_i915_private *i915 = to_i915(connector->base.dev);
332 int num_modes;331 int num_modes;
333 332
334 /*333 /*
@@ -337,8 +336,7 @@ static int intel_dvo_get_modes(struct drm_connector *_connector) · 2 unmodified lines
337 * (TV-out, for example), but for now with just TMDS and LVDS,336 * (TV-out, for example), but for now with just TMDS and LVDS,
338 * that's not the case.337 * that's not the case.
339 */338 */
340 num_modes = intel_ddc_get_modes(&connector->base,339 num_modes = intel_ddc_get_modes(&connector->base, connector->base.ddc);
341 intel_gmbus_get_adapter(i915, GMBUS_PIN_DPC));
342 if (num_modes)340 if (num_modes)
343 return num_modes;341 return num_modes;
344 342
@@ -533,9 +531,10 @@ void intel_dvo_init(struct drm_i915_private *i915) · 188 unmodified lines
533 connector->polled = DRM_CONNECTOR_POLL_CONNECT |531 connector->polled = DRM_CONNECTOR_POLL_CONNECT |
534 DRM_CONNECTOR_POLL_DISCONNECT;532 DRM_CONNECTOR_POLL_DISCONNECT;
535 533
536 drm_connector_init(&i915->drm, &connector->base,534 drm_connector_init_with_ddc(&i915->drm, &connector->base,
537 &intel_dvo_connector_funcs,535 &intel_dvo_connector_funcs,
538 intel_dvo_connector_type(&intel_dvo->dev));536 intel_dvo_connector_type(&intel_dvo->dev),
537 intel_gmbus_get_adapter(i915, GMBUS_PIN_DPC));
539 538
540 drm_connector_helper_add(&connector->base,539 drm_connector_helper_add(&connector->base,
541 &intel_dvo_connector_helper_funcs);540 &intel_dvo_connector_helper_funcs);
drivers/gpu/drm/i915/display/intel_fb.c+58−3
@@ -7,11 +7,15 @@ · 6 unmodified lines
7#include <drm/drm_framebuffer.h>7#include <drm/drm_framebuffer.h>
8#include <drm/drm_modeset_helper.h>8#include <drm/drm_modeset_helper.h>
9 9
10#include <linux/dma-fence.h>
11#include <linux/dma-resv.h>
12
10#include "i915_drv.h"13#include "i915_drv.h"
11#include "intel_display.h"14#include "intel_display.h"
12#include "intel_display_types.h"15#include "intel_display_types.h"
13#include "intel_dpt.h"16#include "intel_dpt.h"
14#include "intel_fb.h"17#include "intel_fb.h"
18#include "intel_frontbuffer.h"
15 19
16#define check_array_bounds(i915, a, i) drm_WARN_ON(&(i915)->drm, (i) >= ARRAY_SIZE(a))20#define check_array_bounds(i915, a, i) drm_WARN_ON(&(i915)->drm, (i) >= ARRAY_SIZE(a))
17 21
@@ -1896,6 +1900,21 @@ static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, · 1878 unmodified lines
1896 return drm_gem_handle_create(file, &obj->base, handle);1900 return drm_gem_handle_create(file, &obj->base, handle);
1897}1901}
1898 1902
1903struct frontbuffer_fence_cb {
1904 struct dma_fence_cb base;
1905 struct intel_frontbuffer *front;
1906};
1907
1908static void intel_user_framebuffer_fence_wake(struct dma_fence *dma,
1909 struct dma_fence_cb *data)
1910{
1911 struct frontbuffer_fence_cb *cb = container_of(data, typeof(*cb), base);
1912
1913 intel_frontbuffer_queue_flush(cb->front);
1914 kfree(cb);
1915 dma_fence_put(dma);
1916}
1917
1899static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,1918static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb,
1900 struct drm_file *file,1919 struct drm_file *file,
1901 unsigned int flags, unsigned int color,1920 unsigned int flags, unsigned int color,
@@ -1903,11 +1922,47 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, · 1 unmodified line
1903 unsigned int num_clips)1922 unsigned int num_clips)
1904{1923{
1905 struct drm_i915_gem_object *obj = intel_fb_obj(fb);1924 struct drm_i915_gem_object *obj = intel_fb_obj(fb);
1925 struct intel_frontbuffer *front = to_intel_frontbuffer(fb);
1926 struct dma_fence *fence;
1927 struct frontbuffer_fence_cb *cb;
1928 int ret = 0;
1906 1929
1907 i915_gem_object_flush_if_display(obj);1930 if (!atomic_read(&front->bits))
1908 intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);1931 return 0;
1909 1932
1910 return 0;1933 if (dma_resv_test_signaled(obj->base.resv, dma_resv_usage_rw(false)))
1934 goto flush;
1935
1936 ret = dma_resv_get_singleton(obj->base.resv, dma_resv_usage_rw(false),
1937 &fence);
1938 if (ret || !fence)
1939 goto flush;
1940
1941 cb = kmalloc(sizeof(*cb), GFP_KERNEL);
1942 if (!cb) {
1943 dma_fence_put(fence);
1944 ret = -ENOMEM;
1945 goto flush;
1946 }
1947
1948 cb->front = front;
1949
1950 intel_frontbuffer_invalidate(front, ORIGIN_DIRTYFB);
1951
1952 ret = dma_fence_add_callback(fence, &cb->base,
1953 intel_user_framebuffer_fence_wake);
1954 if (ret) {
1955 intel_user_framebuffer_fence_wake(fence, &cb->base);
1956 if (ret == -ENOENT)
1957 ret = 0;
1958 }
1959
1960 return ret;
1961
1962flush:
1963 i915_gem_object_flush_if_display(obj);
1964 intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
1965 return ret;
1911}1966}
1912 1967
1913static const struct drm_framebuffer_funcs intel_fb_funcs = {1968static const struct drm_framebuffer_funcs intel_fb_funcs = {
drivers/gpu/drm/i915/display/intel_fb_pin.c+2−1
@@ -35,7 +35,8 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb, · 34 unmodified lines
35 * We are not syncing against the binding (and potential migrations)35 * We are not syncing against the binding (and potential migrations)
36 * below, so this vm must never be async.36 * below, so this vm must never be async.
37 */37 */
38 GEM_WARN_ON(vm->bind_async_flags);38 if (drm_WARN_ON(&dev_priv->drm, vm->bind_async_flags))
39 return ERR_PTR(-EINVAL);
39 40
40 if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))41 if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))
41 return ERR_PTR(-EINVAL);42 return ERR_PTR(-EINVAL);
drivers/gpu/drm/i915/display/intel_fbc.c+12−11
@@ -50,6 +50,7 @@ · 49 unmodified lines
50#include "i915_vma.h"50#include "i915_vma.h"
51#include "intel_cdclk.h"51#include "intel_cdclk.h"
52#include "intel_de.h"52#include "intel_de.h"
53#include "intel_display_device.h"
53#include "intel_display_trace.h"54#include "intel_display_trace.h"
54#include "intel_display_types.h"55#include "intel_display_types.h"
55#include "intel_fbc.h"56#include "intel_fbc.h"
@@ -332,12 +333,14 @@ static void i8xx_fbc_program_cfb(struct intel_fbc *fbc) · 276 unmodified lines
332{333{
333 struct drm_i915_private *i915 = fbc->i915;334 struct drm_i915_private *i915 = fbc->i915;
334 335
335 GEM_BUG_ON(range_overflows_end_t(u64, i915_gem_stolen_area_address(i915),336 drm_WARN_ON(&i915->drm,
336 i915_gem_stolen_node_offset(&fbc->compressed_fb),337 range_overflows_end_t(u64, i915_gem_stolen_area_address(i915),
337 U32_MAX));338 i915_gem_stolen_node_offset(&fbc->compressed_fb),
338 GEM_BUG_ON(range_overflows_end_t(u64, i915_gem_stolen_area_address(i915),339 U32_MAX));
339 i915_gem_stolen_node_offset(&fbc->compressed_llb),340 drm_WARN_ON(&i915->drm,
340 U32_MAX));341 range_overflows_end_t(u64, i915_gem_stolen_area_address(i915),
342 i915_gem_stolen_node_offset(&fbc->compressed_llb),
343 U32_MAX));
341 intel_de_write(i915, FBC_CFB_BASE,344 intel_de_write(i915, FBC_CFB_BASE,
342 i915_gem_stolen_node_address(i915, &fbc->compressed_fb));345 i915_gem_stolen_node_address(i915, &fbc->compressed_fb));
343 intel_de_write(i915, FBC_LL_BASE,346 intel_de_write(i915, FBC_LL_BASE,
@@ -1100,7 +1103,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, · 756 unmodified lines
1100 1103
1101 /* Wa_14016291713 */1104 /* Wa_14016291713 */
1102 if ((IS_DISPLAY_VER(i915, 12, 13) ||1105 if ((IS_DISPLAY_VER(i915, 12, 13) ||
1103 IS_MTL_DISPLAY_STEP(i915, STEP_A0, STEP_C0)) &&1106 IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0)) &&
1104 crtc_state->has_psr) {1107 crtc_state->has_psr) {
1105 plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)";1108 plane_state->no_fbc_reason = "PSR1 enabled (Wa_14016291713)";
1106 return 0;1109 return 0;
@@ -1306,11 +1309,9 @@ static void __intel_fbc_post_update(struct intel_fbc *fbc) · 199 unmodified lines
1306 lockdep_assert_held(&fbc->lock);1309 lockdep_assert_held(&fbc->lock);
1307 1310
1308 fbc->flip_pending = false;1311 fbc->flip_pending = false;
1312 fbc->busy_bits = 0;
1309 1313
1310 if (!fbc->busy_bits)1314 intel_fbc_activate(fbc);
1311 intel_fbc_activate(fbc);
1312 else
1313 intel_fbc_deactivate(fbc, "frontbuffer write");
1314}1315}
1315 1316
1316void intel_fbc_post_update(struct intel_atomic_state *state,1317void intel_fbc_post_update(struct intel_atomic_state *state,
drivers/gpu/drm/i915/display/intel_fbc.h+2−0
@@ -20,6 +20,8 @@ struct intel_plane_state; · 19 unmodified lines
20enum intel_fbc_id {20enum intel_fbc_id {
21 INTEL_FBC_A,21 INTEL_FBC_A,
22 INTEL_FBC_B,22 INTEL_FBC_B,
23 INTEL_FBC_C,
24 INTEL_FBC_D,
23 25
24 I915_MAX_FBCS,26 I915_MAX_FBCS,
25};27};
drivers/gpu/drm/i915/display/intel_fdi.c+149−20
@@ -13,6 +13,7 @@ · 12 unmodified lines
13#include "intel_display_types.h"13#include "intel_display_types.h"
14#include "intel_fdi.h"14#include "intel_fdi.h"
15#include "intel_fdi_regs.h"15#include "intel_fdi_regs.h"
16#include "intel_link_bw.h"
16 17
17struct intel_fdi_funcs {18struct intel_fdi_funcs {
18 void (*fdi_link_train)(struct intel_crtc *crtc,19 void (*fdi_link_train)(struct intel_crtc *crtc,
@@ -119,6 +120,53 @@ void intel_fdi_link_train(struct intel_crtc *crtc, · 100 unmodified lines
119 dev_priv->display.funcs.fdi->fdi_link_train(crtc, crtc_state);120 dev_priv->display.funcs.fdi->fdi_link_train(crtc, crtc_state);
120}121}
121 122
123/**
124 * intel_fdi_add_affected_crtcs - add CRTCs on FDI affected by other modeset CRTCs
125 * @state: intel atomic state
126 *
127 * Add a CRTC using FDI to @state if changing another CRTC's FDI BW usage is
128 * known to affect the available FDI BW for the former CRTC. In practice this
129 * means adding CRTC B on IVYBRIDGE if its use of FDI lanes is limited (by
130 * CRTC C) and CRTC C is getting disabled.
131 *
132 * Returns 0 in case of success, or a negative error code otherwise.
133 */
134int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state)
135{
136 struct drm_i915_private *i915 = to_i915(state->base.dev);
137 const struct intel_crtc_state *old_crtc_state;
138 const struct intel_crtc_state *new_crtc_state;
139 struct intel_crtc *crtc;
140
141 if (!IS_IVYBRIDGE(i915) || INTEL_NUM_PIPES(i915) != 3)
142 return 0;
143
144 crtc = intel_crtc_for_pipe(i915, PIPE_C);
145 new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
146 if (!new_crtc_state)
147 return 0;
148
149 if (!intel_crtc_needs_modeset(new_crtc_state))
150 return 0;
151
152 old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
153 if (!old_crtc_state->fdi_lanes)
154 return 0;
155
156 crtc = intel_crtc_for_pipe(i915, PIPE_B);
157 new_crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
158 if (IS_ERR(new_crtc_state))
159 return PTR_ERR(new_crtc_state);
160
161 old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
162 if (!old_crtc_state->fdi_lanes)
163 return 0;
164
165 return intel_modeset_pipes_in_mask_early(state,
166 "FDI link BW decrease on pipe C",
167 BIT(PIPE_B));
168}
169
122/* units of 100MHz */170/* units of 100MHz */
123static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)171static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
124{172{
@@ -129,13 +177,16 @@ static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state) · 4 unmodified lines
129}177}
130 178
131static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,179static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
132 struct intel_crtc_state *pipe_config)180 struct intel_crtc_state *pipe_config,
181 enum pipe *pipe_to_reduce)
133{182{
134 struct drm_i915_private *dev_priv = to_i915(dev);183 struct drm_i915_private *dev_priv = to_i915(dev);
135 struct drm_atomic_state *state = pipe_config->uapi.state;184 struct drm_atomic_state *state = pipe_config->uapi.state;
136 struct intel_crtc *other_crtc;185 struct intel_crtc *other_crtc;
137 struct intel_crtc_state *other_crtc_state;186 struct intel_crtc_state *other_crtc_state;
138 187
188 *pipe_to_reduce = pipe;
189
139 drm_dbg_kms(&dev_priv->drm,190 drm_dbg_kms(&dev_priv->drm,
140 "checking fdi config on pipe %c, lanes %i\n",191 "checking fdi config on pipe %c, lanes %i\n",
141 pipe_name(pipe), pipe_config->fdi_lanes);192 pipe_name(pipe), pipe_config->fdi_lanes);
@@ -198,6 +249,9 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, · 56 unmodified lines
198 if (pipe_required_fdi_lanes(other_crtc_state) > 2) {249 if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
199 drm_dbg_kms(&dev_priv->drm,250 drm_dbg_kms(&dev_priv->drm,
200 "fdi link B uses too many lanes to enable link C\n");251 "fdi link B uses too many lanes to enable link C\n");
252
253 *pipe_to_reduce = PIPE_B;
254
201 return -EINVAL;255 return -EINVAL;
202 }256 }
203 return 0;257 return 0;
@@ -232,16 +286,42 @@ int intel_fdi_link_freq(struct drm_i915_private *i915, · 28 unmodified lines
232 return i915->display.fdi.pll_freq;286 return i915->display.fdi.pll_freq;
233}287}
234 288
289/**
290 * intel_fdi_compute_pipe_bpp - compute pipe bpp limited by max link bpp
291 * @crtc_state: the crtc state
292 *
293 * Compute the pipe bpp limited by the CRTC's maximum link bpp. Encoders can
294 * call this function during state computation in the simple case where the
295 * link bpp will always match the pipe bpp. This is the case for all non-DP
296 * encoders, while DP encoders will use a link bpp lower than pipe bpp in case
297 * of DSC compression.
298 *
299 * Returns %true in case of success, %false if pipe bpp would need to be
300 * reduced below its valid range.
301 */
302bool intel_fdi_compute_pipe_bpp(struct intel_crtc_state *crtc_state)
303{
304 int pipe_bpp = min(crtc_state->pipe_bpp,
305 to_bpp_int(crtc_state->max_link_bpp_x16));
306
307 pipe_bpp = rounddown(pipe_bpp, 2 * 3);
308
309 if (pipe_bpp < 6 * 3)
310 return false;
311
312 crtc_state->pipe_bpp = pipe_bpp;
313
314 return true;
315}
316
235int ilk_fdi_compute_config(struct intel_crtc *crtc,317int ilk_fdi_compute_config(struct intel_crtc *crtc,
236 struct intel_crtc_state *pipe_config)318 struct intel_crtc_state *pipe_config)
237{319{
238 struct drm_device *dev = crtc->base.dev;320 struct drm_device *dev = crtc->base.dev;
239 struct drm_i915_private *i915 = to_i915(dev);321 struct drm_i915_private *i915 = to_i915(dev);
240 const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;322 const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
241 int lane, link_bw, fdi_dotclock, ret;323 int lane, link_bw, fdi_dotclock;
242 bool needs_recompute = false;
243 324
244retry:
245 /* FDI is a binary signal running at ~2.7GHz, encoding325 /* FDI is a binary signal running at ~2.7GHz, encoding
246 * each output octet as 10 bits. The actual frequency326 * each output octet as 10 bits. The actual frequency
247 * is stored as a divider into a 100MHz clock, and the327 * is stored as a divider into a 100MHz clock, and the
@@ -261,25 +341,69 @@ retry: · 13 unmodified lines
261 intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,341 intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
262 link_bw, &pipe_config->fdi_m_n, false);342 link_bw, &pipe_config->fdi_m_n, false);
263 343
264 ret = ilk_check_fdi_lanes(dev, crtc->pipe, pipe_config);344 return 0;
265 if (ret == -EDEADLK)345}
346
347static int intel_fdi_atomic_check_bw(struct intel_atomic_state *state,
348 struct intel_crtc *crtc,
349 struct intel_crtc_state *pipe_config,
350 struct intel_link_bw_limits *limits)
351{
352 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
353 enum pipe pipe_to_reduce;
354 int ret;
355
356 ret = ilk_check_fdi_lanes(&i915->drm, crtc->pipe, pipe_config,
357 &pipe_to_reduce);
358 if (ret != -EINVAL)
266 return ret;359 return ret;
267 360
268 if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {361 ret = intel_link_bw_reduce_bpp(state, limits,
269 pipe_config->pipe_bpp -= 2*3;362 BIT(pipe_to_reduce),
270 drm_dbg_kms(&i915->drm,363 "FDI link BW");
271 "fdi link bw constraint, reducing pipe bpp to %i\n",
272 pipe_config->pipe_bpp);
273 needs_recompute = true;
274 pipe_config->bw_constrained = true;
275 364
276 goto retry;365 return ret ? : -EAGAIN;
277 }366}
367
368/**
369 * intel_fdi_atomic_check_link - check all modeset FDI link configuration
370 * @state: intel atomic state
371 * @limits: link BW limits
372 *
373 * Check the link configuration for all modeset FDI outputs. If the
374 * configuration is invalid @limits will be updated if possible to
375 * reduce the total BW, after which the configuration for all CRTCs in
376 * @state must be recomputed with the updated @limits.
377 *
378 * Returns:
379 * - 0 if the confugration is valid
380 * - %-EAGAIN, if the configuration is invalid and @limits got updated
381 * with fallback values with which the configuration of all CRTCs
382 * in @state must be recomputed
383 * - Other negative error, if the configuration is invalid without a
384 * fallback possibility, or the check failed for another reason
385 */
386int intel_fdi_atomic_check_link(struct intel_atomic_state *state,
387 struct intel_link_bw_limits *limits)
388{
389 struct intel_crtc *crtc;
390 struct intel_crtc_state *crtc_state;
391 int i;
392
393 for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
394 int ret;
395
396 if (!crtc_state->has_pch_encoder ||
397 !intel_crtc_needs_modeset(crtc_state) ||
398 !crtc_state->hw.enable)
399 continue;
278 400
279 if (needs_recompute)401 ret = intel_fdi_atomic_check_bw(state, crtc, crtc_state, limits);
280 return -EAGAIN;402 if (ret)
403 return ret;
404 }
281 405
282 return ret;406 return 0;
283}407}
284 408
285static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable)409static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable)
@@ -766,7 +890,10 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, · 480 unmodified lines
766 * WaFDIAutoLinkSetTimingOverrride:hsw890 * WaFDIAutoLinkSetTimingOverrride:hsw
767 */891 */
768 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A),892 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A),
769 FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2) | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);893 FDI_RX_PWRDN_LANE1_VAL(2) |
894 FDI_RX_PWRDN_LANE0_VAL(2) |
895 FDI_RX_TP1_TO_TP2_48 |
896 FDI_RX_FDI_DELAY_90);
770 897
771 /* Enable the PCH Receiver FDI PLL */898 /* Enable the PCH Receiver FDI PLL */
772 rx_ctl_val = dev_priv->display.fdi.rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |899 rx_ctl_val = dev_priv->display.fdi.rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
@@ -799,7 +926,9 @@ void hsw_fdi_link_train(struct intel_encoder *encoder, · 26 unmodified lines
799 * achieved on the PCH side in FDI_RX_CTL, so no need to set the926 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
800 * port reversal bit */927 * port reversal bit */
801 intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E),928 intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E),
802 DDI_BUF_CTL_ENABLE | ((crtc_state->fdi_lanes - 1) << 1) | DDI_BUF_TRANS_SELECT(i / 2));929 DDI_BUF_CTL_ENABLE |
930 ((crtc_state->fdi_lanes - 1) << 1) |
931 DDI_BUF_TRANS_SELECT(i / 2));
803 intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));932 intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));
804 933
805 udelay(600);934 udelay(600);
drivers/gpu/drm/i915/display/intel_fdi.h+8−0
@@ -6,16 +6,24 @@ · 5 unmodified lines
6#ifndef _INTEL_FDI_H_6#ifndef _INTEL_FDI_H_
7#define _INTEL_FDI_H_7#define _INTEL_FDI_H_
8 8
9#include <linux/types.h>
10
9enum pipe;11enum pipe;
10struct drm_i915_private;12struct drm_i915_private;
13struct intel_atomic_state;
11struct intel_crtc;14struct intel_crtc;
12struct intel_crtc_state;15struct intel_crtc_state;
13struct intel_encoder;16struct intel_encoder;
17struct intel_link_bw_limits;
14 18
19int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state);
15int intel_fdi_link_freq(struct drm_i915_private *i915,20int intel_fdi_link_freq(struct drm_i915_private *i915,
16 const struct intel_crtc_state *pipe_config);21 const struct intel_crtc_state *pipe_config);
22bool intel_fdi_compute_pipe_bpp(struct intel_crtc_state *crtc_state);
17int ilk_fdi_compute_config(struct intel_crtc *intel_crtc,23int ilk_fdi_compute_config(struct intel_crtc *intel_crtc,
18 struct intel_crtc_state *pipe_config);24 struct intel_crtc_state *pipe_config);
25int intel_fdi_atomic_check_link(struct intel_atomic_state *state,
26 struct intel_link_bw_limits *limits);
19void intel_fdi_normal_train(struct intel_crtc *crtc);27void intel_fdi_normal_train(struct intel_crtc *crtc);
20void ilk_fdi_disable(struct intel_crtc *crtc);28void ilk_fdi_disable(struct intel_crtc *crtc);
21void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc);29void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc);
drivers/gpu/drm/i915/display/intel_frontbuffer.c+32−2
@@ -55,6 +55,7 @@ · 54 unmodified lines
55 * cancelled as soon as busyness is detected.55 * cancelled as soon as busyness is detected.
56 */56 */
57 57
58#include "gem/i915_gem_object_frontbuffer.h"
58#include "i915_drv.h"59#include "i915_drv.h"
59#include "intel_display_trace.h"60#include "intel_display_trace.h"
60#include "intel_display_types.h"61#include "intel_display_types.h"
@@ -202,6 +203,33 @@ void __intel_fb_flush(struct intel_frontbuffer *front, · 141 unmodified lines
202 frontbuffer_flush(i915, frontbuffer_bits, origin);203 frontbuffer_flush(i915, frontbuffer_bits, origin);
203}204}
204 205
206static void intel_frontbuffer_flush_work(struct work_struct *work)
207{
208 struct intel_frontbuffer *front =
209 container_of(work, struct intel_frontbuffer, flush_work);
210
211 i915_gem_object_flush_if_display(front->obj);
212 intel_frontbuffer_flush(front, ORIGIN_DIRTYFB);
213 intel_frontbuffer_put(front);
214}
215
216/**
217 * intel_frontbuffer_queue_flush - queue flushing frontbuffer object
218 * @front: GEM object to flush
219 *
220 * This function is targeted for our dirty callback for queueing flush when
221 * dma fence is signales
222 */
223void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front)
224{
225 if (!front)
226 return;
227
228 kref_get(&front->ref);
229 if (!schedule_work(&front->flush_work))
230 intel_frontbuffer_put(front);
231}
232
205static int frontbuffer_active(struct i915_active *ref)233static int frontbuffer_active(struct i915_active *ref)
206{234{
207 struct intel_frontbuffer *front =235 struct intel_frontbuffer *front =
@@ -223,7 +251,7 @@ static void frontbuffer_retire(struct i915_active *ref) · 15 unmodified lines
223static void frontbuffer_release(struct kref *ref)251static void frontbuffer_release(struct kref *ref)
224 __releases(&intel_bo_to_i915(front->obj)->display.fb_tracking.lock)252 __releases(&intel_bo_to_i915(front->obj)->display.fb_tracking.lock)
225{253{
226 struct intel_frontbuffer *front =254 struct intel_frontbuffer *ret, *front =
227 container_of(ref, typeof(*front), ref);255 container_of(ref, typeof(*front), ref);
228 struct drm_i915_gem_object *obj = front->obj;256 struct drm_i915_gem_object *obj = front->obj;
229 257
@@ -231,7 +259,8 @@ static void frontbuffer_release(struct kref *ref) · 1 unmodified line
231 259
232 i915_ggtt_clear_scanout(obj);260 i915_ggtt_clear_scanout(obj);
233 261
234 i915_gem_object_set_frontbuffer(obj, NULL);262 ret = i915_gem_object_set_frontbuffer(obj, NULL);
263 drm_WARN_ON(&intel_bo_to_i915(obj)->drm, ret);
235 spin_unlock(&intel_bo_to_i915(obj)->display.fb_tracking.lock);264 spin_unlock(&intel_bo_to_i915(obj)->display.fb_tracking.lock);
236 265
237 i915_active_fini(&front->write);266 i915_active_fini(&front->write);
@@ -261,6 +290,7 @@ intel_frontbuffer_get(struct drm_i915_gem_object *obj) · 23 unmodified lines
261 frontbuffer_active,290 frontbuffer_active,
262 frontbuffer_retire,291 frontbuffer_retire,
263 I915_ACTIVE_RETIRE_SLEEPS);292 I915_ACTIVE_RETIRE_SLEEPS);
293 INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work);
264 294
265 spin_lock(&i915->display.fb_tracking.lock);295 spin_lock(&i915->display.fb_tracking.lock);
266 cur = i915_gem_object_set_frontbuffer(obj, front);296 cur = i915_gem_object_set_frontbuffer(obj, front);
drivers/gpu/drm/i915/display/intel_frontbuffer.h+4−0
@@ -46,6 +46,8 @@ struct intel_frontbuffer { · 45 unmodified lines
46 struct i915_active write;46 struct i915_active write;
47 struct drm_i915_gem_object *obj;47 struct drm_i915_gem_object *obj;
48 struct rcu_head rcu;48 struct rcu_head rcu;
49
50 struct work_struct flush_work;
49};51};
50 52
51/*53/*
@@ -135,6 +137,8 @@ static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front, · 83 unmodified lines
135 __intel_fb_flush(front, origin, frontbuffer_bits);137 __intel_fb_flush(front, origin, frontbuffer_bits);
136}138}
137 139
140void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front);
141
138void intel_frontbuffer_track(struct intel_frontbuffer *old,142void intel_frontbuffer_track(struct intel_frontbuffer *old,
139 struct intel_frontbuffer *new,143 struct intel_frontbuffer *new,
140 unsigned int frontbuffer_bits);144 unsigned int frontbuffer_bits);
drivers/gpu/drm/i915/display/intel_gmbus.c+4−1
@@ -155,7 +155,10 @@ static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915, · 154 unmodified lines
155 const struct gmbus_pin *pins;155 const struct gmbus_pin *pins;
156 size_t size;156 size_t size;
157 157
158 if (INTEL_PCH_TYPE(i915) >= PCH_DG2) {158 if (INTEL_PCH_TYPE(i915) >= PCH_LNL) {
159 pins = gmbus_pins_mtp;
160 size = ARRAY_SIZE(gmbus_pins_mtp);
161 } else if (INTEL_PCH_TYPE(i915) >= PCH_DG2) {
159 pins = gmbus_pins_dg2;162 pins = gmbus_pins_dg2;
160 size = ARRAY_SIZE(gmbus_pins_dg2);163 size = ARRAY_SIZE(gmbus_pins_dg2);
161 } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {164 } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) {
drivers/gpu/drm/i915/display/intel_hdcp.c+14−19
@@ -163,7 +163,6 @@ bool intel_hdcp_capable(struct intel_connector *connector) · 162 unmodified lines
163/* Is HDCP2.2 capable on Platform and Sink */163/* Is HDCP2.2 capable on Platform and Sink */
164bool intel_hdcp2_capable(struct intel_connector *connector)164bool intel_hdcp2_capable(struct intel_connector *connector)
165{165{
166 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
167 struct drm_i915_private *i915 = to_i915(connector->base.dev);166 struct drm_i915_private *i915 = to_i915(connector->base.dev);
168 struct intel_hdcp *hdcp = &connector->hdcp;167 struct intel_hdcp *hdcp = &connector->hdcp;
169 bool capable = false;168 bool capable = false;
@@ -193,7 +192,7 @@ bool intel_hdcp2_capable(struct intel_connector *connector) · 23 unmodified lines
193 mutex_unlock(&i915->display.hdcp.hdcp_mutex);192 mutex_unlock(&i915->display.hdcp.hdcp_mutex);
194 193
195 /* Sink's capability for HDCP2.2 */194 /* Sink's capability for HDCP2.2 */
196 hdcp->shim->hdcp_2_2_capable(dig_port, &capable);195 hdcp->shim->hdcp_2_2_capable(connector, &capable);
197 196
198 return capable;197 return capable;
199}198}
@@ -1415,7 +1414,6 @@ static int hdcp2_deauthenticate_port(struct intel_connector *connector) · 1215 unmodified lines
1415/* Authentication flow starts from here */1414/* Authentication flow starts from here */
1416static int hdcp2_authentication_key_exchange(struct intel_connector *connector)1415static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
1417{1416{
1418 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1419 struct drm_i915_private *i915 = to_i915(connector->base.dev);1417 struct drm_i915_private *i915 = to_i915(connector->base.dev);
1420 struct intel_hdcp *hdcp = &connector->hdcp;1418 struct intel_hdcp *hdcp = &connector->hdcp;
1421 union {1419 union {
@@ -1437,12 +1435,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) · 15 unmodified lines
1437 if (ret < 0)1435 if (ret < 0)
1438 return ret;1436 return ret;
1439 1437
1440 ret = shim->write_2_2_msg(dig_port, &msgs.ake_init,1438 ret = shim->write_2_2_msg(connector, &msgs.ake_init,
1441 sizeof(msgs.ake_init));1439 sizeof(msgs.ake_init));
1442 if (ret < 0)1440 if (ret < 0)
1443 return ret;1441 return ret;
1444 1442
1445 ret = shim->read_2_2_msg(dig_port, HDCP_2_2_AKE_SEND_CERT,1443 ret = shim->read_2_2_msg(connector, HDCP_2_2_AKE_SEND_CERT,
1446 &msgs.send_cert, sizeof(msgs.send_cert));1444 &msgs.send_cert, sizeof(msgs.send_cert));
1447 if (ret < 0)1445 if (ret < 0)
1448 return ret;1446 return ret;
@@ -1471,11 +1469,11 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) · 22 unmodified lines
1471 if (ret < 0)1469 if (ret < 0)
1472 return ret;1470 return ret;
1473 1471
1474 ret = shim->write_2_2_msg(dig_port, &msgs.no_stored_km, size);1472 ret = shim->write_2_2_msg(connector, &msgs.no_stored_km, size);
1475 if (ret < 0)1473 if (ret < 0)
1476 return ret;1474 return ret;
1477 1475
1478 ret = shim->read_2_2_msg(dig_port, HDCP_2_2_AKE_SEND_HPRIME,1476 ret = shim->read_2_2_msg(connector, HDCP_2_2_AKE_SEND_HPRIME,
1479 &msgs.send_hprime, sizeof(msgs.send_hprime));1477 &msgs.send_hprime, sizeof(msgs.send_hprime));
1480 if (ret < 0)1478 if (ret < 0)
1481 return ret;1479 return ret;
@@ -1486,7 +1484,7 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) · 4 unmodified lines
1486 1484
1487 if (!hdcp->is_paired) {1485 if (!hdcp->is_paired) {
1488 /* Pairing is required */1486 /* Pairing is required */
1489 ret = shim->read_2_2_msg(dig_port,1487 ret = shim->read_2_2_msg(connector,
1490 HDCP_2_2_AKE_SEND_PAIRING_INFO,1488 HDCP_2_2_AKE_SEND_PAIRING_INFO,
1491 &msgs.pairing_info,1489 &msgs.pairing_info,
1492 sizeof(msgs.pairing_info));1490 sizeof(msgs.pairing_info));
@@ -1504,7 +1502,6 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector) · 11 unmodified lines
1504 1502
1505static int hdcp2_locality_check(struct intel_connector *connector)1503static int hdcp2_locality_check(struct intel_connector *connector)
1506{1504{
1507 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1508 struct intel_hdcp *hdcp = &connector->hdcp;1505 struct intel_hdcp *hdcp = &connector->hdcp;
1509 union {1506 union {
1510 struct hdcp2_lc_init lc_init;1507 struct hdcp2_lc_init lc_init;
@@ -1518,12 +1515,12 @@ static int hdcp2_locality_check(struct intel_connector *connector) · 7 unmodified lines
1518 if (ret < 0)1515 if (ret < 0)
1519 continue;1516 continue;
1520 1517
1521 ret = shim->write_2_2_msg(dig_port, &msgs.lc_init,1518 ret = shim->write_2_2_msg(connector, &msgs.lc_init,
1522 sizeof(msgs.lc_init));1519 sizeof(msgs.lc_init));
1523 if (ret < 0)1520 if (ret < 0)
1524 continue;1521 continue;
1525 1522
1526 ret = shim->read_2_2_msg(dig_port,1523 ret = shim->read_2_2_msg(connector,
1527 HDCP_2_2_LC_SEND_LPRIME,1524 HDCP_2_2_LC_SEND_LPRIME,
1528 &msgs.send_lprime,1525 &msgs.send_lprime,
1529 sizeof(msgs.send_lprime));1526 sizeof(msgs.send_lprime));
@@ -1540,7 +1537,6 @@ static int hdcp2_locality_check(struct intel_connector *connector) · 10 unmodified lines
1540 1537
1541static int hdcp2_session_key_exchange(struct intel_connector *connector)1538static int hdcp2_session_key_exchange(struct intel_connector *connector)
1542{1539{
1543 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1544 struct intel_hdcp *hdcp = &connector->hdcp;1540 struct intel_hdcp *hdcp = &connector->hdcp;
1545 struct hdcp2_ske_send_eks send_eks;1541 struct hdcp2_ske_send_eks send_eks;
1546 int ret;1542 int ret;
@@ -1549,7 +1545,7 @@ static int hdcp2_session_key_exchange(struct intel_connector *connector) · 2 unmodified lines
1549 if (ret < 0)1545 if (ret < 0)
1550 return ret;1546 return ret;
1551 1547
1552 ret = hdcp->shim->write_2_2_msg(dig_port, &send_eks,1548 ret = hdcp->shim->write_2_2_msg(connector, &send_eks,
1553 sizeof(send_eks));1549 sizeof(send_eks));
1554 if (ret < 0)1550 if (ret < 0)
1555 return ret;1551 return ret;
@@ -1587,12 +1583,12 @@ int _hdcp2_propagate_stream_management_info(struct intel_connector *connector) · 31 unmodified lines
1587 streams_size_delta = (HDCP_2_2_MAX_CONTENT_STREAMS_CNT - data->k) *1583 streams_size_delta = (HDCP_2_2_MAX_CONTENT_STREAMS_CNT - data->k) *
1588 sizeof(struct hdcp2_streamid_type);1584 sizeof(struct hdcp2_streamid_type);
1589 /* Send it to Repeater */1585 /* Send it to Repeater */
1590 ret = shim->write_2_2_msg(dig_port, &msgs.stream_manage,1586 ret = shim->write_2_2_msg(connector, &msgs.stream_manage,
1591 sizeof(msgs.stream_manage) - streams_size_delta);1587 sizeof(msgs.stream_manage) - streams_size_delta);
1592 if (ret < 0)1588 if (ret < 0)
1593 goto out;1589 goto out;
1594 1590
1595 ret = shim->read_2_2_msg(dig_port, HDCP_2_2_REP_STREAM_READY,1591 ret = shim->read_2_2_msg(connector, HDCP_2_2_REP_STREAM_READY,
1596 &msgs.stream_ready, sizeof(msgs.stream_ready));1592 &msgs.stream_ready, sizeof(msgs.stream_ready));
1597 if (ret < 0)1593 if (ret < 0)
1598 goto out;1594 goto out;
@@ -1622,7 +1618,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) · 23 unmodified lines
1622 u8 *rx_info;1618 u8 *rx_info;
1623 int ret;1619 int ret;
1624 1620
1625 ret = shim->read_2_2_msg(dig_port, HDCP_2_2_REP_SEND_RECVID_LIST,1621 ret = shim->read_2_2_msg(connector, HDCP_2_2_REP_SEND_RECVID_LIST,
1626 &msgs.recvid_list, sizeof(msgs.recvid_list));1622 &msgs.recvid_list, sizeof(msgs.recvid_list));
1627 if (ret < 0)1623 if (ret < 0)
1628 return ret;1624 return ret;
@@ -1675,7 +1671,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) · 46 unmodified lines
1675 return ret;1671 return ret;
1676 1672
1677 hdcp->seq_num_v = seq_num_v;1673 hdcp->seq_num_v = seq_num_v;
1678 ret = shim->write_2_2_msg(dig_port, &msgs.rep_ack,1674 ret = shim->write_2_2_msg(connector, &msgs.rep_ack,
1679 sizeof(msgs.rep_ack));1675 sizeof(msgs.rep_ack));
1680 if (ret < 0)1676 if (ret < 0)
1681 return ret;1677 return ret;
@@ -1685,7 +1681,6 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector) · 3 unmodified lines
1685 1681
1686static int hdcp2_authenticate_sink(struct intel_connector *connector)1682static int hdcp2_authenticate_sink(struct intel_connector *connector)
1687{1683{
1688 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1689 struct drm_i915_private *i915 = to_i915(connector->base.dev);1684 struct drm_i915_private *i915 = to_i915(connector->base.dev);
1690 struct intel_hdcp *hdcp = &connector->hdcp;1685 struct intel_hdcp *hdcp = &connector->hdcp;
1691 const struct intel_hdcp_shim *shim = hdcp->shim;1686 const struct intel_hdcp_shim *shim = hdcp->shim;
@@ -1711,7 +1706,7 @@ static int hdcp2_authenticate_sink(struct intel_connector *connector) · 19 unmodified lines
1711 }1706 }
1712 1707
1713 if (shim->config_stream_type) {1708 if (shim->config_stream_type) {
1714 ret = shim->config_stream_type(dig_port,1709 ret = shim->config_stream_type(connector,
1715 hdcp->is_repeater,1710 hdcp->is_repeater,
1716 hdcp->content_type);1711 hdcp->content_type);
1717 if (ret < 0)1712 if (ret < 0)
drivers/gpu/drm/i915/display/intel_hdmi.c+39−82
@@ -1240,26 +1240,23 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, · 1239 unmodified lines
1240void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)1240void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
1241{1241{
1242 struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi);1242 struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi);
1243 struct i2c_adapter *adapter;1243 struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc;
1244 1244
1245 if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)1245 if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
1246 return;1246 return;
1247 1247
1248 adapter = intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
1249
1250 drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n",1248 drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n",
1251 enable ? "Enabling" : "Disabling");1249 enable ? "Enabling" : "Disabling");
1252 1250
1253 drm_dp_dual_mode_set_tmds_output(&dev_priv->drm, hdmi->dp_dual_mode.type, adapter, enable);1251 drm_dp_dual_mode_set_tmds_output(&dev_priv->drm,
1252 hdmi->dp_dual_mode.type, ddc, enable);
1254}1253}
1255 1254
1256static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port,1255static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port,
1257 unsigned int offset, void *buffer, size_t size)1256 unsigned int offset, void *buffer, size_t size)
1258{1257{
1259 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1260 struct intel_hdmi *hdmi = &dig_port->hdmi;1258 struct intel_hdmi *hdmi = &dig_port->hdmi;
1261 struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915,1259 struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc;
1262 hdmi->ddc_bus);
1263 int ret;1260 int ret;
1264 u8 start = offset & 0xff;1261 u8 start = offset & 0xff;
1265 struct i2c_msg msgs[] = {1262 struct i2c_msg msgs[] = {
@@ -1276,7 +1273,7 @@ static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, · 10 unmodified lines
1276 .buf = buffer1273 .buf = buffer
1277 }1274 }
1278 };1275 };
1279 ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));1276 ret = i2c_transfer(ddc, msgs, ARRAY_SIZE(msgs));
1280 if (ret == ARRAY_SIZE(msgs))1277 if (ret == ARRAY_SIZE(msgs))
1281 return 0;1278 return 0;
1282 return ret >= 0 ? -EIO : ret;1279 return ret >= 0 ? -EIO : ret;
@@ -1285,10 +1282,8 @@ static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, · 2 unmodified lines
1285static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port,1282static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port,
1286 unsigned int offset, void *buffer, size_t size)1283 unsigned int offset, void *buffer, size_t size)
1287{1284{
1288 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1289 struct intel_hdmi *hdmi = &dig_port->hdmi;1285 struct intel_hdmi *hdmi = &dig_port->hdmi;
1290 struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915,1286 struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc;
1291 hdmi->ddc_bus);
1292 int ret;1287 int ret;
1293 u8 *write_buf;1288 u8 *write_buf;
1294 struct i2c_msg msg;1289 struct i2c_msg msg;
@@ -1305,7 +1300,7 @@ static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port, · 10 unmodified lines
1305 msg.len = size + 1,1300 msg.len = size + 1,
1306 msg.buf = write_buf;1301 msg.buf = write_buf;
1307 1302
1308 ret = i2c_transfer(adapter, &msg, 1);1303 ret = i2c_transfer(ddc, &msg, 1);
1309 if (ret == 1)1304 if (ret == 1)
1310 ret = 0;1305 ret = 0;
1311 else if (ret >= 0)1306 else if (ret >= 0)
@@ -1321,8 +1316,7 @@ int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *dig_port, · 9 unmodified lines
1321{1316{
1322 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);1317 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1323 struct intel_hdmi *hdmi = &dig_port->hdmi;1318 struct intel_hdmi *hdmi = &dig_port->hdmi;
1324 struct i2c_adapter *adapter = intel_gmbus_get_adapter(i915,1319 struct i2c_adapter *ddc = hdmi->attached_connector->base.ddc;
1325 hdmi->ddc_bus);
1326 int ret;1320 int ret;
1327 1321
1328 ret = intel_hdmi_hdcp_write(dig_port, DRM_HDCP_DDC_AN, an,1322 ret = intel_hdmi_hdcp_write(dig_port, DRM_HDCP_DDC_AN, an,
@@ -1333,7 +1327,7 @@ int intel_hdmi_hdcp_write_an_aksv(struct intel_digital_port *dig_port, · 4 unmodified lines
1333 return ret;1327 return ret;
1334 }1328 }
1335 1329
1336 ret = intel_gmbus_output_aksv(adapter);1330 ret = intel_gmbus_output_aksv(ddc);
1337 if (ret < 0) {1331 if (ret < 0) {
1338 drm_dbg_kms(&i915->drm, "Failed to output aksv (%d)\n", ret);1332 drm_dbg_kms(&i915->drm, "Failed to output aksv (%d)\n", ret);
1339 return ret;1333 return ret;
@@ -1665,9 +1659,10 @@ intel_hdmi_hdcp2_wait_for_msg(struct intel_digital_port *dig_port, · 325 unmodified lines
1665}1659}
1666 1660
1667static1661static
1668int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *dig_port,1662int intel_hdmi_hdcp2_write_msg(struct intel_connector *connector,
1669 void *buf, size_t size)1663 void *buf, size_t size)
1670{1664{
1665 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1671 unsigned int offset;1666 unsigned int offset;
1672 1667
1673 offset = HDCP_2_2_HDMI_REG_WR_MSG_OFFSET;1668 offset = HDCP_2_2_HDMI_REG_WR_MSG_OFFSET;
@@ -1675,9 +1670,10 @@ int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *dig_port, · 1 unmodified line
1675}1670}
1676 1671
1677static1672static
1678int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *dig_port,1673int intel_hdmi_hdcp2_read_msg(struct intel_connector *connector,
1679 u8 msg_id, void *buf, size_t size)1674 u8 msg_id, void *buf, size_t size)
1680{1675{
1676 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1681 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);1677 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
1682 struct intel_hdmi *hdmi = &dig_port->hdmi;1678 struct intel_hdmi *hdmi = &dig_port->hdmi;
1683 struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp;1679 struct intel_hdcp *hdcp = &hdmi->attached_connector->hdcp;
@@ -1733,9 +1729,10 @@ int intel_hdmi_hdcp2_check_link(struct intel_digital_port *dig_port, · 49 unmodified lines
1733}1729}
1734 1730
1735static1731static
1736int intel_hdmi_hdcp2_capable(struct intel_digital_port *dig_port,1732int intel_hdmi_hdcp2_capable(struct intel_connector *connector,
1737 bool *capable)1733 bool *capable)
1738{1734{
1735 struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
1739 u8 hdcp2_version;1736 u8 hdcp2_version;
1740 int ret;1737 int ret;
1741 1738
@@ -2400,9 +2397,10 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) · 658 unmodified lines
2400 struct drm_i915_private *dev_priv = to_i915(connector->dev);2397 struct drm_i915_private *dev_priv = to_i915(connector->dev);
2401 struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));2398 struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
2402 struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base;2399 struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base;
2403 struct i2c_adapter *adapter =2400 struct i2c_adapter *ddc = connector->ddc;
2404 intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);2401 enum drm_dp_dual_mode_type type;
2405 enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(&dev_priv->drm, adapter);2402
2403 type = drm_dp_dual_mode_detect(&dev_priv->drm, ddc);
2406 2404
2407 /*2405 /*
2408 * Type 1 DVI adaptors are not required to implement any2406 * Type 1 DVI adaptors are not required to implement any
@@ -2429,7 +2427,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) · 20 unmodified lines
2429 2427
2430 hdmi->dp_dual_mode.type = type;2428 hdmi->dp_dual_mode.type = type;
2431 hdmi->dp_dual_mode.max_tmds_clock =2429 hdmi->dp_dual_mode.max_tmds_clock =
2432 drm_dp_dual_mode_max_tmds_clock(&dev_priv->drm, type, adapter);2430 drm_dp_dual_mode_max_tmds_clock(&dev_priv->drm, type, ddc);
2433 2431
2434 drm_dbg_kms(&dev_priv->drm,2432 drm_dbg_kms(&dev_priv->drm,
2435 "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",2433 "DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
@@ -2450,24 +2448,21 @@ intel_hdmi_set_edid(struct drm_connector *connector) · 14 unmodified lines
2450{2448{
2451 struct drm_i915_private *dev_priv = to_i915(connector->dev);2449 struct drm_i915_private *dev_priv = to_i915(connector->dev);
2452 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));2450 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
2451 struct i2c_adapter *ddc = connector->ddc;
2453 intel_wakeref_t wakeref;2452 intel_wakeref_t wakeref;
2454 const struct drm_edid *drm_edid;2453 const struct drm_edid *drm_edid;
2455 const struct edid *edid;
2456 bool connected = false;2454 bool connected = false;
2457 struct i2c_adapter *i2c;
2458 2455
2459 wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);2456 wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
2460 2457
2461 i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);2458 drm_edid = drm_edid_read_ddc(connector, ddc);
2462 2459
2463 drm_edid = drm_edid_read_ddc(connector, i2c);2460 if (!drm_edid && !intel_gmbus_is_forced_bit(ddc)) {
2464
2465 if (!drm_edid && !intel_gmbus_is_forced_bit(i2c)) {
2466 drm_dbg_kms(&dev_priv->drm,2461 drm_dbg_kms(&dev_priv->drm,
2467 "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");2462 "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
2468 intel_gmbus_force_bit(i2c, true);2463 intel_gmbus_force_bit(ddc, true);
2469 drm_edid = drm_edid_read_ddc(connector, i2c);2464 drm_edid = drm_edid_read_ddc(connector, ddc);
2470 intel_gmbus_force_bit(i2c, false);2465 intel_gmbus_force_bit(ddc, false);
2471 }2466 }
2472 2467
2473 /* Below we depend on display info having been updated */2468 /* Below we depend on display info having been updated */
@@ -2475,9 +2470,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) · 1 unmodified line
2475 2470
2476 to_intel_connector(connector)->detect_edid = drm_edid;2471 to_intel_connector(connector)->detect_edid = drm_edid;
2477 2472
2478 /* FIXME: Get rid of drm_edid_raw() */2473 if (drm_edid_is_digital(drm_edid)) {
2479 edid = drm_edid_raw(drm_edid);
2480 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
2481 intel_hdmi_dp_dual_mode_detect(connector);2474 intel_hdmi_dp_dual_mode_detect(connector);
2482 2475
2483 connected = true;2476 connected = true;
@@ -2485,7 +2478,8 @@ intel_hdmi_set_edid(struct drm_connector *connector) · 1 unmodified line
2485 2478
2486 intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);2479 intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
2487 2480
2488 cec_notifier_set_phys_addr_from_edid(intel_hdmi->cec_notifier, edid);2481 cec_notifier_set_phys_addr(intel_hdmi->cec_notifier,
2482 connector->display_info.source_physical_address);
2489 2483
2490 return connected;2484 return connected;
2491}2485}
@@ -2522,12 +2516,6 @@ out: · 30 unmodified lines
2522 if (status != connector_status_connected)2516 if (status != connector_status_connected)
2523 cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);2517 cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
2524 2518
2525 /*
2526 * Make sure the refs for power wells enabled during detect are
2527 * dropped to avoid a new detect cycle triggered by HPD polling.
2528 */
2529 intel_display_power_flush_work(dev_priv);
2530
2531 return status;2519 return status;
2532}2520}
2533 2521
@@ -2553,37 +2541,6 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) · 19 unmodified lines
2553 return drm_edid_connector_add_modes(connector);2541 return drm_edid_connector_add_modes(connector);
2554}2542}
2555 2543
2556static struct i2c_adapter *
2557intel_hdmi_get_i2c_adapter(struct drm_connector *connector)
2558{
2559 struct drm_i915_private *dev_priv = to_i915(connector->dev);
2560 struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
2561
2562 return intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
2563}
2564
2565static void intel_hdmi_create_i2c_symlink(struct drm_connector *connector)
2566{
2567 struct drm_i915_private *i915 = to_i915(connector->dev);
2568 struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector);
2569 struct kobject *i2c_kobj = &adapter->dev.kobj;
2570 struct kobject *connector_kobj = &connector->kdev->kobj;
2571 int ret;
2572
2573 ret = sysfs_create_link(connector_kobj, i2c_kobj, i2c_kobj->name);
2574 if (ret)
2575 drm_err(&i915->drm, "Failed to create i2c symlink (%d)\n", ret);
2576}
2577
2578static void intel_hdmi_remove_i2c_symlink(struct drm_connector *connector)
2579{
2580 struct i2c_adapter *adapter = intel_hdmi_get_i2c_adapter(connector);
2581 struct kobject *i2c_kobj = &adapter->dev.kobj;
2582 struct kobject *connector_kobj = &connector->kdev->kobj;
2583
2584 sysfs_remove_link(connector_kobj, i2c_kobj->name);
2585}
2586
2587static int2544static int
2588intel_hdmi_connector_register(struct drm_connector *connector)2545intel_hdmi_connector_register(struct drm_connector *connector)
2589{2546{
@@ -2593,8 +2550,6 @@ intel_hdmi_connector_register(struct drm_connector *connector) · 3 unmodified lines
2593 if (ret)2550 if (ret)
2594 return ret;2551 return ret;
2595 2552
2596 intel_hdmi_create_i2c_symlink(connector);
2597
2598 return ret;2553 return ret;
2599}2554}
2600 2555
@@ -2604,7 +2559,6 @@ static void intel_hdmi_connector_unregister(struct drm_connector *connector) · 3 unmodified lines
2604 2559
2605 cec_notifier_conn_unregister(n);2560 cec_notifier_conn_unregister(n);
2606 2561
2607 intel_hdmi_remove_i2c_symlink(connector);
2608 intel_connector_unregister(connector);2562 intel_connector_unregister(connector);
2609}2563}
2610 2564
@@ -2918,13 +2872,17 @@ get_encoder_by_ddc_pin(struct intel_encoder *encoder, u8 ddc_pin) · 307 unmodified lines
2918 struct intel_encoder *other;2872 struct intel_encoder *other;
2919 2873
2920 for_each_intel_encoder(&i915->drm, other) {2874 for_each_intel_encoder(&i915->drm, other) {
2875 struct intel_connector *connector;
2876
2921 if (other == encoder)2877 if (other == encoder)
2922 continue;2878 continue;
2923 2879
2924 if (!intel_encoder_is_dig_port(other))2880 if (!intel_encoder_is_dig_port(other))
2925 continue;2881 continue;
2926 2882
2927 if (enc_to_dig_port(other)->hdmi.ddc_bus == ddc_pin)2883 connector = enc_to_dig_port(other)->hdmi.attached_connector;
2884
2885 if (connector && connector->base.ddc == intel_gmbus_get_adapter(i915, ddc_pin))
2928 return other;2886 return other;
2929 }2887 }
2930 2888
@@ -3016,9 +2974,9 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port, · 85 unmodified lines
3016 struct intel_encoder *intel_encoder = &dig_port->base;2974 struct intel_encoder *intel_encoder = &dig_port->base;
3017 struct drm_device *dev = intel_encoder->base.dev;2975 struct drm_device *dev = intel_encoder->base.dev;
3018 struct drm_i915_private *dev_priv = to_i915(dev);2976 struct drm_i915_private *dev_priv = to_i915(dev);
3019 struct i2c_adapter *ddc;
3020 enum port port = intel_encoder->port;2977 enum port port = intel_encoder->port;
3021 struct cec_connector_info conn_info;2978 struct cec_connector_info conn_info;
2979 u8 ddc_pin;
3022 2980
3023 drm_dbg_kms(&dev_priv->drm,2981 drm_dbg_kms(&dev_priv->drm,
3024 "Adding HDMI connector on [ENCODER:%d:%s]\n",2982 "Adding HDMI connector on [ENCODER:%d:%s]\n",
@@ -3033,16 +2991,15 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port, · 8 unmodified lines
3033 intel_encoder->base.name))2991 intel_encoder->base.name))
3034 return;2992 return;
3035 2993
3036 intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(intel_encoder);2994 ddc_pin = intel_hdmi_ddc_pin(intel_encoder);
3037 if (!intel_hdmi->ddc_bus)2995 if (!ddc_pin)
3038 return;2996 return;
3039 2997
3040 ddc = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
3041
3042 drm_connector_init_with_ddc(dev, connector,2998 drm_connector_init_with_ddc(dev, connector,
3043 &intel_hdmi_connector_funcs,2999 &intel_hdmi_connector_funcs,
3044 DRM_MODE_CONNECTOR_HDMIA,3000 DRM_MODE_CONNECTOR_HDMIA,
3045 ddc);3001 intel_gmbus_get_adapter(dev_priv, ddc_pin));
3002
3046 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);3003 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
3047 3004
3048 if (DISPLAY_VER(dev_priv) < 12)3005 if (DISPLAY_VER(dev_priv) < 12)
drivers/gpu/drm/i915/display/intel_hotplug.c+78−7
@@ -25,6 +25,7 @@ · 24 unmodified lines
25 25
26#include "i915_drv.h"26#include "i915_drv.h"
27#include "i915_irq.h"27#include "i915_irq.h"
28#include "intel_display_power.h"
28#include "intel_display_types.h"29#include "intel_display_types.h"
29#include "intel_hotplug.h"30#include "intel_hotplug.h"
30#include "intel_hotplug_irq.h"31#include "intel_hotplug_irq.h"
@@ -259,21 +260,22 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) · 228 unmodified lines
259 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);260 intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
260}261}
261 262
262enum intel_hotplug_state263static enum intel_hotplug_state
263intel_encoder_hotplug(struct intel_encoder *encoder,264intel_hotplug_detect_connector(struct intel_connector *connector)
264 struct intel_connector *connector)
265{265{
266 struct drm_device *dev = connector->base.dev;266 struct drm_device *dev = connector->base.dev;
267 enum drm_connector_status old_status;267 enum drm_connector_status old_status;
268 u64 old_epoch_counter;268 u64 old_epoch_counter;
269 int status;
269 bool ret = false;270 bool ret = false;
270 271
271 drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex));272 drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex));
272 old_status = connector->base.status;273 old_status = connector->base.status;
273 old_epoch_counter = connector->base.epoch_counter;274 old_epoch_counter = connector->base.epoch_counter;
274 275
275 connector->base.status =276 status = drm_helper_probe_detect(&connector->base, NULL, false);
276 drm_helper_probe_detect(&connector->base, NULL, false);277 if (!connector->base.force)
278 connector->base.status = status;
277 279
278 if (old_epoch_counter != connector->base.epoch_counter)280 if (old_epoch_counter != connector->base.epoch_counter)
279 ret = true;281 ret = true;
@@ -291,6 +293,13 @@ intel_encoder_hotplug(struct intel_encoder *encoder, · 11 unmodified lines
291 return INTEL_HOTPLUG_UNCHANGED;293 return INTEL_HOTPLUG_UNCHANGED;
292}294}
293 295
296enum intel_hotplug_state
297intel_encoder_hotplug(struct intel_encoder *encoder,
298 struct intel_connector *connector)
299{
300 return intel_hotplug_detect_connector(connector);
301}
302
294static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder)303static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder)
295{304{
296 return intel_encoder_is_dig_port(encoder) &&305 return intel_encoder_is_dig_port(encoder) &&
@@ -631,6 +640,49 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) · 334 unmodified lines
631 spin_unlock_irq(&dev_priv->irq_lock);640 spin_unlock_irq(&dev_priv->irq_lock);
632}641}
633 642
643static void i915_hpd_poll_detect_connectors(struct drm_i915_private *i915)
644{
645 struct drm_connector_list_iter conn_iter;
646 struct intel_connector *connector;
647 struct intel_connector *first_changed_connector = NULL;
648 int changed = 0;
649
650 mutex_lock(&i915->drm.mode_config.mutex);
651
652 if (!i915->drm.mode_config.poll_enabled)
653 goto out;
654
655 drm_connector_list_iter_begin(&i915->drm, &conn_iter);
656 for_each_intel_connector_iter(connector, &conn_iter) {
657 if (!(connector->base.polled & DRM_CONNECTOR_POLL_HPD))
658 continue;
659
660 if (intel_hotplug_detect_connector(connector) != INTEL_HOTPLUG_CHANGED)
661 continue;
662
663 changed++;
664
665 if (changed == 1) {
666 drm_connector_get(&connector->base);
667 first_changed_connector = connector;
668 }
669 }
670 drm_connector_list_iter_end(&conn_iter);
671
672out:
673 mutex_unlock(&i915->drm.mode_config.mutex);
674
675 if (!changed)
676 return;
677
678 if (changed == 1)
679 drm_kms_helper_connector_hotplug_event(&first_changed_connector->base);
680 else
681 drm_kms_helper_hotplug_event(&i915->drm);
682
683 drm_connector_put(&first_changed_connector->base);
684}
685
634static void i915_hpd_poll_init_work(struct work_struct *work)686static void i915_hpd_poll_init_work(struct work_struct *work)
635{687{
636 struct drm_i915_private *dev_priv =688 struct drm_i915_private *dev_priv =
@@ -638,11 +690,25 @@ static void i915_hpd_poll_init_work(struct work_struct *work) · 1 unmodified line
638 display.hotplug.poll_init_work);690 display.hotplug.poll_init_work);
639 struct drm_connector_list_iter conn_iter;691 struct drm_connector_list_iter conn_iter;
640 struct intel_connector *connector;692 struct intel_connector *connector;
693 intel_wakeref_t wakeref;
641 bool enabled;694 bool enabled;
642 695
643 mutex_lock(&dev_priv->drm.mode_config.mutex);696 mutex_lock(&dev_priv->drm.mode_config.mutex);
644 697
645 enabled = READ_ONCE(dev_priv->display.hotplug.poll_enabled);698 enabled = READ_ONCE(dev_priv->display.hotplug.poll_enabled);
699 /*
700 * Prevent taking a power reference from this sequence of
701 * i915_hpd_poll_init_work() -> drm_helper_hpd_irq_event() ->
702 * connector detect which would requeue i915_hpd_poll_init_work()
703 * and so risk an endless loop of this same sequence.
704 */
705 if (!enabled) {
706 wakeref = intel_display_power_get(dev_priv,
707 POWER_DOMAIN_DISPLAY_CORE);
708 drm_WARN_ON(&dev_priv->drm,
709 READ_ONCE(dev_priv->display.hotplug.poll_enabled));
710 cancel_work(&dev_priv->display.hotplug.poll_init_work);
711 }
646 712
647 drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);713 drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
648 for_each_intel_connector_iter(connector, &conn_iter) {714 for_each_intel_connector_iter(connector, &conn_iter) {
@@ -669,8 +735,13 @@ static void i915_hpd_poll_init_work(struct work_struct *work) · 20 unmodified lines
669 * We might have missed any hotplugs that happened while we were735 * We might have missed any hotplugs that happened while we were
670 * in the middle of disabling polling736 * in the middle of disabling polling
671 */737 */
672 if (!enabled)738 if (!enabled) {
673 drm_helper_hpd_irq_event(&dev_priv->drm);739 i915_hpd_poll_detect_connectors(dev_priv);
740
741 intel_display_power_put(dev_priv,
742 POWER_DOMAIN_DISPLAY_CORE,
743 wakeref);
744 }
674}745}
675 746
676/**747/**
drivers/gpu/drm/i915/display/intel_hotplug_irq.c+22−2
@@ -163,7 +163,9 @@ static void intel_hpd_init_pins(struct drm_i915_private *dev_priv) · 162 unmodified lines
163 (!HAS_PCH_SPLIT(dev_priv) || HAS_PCH_NOP(dev_priv)))163 (!HAS_PCH_SPLIT(dev_priv) || HAS_PCH_NOP(dev_priv)))
164 return;164 return;
165 165
166 if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)166 if (INTEL_PCH_TYPE(dev_priv) >= PCH_LNL)
167 hpd->pch_hpd = hpd_mtp;
168 else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
167 hpd->pch_hpd = hpd_sde_dg1;169 hpd->pch_hpd = hpd_sde_dg1;
168 else if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTP)170 else if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTP)
169 hpd->pch_hpd = hpd_mtp;171 hpd->pch_hpd = hpd_mtp;
@@ -514,6 +516,9 @@ void xelpdp_pica_irq_handler(struct drm_i915_private *i915, u32 iir) · 344 unmodified lines
514 u32 trigger_aux = iir & XELPDP_AUX_TC_MASK;516 u32 trigger_aux = iir & XELPDP_AUX_TC_MASK;
515 u32 pin_mask = 0, long_mask = 0;517 u32 pin_mask = 0, long_mask = 0;
516 518
519 if (DISPLAY_VER(i915) >= 20)
520 trigger_aux |= iir & XE2LPD_AUX_DDI_MASK;
521
517 for (pin = HPD_PORT_TC1; pin <= HPD_PORT_TC4; pin++) {522 for (pin = HPD_PORT_TC1; pin <= HPD_PORT_TC4; pin++) {
518 u32 val;523 u32 val;
519 524
@@ -1060,6 +1065,19 @@ static void mtp_hpd_irq_setup(struct drm_i915_private *i915) · 540 unmodified lines
1060 mtp_tc_hpd_detection_setup(i915);1065 mtp_tc_hpd_detection_setup(i915);
1061}1066}
1062 1067
1068static void xe2lpd_sde_hpd_irq_setup(struct drm_i915_private *i915)
1069{
1070 u32 hotplug_irqs, enabled_irqs;
1071
1072 enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.pch_hpd);
1073 hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.pch_hpd);
1074
1075 ibx_display_interrupt_update(i915, hotplug_irqs, enabled_irqs);
1076
1077 mtp_ddi_hpd_detection_setup(i915);
1078 mtp_tc_hpd_detection_setup(i915);
1079}
1080
1063static bool is_xelpdp_pica_hpd_pin(enum hpd_pin hpd_pin)1081static bool is_xelpdp_pica_hpd_pin(enum hpd_pin hpd_pin)
1064{1082{
1065 return hpd_pin >= HPD_PORT_TC1 && hpd_pin <= HPD_PORT_TC4;1083 return hpd_pin >= HPD_PORT_TC1 && hpd_pin <= HPD_PORT_TC4;
@@ -1119,7 +1137,9 @@ static void xelpdp_hpd_irq_setup(struct drm_i915_private *i915) · 53 unmodified lines
1119 1137
1120 xelpdp_pica_hpd_detection_setup(i915);1138 xelpdp_pica_hpd_detection_setup(i915);
1121 1139
1122 if (INTEL_PCH_TYPE(i915) >= PCH_MTP)1140 if (INTEL_PCH_TYPE(i915) >= PCH_LNL)
1141 xe2lpd_sde_hpd_irq_setup(i915);
1142 else if (INTEL_PCH_TYPE(i915) >= PCH_MTP)
1123 mtp_hpd_irq_setup(i915);1143 mtp_hpd_irq_setup(i915);
1124}1144}
1125 1145
drivers/gpu/drm/i915/display/intel_link_bw.c+212−0
@@ -0,0 +1,212 @@
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#include "i915_drv.h"
7
8#include "intel_atomic.h"
9#include "intel_display_types.h"
10#include "intel_fdi.h"
11#include "intel_link_bw.h"
12
13/**
14 * intel_link_bw_init_limits - initialize BW limits
15 * @i915: device instance
16 * @limits: link BW limits
17 *
18 * Initialize @limits.
19 */
20void intel_link_bw_init_limits(struct drm_i915_private *i915, struct intel_link_bw_limits *limits)
21{
22 enum pipe pipe;
23
24 limits->bpp_limit_reached_pipes = 0;
25 for_each_pipe(i915, pipe)
26 limits->max_bpp_x16[pipe] = INT_MAX;
27}
28
29/**
30 * intel_link_bw_reduce_bpp - reduce maximum link bpp for a selected pipe
31 * @state: atomic state
32 * @limits: link BW limits
33 * @pipe_mask: mask of pipes to select from
34 * @reason: explanation of why bpp reduction is needed
35 *
36 * Select the pipe from @pipe_mask with the biggest link bpp value and set the
37 * maximum of link bpp in @limits below this value. Modeset the selected pipe,
38 * so that its state will get recomputed.
39 *
40 * This function can be called to resolve a link's BW overallocation by reducing
41 * the link bpp of one pipe on the link and hence reducing the total link BW.
42 *
43 * Returns
44 * - 0 in case of success
45 * - %-ENOSPC if no pipe can further reduce its link bpp
46 * - Other negative error, if modesetting the selected pipe failed
47 */
48int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
49 struct intel_link_bw_limits *limits,
50 u8 pipe_mask,
51 const char *reason)
52{
53 struct drm_i915_private *i915 = to_i915(state->base.dev);
54 enum pipe max_bpp_pipe = INVALID_PIPE;
55 struct intel_crtc *crtc;
56 int max_bpp = 0;
57
58 for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) {
59 struct intel_crtc_state *crtc_state;
60 int link_bpp;
61
62 if (limits->bpp_limit_reached_pipes & BIT(crtc->pipe))
63 continue;
64
65 crtc_state = intel_atomic_get_crtc_state(&state->base,
66 crtc);
67 if (IS_ERR(crtc_state))
68 return PTR_ERR(crtc_state);
69
70 if (crtc_state->dsc.compression_enable)
71 link_bpp = crtc_state->dsc.compressed_bpp;
72 else
73 /*
74 * TODO: for YUV420 the actual link bpp is only half
75 * of the pipe bpp value. The MST encoder's BW allocation
76 * is based on the pipe bpp value, set the actual link bpp
77 * limit here once the MST BW allocation is fixed.
78 */
79 link_bpp = crtc_state->pipe_bpp;
80
81 if (link_bpp > max_bpp) {
82 max_bpp = link_bpp;
83 max_bpp_pipe = crtc->pipe;
84 }
85 }
86
87 if (max_bpp_pipe == INVALID_PIPE)
88 return -ENOSPC;
89
90 limits->max_bpp_x16[max_bpp_pipe] = to_bpp_x16(max_bpp) - 1;
91
92 return intel_modeset_pipes_in_mask_early(state, reason,
93 BIT(max_bpp_pipe));
94}
95
96/**
97 * intel_link_bw_set_bpp_limit_for_pipe - set link bpp limit for a pipe to its minimum
98 * @state: atomic state
99 * @old_limits: link BW limits
100 * @new_limits: link BW limits
101 * @pipe: pipe
102 *
103 * Set the link bpp limit for @pipe in @new_limits to its value in
104 * @old_limits and mark this limit as the minimum. This function must be
105 * called after a pipe's compute config function failed, @old_limits
106 * containing the bpp limit with which compute config previously passed.
107 *
108 * The function will fail if setting a minimum is not possible, either
109 * because the old and new limits match (and so would lead to a pipe compute
110 * config failure) or the limit is already at the minimum.
111 *
112 * Returns %true in case of success.
113 */
114bool
115intel_link_bw_set_bpp_limit_for_pipe(struct intel_atomic_state *state,
116 const struct intel_link_bw_limits *old_limits,
117 struct intel_link_bw_limits *new_limits,
118 enum pipe pipe)
119{
120 struct drm_i915_private *i915 = to_i915(state->base.dev);
121
122 if (pipe == INVALID_PIPE)
123 return false;
124
125 if (new_limits->max_bpp_x16[pipe] ==
126 old_limits->max_bpp_x16[pipe])
127 return false;
128
129 if (drm_WARN_ON(&i915->drm,
130 new_limits->bpp_limit_reached_pipes & BIT(pipe)))
131 return false;
132
133 new_limits->max_bpp_x16[pipe] =
134 old_limits->max_bpp_x16[pipe];
135 new_limits->bpp_limit_reached_pipes |= BIT(pipe);
136
137 return true;
138}
139
140static int check_all_link_config(struct intel_atomic_state *state,
141 struct intel_link_bw_limits *limits)
142{
143 /* TODO: Check additional shared display link configurations like MST */
144 int ret;
145
146 ret = intel_fdi_atomic_check_link(state, limits);
147 if (ret)
148 return ret;
149
150 return 0;
151}
152
153static bool
154assert_link_limit_change_valid(struct drm_i915_private *i915,
155 const struct intel_link_bw_limits *old_limits,
156 const struct intel_link_bw_limits *new_limits)
157{
158 bool bpps_changed = false;
159 enum pipe pipe;
160
161 for_each_pipe(i915, pipe) {
162 /* The bpp limit can only decrease. */
163 if (drm_WARN_ON(&i915->drm,
164 new_limits->max_bpp_x16[pipe] >
165 old_limits->max_bpp_x16[pipe]))
166 return false;
167
168 if (new_limits->max_bpp_x16[pipe] <
169 old_limits->max_bpp_x16[pipe])
170 bpps_changed = true;
171 }
172
173 /* At least one limit must change. */
174 if (drm_WARN_ON(&i915->drm,
175 !bpps_changed))
176 return false;
177
178 return true;
179}
180
181/**
182 * intel_link_bw_atomic_check - check display link states and set a fallback config if needed
183 * @state: atomic state
184 * @new_limits: link BW limits
185 *
186 * Check the configuration of all shared display links in @state and set new BW
187 * limits in @new_limits if there is a BW limitation.
188 *
189 * Returns:
190 * - 0 if the confugration is valid
191 * - %-EAGAIN, if the configuration is invalid and @new_limits got updated
192 * with fallback values with which the configuration of all CRTCs
193 * in @state must be recomputed
194 * - Other negative error, if the configuration is invalid without a
195 * fallback possibility, or the check failed for another reason
196 */
197int intel_link_bw_atomic_check(struct intel_atomic_state *state,
198 struct intel_link_bw_limits *new_limits)
199{
200 struct drm_i915_private *i915 = to_i915(state->base.dev);
201 struct intel_link_bw_limits old_limits = *new_limits;
202 int ret;
203
204 ret = check_all_link_config(state, new_limits);
205 if (ret != -EAGAIN)
206 return ret;
207
208 if (!assert_link_limit_change_valid(i915, &old_limits, new_limits))
209 return -EINVAL;
210
211 return -EAGAIN;
212}
drivers/gpu/drm/i915/display/intel_link_bw.h+37−0
@@ -0,0 +1,37 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#ifndef __INTEL_LINK_BW_H__
7#define __INTEL_LINK_BW_H__
8
9#include <linux/types.h>
10
11#include "intel_display_limits.h"
12
13struct drm_i915_private;
14
15struct intel_atomic_state;
16struct intel_crtc_state;
17
18struct intel_link_bw_limits {
19 u8 bpp_limit_reached_pipes;
20 /* in 1/16 bpp units */
21 int max_bpp_x16[I915_MAX_PIPES];
22};
23
24void intel_link_bw_init_limits(struct drm_i915_private *i915,
25 struct intel_link_bw_limits *limits);
26int intel_link_bw_reduce_bpp(struct intel_atomic_state *state,
27 struct intel_link_bw_limits *limits,
28 u8 pipe_mask,
29 const char *reason);
30bool intel_link_bw_set_bpp_limit_for_pipe(struct intel_atomic_state *state,
31 const struct intel_link_bw_limits *old_limits,
32 struct intel_link_bw_limits *new_limits,
33 enum pipe pipe);
34int intel_link_bw_atomic_check(struct intel_atomic_state *state,
35 struct intel_link_bw_limits *new_limits);
36
37#endif
drivers/gpu/drm/i915/display/intel_lspcon.c+7−7
@@ -144,9 +144,9 @@ static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) · 143 unmodified lines
144 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);144 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
145 struct drm_i915_private *i915 = dp_to_i915(intel_dp);145 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
146 enum drm_lspcon_mode current_mode;146 enum drm_lspcon_mode current_mode;
147 struct i2c_adapter *adapter = &intel_dp->aux.ddc;147 struct i2c_adapter *ddc = &intel_dp->aux.ddc;
148 148
149 if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode)) {149 if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, &current_mode)) {
150 drm_dbg_kms(&i915->drm, "Error reading LSPCON mode\n");150 drm_dbg_kms(&i915->drm, "Error reading LSPCON mode\n");
151 return DRM_LSPCON_MODE_INVALID;151 return DRM_LSPCON_MODE_INVALID;
152 }152 }
@@ -185,9 +185,9 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon, · 32 unmodified lines
185 struct drm_i915_private *i915 = dp_to_i915(intel_dp);185 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
186 int err;186 int err;
187 enum drm_lspcon_mode current_mode;187 enum drm_lspcon_mode current_mode;
188 struct i2c_adapter *adapter = &intel_dp->aux.ddc;188 struct i2c_adapter *ddc = &intel_dp->aux.ddc;
189 189
190 err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, adapter, &current_mode);190 err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, &current_mode);
191 if (err) {191 if (err) {
192 drm_err(&i915->drm, "Error reading LSPCON mode\n");192 drm_err(&i915->drm, "Error reading LSPCON mode\n");
193 return err;193 return err;
@@ -198,7 +198,7 @@ static int lspcon_change_mode(struct intel_lspcon *lspcon, · 4 unmodified lines
198 return 0;198 return 0;
199 }199 }
200 200
201 err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, adapter, mode);201 err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, ddc, mode);
202 if (err < 0) {202 if (err < 0) {
203 drm_err(&i915->drm, "LSPCON mode change failed\n");203 drm_err(&i915->drm, "LSPCON mode change failed\n");
204 return err;204 return err;
@@ -233,7 +233,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) · 28 unmodified lines
233 enum drm_dp_dual_mode_type adaptor_type;233 enum drm_dp_dual_mode_type adaptor_type;
234 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);234 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon);
235 struct drm_i915_private *i915 = dp_to_i915(intel_dp);235 struct drm_i915_private *i915 = dp_to_i915(intel_dp);
236 struct i2c_adapter *adapter = &intel_dp->aux.ddc;236 struct i2c_adapter *ddc = &intel_dp->aux.ddc;
237 enum drm_lspcon_mode expected_mode;237 enum drm_lspcon_mode expected_mode;
238 238
239 expected_mode = lspcon_wake_native_aux_ch(lspcon) ?239 expected_mode = lspcon_wake_native_aux_ch(lspcon) ?
@@ -244,7 +244,7 @@ static bool lspcon_probe(struct intel_lspcon *lspcon) · 4 unmodified lines
244 if (retry)244 if (retry)
245 usleep_range(500, 1000);245 usleep_range(500, 1000);
246 246
247 adaptor_type = drm_dp_dual_mode_detect(intel_dp->aux.drm_dev, adapter);247 adaptor_type = drm_dp_dual_mode_detect(intel_dp->aux.drm_dev, ddc);
248 if (adaptor_type == DRM_DP_DUAL_MODE_LSPCON)248 if (adaptor_type == DRM_DP_DUAL_MODE_LSPCON)
249 break;249 break;
250 }250 }
drivers/gpu/drm/i915/display/intel_lvds.c+18−15
@@ -425,11 +425,18 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder, · 424 unmodified lines
425 return -EINVAL;425 return -EINVAL;
426 }426 }
427 427
428 if (HAS_PCH_SPLIT(i915)) {
429 crtc_state->has_pch_encoder = true;
430 if (!intel_fdi_compute_pipe_bpp(crtc_state))
431 return -EINVAL;
432 }
433
428 if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)434 if (lvds_encoder->a3_power == LVDS_A3_POWER_UP)
429 lvds_bpp = 8*3;435 lvds_bpp = 8*3;
430 else436 else
431 lvds_bpp = 6*3;437 lvds_bpp = 6*3;
432 438
439 /* TODO: Check crtc_state->max_link_bpp_x16 instead of bw_constrained */
433 if (lvds_bpp != crtc_state->pipe_bpp && !crtc_state->bw_constrained) {440 if (lvds_bpp != crtc_state->pipe_bpp && !crtc_state->bw_constrained) {
434 drm_dbg_kms(&i915->drm,441 drm_dbg_kms(&i915->drm,
435 "forcing display bpp (was %d) to LVDS (%d)\n",442 "forcing display bpp (was %d) to LVDS (%d)\n",
@@ -453,9 +460,6 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder, · 17 unmodified lines
453 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)460 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
454 return -EINVAL;461 return -EINVAL;
455 462
456 if (HAS_PCH_SPLIT(i915))
457 crtc_state->has_pch_encoder = true;
458
459 ret = intel_panel_fitting(crtc_state, conn_state);463 ret = intel_panel_fitting(crtc_state, conn_state);
460 if (ret)464 if (ret)
461 return ret;465 return ret;
@@ -837,7 +841,7 @@ void intel_lvds_init(struct drm_i915_private *i915) · 375 unmodified lines
837 struct intel_encoder *encoder;841 struct intel_encoder *encoder;
838 i915_reg_t lvds_reg;842 i915_reg_t lvds_reg;
839 u32 lvds;843 u32 lvds;
840 u8 pin;844 u8 ddc_pin;
841 845
842 /* Skip init on machines we know falsely report LVDS */846 /* Skip init on machines we know falsely report LVDS */
843 if (dmi_check_system(intel_no_lvds)) {847 if (dmi_check_system(intel_no_lvds)) {
@@ -864,8 +868,8 @@ void intel_lvds_init(struct drm_i915_private *i915) · 20 unmodified lines
864 return;868 return;
865 }869 }
866 870
867 pin = GMBUS_PIN_PANEL;871 ddc_pin = GMBUS_PIN_PANEL;
868 if (!intel_bios_is_lvds_present(i915, &pin)) {872 if (!intel_bios_is_lvds_present(i915, &ddc_pin)) {
869 if ((lvds & LVDS_PORT_EN) == 0) {873 if ((lvds & LVDS_PORT_EN) == 0) {
870 drm_dbg_kms(&i915->drm,874 drm_dbg_kms(&i915->drm,
871 "LVDS is not present in VBT\n");875 "LVDS is not present in VBT\n");
@@ -888,8 +892,10 @@ void intel_lvds_init(struct drm_i915_private *i915) · 16 unmodified lines
888 lvds_encoder->attached_connector = connector;892 lvds_encoder->attached_connector = connector;
889 encoder = &lvds_encoder->base;893 encoder = &lvds_encoder->base;
890 894
891 drm_connector_init(&i915->drm, &connector->base, &intel_lvds_connector_funcs,895 drm_connector_init_with_ddc(&i915->drm, &connector->base,
892 DRM_MODE_CONNECTOR_LVDS);896 &intel_lvds_connector_funcs,
897 DRM_MODE_CONNECTOR_LVDS,
898 intel_gmbus_get_adapter(i915, ddc_pin));
893 899
894 drm_encoder_init(&i915->drm, &encoder->base, &intel_lvds_enc_funcs,900 drm_encoder_init(&i915->drm, &encoder->base, &intel_lvds_enc_funcs,
895 DRM_MODE_ENCODER_LVDS, "LVDS");901 DRM_MODE_ENCODER_LVDS, "LVDS");
@@ -943,13 +949,10 @@ void intel_lvds_init(struct drm_i915_private *i915) · 47 unmodified lines
943 * preferred mode is the right one.949 * preferred mode is the right one.
944 */950 */
945 mutex_lock(&i915->drm.mode_config.mutex);951 mutex_lock(&i915->drm.mode_config.mutex);
946 if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) {952 if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
947 drm_edid = drm_edid_read_switcheroo(&connector->base,953 drm_edid = drm_edid_read_switcheroo(&connector->base, connector->base.ddc);
948 intel_gmbus_get_adapter(i915, pin));954 else
949 } else {955 drm_edid = drm_edid_read_ddc(&connector->base, connector->base.ddc);
950 drm_edid = drm_edid_read_ddc(&connector->base,
951 intel_gmbus_get_adapter(i915, pin));
952 }
953 if (drm_edid) {956 if (drm_edid) {
954 if (drm_edid_connector_update(&connector->base, drm_edid) ||957 if (drm_edid_connector_update(&connector->base, drm_edid) ||
955 !drm_edid_connector_add_modes(&connector->base)) {958 !drm_edid_connector_add_modes(&connector->base)) {
drivers/gpu/drm/i915/display/intel_overlay.c+2−0
@@ -29,12 +29,14 @@ · 28 unmodified lines
29#include <drm/drm_fourcc.h>29#include <drm/drm_fourcc.h>
30 30
31#include "gem/i915_gem_internal.h"31#include "gem/i915_gem_internal.h"
32#include "gem/i915_gem_object_frontbuffer.h"
32#include "gem/i915_gem_pm.h"33#include "gem/i915_gem_pm.h"
33#include "gt/intel_gpu_commands.h"34#include "gt/intel_gpu_commands.h"
34#include "gt/intel_ring.h"35#include "gt/intel_ring.h"
35 36
36#include "i915_drv.h"37#include "i915_drv.h"
37#include "i915_reg.h"38#include "i915_reg.h"
39#include "intel_color_regs.h"
38#include "intel_de.h"40#include "intel_de.h"
39#include "intel_display_types.h"41#include "intel_display_types.h"
40#include "intel_frontbuffer.h"42#include "intel_frontbuffer.h"
drivers/gpu/drm/i915/display/intel_panel.c+4−13
@@ -59,15 +59,6 @@ intel_panel_preferred_fixed_mode(struct intel_connector *connector) · 58 unmodified lines
59 struct drm_display_mode, head);59 struct drm_display_mode, head);
60}60}
61 61
62static bool is_in_vrr_range(struct intel_connector *connector, int vrefresh)
63{
64 const struct drm_display_info *info = &connector->base.display_info;
65
66 return intel_vrr_is_capable(connector) &&
67 vrefresh >= info->monitor_range.min_vfreq &&
68 vrefresh <= info->monitor_range.max_vfreq;
69}
70
71static bool is_best_fixed_mode(struct intel_connector *connector,62static bool is_best_fixed_mode(struct intel_connector *connector,
72 int vrefresh, int fixed_mode_vrefresh,63 int vrefresh, int fixed_mode_vrefresh,
73 const struct drm_display_mode *best_mode)64 const struct drm_display_mode *best_mode)
@@ -81,8 +72,8 @@ static bool is_best_fixed_mode(struct intel_connector *connector, · 7 unmodified lines
81 * vrefresh, which we can then reduce to match the requested72 * vrefresh, which we can then reduce to match the requested
82 * vrefresh by extending the vblank length.73 * vrefresh by extending the vblank length.
83 */74 */
84 if (is_in_vrr_range(connector, vrefresh) &&75 if (intel_vrr_is_in_range(connector, vrefresh) &&
85 is_in_vrr_range(connector, fixed_mode_vrefresh) &&76 intel_vrr_is_in_range(connector, fixed_mode_vrefresh) &&
86 fixed_mode_vrefresh < vrefresh)77 fixed_mode_vrefresh < vrefresh)
87 return false;78 return false;
88 79
@@ -224,8 +215,8 @@ int intel_panel_compute_config(struct intel_connector *connector, · 135 unmodified lines
224 * Assume that we shouldn't muck about with the215 * Assume that we shouldn't muck about with the
225 * timings if they don't land in the VRR range.216 * timings if they don't land in the VRR range.
226 */217 */
227 is_vrr = is_in_vrr_range(connector, vrefresh) &&218 is_vrr = intel_vrr_is_in_range(connector, vrefresh) &&
228 is_in_vrr_range(connector, fixed_mode_vrefresh);219 intel_vrr_is_in_range(connector, fixed_mode_vrefresh);
229 220
230 if (!is_vrr) {221 if (!is_vrr) {
231 /*222 /*
drivers/gpu/drm/i915/display/intel_plane_initial.c+1−0
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include "intel_display.h"9#include "intel_display.h"
10#include "intel_display_types.h"10#include "intel_display_types.h"
11#include "intel_fb.h"11#include "intel_fb.h"
12#include "intel_frontbuffer.h"
12#include "intel_plane_initial.h"13#include "intel_plane_initial.h"
13 14
14static bool15static bool
drivers/gpu/drm/i915/display/intel_pmdemand.c+1−1
@@ -92,7 +92,7 @@ int intel_pmdemand_init(struct drm_i915_private *i915) · 91 unmodified lines
92 &pmdemand_state->base,92 &pmdemand_state->base,
93 &intel_pmdemand_funcs);93 &intel_pmdemand_funcs);
94 94
95 if (IS_MTL_DISPLAY_STEP(i915, STEP_A0, STEP_C0))95 if (IS_DISPLAY_IP_STEP(i915, IP_VER(14, 0), STEP_A0, STEP_C0))
96 /* Wa_14016740474 */96 /* Wa_14016740474 */
97 intel_de_rmw(i915, XELPD_CHICKEN_DCPR_3, 0, DMD_RSP_TIMEOUT_DISABLE);97 intel_de_rmw(i915, XELPD_CHICKEN_DCPR_3, 0, DMD_RSP_TIMEOUT_DISABLE);
98 98
drivers/gpu/drm/i915/display/intel_psr.c+37−15
@@ -23,6 +23,7 @@ · 22 unmodified lines
23 23
24#include <drm/drm_atomic_helper.h>24#include <drm/drm_atomic_helper.h>
25#include <drm/drm_damage_helper.h>25#include <drm/drm_damage_helper.h>
26#include <drm/drm_debugfs.h>
26 27
27#include "i915_drv.h"28#include "i915_drv.h"
28#include "i915_reg.h"29#include "i915_reg.h"
@@ -32,6 +33,7 @@ · 3 unmodified lines
32#include "intel_display_types.h"33#include "intel_display_types.h"
33#include "intel_dp.h"34#include "intel_dp.h"
34#include "intel_dp_aux.h"35#include "intel_dp_aux.h"
36#include "intel_frontbuffer.h"
35#include "intel_hdmi.h"37#include "intel_hdmi.h"
36#include "intel_psr.h"38#include "intel_psr.h"
37#include "intel_psr_regs.h"39#include "intel_psr_regs.h"
@@ -1360,8 +1362,7 @@ static void wm_optimization_wa(struct intel_dp *intel_dp, · 1322 unmodified lines
1360 bool set_wa_bit = false;1362 bool set_wa_bit = false;
1361 1363
1362 /* Wa_14015648006 */1364 /* Wa_14015648006 */
1363 if (IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) ||1365 if (IS_DISPLAY_VER(dev_priv, 11, 14))
1364 IS_DISPLAY_VER(dev_priv, 11, 13))
1365 set_wa_bit |= crtc_state->wm_level_disabled;1366 set_wa_bit |= crtc_state->wm_level_disabled;
1366 1367
1367 /* Wa_16013835468 */1368 /* Wa_16013835468 */
@@ -1447,7 +1448,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, · 79 unmodified lines
1447 * All supported adlp panels have 1-based X granularity, this may1448 * All supported adlp panels have 1-based X granularity, this may
1448 * cause issues if non-supported panels are used.1449 * cause issues if non-supported panels are used.
1449 */1450 */
1450 if (IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))1451 if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
1451 intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(cpu_transcoder), 0,1452 intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(cpu_transcoder), 0,
1452 ADLP_1_BASED_X_GRANULARITY);1453 ADLP_1_BASED_X_GRANULARITY);
1453 else if (IS_ALDERLAKE_P(dev_priv))1454 else if (IS_ALDERLAKE_P(dev_priv))
@@ -1455,7 +1456,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, · 1 unmodified line
1455 ADLP_1_BASED_X_GRANULARITY);1456 ADLP_1_BASED_X_GRANULARITY);
1456 1457
1457 /* Wa_16012604467:adlp,mtl[a0,b0] */1458 /* Wa_16012604467:adlp,mtl[a0,b0] */
1458 if (IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))1459 if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
1459 intel_de_rmw(dev_priv,1460 intel_de_rmw(dev_priv,
1460 MTL_CLKGATE_DIS_TRANS(cpu_transcoder), 0,1461 MTL_CLKGATE_DIS_TRANS(cpu_transcoder), 0,
1461 MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS);1462 MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS);
@@ -1613,7 +1614,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) · 151 unmodified lines
1613 1614
1614 if (intel_dp->psr.psr2_enabled) {1615 if (intel_dp->psr.psr2_enabled) {
1615 /* Wa_16012604467:adlp,mtl[a0,b0] */1616 /* Wa_16012604467:adlp,mtl[a0,b0] */
1616 if (IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))1617 if (IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0))
1617 intel_de_rmw(dev_priv,1618 intel_de_rmw(dev_priv,
1618 MTL_CLKGATE_DIS_TRANS(cpu_transcoder),1619 MTL_CLKGATE_DIS_TRANS(cpu_transcoder),
1619 MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS, 0);1620 MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS, 0);
@@ -2087,7 +2088,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, · 467 unmodified lines
2087 goto skip_sel_fetch_set_loop;2088 goto skip_sel_fetch_set_loop;
2088 2089
2089 /* Wa_14014971492 */2090 /* Wa_14014971492 */
2090 if ((IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) ||2091 if ((IS_DISPLAY_IP_STEP(dev_priv, IP_VER(14, 0), STEP_A0, STEP_B0) ||
2091 IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv)) &&2092 IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv)) &&
2092 crtc_state->splitter.enable)2093 crtc_state->splitter.enable)
2093 pipe_clip.y1 = 0;2094 pipe_clip.y1 = 0;
@@ -2230,6 +2231,12 @@ static void _intel_psr_post_plane_update(const struct intel_atomic_state *state, · 136 unmodified lines
2230 if (crtc_state->crc_enabled && psr->enabled)2231 if (crtc_state->crc_enabled && psr->enabled)
2231 psr_force_hw_tracking_exit(intel_dp);2232 psr_force_hw_tracking_exit(intel_dp);
2232 2233
2234 /*
2235 * Clear possible busy bits in case we have
2236 * invalidate -> flip -> flush sequence.
2237 */
2238 intel_dp->psr.busy_frontbuffer_bits = 0;
2239
2233 mutex_unlock(&psr->lock);2240 mutex_unlock(&psr->lock);
2234 }2241 }
2235}2242}
@@ -3153,7 +3160,7 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data) · 917 unmodified lines
3153 };3160 };
3154 const char *str;3161 const char *str;
3155 int ret;3162 int ret;
3156 u8 val;3163 u8 status, error_status;
3157 3164
3158 if (!CAN_PSR(intel_dp)) {3165 if (!CAN_PSR(intel_dp)) {
3159 seq_puts(m, "PSR Unsupported\n");3166 seq_puts(m, "PSR Unsupported\n");
@@ -3163,19 +3170,34 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data) · 3 unmodified lines
3163 if (connector->base.status != connector_status_connected)3170 if (connector->base.status != connector_status_connected)
3164 return -ENODEV;3171 return -ENODEV;
3165 3172
3166 ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val);3173 ret = psr_get_status_and_error_status(intel_dp, &status, &error_status);
3167 if (ret != 1)3174 if (ret)
3168 return ret < 0 ? ret : -EIO;3175 return ret;
3169 3176
3170 val &= DP_PSR_SINK_STATE_MASK;3177 status &= DP_PSR_SINK_STATE_MASK;
3171 if (val < ARRAY_SIZE(sink_status))3178 if (status < ARRAY_SIZE(sink_status))
3172 str = sink_status[val];3179 str = sink_status[status];
3173 else3180 else
3174 str = "unknown";3181 str = "unknown";
3175 3182
3176 seq_printf(m, "Sink PSR status: 0x%x [%s]\n", val, str);3183 seq_printf(m, "Sink PSR status: 0x%x [%s]\n", status, str);
3177 3184
3178 return 0;3185 seq_printf(m, "Sink PSR error status: 0x%x", error_status);
3186
3187 if (error_status & (DP_PSR_RFB_STORAGE_ERROR |
3188 DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR |
3189 DP_PSR_LINK_CRC_ERROR))
3190 seq_puts(m, ":\n");
3191 else
3192 seq_puts(m, "\n");
3193 if (error_status & DP_PSR_RFB_STORAGE_ERROR)
3194 seq_puts(m, "\tPSR RFB storage error\n");
3195 if (error_status & DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR)
3196 seq_puts(m, "\tPSR VSC SDP uncorrectable error\n");
3197 if (error_status & DP_PSR_LINK_CRC_ERROR)
3198 seq_puts(m, "\tPSR Link CRC error\n");
3199
3200 return ret;
3179}3201}
3180DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);3202DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
3181 3203
drivers/gpu/drm/i915/display/intel_sdvo.c+196−185
@@ -44,6 +44,7 @@ · 43 unmodified lines
44#include "intel_crtc.h"44#include "intel_crtc.h"
45#include "intel_de.h"45#include "intel_de.h"
46#include "intel_display_types.h"46#include "intel_display_types.h"
47#include "intel_fdi.h"
47#include "intel_fifo_underrun.h"48#include "intel_fifo_underrun.h"
48#include "intel_gmbus.h"49#include "intel_gmbus.h"
49#include "intel_hdmi.h"50#include "intel_hdmi.h"
@@ -57,15 +58,16 @@ · 7 unmodified lines
57#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)58#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)
58#define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_YPRPB0)59#define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_YPRPB0)
59 60
60#define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\61#define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK | SDVO_TV_MASK)
61 SDVO_TV_MASK)
62 62
63#define IS_TV(c) (c->output_flag & SDVO_TV_MASK)63#define IS_TV(c) ((c)->output_flag & SDVO_TV_MASK)
64#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK)64#define IS_TMDS(c) ((c)->output_flag & SDVO_TMDS_MASK)
65#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK)65#define IS_LVDS(c) ((c)->output_flag & SDVO_LVDS_MASK)
66#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))66#define IS_TV_OR_LVDS(c) ((c)->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
67#define IS_DIGITAL(c) (c->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK))67#define IS_DIGITAL(c) ((c)->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK))
68 68
69#define HAS_DDC(c) ((c)->output_flag & (SDVO_RGB_MASK | SDVO_TMDS_MASK | \
70 SDVO_LVDS_MASK))
69 71
70static const char * const tv_format_names[] = {72static const char * const tv_format_names[] = {
71 "NTSC_M" , "NTSC_J" , "NTSC_443",73 "NTSC_M" , "NTSC_J" , "NTSC_443",
@@ -79,20 +81,25 @@ static const char * const tv_format_names[] = { · 7 unmodified lines
79 81
80#define TV_FORMAT_NUM ARRAY_SIZE(tv_format_names)82#define TV_FORMAT_NUM ARRAY_SIZE(tv_format_names)
81 83
84struct intel_sdvo;
85
86struct intel_sdvo_ddc {
87 struct i2c_adapter ddc;
88 struct intel_sdvo *sdvo;
89 u8 ddc_bus;
90};
91
82struct intel_sdvo {92struct intel_sdvo {
83 struct intel_encoder base;93 struct intel_encoder base;
84 94
85 struct i2c_adapter *i2c;95 struct i2c_adapter *i2c;
86 u8 slave_addr;96 u8 slave_addr;
87 97
88 struct i2c_adapter ddc;98 struct intel_sdvo_ddc ddc[3];
89 99
90 /* Register for the SDVO device: SDVOB or SDVOC */100 /* Register for the SDVO device: SDVOB or SDVOC */
91 i915_reg_t sdvo_reg;101 i915_reg_t sdvo_reg;
92 102
93 /* Active outputs controlled by this SDVO output */
94 u16 controlled_output;
95
96 /*103 /*
97 * Capabilities of the SDVO device returned by104 * Capabilities of the SDVO device returned by
98 * intel_sdvo_get_capabilities()105 * intel_sdvo_get_capabilities()
@@ -104,22 +111,11 @@ struct intel_sdvo { · 5 unmodified lines
104 /* Pixel clock limitations reported by the SDVO device, in kHz */111 /* Pixel clock limitations reported by the SDVO device, in kHz */
105 int pixel_clock_min, pixel_clock_max;112 int pixel_clock_min, pixel_clock_max;
106 113
107 /*
108 * For multiple function SDVO device,
109 * this is for current attached outputs.
110 */
111 u16 attached_output;
112
113 /*114 /*
114 * Hotplug activation bits for this device115 * Hotplug activation bits for this device
115 */116 */
116 u16 hotplug_active;117 u16 hotplug_active;
117 118
118 enum port port;
119
120 /* DDC bus used by this SDVO encoder */
121 u8 ddc_bus;
122
123 /*119 /*
124 * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd120 * the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd
125 */121 */
@@ -233,7 +229,7 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) · 107 unmodified lines
233 return;229 return;
234 }230 }
235 231
236 if (intel_sdvo->port == PORT_B)232 if (intel_sdvo->base.port == PORT_B)
237 cval = intel_de_read(dev_priv, GEN3_SDVOC);233 cval = intel_de_read(dev_priv, GEN3_SDVOC);
238 else234 else
239 bval = intel_de_read(dev_priv, GEN3_SDVOB);235 bval = intel_de_read(dev_priv, GEN3_SDVOB);
@@ -410,7 +406,7 @@ static const char *sdvo_cmd_name(u8 cmd) · 170 unmodified lines
410 return NULL;406 return NULL;
411}407}
412 408
413#define SDVO_NAME(svdo) ((svdo)->port == PORT_B ? "SDVOB" : "SDVOC")409#define SDVO_NAME(svdo) ((svdo)->base.port == PORT_B ? "SDVOB" : "SDVOC")
414 410
415static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,411static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd,
416 const void *args, int args_len)412 const void *args, int args_len)
@@ -1224,12 +1220,13 @@ static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo, · 807 unmodified lines
1224 1220
1225static bool1221static bool
1226intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,1222intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
1223 struct intel_sdvo_connector *intel_sdvo_connector,
1227 const struct drm_display_mode *mode)1224 const struct drm_display_mode *mode)
1228{1225{
1229 struct intel_sdvo_dtd output_dtd;1226 struct intel_sdvo_dtd output_dtd;
1230 1227
1231 if (!intel_sdvo_set_target_output(intel_sdvo,1228 if (!intel_sdvo_set_target_output(intel_sdvo,
1232 intel_sdvo->attached_output))1229 intel_sdvo_connector->output_flag))
1233 return false;1230 return false;
1234 1231
1235 intel_sdvo_get_dtd_from_mode(&output_dtd, mode);1232 intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
@@ -1270,10 +1267,10 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, · 34 unmodified lines
1270 return true;1267 return true;
1271}1268}
1272 1269
1273static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)1270static int i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config)
1274{1271{
1275 struct drm_i915_private *dev_priv = to_i915(pipe_config->uapi.crtc->dev);1272 struct drm_i915_private *dev_priv = to_i915(pipe_config->uapi.crtc->dev);
1276 unsigned dotclock = pipe_config->port_clock;1273 unsigned int dotclock = pipe_config->hw.adjusted_mode.crtc_clock;
1277 struct dpll *clock = &pipe_config->dpll;1274 struct dpll *clock = &pipe_config->dpll;
1278 1275
1279 /*1276 /*
@@ -1293,11 +1290,14 @@ static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config) · 13 unmodified lines
1293 clock->m1 = 12;1290 clock->m1 = 12;
1294 clock->m2 = 8;1291 clock->m2 = 8;
1295 } else {1292 } else {
1296 drm_WARN(&dev_priv->drm, 1,1293 drm_dbg_kms(&dev_priv->drm,
1297 "SDVO TV clock out of range: %i\n", dotclock);1294 "SDVO TV clock out of range: %i\n", dotclock);
1295 return -EINVAL;
1298 }1296 }
1299 1297
1300 pipe_config->clock_set = true;1298 pipe_config->clock_set = true;
1299
1300 return 0;
1301}1301}
1302 1302
1303static bool intel_has_hdmi_sink(struct intel_sdvo_connector *intel_sdvo_connector,1303static bool intel_has_hdmi_sink(struct intel_sdvo_connector *intel_sdvo_connector,
@@ -1352,14 +1352,18 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, · 48 unmodified lines
1352 struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;1352 struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
1353 struct drm_display_mode *mode = &pipe_config->hw.mode;1353 struct drm_display_mode *mode = &pipe_config->hw.mode;
1354 1354
1355 if (HAS_PCH_SPLIT(to_i915(encoder->base.dev))) {
1356 pipe_config->has_pch_encoder = true;
1357 if (!intel_fdi_compute_pipe_bpp(pipe_config))
1358 return -EINVAL;
1359 }
1360
1355 DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");1361 DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
1362 /* FIXME: Don't increase pipe_bpp */
1356 pipe_config->pipe_bpp = 8*3;1363 pipe_config->pipe_bpp = 8*3;
1357 pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;1364 pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
1358 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;1365 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
1359 1366
1360 if (HAS_PCH_SPLIT(to_i915(encoder->base.dev)))
1361 pipe_config->has_pch_encoder = true;
1362
1363 /*1367 /*
1364 * We need to construct preferred input timings based on our1368 * We need to construct preferred input timings based on our
1365 * output timings. To do that, we have to set the output1369 * output timings. To do that, we have to set the output
@@ -1367,7 +1371,9 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, · 1 unmodified line
1367 * the sequence to do it. Oh well.1371 * the sequence to do it. Oh well.
1368 */1372 */
1369 if (IS_TV(intel_sdvo_connector)) {1373 if (IS_TV(intel_sdvo_connector)) {
1370 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))1374 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
1375 intel_sdvo_connector,
1376 mode))
1371 return -EINVAL;1377 return -EINVAL;
1372 1378
1373 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,1379 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
@@ -1385,7 +1391,9 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, · 11 unmodified lines
1385 if (ret)1391 if (ret)
1386 return ret;1392 return ret;
1387 1393
1388 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, fixed_mode))1394 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
1395 intel_sdvo_connector,
1396 fixed_mode))
1389 return -EINVAL;1397 return -EINVAL;
1390 1398
1391 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,1399 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
@@ -1415,8 +1423,13 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, · 23 unmodified lines
1415 conn_state);1423 conn_state);
1416 1424
1417 /* Clock computation needs to happen after pixel multiplier. */1425 /* Clock computation needs to happen after pixel multiplier. */
1418 if (IS_TV(intel_sdvo_connector))1426 if (IS_TV(intel_sdvo_connector)) {
1419 i9xx_adjust_sdvo_tv_clock(pipe_config);1427 int ret;
1428
1429 ret = i9xx_adjust_sdvo_tv_clock(pipe_config);
1430 if (ret)
1431 return ret;
1432 }
1420 1433
1421 if (conn_state->picture_aspect_ratio)1434 if (conn_state->picture_aspect_ratio)
1422 adjusted_mode->picture_aspect_ratio =1435 adjusted_mode->picture_aspect_ratio =
@@ -1521,7 +1534,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, · 98 unmodified lines
1521 * channel on the motherboard. In a two-input device, the first input1534 * channel on the motherboard. In a two-input device, the first input
1522 * will be SDVOB and the second SDVOC.1535 * will be SDVOB and the second SDVOC.
1523 */1536 */
1524 in_out.in0 = intel_sdvo->attached_output;1537 in_out.in0 = intel_sdvo_connector->output_flag;
1525 in_out.in1 = 0;1538 in_out.in1 = 0;
1526 1539
1527 intel_sdvo_set_value(intel_sdvo,1540 intel_sdvo_set_value(intel_sdvo,
@@ -1530,7 +1543,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, · 2 unmodified lines
1530 1543
1531 /* Set the output timings to the screen */1544 /* Set the output timings to the screen */
1532 if (!intel_sdvo_set_target_output(intel_sdvo,1545 if (!intel_sdvo_set_target_output(intel_sdvo,
1533 intel_sdvo->attached_output))1546 intel_sdvo_connector->output_flag))
1534 return;1547 return;
1535 1548
1536 /* lvds has a special fixed output timing. */1549 /* lvds has a special fixed output timing. */
@@ -1598,7 +1611,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, · 61 unmodified lines
1598 sdvox |= SDVO_BORDER_ENABLE;1611 sdvox |= SDVO_BORDER_ENABLE;
1599 } else {1612 } else {
1600 sdvox = intel_de_read(dev_priv, intel_sdvo->sdvo_reg);1613 sdvox = intel_de_read(dev_priv, intel_sdvo->sdvo_reg);
1601 if (intel_sdvo->port == PORT_B)1614 if (intel_sdvo->base.port == PORT_B)
1602 sdvox &= SDVOB_PRESERVE_MASK;1615 sdvox &= SDVOB_PRESERVE_MASK;
1603 else1616 else
1604 sdvox &= SDVOC_PRESERVE_MASK;1617 sdvox &= SDVOC_PRESERVE_MASK;
@@ -1867,6 +1880,8 @@ static void intel_enable_sdvo(struct intel_atomic_state *state, · 262 unmodified lines
1867 struct drm_device *dev = encoder->base.dev;1880 struct drm_device *dev = encoder->base.dev;
1868 struct drm_i915_private *dev_priv = to_i915(dev);1881 struct drm_i915_private *dev_priv = to_i915(dev);
1869 struct intel_sdvo *intel_sdvo = to_sdvo(encoder);1882 struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
1883 struct intel_sdvo_connector *intel_sdvo_connector =
1884 to_intel_sdvo_connector(conn_state->connector);
1870 struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);1885 struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
1871 u32 temp;1886 u32 temp;
1872 bool input1, input2;1887 bool input1, input2;
@@ -1896,7 +1911,7 @@ static void intel_enable_sdvo(struct intel_atomic_state *state, · 23 unmodified lines
1896 if (0)1911 if (0)
1897 intel_sdvo_set_encoder_power_state(intel_sdvo,1912 intel_sdvo_set_encoder_power_state(intel_sdvo,
1898 DRM_MODE_DPMS_ON);1913 DRM_MODE_DPMS_ON);
1899 intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);1914 intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo_connector->output_flag);
1900 1915
1901 if (pipe_config->has_audio)1916 if (pipe_config->has_audio)
1902 intel_sdvo_enable_audio(intel_sdvo, pipe_config, conn_state);1917 intel_sdvo_enable_audio(intel_sdvo, pipe_config, conn_state);
@@ -1956,7 +1971,7 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in · 53 unmodified lines
1956 " device_rev_id: %d\n"1971 " device_rev_id: %d\n"
1957 " sdvo_version_major: %d\n"1972 " sdvo_version_major: %d\n"
1958 " sdvo_version_minor: %d\n"1973 " sdvo_version_minor: %d\n"
1959 " sdvo_inputs_mask: %d\n"1974 " sdvo_num_inputs: %d\n"
1960 " smooth_scaling: %d\n"1975 " smooth_scaling: %d\n"
1961 " sharp_scaling: %d\n"1976 " sharp_scaling: %d\n"
1962 " up_scaling: %d\n"1977 " up_scaling: %d\n"
@@ -1968,7 +1983,7 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in · 5 unmodified lines
1968 caps->device_rev_id,1983 caps->device_rev_id,
1969 caps->sdvo_version_major,1984 caps->sdvo_version_major,
1970 caps->sdvo_version_minor,1985 caps->sdvo_version_minor,
1971 caps->sdvo_inputs_mask,1986 caps->sdvo_num_inputs,
1972 caps->smooth_scaling,1987 caps->smooth_scaling,
1973 caps->sharp_scaling,1988 caps->sharp_scaling,
1974 caps->up_scaling,1989 caps->up_scaling,
@@ -2029,18 +2044,15 @@ intel_sdvo_hotplug(struct intel_encoder *encoder, · 54 unmodified lines
2029 return intel_encoder_hotplug(encoder, connector);2044 return intel_encoder_hotplug(encoder, connector);
2030}2045}
2031 2046
2032static bool
2033intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
2034{
2035 /* Is there more than one type of output? */
2036 return hweight16(intel_sdvo->caps.output_flags) > 1;
2037}
2038
2039static const struct drm_edid *2047static const struct drm_edid *
2040intel_sdvo_get_edid(struct drm_connector *connector)2048intel_sdvo_get_edid(struct drm_connector *connector)
2041{2049{
2042 struct intel_sdvo *sdvo = intel_attached_sdvo(to_intel_connector(connector));2050 struct i2c_adapter *ddc = connector->ddc;
2043 return drm_edid_read_ddc(connector, &sdvo->ddc);2051
2052 if (!ddc)
2053 return NULL;
2054
2055 return drm_edid_read_ddc(connector, ddc);
2044}2056}
2045 2057
2046/* Mac mini hack -- use the same DDC as the analog connector */2058/* Mac mini hack -- use the same DDC as the analog connector */
@@ -2048,43 +2060,23 @@ static const struct drm_edid * · 1 unmodified line
2048intel_sdvo_get_analog_edid(struct drm_connector *connector)2060intel_sdvo_get_analog_edid(struct drm_connector *connector)
2049{2061{
2050 struct drm_i915_private *i915 = to_i915(connector->dev);2062 struct drm_i915_private *i915 = to_i915(connector->dev);
2051 struct i2c_adapter *i2c;2063 struct i2c_adapter *ddc;
2052 2064
2053 i2c = intel_gmbus_get_adapter(i915, i915->display.vbt.crt_ddc_pin);2065 ddc = intel_gmbus_get_adapter(i915, i915->display.vbt.crt_ddc_pin);
2066 if (!ddc)
2067 return NULL;
2054 2068
2055 return drm_edid_read_ddc(connector, i2c);2069 return drm_edid_read_ddc(connector, ddc);
2056}2070}
2057 2071
2058static enum drm_connector_status2072static enum drm_connector_status
2059intel_sdvo_tmds_sink_detect(struct drm_connector *connector)2073intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
2060{2074{
2061 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector));
2062 enum drm_connector_status status;2075 enum drm_connector_status status;
2063 const struct drm_edid *drm_edid;2076 const struct drm_edid *drm_edid;
2064 2077
2065 drm_edid = intel_sdvo_get_edid(connector);2078 drm_edid = intel_sdvo_get_edid(connector);
2066 2079
2067 if (!drm_edid && intel_sdvo_multifunc_encoder(intel_sdvo)) {
2068 u8 ddc, saved_ddc = intel_sdvo->ddc_bus;
2069
2070 /*
2071 * Don't use the 1 as the argument of DDC bus switch to get
2072 * the EDID. It is used for SDVO SPD ROM.
2073 */
2074 for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) {
2075 intel_sdvo->ddc_bus = ddc;
2076 drm_edid = intel_sdvo_get_edid(connector);
2077 if (drm_edid)
2078 break;
2079 }
2080 /*
2081 * If we found the EDID on the other bus,
2082 * assume that is the correct DDC bus.
2083 */
2084 if (!drm_edid)
2085 intel_sdvo->ddc_bus = saved_ddc;
2086 }
2087
2088 /*2080 /*
2089 * When there is no edid and no monitor is connected with VGA2081 * When there is no edid and no monitor is connected with VGA
2090 * port, try to use the CRT ddc to read the EDID for DVI-connector.2082 * port, try to use the CRT ddc to read the EDID for DVI-connector.
@@ -2094,10 +2086,8 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector) · 3 unmodified lines
2094 2086
2095 status = connector_status_unknown;2087 status = connector_status_unknown;
2096 if (drm_edid) {2088 if (drm_edid) {
2097 const struct edid *edid = drm_edid_raw(drm_edid);
2098
2099 /* DDC bus is shared, match EDID to connector type */2089 /* DDC bus is shared, match EDID to connector type */
2100 if (edid && edid->input & DRM_EDID_INPUT_DIGITAL)2090 if (drm_edid_is_digital(drm_edid))
2101 status = connector_status_connected;2091 status = connector_status_connected;
2102 else2092 else
2103 status = connector_status_disconnected;2093 status = connector_status_disconnected;
@@ -2111,8 +2101,7 @@ static bool · 7 unmodified lines
2111intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo,2101intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo,
2112 const struct drm_edid *drm_edid)2102 const struct drm_edid *drm_edid)
2113{2103{
2114 const struct edid *edid = drm_edid_raw(drm_edid);2104 bool monitor_is_digital = drm_edid_is_digital(drm_edid);
2115 bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
2116 bool connector_is_digital = !!IS_DIGITAL(sdvo);2105 bool connector_is_digital = !!IS_DIGITAL(sdvo);
2117 2106
2118 DRM_DEBUG_KMS("connector_is_digital? %d, monitor_is_digital? %d\n",2107 DRM_DEBUG_KMS("connector_is_digital? %d, monitor_is_digital? %d\n",
@@ -2135,6 +2124,10 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) · 16 unmodified lines
2135 if (!INTEL_DISPLAY_ENABLED(i915))2124 if (!INTEL_DISPLAY_ENABLED(i915))
2136 return connector_status_disconnected;2125 return connector_status_disconnected;
2137 2126
2127 if (!intel_sdvo_set_target_output(intel_sdvo,
2128 intel_sdvo_connector->output_flag))
2129 return connector_status_unknown;
2130
2138 if (!intel_sdvo_get_value(intel_sdvo,2131 if (!intel_sdvo_get_value(intel_sdvo,
2139 SDVO_CMD_GET_ATTACHED_DISPLAYS,2132 SDVO_CMD_GET_ATTACHED_DISPLAYS,
2140 &response, 2))2133 &response, 2))
@@ -2147,8 +2140,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) · 6 unmodified lines
2147 if (response == 0)2140 if (response == 0)
2148 return connector_status_disconnected;2141 return connector_status_disconnected;
2149 2142
2150 intel_sdvo->attached_output = response;
2151
2152 if ((intel_sdvo_connector->output_flag & response) == 0)2143 if ((intel_sdvo_connector->output_flag & response) == 0)
2153 ret = connector_status_disconnected;2144 ret = connector_status_disconnected;
2154 else if (IS_TMDS(intel_sdvo_connector))2145 else if (IS_TMDS(intel_sdvo_connector))
@@ -2276,6 +2267,8 @@ static const struct drm_display_mode sdvo_tv_modes[] = { · 121 unmodified lines
2276static int intel_sdvo_get_tv_modes(struct drm_connector *connector)2267static int intel_sdvo_get_tv_modes(struct drm_connector *connector)
2277{2268{
2278 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector));2269 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector));
2270 struct intel_sdvo_connector *intel_sdvo_connector =
2271 to_intel_sdvo_connector(connector);
2279 const struct drm_connector_state *conn_state = connector->state;2272 const struct drm_connector_state *conn_state = connector->state;
2280 struct intel_sdvo_sdtv_resolution_request tv_res;2273 struct intel_sdvo_sdtv_resolution_request tv_res;
2281 u32 reply = 0, format_map = 0;2274 u32 reply = 0, format_map = 0;
@@ -2293,7 +2286,7 @@ static int intel_sdvo_get_tv_modes(struct drm_connector *connector) · 11 unmodified lines
2293 memcpy(&tv_res, &format_map,2286 memcpy(&tv_res, &format_map,
2294 min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request)));2287 min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request)));
2295 2288
2296 if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output))2289 if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo_connector->output_flag))
2297 return 0;2290 return 0;
2298 2291
2299 BUILD_BUG_ON(sizeof(tv_res) != 3);2292 BUILD_BUG_ON(sizeof(tv_res) != 3);
@@ -2458,31 +2451,6 @@ intel_sdvo_connector_atomic_set_property(struct drm_connector *connector, · 158 unmodified lines
2458 return 0;2451 return 0;
2459}2452}
2460 2453
2461static int
2462intel_sdvo_connector_register(struct drm_connector *connector)
2463{
2464 struct intel_sdvo *sdvo = intel_attached_sdvo(to_intel_connector(connector));
2465 int ret;
2466
2467 ret = intel_connector_register(connector);
2468 if (ret)
2469 return ret;
2470
2471 return sysfs_create_link(&connector->kdev->kobj,
2472 &sdvo->ddc.dev.kobj,
2473 sdvo->ddc.dev.kobj.name);
2474}
2475
2476static void
2477intel_sdvo_connector_unregister(struct drm_connector *connector)
2478{
2479 struct intel_sdvo *sdvo = intel_attached_sdvo(to_intel_connector(connector));
2480
2481 sysfs_remove_link(&connector->kdev->kobj,
2482 sdvo->ddc.dev.kobj.name);
2483 intel_connector_unregister(connector);
2484}
2485
2486static struct drm_connector_state *2454static struct drm_connector_state *
2487intel_sdvo_connector_duplicate_state(struct drm_connector *connector)2455intel_sdvo_connector_duplicate_state(struct drm_connector *connector)
2488{2456{
@@ -2501,8 +2469,8 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { · 12 unmodified lines
2501 .fill_modes = drm_helper_probe_single_connector_modes,2469 .fill_modes = drm_helper_probe_single_connector_modes,
2502 .atomic_get_property = intel_sdvo_connector_atomic_get_property,2470 .atomic_get_property = intel_sdvo_connector_atomic_get_property,
2503 .atomic_set_property = intel_sdvo_connector_atomic_set_property,2471 .atomic_set_property = intel_sdvo_connector_atomic_set_property,
2504 .late_register = intel_sdvo_connector_register,2472 .late_register = intel_connector_register,
2505 .early_unregister = intel_sdvo_connector_unregister,2473 .early_unregister = intel_connector_unregister,
2506 .destroy = intel_connector_destroy,2474 .destroy = intel_connector_destroy,
2507 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,2475 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
2508 .atomic_duplicate_state = intel_sdvo_connector_duplicate_state,2476 .atomic_duplicate_state = intel_sdvo_connector_duplicate_state,
@@ -2539,29 +2507,37 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs · 30 unmodified lines
2539 .atomic_check = intel_sdvo_atomic_check,2507 .atomic_check = intel_sdvo_atomic_check,
2540};2508};
2541 2509
2542static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)2510static void intel_sdvo_encoder_destroy(struct drm_encoder *_encoder)
2543{2511{
2544 struct intel_sdvo *intel_sdvo = to_sdvo(to_intel_encoder(encoder));2512 struct intel_encoder *encoder = to_intel_encoder(_encoder);
2513 struct intel_sdvo *sdvo = to_sdvo(encoder);
2514 int i;
2545 2515
2546 i2c_del_adapter(&intel_sdvo->ddc);2516 for (i = 0; i < ARRAY_SIZE(sdvo->ddc); i++) {
2547 intel_encoder_destroy(encoder);2517 if (sdvo->ddc[i].ddc_bus)
2548}2518 i2c_del_adapter(&sdvo->ddc[i].ddc);
2519 }
2520
2521 drm_encoder_cleanup(&encoder->base);
2522 kfree(sdvo);
2523};
2549 2524
2550static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {2525static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
2551 .destroy = intel_sdvo_enc_destroy,2526 .destroy = intel_sdvo_encoder_destroy,
2552};2527};
2553 2528
2554static void2529static int
2555intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)2530intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo,
2531 struct intel_sdvo_connector *connector)
2556{2532{
2557 u16 mask = 0;2533 u16 mask = 0;
2558 unsigned int num_bits;2534 int num_bits;
2559 2535
2560 /*2536 /*
2561 * Make a mask of outputs less than or equal to our own priority in the2537 * Make a mask of outputs less than or equal to our own priority in the
2562 * list.2538 * list.
2563 */2539 */
2564 switch (sdvo->controlled_output) {2540 switch (connector->output_flag) {
2565 case SDVO_OUTPUT_LVDS1:2541 case SDVO_OUTPUT_LVDS1:
2566 mask |= SDVO_OUTPUT_LVDS1;2542 mask |= SDVO_OUTPUT_LVDS1;
2567 fallthrough;2543 fallthrough;
@@ -2590,7 +2566,7 @@ intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) · 22 unmodified lines
2590 num_bits = 3;2566 num_bits = 3;
2591 2567
2592 /* Corresponds to SDVO_CONTROL_BUS_DDCx */2568 /* Corresponds to SDVO_CONTROL_BUS_DDCx */
2593 sdvo->ddc_bus = 1 << num_bits;2569 return num_bits;
2594}2570}
2595 2571
2596/*2572/*
@@ -2600,31 +2576,38 @@ intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) · 3 unmodified lines
2600 * DDC bus number assignment is in a priority order of RGB outputs, then TMDS2576 * DDC bus number assignment is in a priority order of RGB outputs, then TMDS
2601 * outputs, then LVDS outputs.2577 * outputs, then LVDS outputs.
2602 */2578 */
2603static void2579static struct intel_sdvo_ddc *
2604intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,2580intel_sdvo_select_ddc_bus(struct intel_sdvo *sdvo,
2605 struct intel_sdvo *sdvo)2581 struct intel_sdvo_connector *connector)
2606{2582{
2607 struct sdvo_device_mapping *mapping;2583 struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev);
2584 const struct sdvo_device_mapping *mapping;
2585 int ddc_bus;
2608 2586
2609 if (sdvo->port == PORT_B)2587 if (sdvo->base.port == PORT_B)
2610 mapping = &dev_priv->display.vbt.sdvo_mappings[0];2588 mapping = &dev_priv->display.vbt.sdvo_mappings[0];
2611 else2589 else
2612 mapping = &dev_priv->display.vbt.sdvo_mappings[1];2590 mapping = &dev_priv->display.vbt.sdvo_mappings[1];
2613 2591
2614 if (mapping->initialized)2592 if (mapping->initialized)
2615 sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);2593 ddc_bus = (mapping->ddc_pin & 0xf0) >> 4;
2616 else2594 else
2617 intel_sdvo_guess_ddc_bus(sdvo);2595 ddc_bus = intel_sdvo_guess_ddc_bus(sdvo, connector);
2596
2597 if (ddc_bus < 1 || ddc_bus > 3)
2598 return NULL;
2599
2600 return &sdvo->ddc[ddc_bus - 1];
2618}2601}
2619 2602
2620static void2603static void
2621intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,2604intel_sdvo_select_i2c_bus(struct intel_sdvo *sdvo)
2622 struct intel_sdvo *sdvo)
2623{2605{
2624 struct sdvo_device_mapping *mapping;2606 struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev);
2607 const struct sdvo_device_mapping *mapping;
2625 u8 pin;2608 u8 pin;
2626 2609
2627 if (sdvo->port == PORT_B)2610 if (sdvo->base.port == PORT_B)
2628 mapping = &dev_priv->display.vbt.sdvo_mappings[0];2611 mapping = &dev_priv->display.vbt.sdvo_mappings[0];
2629 else2612 else
2630 mapping = &dev_priv->display.vbt.sdvo_mappings[1];2613 mapping = &dev_priv->display.vbt.sdvo_mappings[1];
@@ -2635,6 +2618,10 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, · 4 unmodified lines
2635 else2618 else
2636 pin = GMBUS_PIN_DPB;2619 pin = GMBUS_PIN_DPB;
2637 2620
2621 drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] I2C pin %d, slave addr 0x%x\n",
2622 sdvo->base.base.base.id, sdvo->base.base.name,
2623 pin, sdvo->slave_addr);
2624
2638 sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);2625 sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
2639 2626
2640 /*2627 /*
@@ -2659,12 +2646,12 @@ intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo) · 18 unmodified lines
2659}2646}
2660 2647
2661static u82648static u8
2662intel_sdvo_get_slave_addr(struct drm_i915_private *dev_priv,2649intel_sdvo_get_slave_addr(struct intel_sdvo *sdvo)
2663 struct intel_sdvo *sdvo)
2664{2650{
2665 struct sdvo_device_mapping *my_mapping, *other_mapping;2651 struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev);
2652 const struct sdvo_device_mapping *my_mapping, *other_mapping;
2666 2653
2667 if (sdvo->port == PORT_B) {2654 if (sdvo->base.port == PORT_B) {
2668 my_mapping = &dev_priv->display.vbt.sdvo_mappings[0];2655 my_mapping = &dev_priv->display.vbt.sdvo_mappings[0];
2669 other_mapping = &dev_priv->display.vbt.sdvo_mappings[1];2656 other_mapping = &dev_priv->display.vbt.sdvo_mappings[1];
2670 } else {2657 } else {
@@ -2691,28 +2678,36 @@ intel_sdvo_get_slave_addr(struct drm_i915_private *dev_priv, · 20 unmodified lines
2691 * No SDVO device info is found for another DVO port,2678 * No SDVO device info is found for another DVO port,
2692 * so use mapping assumption we had before BIOS parsing.2679 * so use mapping assumption we had before BIOS parsing.
2693 */2680 */
2694 if (sdvo->port == PORT_B)2681 if (sdvo->base.port == PORT_B)
2695 return 0x70;2682 return 0x70;
2696 else2683 else
2697 return 0x72;2684 return 0x72;
2698}2685}
2699 2686
2687static int
2688intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc,
2689 struct intel_sdvo *sdvo, int bit);
2690
2700static int2691static int
2701intel_sdvo_connector_init(struct intel_sdvo_connector *connector,2692intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
2702 struct intel_sdvo *encoder)2693 struct intel_sdvo *encoder)
2703{2694{
2704 struct drm_connector *drm_connector;2695 struct drm_i915_private *i915 = to_i915(encoder->base.base.dev);
2696 struct intel_sdvo_ddc *ddc = NULL;
2705 int ret;2697 int ret;
2706 2698
2707 drm_connector = &connector->base.base;2699 if (HAS_DDC(connector))
2708 ret = drm_connector_init(encoder->base.base.dev,2700 ddc = intel_sdvo_select_ddc_bus(encoder, connector);
2709 drm_connector,2701
2710 &intel_sdvo_connector_funcs,2702 ret = drm_connector_init_with_ddc(encoder->base.base.dev,
2711 connector->base.base.connector_type);2703 &connector->base.base,
2704 &intel_sdvo_connector_funcs,
2705 connector->base.base.connector_type,
2706 ddc ? &ddc->ddc : NULL);
2712 if (ret < 0)2707 if (ret < 0)
2713 return ret;2708 return ret;
2714 2709
2715 drm_connector_helper_add(drm_connector,2710 drm_connector_helper_add(&connector->base.base,
2716 &intel_sdvo_connector_helper_funcs);2711 &intel_sdvo_connector_helper_funcs);
2717 2712
2718 connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;2713 connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
@@ -2721,6 +2716,11 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, · 2 unmodified lines
2721 2716
2722 intel_connector_attach_encoder(&connector->base, &encoder->base);2717 intel_connector_attach_encoder(&connector->base, &encoder->base);
2723 2718
2719 if (ddc)
2720 drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s] using %s\n",
2721 connector->base.base.base.id, connector->base.base.name,
2722 ddc->ddc.name);
2723
2724 return 0;2724 return 0;
2725}2725}
2726 2726
@@ -2918,7 +2918,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, u16 type) · 191 unmodified lines
2918 if (!intel_panel_preferred_fixed_mode(intel_connector)) {2918 if (!intel_panel_preferred_fixed_mode(intel_connector)) {
2919 mutex_lock(&i915->drm.mode_config.mutex);2919 mutex_lock(&i915->drm.mode_config.mutex);
2920 2920
2921 intel_ddc_get_modes(connector, &intel_sdvo->ddc);2921 intel_ddc_get_modes(connector, connector->ddc);
2922 intel_panel_add_edid_fixed_modes(intel_connector, false);2922 intel_panel_add_edid_fixed_modes(intel_connector, false);
2923 2923
2924 mutex_unlock(&i915->drm.mode_config.mutex);2924 mutex_unlock(&i915->drm.mode_config.mutex);
@@ -2982,7 +2982,6 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo) · 57 unmodified lines
2982 SDVO_OUTPUT_LVDS0,2982 SDVO_OUTPUT_LVDS0,
2983 SDVO_OUTPUT_LVDS1,2983 SDVO_OUTPUT_LVDS1,
2984 };2984 };
2985 struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev);
2986 u16 flags;2985 u16 flags;
2987 int i;2986 int i;
2988 2987
@@ -2994,10 +2993,6 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo) · 5 unmodified lines
2994 return false;2993 return false;
2995 }2994 }
2996 2995
2997 intel_sdvo->controlled_output = flags;
2998
2999 intel_sdvo_select_ddc_bus(i915, intel_sdvo);
3000
3001 for (i = 0; i < ARRAY_SIZE(probe_order); i++) {2996 for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
3002 u16 type = flags & probe_order[i];2997 u16 type = flags & probe_order[i];
3003 2998
@@ -3250,9 +3245,10 @@ static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter, · 246 unmodified lines
3250 struct i2c_msg *msgs,3245 struct i2c_msg *msgs,
3251 int num)3246 int num)
3252{3247{
3253 struct intel_sdvo *sdvo = adapter->algo_data;3248 struct intel_sdvo_ddc *ddc = adapter->algo_data;
3249 struct intel_sdvo *sdvo = ddc->sdvo;
3254 3250
3255 if (!__intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))3251 if (!__intel_sdvo_set_control_bus_switch(sdvo, 1 << ddc->ddc_bus))
3256 return -EIO;3252 return -EIO;
3257 3253
3258 return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);3254 return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);
@@ -3260,7 +3256,9 @@ static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter, · 1 unmodified line
3260 3256
3261static u32 intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter)3257static u32 intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter)
3262{3258{
3263 struct intel_sdvo *sdvo = adapter->algo_data;3259 struct intel_sdvo_ddc *ddc = adapter->algo_data;
3260 struct intel_sdvo *sdvo = ddc->sdvo;
3261
3264 return sdvo->i2c->algo->functionality(sdvo->i2c);3262 return sdvo->i2c->algo->functionality(sdvo->i2c);
3265}3263}
3266 3264
@@ -3272,21 +3270,27 @@ static const struct i2c_algorithm intel_sdvo_ddc_proxy = { · 5 unmodified lines
3272static void proxy_lock_bus(struct i2c_adapter *adapter,3270static void proxy_lock_bus(struct i2c_adapter *adapter,
3273 unsigned int flags)3271 unsigned int flags)
3274{3272{
3275 struct intel_sdvo *sdvo = adapter->algo_data;3273 struct intel_sdvo_ddc *ddc = adapter->algo_data;
3274 struct intel_sdvo *sdvo = ddc->sdvo;
3275
3276 sdvo->i2c->lock_ops->lock_bus(sdvo->i2c, flags);3276 sdvo->i2c->lock_ops->lock_bus(sdvo->i2c, flags);
3277}3277}
3278 3278
3279static int proxy_trylock_bus(struct i2c_adapter *adapter,3279static int proxy_trylock_bus(struct i2c_adapter *adapter,
3280 unsigned int flags)3280 unsigned int flags)
3281{3281{
3282 struct intel_sdvo *sdvo = adapter->algo_data;3282 struct intel_sdvo_ddc *ddc = adapter->algo_data;
3283 struct intel_sdvo *sdvo = ddc->sdvo;
3284
3283 return sdvo->i2c->lock_ops->trylock_bus(sdvo->i2c, flags);3285 return sdvo->i2c->lock_ops->trylock_bus(sdvo->i2c, flags);
3284}3286}
3285 3287
3286static void proxy_unlock_bus(struct i2c_adapter *adapter,3288static void proxy_unlock_bus(struct i2c_adapter *adapter,
3287 unsigned int flags)3289 unsigned int flags)
3288{3290{
3289 struct intel_sdvo *sdvo = adapter->algo_data;3291 struct intel_sdvo_ddc *ddc = adapter->algo_data;
3292 struct intel_sdvo *sdvo = ddc->sdvo;
3293
3290 sdvo->i2c->lock_ops->unlock_bus(sdvo->i2c, flags);3294 sdvo->i2c->lock_ops->unlock_bus(sdvo->i2c, flags);
3291}3295}
3292 3296
@@ -3296,21 +3300,26 @@ static const struct i2c_lock_operations proxy_lock_ops = { · 3 unmodified lines
3296 .unlock_bus = proxy_unlock_bus,3300 .unlock_bus = proxy_unlock_bus,
3297};3301};
3298 3302
3299static bool3303static int
3300intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,3304intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc,
3301 struct drm_i915_private *dev_priv)3305 struct intel_sdvo *sdvo, int ddc_bus)
3302{3306{
3307 struct drm_i915_private *dev_priv = to_i915(sdvo->base.base.dev);
3303 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);3308 struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
3304 3309
3305 sdvo->ddc.owner = THIS_MODULE;3310 ddc->sdvo = sdvo;
3306 sdvo->ddc.class = I2C_CLASS_DDC;3311 ddc->ddc_bus = ddc_bus;
3307 snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy");
3308 sdvo->ddc.dev.parent = &pdev->dev;
3309 sdvo->ddc.algo_data = sdvo;
3310 sdvo->ddc.algo = &intel_sdvo_ddc_proxy;
3311 sdvo->ddc.lock_ops = &proxy_lock_ops;
3312 3312
3313 return i2c_add_adapter(&sdvo->ddc) == 0;3313 ddc->ddc.owner = THIS_MODULE;
3314 ddc->ddc.class = I2C_CLASS_DDC;
3315 snprintf(ddc->ddc.name, I2C_NAME_SIZE, "SDVO %c DDC%d",
3316 port_name(sdvo->base.port), ddc_bus);
3317 ddc->ddc.dev.parent = &pdev->dev;
3318 ddc->ddc.algo_data = ddc;
3319 ddc->ddc.algo = &intel_sdvo_ddc_proxy;
3320 ddc->ddc.lock_ops = &proxy_lock_ops;
3321
3322 return i2c_add_adapter(&ddc->ddc);
3314}3323}
3315 3324
3316static bool is_sdvo_port_valid(struct drm_i915_private *dev_priv, enum port port)3325static bool is_sdvo_port_valid(struct drm_i915_private *dev_priv, enum port port)
@@ -3345,23 +3354,21 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, · 28 unmodified lines
3345 if (!intel_sdvo)3354 if (!intel_sdvo)
3346 return false;3355 return false;
3347 3356
3348 intel_sdvo->sdvo_reg = sdvo_reg;
3349 intel_sdvo->port = port;
3350 intel_sdvo->slave_addr =
3351 intel_sdvo_get_slave_addr(dev_priv, intel_sdvo) >> 1;
3352 intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo);
3353 if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev_priv))
3354 goto err_i2c_bus;
3355
3356 /* encoder type will be decided later */3357 /* encoder type will be decided later */
3357 intel_encoder = &intel_sdvo->base;3358 intel_encoder = &intel_sdvo->base;
3358 intel_encoder->type = INTEL_OUTPUT_SDVO;3359 intel_encoder->type = INTEL_OUTPUT_SDVO;
3359 intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;3360 intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
3360 intel_encoder->port = port;3361 intel_encoder->port = port;
3362
3361 drm_encoder_init(&dev_priv->drm, &intel_encoder->base,3363 drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
3362 &intel_sdvo_enc_funcs, 0,3364 &intel_sdvo_enc_funcs, 0,
3363 "SDVO %c", port_name(port));3365 "SDVO %c", port_name(port));
3364 3366
3367 intel_sdvo->sdvo_reg = sdvo_reg;
3368 intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(intel_sdvo) >> 1;
3369
3370 intel_sdvo_select_i2c_bus(intel_sdvo);
3371
3365 /* Read the regs to test if we can talk to the device */3372 /* Read the regs to test if we can talk to the device */
3366 for (i = 0; i < 0x40; i++) {3373 for (i = 0; i < 0x40; i++) {
3367 u8 byte;3374 u8 byte;
@@ -3393,6 +3400,15 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, · 25 unmodified lines
3393 intel_sdvo->colorimetry_cap =3400 intel_sdvo->colorimetry_cap =
3394 intel_sdvo_get_colorimetry_cap(intel_sdvo);3401 intel_sdvo_get_colorimetry_cap(intel_sdvo);
3395 3402
3403 for (i = 0; i < ARRAY_SIZE(intel_sdvo->ddc); i++) {
3404 int ret;
3405
3406 ret = intel_sdvo_init_ddc_proxy(&intel_sdvo->ddc[i],
3407 intel_sdvo, i + 1);
3408 if (ret)
3409 goto err;
3410 }
3411
3396 if (!intel_sdvo_output_setup(intel_sdvo)) {3412 if (!intel_sdvo_output_setup(intel_sdvo)) {
3397 drm_dbg_kms(&dev_priv->drm,3413 drm_dbg_kms(&dev_priv->drm,
3398 "SDVO output failed to setup on %s\n",3414 "SDVO output failed to setup on %s\n",
@@ -3406,7 +3422,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, · 7 unmodified lines
3406 * hotplug lines.3422 * hotplug lines.
3407 */3423 */
3408 if (intel_sdvo->hotplug_active) {3424 if (intel_sdvo->hotplug_active) {
3409 if (intel_sdvo->port == PORT_B)3425 if (intel_sdvo->base.port == PORT_B)
3410 intel_encoder->hpd_pin = HPD_SDVO_B;3426 intel_encoder->hpd_pin = HPD_SDVO_B;
3411 else3427 else
3412 intel_encoder->hpd_pin = HPD_SDVO_C;3428 intel_encoder->hpd_pin = HPD_SDVO_C;
@@ -3433,15 +3449,14 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, · 20 unmodified lines
3433 3449
3434 drm_dbg_kms(&dev_priv->drm, "%s device VID/DID: %02X:%02X.%02X, "3450 drm_dbg_kms(&dev_priv->drm, "%s device VID/DID: %02X:%02X.%02X, "
3435 "clock range %dMHz - %dMHz, "3451 "clock range %dMHz - %dMHz, "
3436 "input 1: %c, input 2: %c, "3452 "num inputs: %d, "
3437 "output 1: %c, output 2: %c\n",3453 "output 1: %c, output 2: %c\n",
3438 SDVO_NAME(intel_sdvo),3454 SDVO_NAME(intel_sdvo),
3439 intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id,3455 intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id,
3440 intel_sdvo->caps.device_rev_id,3456 intel_sdvo->caps.device_rev_id,
3441 intel_sdvo->pixel_clock_min / 1000,3457 intel_sdvo->pixel_clock_min / 1000,
3442 intel_sdvo->pixel_clock_max / 1000,3458 intel_sdvo->pixel_clock_max / 1000,
3443 (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',3459 intel_sdvo->caps.sdvo_num_inputs,
3444 (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
3445 /* check currently supported outputs */3460 /* check currently supported outputs */
3446 intel_sdvo->caps.output_flags &3461 intel_sdvo->caps.output_flags &
3447 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0 |3462 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0 |
@@ -3454,13 +3469,9 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, · 6 unmodified lines
3454 3469
3455err_output:3470err_output:
3456 intel_sdvo_output_cleanup(intel_sdvo);3471 intel_sdvo_output_cleanup(intel_sdvo);
3457
3458err:3472err:
3459 drm_encoder_cleanup(&intel_encoder->base);
3460 i2c_del_adapter(&intel_sdvo->ddc);
3461err_i2c_bus:
3462 intel_sdvo_unselect_i2c_bus(intel_sdvo);3473 intel_sdvo_unselect_i2c_bus(intel_sdvo);
3463 kfree(intel_sdvo);3474 intel_sdvo_encoder_destroy(&intel_encoder->base);
3464 3475
3465 return false;3476 return false;
3466}3477}
drivers/gpu/drm/i915/display/intel_sdvo_regs.h+1−1
@@ -57,7 +57,7 @@ struct intel_sdvo_caps { · 56 unmodified lines
57 u8 device_rev_id;57 u8 device_rev_id;
58 u8 sdvo_version_major;58 u8 sdvo_version_major;
59 u8 sdvo_version_minor;59 u8 sdvo_version_minor;
60 unsigned int sdvo_inputs_mask:2;60 unsigned int sdvo_num_inputs:2;
61 unsigned int smooth_scaling:1;61 unsigned int smooth_scaling:1;
62 unsigned int sharp_scaling:1;62 unsigned int sharp_scaling:1;
63 unsigned int up_scaling:1;63 unsigned int up_scaling:1;
drivers/gpu/drm/i915/display/intel_sprite.c+1−0
@@ -45,6 +45,7 @@ · 44 unmodified lines
45#include "intel_de.h"45#include "intel_de.h"
46#include "intel_display_types.h"46#include "intel_display_types.h"
47#include "intel_fb.h"47#include "intel_fb.h"
48#include "intel_frontbuffer.h"
48#include "intel_sprite.h"49#include "intel_sprite.h"
49 50
50static void i9xx_plane_linear_gamma(u16 gamma[8])51static void i9xx_plane_linear_gamma(u16 gamma[8])
drivers/gpu/drm/i915/display/intel_tc.c+50−16
@@ -260,7 +260,7 @@ assert_tc_port_power_enabled(struct intel_tc_port *tc) · 259 unmodified lines
260 !intel_display_power_is_enabled(i915, tc_port_power_domain(tc)));260 !intel_display_power_is_enabled(i915, tc_port_power_domain(tc)));
261}261}
262 262
263u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port)263static u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port)
264{264{
265 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);265 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
266 struct intel_tc_port *tc = to_tc_port(dig_port);266 struct intel_tc_port *tc = to_tc_port(dig_port);
@@ -290,7 +290,32 @@ u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port) · 23 unmodified lines
290 DP_PIN_ASSIGNMENT_SHIFT(tc->phy_fia_idx);290 DP_PIN_ASSIGNMENT_SHIFT(tc->phy_fia_idx);
291}291}
292 292
293static int mtl_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port)293static int lnl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
294{
295 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
296 enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
297 intel_wakeref_t wakeref;
298 u32 val, pin_assignment;
299
300 with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref)
301 val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port));
302
303 pin_assignment =
304 REG_FIELD_GET(TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK, val);
305
306 switch (pin_assignment) {
307 default:
308 MISSING_CASE(pin_assignment);
309 fallthrough;
310 case DP_PIN_ASSIGNMENT_D:
311 return 2;
312 case DP_PIN_ASSIGNMENT_C:
313 case DP_PIN_ASSIGNMENT_E:
314 return 4;
315 }
316}
317
318static int mtl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
294{319{
295 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);320 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
296 intel_wakeref_t wakeref;321 intel_wakeref_t wakeref;
@@ -311,23 +336,12 @@ static int mtl_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_po · 14 unmodified lines
311 }336 }
312}337}
313 338
314int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port)339static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
315{340{
316 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);341 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
317 struct intel_tc_port *tc = to_tc_port(dig_port);
318 enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
319 intel_wakeref_t wakeref;342 intel_wakeref_t wakeref;
320 u32 lane_mask;343 u32 lane_mask = 0;
321
322 if (!intel_phy_is_tc(i915, phy) || tc->mode != TC_PORT_DP_ALT)
323 return 4;
324
325 assert_tc_cold_blocked(tc);
326
327 if (DISPLAY_VER(i915) >= 14)
328 return mtl_tc_port_get_pin_assignment_mask(dig_port);
329 344
330 lane_mask = 0;
331 with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref)345 with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref)
332 lane_mask = intel_tc_port_get_lane_mask(dig_port);346 lane_mask = intel_tc_port_get_lane_mask(dig_port);
333 347
@@ -348,6 +362,26 @@ int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port) · 14 unmodified lines
348 }362 }
349}363}
350 364
365int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port)
366{
367 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
368 struct intel_tc_port *tc = to_tc_port(dig_port);
369 enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
370
371 if (!intel_phy_is_tc(i915, phy) || tc->mode != TC_PORT_DP_ALT)
372 return 4;
373
374 assert_tc_cold_blocked(tc);
375
376 if (DISPLAY_VER(i915) >= 20)
377 return lnl_tc_port_get_max_lane_count(dig_port);
378
379 if (DISPLAY_VER(i915) >= 14)
380 return mtl_tc_port_get_max_lane_count(dig_port);
381
382 return intel_tc_port_get_max_lane_count(dig_port);
383}
384
351void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,385void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
352 int required_lanes)386 int required_lanes)
353{387{
@@ -583,7 +617,7 @@ static bool tc_phy_verify_legacy_or_dp_alt_mode(struct intel_tc_port *tc, · 229 unmodified lines
583 struct intel_digital_port *dig_port = tc->dig_port;617 struct intel_digital_port *dig_port = tc->dig_port;
584 int max_lanes;618 int max_lanes;
585 619
586 max_lanes = intel_tc_port_fia_max_lane_count(dig_port);620 max_lanes = intel_tc_port_max_lane_count(dig_port);
587 if (tc->mode == TC_PORT_LEGACY) {621 if (tc->mode == TC_PORT_LEGACY) {
588 drm_WARN_ON(&i915->drm, max_lanes != 4);622 drm_WARN_ON(&i915->drm, max_lanes != 4);
589 return true;623 return true;
drivers/gpu/drm/i915/display/intel_tc.h+1−2
@@ -19,9 +19,8 @@ bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port); · 18 unmodified lines
19bool intel_tc_port_connected(struct intel_encoder *encoder);19bool intel_tc_port_connected(struct intel_encoder *encoder);
20bool intel_tc_port_connected_locked(struct intel_encoder *encoder);20bool intel_tc_port_connected_locked(struct intel_encoder *encoder);
21 21
22u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port);
23u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port);22u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port);
24int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port);23int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port);
25void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,24void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port,
26 int required_lanes);25 int required_lanes);
27 26
drivers/gpu/drm/i915/display/intel_vblank.c+14−0
@@ -251,6 +251,20 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) · 250 unmodified lines
251 return (position + crtc->scanline_offset) % vtotal;251 return (position + crtc->scanline_offset) % vtotal;
252}252}
253 253
254int intel_crtc_scanline_to_hw(struct intel_crtc *crtc, int scanline)
255{
256 const struct drm_vblank_crtc *vblank =
257 &crtc->base.dev->vblank[drm_crtc_index(&crtc->base)];
258 const struct drm_display_mode *mode = &vblank->hwmode;
259 int vtotal;
260
261 vtotal = mode->crtc_vtotal;
262 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
263 vtotal /= 2;
264
265 return (scanline + vtotal - crtc->scanline_offset) % vtotal;
266}
267
254static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,268static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc,
255 bool in_vblank_irq,269 bool in_vblank_irq,
256 int *vpos, int *hpos,270 int *vpos, int *hpos,
drivers/gpu/drm/i915/display/intel_vblank.h+1−0
@@ -22,5 +22,6 @@ void intel_wait_for_pipe_scanline_stopped(struct intel_crtc *crtc); · 21 unmodified lines
22void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc);22void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc);
23void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,23void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state,
24 bool vrr_enable);24 bool vrr_enable);
25int intel_crtc_scanline_to_hw(struct intel_crtc *crtc, int scanline);
25 26
26#endif /* __INTEL_VBLANK_H__ */27#endif /* __INTEL_VBLANK_H__ */
drivers/gpu/drm/i915/display/intel_vdsc.c+287−343
@@ -80,13 +80,19 @@ calculate_rc_params(struct drm_dsc_config *vdsc_cfg) · 79 unmodified lines
80 int bpc = vdsc_cfg->bits_per_component;80 int bpc = vdsc_cfg->bits_per_component;
81 int bpp = vdsc_cfg->bits_per_pixel >> 4;81 int bpp = vdsc_cfg->bits_per_pixel >> 4;
82 int qp_bpc_modifier = (bpc - 8) * 2;82 int qp_bpc_modifier = (bpc - 8) * 2;
83 int uncompressed_bpg_rate;
84 int first_line_bpg_offset;
83 u32 res, buf_i, bpp_i;85 u32 res, buf_i, bpp_i;
84 86
85 if (vdsc_cfg->slice_height >= 8)87 if (vdsc_cfg->slice_height >= 8)
86 vdsc_cfg->first_line_bpg_offset =88 first_line_bpg_offset =
87 12 + DIV_ROUND_UP((9 * min(34, vdsc_cfg->slice_height - 8)), 100);89 12 + (9 * min(34, vdsc_cfg->slice_height - 8)) / 100;
88 else90 else
89 vdsc_cfg->first_line_bpg_offset = 2 * (vdsc_cfg->slice_height - 1);91 first_line_bpg_offset = 2 * (vdsc_cfg->slice_height - 1);
92
93 uncompressed_bpg_rate = (3 * bpc + (vdsc_cfg->convert_rgb ? 0 : 2)) * 3;
94 vdsc_cfg->first_line_bpg_offset = clamp(first_line_bpg_offset, 0,
95 uncompressed_bpg_rate - 3 * bpp);
90 96
91 /*97 /*
92 * According to DSC 1.2 spec in Section 4.1 if native_420 is set:98 * According to DSC 1.2 spec in Section 4.1 if native_420 is set:
@@ -350,9 +356,14 @@ intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder) · 257 unmodified lines
350 return POWER_DOMAIN_TRANSCODER_VDSC_PW2;356 return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
351}357}
352 358
359static int intel_dsc_get_vdsc_per_pipe(const struct intel_crtc_state *crtc_state)
360{
361 return crtc_state->dsc.dsc_split ? 2 : 1;
362}
363
353int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state)364int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state)
354{365{
355 int num_vdsc_instances = (crtc_state->dsc.dsc_split) ? 2 : 1;366 int num_vdsc_instances = intel_dsc_get_vdsc_per_pipe(crtc_state);
356 367
357 if (crtc_state->bigjoiner_pipes)368 if (crtc_state->bigjoiner_pipes)
358 num_vdsc_instances *= 2;369 num_vdsc_instances *= 2;
@@ -360,6 +371,43 @@ int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state) · 1 unmodified line
360 return num_vdsc_instances;371 return num_vdsc_instances;
361}372}
362 373
374static void intel_dsc_get_pps_reg(const struct intel_crtc_state *crtc_state, int pps,
375 i915_reg_t *dsc_reg, int dsc_reg_num)
376{
377 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
378 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
379 enum pipe pipe = crtc->pipe;
380 bool pipe_dsc;
381
382 pipe_dsc = is_pipe_dsc(crtc, cpu_transcoder);
383
384 if (dsc_reg_num >= 3)
385 MISSING_CASE(dsc_reg_num);
386 if (dsc_reg_num >= 2)
387 dsc_reg[1] = pipe_dsc ? ICL_DSC1_PPS(pipe, pps) : DSCC_PPS(pps);
388 if (dsc_reg_num >= 1)
389 dsc_reg[0] = pipe_dsc ? ICL_DSC0_PPS(pipe, pps) : DSCA_PPS(pps);
390}
391
392static void intel_dsc_pps_write(const struct intel_crtc_state *crtc_state,
393 int pps, u32 pps_val)
394{
395 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
396 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
397 i915_reg_t dsc_reg[2];
398 int i, vdsc_per_pipe, dsc_reg_num;
399
400 vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
401 dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe);
402
403 drm_WARN_ON_ONCE(&i915->drm, dsc_reg_num < vdsc_per_pipe);
404
405 intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num);
406
407 for (i = 0; i < dsc_reg_num; i++)
408 intel_de_write(i915, dsc_reg[i], pps_val);
409}
410
363static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)411static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
364{412{
365 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);413 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -367,359 +415,119 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) · 1 unmodified line
367 const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;415 const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
368 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;416 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
369 enum pipe pipe = crtc->pipe;417 enum pipe pipe = crtc->pipe;
370 u32 pps_val = 0;418 u32 pps_val;
371 u32 rc_buf_thresh_dword[4];419 u32 rc_buf_thresh_dword[4];
372 u32 rc_range_params_dword[8];420 u32 rc_range_params_dword[8];
373 int i = 0;421 int i = 0;
374 int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);422 int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
423 int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
375 424
376 /* Populate PICTURE_PARAMETER_SET_0 registers */425 /* PPS 0 */
377 pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<426 pps_val = DSC_PPS0_VER_MAJOR(1) |
378 DSC_VER_MIN_SHIFT |427 DSC_PPS0_VER_MINOR(vdsc_cfg->dsc_version_minor) |
379 vdsc_cfg->bits_per_component << DSC_BPC_SHIFT |428 DSC_PPS0_BPC(vdsc_cfg->bits_per_component) |
380 vdsc_cfg->line_buf_depth << DSC_LINE_BUF_DEPTH_SHIFT;429 DSC_PPS0_LINE_BUF_DEPTH(vdsc_cfg->line_buf_depth);
381 if (vdsc_cfg->dsc_version_minor == 2) {430 if (vdsc_cfg->dsc_version_minor == 2) {
382 pps_val |= DSC_ALT_ICH_SEL;431 pps_val |= DSC_PPS0_ALT_ICH_SEL;
383 if (vdsc_cfg->native_420)432 if (vdsc_cfg->native_420)
384 pps_val |= DSC_NATIVE_420_ENABLE;433 pps_val |= DSC_PPS0_NATIVE_420_ENABLE;
385 if (vdsc_cfg->native_422)434 if (vdsc_cfg->native_422)
386 pps_val |= DSC_NATIVE_422_ENABLE;435 pps_val |= DSC_PPS0_NATIVE_422_ENABLE;
387 }436 }
388 if (vdsc_cfg->block_pred_enable)437 if (vdsc_cfg->block_pred_enable)
389 pps_val |= DSC_BLOCK_PREDICTION;438 pps_val |= DSC_PPS0_BLOCK_PREDICTION;
390 if (vdsc_cfg->convert_rgb)439 if (vdsc_cfg->convert_rgb)
391 pps_val |= DSC_COLOR_SPACE_CONVERSION;440 pps_val |= DSC_PPS0_COLOR_SPACE_CONVERSION;
392 if (vdsc_cfg->simple_422)441 if (vdsc_cfg->simple_422)
393 pps_val |= DSC_422_ENABLE;442 pps_val |= DSC_PPS0_422_ENABLE;
394 if (vdsc_cfg->vbr_enable)443 if (vdsc_cfg->vbr_enable)
395 pps_val |= DSC_VBR_ENABLE;444 pps_val |= DSC_PPS0_VBR_ENABLE;
396 drm_dbg_kms(&dev_priv->drm, "PPS0 = 0x%08x\n", pps_val);445 drm_dbg_kms(&dev_priv->drm, "PPS0 = 0x%08x\n", pps_val);
397 if (!is_pipe_dsc(crtc, cpu_transcoder)) {446 intel_dsc_pps_write(crtc_state, 0, pps_val);
398 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_0,
399 pps_val);
400 /*
401 * If 2 VDSC instances are needed, configure PPS for second
402 * VDSC
403 */
404 if (crtc_state->dsc.dsc_split)
405 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_0,
406 pps_val);
407 } else {
408 intel_de_write(dev_priv,
409 ICL_DSC0_PICTURE_PARAMETER_SET_0(pipe),
410 pps_val);
411 if (crtc_state->dsc.dsc_split)
412 intel_de_write(dev_priv,
413 ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe),
414 pps_val);
415 }
416 447
417 /* Populate PICTURE_PARAMETER_SET_1 registers */448 /* PPS 1 */
418 pps_val = 0;449 pps_val = DSC_PPS1_BPP(vdsc_cfg->bits_per_pixel);
419 pps_val |= DSC_BPP(vdsc_cfg->bits_per_pixel);
420 drm_dbg_kms(&dev_priv->drm, "PPS1 = 0x%08x\n", pps_val);450 drm_dbg_kms(&dev_priv->drm, "PPS1 = 0x%08x\n", pps_val);
421 if (!is_pipe_dsc(crtc, cpu_transcoder)) {451 intel_dsc_pps_write(crtc_state, 1, pps_val);
422 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_1,
423 pps_val);
424 /*
425 * If 2 VDSC instances are needed, configure PPS for second
426 * VDSC
427 */
428 if (crtc_state->dsc.dsc_split)
429 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_1,
430 pps_val);
431 } else {
432 intel_de_write(dev_priv,
433 ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe),
434 pps_val);
435 if (crtc_state->dsc.dsc_split)
436 intel_de_write(dev_priv,
437 ICL_DSC1_PICTURE_PARAMETER_SET_1(pipe),
438 pps_val);
439 }
440 452
441 /* Populate PICTURE_PARAMETER_SET_2 registers */453 /* PPS 2 */
442 pps_val = 0;454 pps_val = DSC_PPS2_PIC_HEIGHT(vdsc_cfg->pic_height) |
443 pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) |455 DSC_PPS2_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances);
444 DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances);
445 drm_dbg_kms(&dev_priv->drm, "PPS2 = 0x%08x\n", pps_val);456 drm_dbg_kms(&dev_priv->drm, "PPS2 = 0x%08x\n", pps_val);
446 if (!is_pipe_dsc(crtc, cpu_transcoder)) {457 intel_dsc_pps_write(crtc_state, 2, pps_val);
447 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_2,
448 pps_val);
449 /*
450 * If 2 VDSC instances are needed, configure PPS for second
451 * VDSC
452 */
453 if (crtc_state->dsc.dsc_split)
454 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_2,
455 pps_val);
456 } else {
457 intel_de_write(dev_priv,
458 ICL_DSC0_PICTURE_PARAMETER_SET_2(pipe),
459 pps_val);
460 if (crtc_state->dsc.dsc_split)
461 intel_de_write(dev_priv,
462 ICL_DSC1_PICTURE_PARAMETER_SET_2(pipe),
463 pps_val);
464 }
465 458
466 /* Populate PICTURE_PARAMETER_SET_3 registers */459 /* PPS 3 */
467 pps_val = 0;460 pps_val = DSC_PPS3_SLICE_HEIGHT(vdsc_cfg->slice_height) |
468 pps_val |= DSC_SLICE_HEIGHT(vdsc_cfg->slice_height) |461 DSC_PPS3_SLICE_WIDTH(vdsc_cfg->slice_width);
469 DSC_SLICE_WIDTH(vdsc_cfg->slice_width);
470 drm_dbg_kms(&dev_priv->drm, "PPS3 = 0x%08x\n", pps_val);462 drm_dbg_kms(&dev_priv->drm, "PPS3 = 0x%08x\n", pps_val);
471 if (!is_pipe_dsc(crtc, cpu_transcoder)) {463 intel_dsc_pps_write(crtc_state, 3, pps_val);
472 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_3,
473 pps_val);
474 /*
475 * If 2 VDSC instances are needed, configure PPS for second
476 * VDSC
477 */
478 if (crtc_state->dsc.dsc_split)
479 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_3,
480 pps_val);
481 } else {
482 intel_de_write(dev_priv,
483 ICL_DSC0_PICTURE_PARAMETER_SET_3(pipe),
484 pps_val);
485 if (crtc_state->dsc.dsc_split)
486 intel_de_write(dev_priv,
487 ICL_DSC1_PICTURE_PARAMETER_SET_3(pipe),
488 pps_val);
489 }
490 464
491 /* Populate PICTURE_PARAMETER_SET_4 registers */465 /* PPS 4 */
492 pps_val = 0;466 pps_val = DSC_PPS4_INITIAL_XMIT_DELAY(vdsc_cfg->initial_xmit_delay) |
493 pps_val |= DSC_INITIAL_XMIT_DELAY(vdsc_cfg->initial_xmit_delay) |467 DSC_PPS4_INITIAL_DEC_DELAY(vdsc_cfg->initial_dec_delay);
494 DSC_INITIAL_DEC_DELAY(vdsc_cfg->initial_dec_delay);
495 drm_dbg_kms(&dev_priv->drm, "PPS4 = 0x%08x\n", pps_val);468 drm_dbg_kms(&dev_priv->drm, "PPS4 = 0x%08x\n", pps_val);
496 if (!is_pipe_dsc(crtc, cpu_transcoder)) {469 intel_dsc_pps_write(crtc_state, 4, pps_val);
497 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_4,
498 pps_val);
499 /*
500 * If 2 VDSC instances are needed, configure PPS for second
501 * VDSC
502 */
503 if (crtc_state->dsc.dsc_split)
504 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_4,
505 pps_val);
506 } else {
507 intel_de_write(dev_priv,
508 ICL_DSC0_PICTURE_PARAMETER_SET_4(pipe),
509 pps_val);
510 if (crtc_state->dsc.dsc_split)
511 intel_de_write(dev_priv,
512 ICL_DSC1_PICTURE_PARAMETER_SET_4(pipe),
513 pps_val);
514 }
515 470
516 /* Populate PICTURE_PARAMETER_SET_5 registers */471 /* PPS 5 */
517 pps_val = 0;472 pps_val = DSC_PPS5_SCALE_INC_INT(vdsc_cfg->scale_increment_interval) |
518 pps_val |= DSC_SCALE_INC_INT(vdsc_cfg->scale_increment_interval) |473 DSC_PPS5_SCALE_DEC_INT(vdsc_cfg->scale_decrement_interval);
519 DSC_SCALE_DEC_INT(vdsc_cfg->scale_decrement_interval);
520 drm_dbg_kms(&dev_priv->drm, "PPS5 = 0x%08x\n", pps_val);474 drm_dbg_kms(&dev_priv->drm, "PPS5 = 0x%08x\n", pps_val);
521 if (!is_pipe_dsc(crtc, cpu_transcoder)) {475 intel_dsc_pps_write(crtc_state, 5, pps_val);
522 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_5,
523 pps_val);
524 /*
525 * If 2 VDSC instances are needed, configure PPS for second
526 * VDSC
527 */
528 if (crtc_state->dsc.dsc_split)
529 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_5,
530 pps_val);
531 } else {
532 intel_de_write(dev_priv,
533 ICL_DSC0_PICTURE_PARAMETER_SET_5(pipe),
534 pps_val);
535 if (crtc_state->dsc.dsc_split)
536 intel_de_write(dev_priv,
537 ICL_DSC1_PICTURE_PARAMETER_SET_5(pipe),
538 pps_val);
539 }
540 476
541 /* Populate PICTURE_PARAMETER_SET_6 registers */477 /* PPS 6 */
542 pps_val = 0;478 pps_val = DSC_PPS6_INITIAL_SCALE_VALUE(vdsc_cfg->initial_scale_value) |
543 pps_val |= DSC_INITIAL_SCALE_VALUE(vdsc_cfg->initial_scale_value) |479 DSC_PPS6_FIRST_LINE_BPG_OFFSET(vdsc_cfg->first_line_bpg_offset) |
544 DSC_FIRST_LINE_BPG_OFFSET(vdsc_cfg->first_line_bpg_offset) |480 DSC_PPS6_FLATNESS_MIN_QP(vdsc_cfg->flatness_min_qp) |
545 DSC_FLATNESS_MIN_QP(vdsc_cfg->flatness_min_qp) |481 DSC_PPS6_FLATNESS_MAX_QP(vdsc_cfg->flatness_max_qp);
546 DSC_FLATNESS_MAX_QP(vdsc_cfg->flatness_max_qp);
547 drm_dbg_kms(&dev_priv->drm, "PPS6 = 0x%08x\n", pps_val);482 drm_dbg_kms(&dev_priv->drm, "PPS6 = 0x%08x\n", pps_val);
548 if (!is_pipe_dsc(crtc, cpu_transcoder)) {483 intel_dsc_pps_write(crtc_state, 6, pps_val);
549 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_6,
550 pps_val);
551 /*
552 * If 2 VDSC instances are needed, configure PPS for second
553 * VDSC
554 */
555 if (crtc_state->dsc.dsc_split)
556 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_6,
557 pps_val);
558 } else {
559 intel_de_write(dev_priv,
560 ICL_DSC0_PICTURE_PARAMETER_SET_6(pipe),
561 pps_val);
562 if (crtc_state->dsc.dsc_split)
563 intel_de_write(dev_priv,
564 ICL_DSC1_PICTURE_PARAMETER_SET_6(pipe),
565 pps_val);
566 }
567 484
568 /* Populate PICTURE_PARAMETER_SET_7 registers */485 /* PPS 7 */
569 pps_val = 0;486 pps_val = DSC_PPS7_SLICE_BPG_OFFSET(vdsc_cfg->slice_bpg_offset) |
570 pps_val |= DSC_SLICE_BPG_OFFSET(vdsc_cfg->slice_bpg_offset) |487 DSC_PPS7_NFL_BPG_OFFSET(vdsc_cfg->nfl_bpg_offset);
571 DSC_NFL_BPG_OFFSET(vdsc_cfg->nfl_bpg_offset);
572 drm_dbg_kms(&dev_priv->drm, "PPS7 = 0x%08x\n", pps_val);488 drm_dbg_kms(&dev_priv->drm, "PPS7 = 0x%08x\n", pps_val);
573 if (!is_pipe_dsc(crtc, cpu_transcoder)) {489 intel_dsc_pps_write(crtc_state, 7, pps_val);
574 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_7,
575 pps_val);
576 /*
577 * If 2 VDSC instances are needed, configure PPS for second
578 * VDSC
579 */
580 if (crtc_state->dsc.dsc_split)
581 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_7,
582 pps_val);
583 } else {
584 intel_de_write(dev_priv,
585 ICL_DSC0_PICTURE_PARAMETER_SET_7(pipe),
586 pps_val);
587 if (crtc_state->dsc.dsc_split)
588 intel_de_write(dev_priv,
589 ICL_DSC1_PICTURE_PARAMETER_SET_7(pipe),
590 pps_val);
591 }
592 490
593 /* Populate PICTURE_PARAMETER_SET_8 registers */491 /* PPS 8 */
594 pps_val = 0;492 pps_val = DSC_PPS8_FINAL_OFFSET(vdsc_cfg->final_offset) |
595 pps_val |= DSC_FINAL_OFFSET(vdsc_cfg->final_offset) |493 DSC_PPS8_INITIAL_OFFSET(vdsc_cfg->initial_offset);
596 DSC_INITIAL_OFFSET(vdsc_cfg->initial_offset);
597 drm_dbg_kms(&dev_priv->drm, "PPS8 = 0x%08x\n", pps_val);494 drm_dbg_kms(&dev_priv->drm, "PPS8 = 0x%08x\n", pps_val);
598 if (!is_pipe_dsc(crtc, cpu_transcoder)) {495 intel_dsc_pps_write(crtc_state, 8, pps_val);
599 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_8,
600 pps_val);
601 /*
602 * If 2 VDSC instances are needed, configure PPS for second
603 * VDSC
604 */
605 if (crtc_state->dsc.dsc_split)
606 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_8,
607 pps_val);
608 } else {
609 intel_de_write(dev_priv,
610 ICL_DSC0_PICTURE_PARAMETER_SET_8(pipe),
611 pps_val);
612 if (crtc_state->dsc.dsc_split)
613 intel_de_write(dev_priv,
614 ICL_DSC1_PICTURE_PARAMETER_SET_8(pipe),
615 pps_val);
616 }
617 496
618 /* Populate PICTURE_PARAMETER_SET_9 registers */497 /* PPS 9 */
619 pps_val = 0;498 pps_val = DSC_PPS9_RC_MODEL_SIZE(vdsc_cfg->rc_model_size) |
620 pps_val |= DSC_RC_MODEL_SIZE(vdsc_cfg->rc_model_size) |499 DSC_PPS9_RC_EDGE_FACTOR(DSC_RC_EDGE_FACTOR_CONST);
621 DSC_RC_EDGE_FACTOR(DSC_RC_EDGE_FACTOR_CONST);
622 drm_dbg_kms(&dev_priv->drm, "PPS9 = 0x%08x\n", pps_val);500 drm_dbg_kms(&dev_priv->drm, "PPS9 = 0x%08x\n", pps_val);
623 if (!is_pipe_dsc(crtc, cpu_transcoder)) {501 intel_dsc_pps_write(crtc_state, 9, pps_val);
624 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_9,
625 pps_val);
626 /*
627 * If 2 VDSC instances are needed, configure PPS for second
628 * VDSC
629 */
630 if (crtc_state->dsc.dsc_split)
631 intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_9,
632 pps_val);
633 } else {
634 intel_de_write(dev_priv,
635 ICL_DSC0_PICTURE_PARAMETER_SET_9(pipe),
636 pps_val);
637 if (crtc_state->dsc.dsc_split)
638 intel_de_write(dev_priv,
639 ICL_DSC1_PICTURE_PARAMETER_SET_9(pipe),
640 pps_val);
641 }
642 502
643 /* Populate PICTURE_PARAMETER_SET_10 registers */503 /* PPS 10 */
644 pps_val = 0;504 pps_val = DSC_PPS10_RC_QUANT_INC_LIMIT0(vdsc_cfg->rc_quant_incr_limit0) |
645 pps_val |= DSC_RC_QUANT_INC_LIMIT0(vdsc_cfg->rc_quant_incr_limit0) |505 DSC_PPS10_RC_QUANT_INC_LIMIT1(vdsc_cfg->rc_quant_incr_limit1) |
646 DSC_RC_QUANT_INC_LIMIT1(vdsc_cfg->rc_quant_incr_limit1) |506 DSC_PPS10_RC_TARGET_OFF_HIGH(DSC_RC_TGT_OFFSET_HI_CONST) |
647 DSC_RC_TARGET_OFF_HIGH(DSC_RC_TGT_OFFSET_HI_CONST) |507 DSC_PPS10_RC_TARGET_OFF_LOW(DSC_RC_TGT_OFFSET_LO_CONST);
648 DSC_RC_TARGET_OFF_LOW(DSC_RC_TGT_OFFSET_LO_CONST);
649 drm_dbg_kms(&dev_priv->drm, "PPS10 = 0x%08x\n", pps_val);508 drm_dbg_kms(&dev_priv->drm, "PPS10 = 0x%08x\n", pps_val);
650 if (!is_pipe_dsc(crtc, cpu_transcoder)) {509 intel_dsc_pps_write(crtc_state, 10, pps_val);
651 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_10,510
652 pps_val);511 /* PPS 16 */
653 /*512 pps_val = DSC_PPS16_SLICE_CHUNK_SIZE(vdsc_cfg->slice_chunk_size) |
654 * If 2 VDSC instances are needed, configure PPS for second513 DSC_PPS16_SLICE_PER_LINE((vdsc_cfg->pic_width / num_vdsc_instances) /
655 * VDSC514 vdsc_cfg->slice_width) |
656 */515 DSC_PPS16_SLICE_ROW_PER_FRAME(vdsc_cfg->pic_height /
657 if (crtc_state->dsc.dsc_split)516 vdsc_cfg->slice_height);
658 intel_de_write(dev_priv,
659 DSCC_PICTURE_PARAMETER_SET_10, pps_val);
660 } else {
661 intel_de_write(dev_priv,
662 ICL_DSC0_PICTURE_PARAMETER_SET_10(pipe),
663 pps_val);
664 if (crtc_state->dsc.dsc_split)
665 intel_de_write(dev_priv,
666 ICL_DSC1_PICTURE_PARAMETER_SET_10(pipe),
667 pps_val);
668 }
669
670 /* Populate Picture parameter set 16 */
671 pps_val = 0;
672 pps_val |= DSC_SLICE_CHUNK_SIZE(vdsc_cfg->slice_chunk_size) |
673 DSC_SLICE_PER_LINE((vdsc_cfg->pic_width / num_vdsc_instances) /
674 vdsc_cfg->slice_width) |
675 DSC_SLICE_ROW_PER_FRAME(vdsc_cfg->pic_height /
676 vdsc_cfg->slice_height);
677 drm_dbg_kms(&dev_priv->drm, "PPS16 = 0x%08x\n", pps_val);517 drm_dbg_kms(&dev_priv->drm, "PPS16 = 0x%08x\n", pps_val);
678 if (!is_pipe_dsc(crtc, cpu_transcoder)) {518 intel_dsc_pps_write(crtc_state, 16, pps_val);
679 intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_16,
680 pps_val);
681 /*
682 * If 2 VDSC instances are needed, configure PPS for second
683 * VDSC
684 */
685 if (crtc_state->dsc.dsc_split)
686 intel_de_write(dev_priv,
687 DSCC_PICTURE_PARAMETER_SET_16, pps_val);
688 } else {
689 intel_de_write(dev_priv,
690 ICL_DSC0_PICTURE_PARAMETER_SET_16(pipe),
691 pps_val);
692 if (crtc_state->dsc.dsc_split)
693 intel_de_write(dev_priv,
694 ICL_DSC1_PICTURE_PARAMETER_SET_16(pipe),
695 pps_val);
696 }
697 519
698 if (DISPLAY_VER(dev_priv) >= 14) {520 if (DISPLAY_VER(dev_priv) >= 14) {
699 /* Populate PICTURE_PARAMETER_SET_17 registers */521 /* PPS 17 */
700 pps_val = 0;522 pps_val = DSC_PPS17_SL_BPG_OFFSET(vdsc_cfg->second_line_bpg_offset);
701 pps_val |= DSC_SL_BPG_OFFSET(vdsc_cfg->second_line_bpg_offset);
702 drm_dbg_kms(&dev_priv->drm, "PPS17 = 0x%08x\n", pps_val);523 drm_dbg_kms(&dev_priv->drm, "PPS17 = 0x%08x\n", pps_val);
703 intel_de_write(dev_priv,524 intel_dsc_pps_write(crtc_state, 17, pps_val);
704 MTL_DSC0_PICTURE_PARAMETER_SET_17(pipe),
705 pps_val);
706 if (crtc_state->dsc.dsc_split)
707 intel_de_write(dev_priv,
708 MTL_DSC1_PICTURE_PARAMETER_SET_17(pipe),
709 pps_val);
710 525
711 /* Populate PICTURE_PARAMETER_SET_18 registers */526 /* PPS 18 */
712 pps_val = 0;527 pps_val = DSC_PPS18_NSL_BPG_OFFSET(vdsc_cfg->nsl_bpg_offset) |
713 pps_val |= DSC_NSL_BPG_OFFSET(vdsc_cfg->nsl_bpg_offset) |528 DSC_PPS18_SL_OFFSET_ADJ(vdsc_cfg->second_line_offset_adj);
714 DSC_SL_OFFSET_ADJ(vdsc_cfg->second_line_offset_adj);
715 drm_dbg_kms(&dev_priv->drm, "PPS18 = 0x%08x\n", pps_val);529 drm_dbg_kms(&dev_priv->drm, "PPS18 = 0x%08x\n", pps_val);
716 intel_de_write(dev_priv,530 intel_dsc_pps_write(crtc_state, 18, pps_val);
717 MTL_DSC0_PICTURE_PARAMETER_SET_18(pipe),
718 pps_val);
719 if (crtc_state->dsc.dsc_split)
720 intel_de_write(dev_priv,
721 MTL_DSC1_PICTURE_PARAMETER_SET_18(pipe),
722 pps_val);
723 }531 }
724 532
725 /* Populate the RC_BUF_THRESH registers */533 /* Populate the RC_BUF_THRESH registers */
@@ -740,7 +548,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) · 14 unmodified lines
740 rc_buf_thresh_dword[2]);548 rc_buf_thresh_dword[2]);
741 intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1_UDW,549 intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1_UDW,
742 rc_buf_thresh_dword[3]);550 rc_buf_thresh_dword[3]);
743 if (crtc_state->dsc.dsc_split) {551 if (vdsc_instances_per_pipe > 1) {
744 intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0,552 intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0,
745 rc_buf_thresh_dword[0]);553 rc_buf_thresh_dword[0]);
746 intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0_UDW,554 intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0_UDW,
@@ -759,7 +567,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) · 12 unmodified lines
759 rc_buf_thresh_dword[2]);567 rc_buf_thresh_dword[2]);
760 intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe),568 intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe),
761 rc_buf_thresh_dword[3]);569 rc_buf_thresh_dword[3]);
762 if (crtc_state->dsc.dsc_split) {570 if (vdsc_instances_per_pipe > 1) {
763 intel_de_write(dev_priv,571 intel_de_write(dev_priv,
764 ICL_DSC1_RC_BUF_THRESH_0(pipe),572 ICL_DSC1_RC_BUF_THRESH_0(pipe),
765 rc_buf_thresh_dword[0]);573 rc_buf_thresh_dword[0]);
@@ -805,7 +613,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) · 39 unmodified lines
805 rc_range_params_dword[6]);613 rc_range_params_dword[6]);
806 intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3_UDW,614 intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3_UDW,
807 rc_range_params_dword[7]);615 rc_range_params_dword[7]);
808 if (crtc_state->dsc.dsc_split) {616 if (vdsc_instances_per_pipe > 1) {
809 intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_0,617 intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_0,
810 rc_range_params_dword[0]);618 rc_range_params_dword[0]);
811 intel_de_write(dev_priv,619 intel_de_write(dev_priv,
@@ -848,7 +656,7 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) · 36 unmodified lines
848 intel_de_write(dev_priv,656 intel_de_write(dev_priv,
849 ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe),657 ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe),
850 rc_range_params_dword[7]);658 rc_range_params_dword[7]);
851 if (crtc_state->dsc.dsc_split) {659 if (vdsc_instances_per_pipe > 1) {
852 intel_de_write(dev_priv,660 intel_de_write(dev_priv,
853 ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe),661 ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe),
854 rc_range_params_dword[0]);662 rc_range_params_dword[0]);
@@ -954,6 +762,7 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state) · 99 unmodified lines
954 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);762 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
955 u32 dss_ctl1_val = 0;763 u32 dss_ctl1_val = 0;
956 u32 dss_ctl2_val = 0;764 u32 dss_ctl2_val = 0;
765 int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
957 766
958 if (!crtc_state->dsc.compression_enable)767 if (!crtc_state->dsc.compression_enable)
959 return;768 return;
@@ -961,7 +770,7 @@ void intel_dsc_enable(const struct intel_crtc_state *crtc_state) · 1 unmodified line
961 intel_dsc_pps_configure(crtc_state);770 intel_dsc_pps_configure(crtc_state);
962 771
963 dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;772 dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
964 if (crtc_state->dsc.dsc_split) {773 if (vdsc_instances_per_pipe > 1) {
965 dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;774 dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
966 dss_ctl1_val |= JOINER_ENABLE;775 dss_ctl1_val |= JOINER_ENABLE;
967 }776 }
@@ -987,16 +796,168 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) · 19 unmodified lines
987 }796 }
988}797}
989 798
799static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps,
800 bool *check_equal)
801{
802 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
803 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
804 i915_reg_t dsc_reg[2];
805 int i, vdsc_per_pipe, dsc_reg_num;
806 u32 val = 0;
807
808 vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
809 dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe);
810
811 drm_WARN_ON_ONCE(&i915->drm, dsc_reg_num < vdsc_per_pipe);
812
813 intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num);
814
815 if (check_equal)
816 *check_equal = true;
817
818 for (i = 0; i < dsc_reg_num; i++) {
819 u32 tmp;
820
821 tmp = intel_de_read(i915, dsc_reg[i]);
822
823 if (i == 0) {
824 val = tmp;
825 } else if (check_equal && tmp != val) {
826 *check_equal = false;
827 break;
828 } else if (!check_equal) {
829 break;
830 }
831 }
832
833 return val;
834}
835
836static u32 intel_dsc_pps_read_and_verify(struct intel_crtc_state *crtc_state, int pps)
837{
838 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
839 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
840 u32 val;
841 bool all_equal;
842
843 val = intel_dsc_pps_read(crtc_state, pps, &all_equal);
844 drm_WARN_ON(&i915->drm, !all_equal);
845
846 return val;
847}
848
849static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state)
850{
851 struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
852 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
853 struct drm_i915_private *i915 = to_i915(crtc->base.dev);
854 int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
855 u32 pps_temp;
856
857 /* PPS 0 */
858 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 0);
859
860 vdsc_cfg->bits_per_component = REG_FIELD_GET(DSC_PPS0_BPC_MASK, pps_temp);
861 vdsc_cfg->line_buf_depth = REG_FIELD_GET(DSC_PPS0_LINE_BUF_DEPTH_MASK, pps_temp);
862 vdsc_cfg->block_pred_enable = pps_temp & DSC_PPS0_BLOCK_PREDICTION;
863 vdsc_cfg->convert_rgb = pps_temp & DSC_PPS0_COLOR_SPACE_CONVERSION;
864 vdsc_cfg->simple_422 = pps_temp & DSC_PPS0_422_ENABLE;
865 vdsc_cfg->native_422 = pps_temp & DSC_PPS0_NATIVE_422_ENABLE;
866 vdsc_cfg->native_420 = pps_temp & DSC_PPS0_NATIVE_420_ENABLE;
867 vdsc_cfg->vbr_enable = pps_temp & DSC_PPS0_VBR_ENABLE;
868
869 /* PPS 1 */
870 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 1);
871
872 vdsc_cfg->bits_per_pixel = REG_FIELD_GET(DSC_PPS1_BPP_MASK, pps_temp);
873
874 if (vdsc_cfg->native_420)
875 vdsc_cfg->bits_per_pixel >>= 1;
876
877 crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
878
879 /* PPS 2 */
880 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 2);
881
882 vdsc_cfg->pic_width = REG_FIELD_GET(DSC_PPS2_PIC_WIDTH_MASK, pps_temp) * num_vdsc_instances;
883 vdsc_cfg->pic_height = REG_FIELD_GET(DSC_PPS2_PIC_HEIGHT_MASK, pps_temp);
884
885 /* PPS 3 */
886 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 3);
887
888 vdsc_cfg->slice_width = REG_FIELD_GET(DSC_PPS3_SLICE_WIDTH_MASK, pps_temp);
889 vdsc_cfg->slice_height = REG_FIELD_GET(DSC_PPS3_SLICE_HEIGHT_MASK, pps_temp);
890
891 /* PPS 4 */
892 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 4);
893
894 vdsc_cfg->initial_dec_delay = REG_FIELD_GET(DSC_PPS4_INITIAL_DEC_DELAY_MASK, pps_temp);
895 vdsc_cfg->initial_xmit_delay = REG_FIELD_GET(DSC_PPS4_INITIAL_XMIT_DELAY_MASK, pps_temp);
896
897 /* PPS 5 */
898 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 5);
899
900 vdsc_cfg->scale_decrement_interval = REG_FIELD_GET(DSC_PPS5_SCALE_DEC_INT_MASK, pps_temp);
901 vdsc_cfg->scale_increment_interval = REG_FIELD_GET(DSC_PPS5_SCALE_INC_INT_MASK, pps_temp);
902
903 /* PPS 6 */
904 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 6);
905
906 vdsc_cfg->initial_scale_value = REG_FIELD_GET(DSC_PPS6_INITIAL_SCALE_VALUE_MASK, pps_temp);
907 vdsc_cfg->first_line_bpg_offset = REG_FIELD_GET(DSC_PPS6_FIRST_LINE_BPG_OFFSET_MASK, pps_temp);
908 vdsc_cfg->flatness_min_qp = REG_FIELD_GET(DSC_PPS6_FLATNESS_MIN_QP_MASK, pps_temp);
909 vdsc_cfg->flatness_max_qp = REG_FIELD_GET(DSC_PPS6_FLATNESS_MAX_QP_MASK, pps_temp);
910
911 /* PPS 7 */
912 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 7);
913
914 vdsc_cfg->nfl_bpg_offset = REG_FIELD_GET(DSC_PPS7_NFL_BPG_OFFSET_MASK, pps_temp);
915 vdsc_cfg->slice_bpg_offset = REG_FIELD_GET(DSC_PPS7_SLICE_BPG_OFFSET_MASK, pps_temp);
916
917 /* PPS 8 */
918 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 8);
919
920 vdsc_cfg->initial_offset = REG_FIELD_GET(DSC_PPS8_INITIAL_OFFSET_MASK, pps_temp);
921 vdsc_cfg->final_offset = REG_FIELD_GET(DSC_PPS8_FINAL_OFFSET_MASK, pps_temp);
922
923 /* PPS 9 */
924 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 9);
925
926 vdsc_cfg->rc_model_size = REG_FIELD_GET(DSC_PPS9_RC_MODEL_SIZE_MASK, pps_temp);
927
928 /* PPS 10 */
929 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 10);
930
931 vdsc_cfg->rc_quant_incr_limit0 = REG_FIELD_GET(DSC_PPS10_RC_QUANT_INC_LIMIT0_MASK, pps_temp);
932 vdsc_cfg->rc_quant_incr_limit1 = REG_FIELD_GET(DSC_PPS10_RC_QUANT_INC_LIMIT1_MASK, pps_temp);
933
934 /* PPS 16 */
935 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 16);
936
937 vdsc_cfg->slice_chunk_size = REG_FIELD_GET(DSC_PPS16_SLICE_CHUNK_SIZE_MASK, pps_temp);
938
939 if (DISPLAY_VER(i915) >= 14) {
940 /* PPS 17 */
941 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 17);
942
943 vdsc_cfg->second_line_bpg_offset = REG_FIELD_GET(DSC_PPS17_SL_BPG_OFFSET_MASK, pps_temp);
944
945 /* PPS 18 */
946 pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 18);
947
948 vdsc_cfg->nsl_bpg_offset = REG_FIELD_GET(DSC_PPS18_NSL_BPG_OFFSET_MASK, pps_temp);
949 vdsc_cfg->second_line_offset_adj = REG_FIELD_GET(DSC_PPS18_SL_OFFSET_ADJ_MASK, pps_temp);
950 }
951}
952
990void intel_dsc_get_config(struct intel_crtc_state *crtc_state)953void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
991{954{
992 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);955 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
993 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);956 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
994 struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
995 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;957 enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
996 enum pipe pipe = crtc->pipe;
997 enum intel_display_power_domain power_domain;958 enum intel_display_power_domain power_domain;
998 intel_wakeref_t wakeref;959 intel_wakeref_t wakeref;
999 u32 dss_ctl1, dss_ctl2, pps0 = 0, pps1 = 0;960 u32 dss_ctl1, dss_ctl2;
1000 961
1001 if (!intel_dsc_source_support(crtc_state))962 if (!intel_dsc_source_support(crtc_state))
1002 return;963 return;
@@ -1017,24 +978,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) · 14 unmodified lines
1017 crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&978 crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
1018 (dss_ctl1 & JOINER_ENABLE);979 (dss_ctl1 & JOINER_ENABLE);
1019 980
1020 /* FIXME: add more state readout as needed */981 intel_dsc_get_pps_config(crtc_state);
1021
1022 /* PPS0 & PPS1 */
1023 if (!is_pipe_dsc(crtc, cpu_transcoder)) {
1024 pps1 = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
1025 } else {
1026 pps0 = intel_de_read(dev_priv,
1027 ICL_DSC0_PICTURE_PARAMETER_SET_0(pipe));
1028 pps1 = intel_de_read(dev_priv,
1029 ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
1030 }
1031
1032 vdsc_cfg->bits_per_pixel = pps1;
1033
1034 if (pps0 & DSC_NATIVE_420_ENABLE)
1035 vdsc_cfg->bits_per_pixel >>= 1;
1036
1037 crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
1038out:982out:
1039 intel_display_power_put(dev_priv, power_domain, wakeref);983 intel_display_power_put(dev_priv, power_domain, wakeref);
1040}984}
drivers/gpu/drm/i915/display/intel_vdsc_regs.h+126−271
@@ -46,35 +46,13 @@ · 45 unmodified lines
46 _ICL_PIPE_DSS_CTL2_PB, \46 _ICL_PIPE_DSS_CTL2_PB, \
47 _ICL_PIPE_DSS_CTL2_PC)47 _ICL_PIPE_DSS_CTL2_PC)
48 48
49/* MTL Display Stream Compression registers */
50#define _MTL_DSC0_PICTURE_PARAMETER_SET_17_PB 0x782B4
51#define _MTL_DSC1_PICTURE_PARAMETER_SET_17_PB 0x783B4
52#define _MTL_DSC0_PICTURE_PARAMETER_SET_17_PC 0x784B4
53#define _MTL_DSC1_PICTURE_PARAMETER_SET_17_PC 0x785B4
54#define MTL_DSC0_PICTURE_PARAMETER_SET_17(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
55 _MTL_DSC0_PICTURE_PARAMETER_SET_17_PB, \
56 _MTL_DSC0_PICTURE_PARAMETER_SET_17_PC)
57#define MTL_DSC1_PICTURE_PARAMETER_SET_17(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
58 _MTL_DSC1_PICTURE_PARAMETER_SET_17_PB, \
59 _MTL_DSC1_PICTURE_PARAMETER_SET_17_PC)
60#define DSC_SL_BPG_OFFSET(offset) ((offset) << 27)
61
62#define _MTL_DSC0_PICTURE_PARAMETER_SET_18_PB 0x782B8
63#define _MTL_DSC1_PICTURE_PARAMETER_SET_18_PB 0x783B8
64#define _MTL_DSC0_PICTURE_PARAMETER_SET_18_PC 0x784B8
65#define _MTL_DSC1_PICTURE_PARAMETER_SET_18_PC 0x785B8
66#define MTL_DSC0_PICTURE_PARAMETER_SET_18(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
67 _MTL_DSC0_PICTURE_PARAMETER_SET_18_PB, \
68 _MTL_DSC0_PICTURE_PARAMETER_SET_18_PC)
69#define MTL_DSC1_PICTURE_PARAMETER_SET_18(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
70 _MTL_DSC1_PICTURE_PARAMETER_SET_18_PB, \
71 _MTL_DSC1_PICTURE_PARAMETER_SET_18_PC)
72#define DSC_NSL_BPG_OFFSET(offset) ((offset) << 16)
73#define DSC_SL_OFFSET_ADJ(offset) ((offset) << 0)
74
75/* Icelake Display Stream Compression Registers */49/* Icelake Display Stream Compression Registers */
76#define DSCA_PICTURE_PARAMETER_SET_0 _MMIO(0x6B200)50#define DSCA_PICTURE_PARAMETER_SET_0 _MMIO(0x6B200)
77#define DSCC_PICTURE_PARAMETER_SET_0 _MMIO(0x6BA00)51#define DSCC_PICTURE_PARAMETER_SET_0 _MMIO(0x6BA00)
52#define _DSCA_PPS_0 0x6B200
53#define _DSCC_PPS_0 0x6BA00
54#define DSCA_PPS(pps) _MMIO(_DSCA_PPS_0 + (pps) * 4)
55#define DSCC_PPS(pps) _MMIO(_DSCC_PPS_0 + (pps) * 4)
78#define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PB 0x7827056#define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PB 0x78270
79#define _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB 0x7837057#define _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB 0x78370
80#define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PC 0x7847058#define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PC 0x78470
@@ -85,251 +63,128 @@ · 4 unmodified lines
85#define ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe) _MMIO_PIPE((pipe) - PIPE_B, \63#define ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
86 _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB, \64 _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB, \
87 _ICL_DSC1_PICTURE_PARAMETER_SET_0_PC)65 _ICL_DSC1_PICTURE_PARAMETER_SET_0_PC)
88#define DSC_NATIVE_422_ENABLE BIT(23)66#define _ICL_DSC0_PPS_0(pipe) _PICK_EVEN((pipe) - PIPE_B, \
89#define DSC_NATIVE_420_ENABLE BIT(22)67 _ICL_DSC0_PICTURE_PARAMETER_SET_0_PB, \
90#define DSC_ALT_ICH_SEL (1 << 20)68 _ICL_DSC0_PICTURE_PARAMETER_SET_0_PC)
91#define DSC_VBR_ENABLE (1 << 19)69#define _ICL_DSC1_PPS_0(pipe) _PICK_EVEN((pipe) - PIPE_B, \
92#define DSC_422_ENABLE (1 << 18)70 _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB, \
93#define DSC_COLOR_SPACE_CONVERSION (1 << 17)71 _ICL_DSC1_PICTURE_PARAMETER_SET_0_PC)
94#define DSC_BLOCK_PREDICTION (1 << 16)72#define ICL_DSC0_PPS(pipe, pps) _MMIO(_ICL_DSC0_PPS_0(pipe) + ((pps) * 4))
95#define DSC_LINE_BUF_DEPTH_SHIFT 1273#define ICL_DSC1_PPS(pipe, pps) _MMIO(_ICL_DSC1_PPS_0(pipe) + ((pps) * 4))
96#define DSC_BPC_SHIFT 874
97#define DSC_VER_MIN_SHIFT 475/* PPS 0 */
98#define DSC_VER_MAJ (0x1 << 0)76#define DSC_PPS0_NATIVE_422_ENABLE REG_BIT(23)
99 77#define DSC_PPS0_NATIVE_420_ENABLE REG_BIT(22)
100#define DSCA_PICTURE_PARAMETER_SET_1 _MMIO(0x6B204)78#define DSC_PPS0_ALT_ICH_SEL REG_BIT(20)
101#define DSCC_PICTURE_PARAMETER_SET_1 _MMIO(0x6BA04)79#define DSC_PPS0_VBR_ENABLE REG_BIT(19)
102#define _ICL_DSC0_PICTURE_PARAMETER_SET_1_PB 0x7827480#define DSC_PPS0_422_ENABLE REG_BIT(18)
103#define _ICL_DSC1_PICTURE_PARAMETER_SET_1_PB 0x7837481#define DSC_PPS0_COLOR_SPACE_CONVERSION REG_BIT(17)
104#define _ICL_DSC0_PICTURE_PARAMETER_SET_1_PC 0x7847482#define DSC_PPS0_BLOCK_PREDICTION REG_BIT(16)
105#define _ICL_DSC1_PICTURE_PARAMETER_SET_1_PC 0x7857483#define DSC_PPS0_LINE_BUF_DEPTH_MASK REG_GENMASK(15, 12)
106#define ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe) _MMIO_PIPE((pipe) - PIPE_B, \84#define DSC_PPS0_LINE_BUF_DEPTH(depth) REG_FIELD_PREP(DSC_PPS0_LINE_BUF_DEPTH_MASK, depth)
107 _ICL_DSC0_PICTURE_PARAMETER_SET_1_PB, \85#define DSC_PPS0_BPC_MASK REG_GENMASK(11, 8)
108 _ICL_DSC0_PICTURE_PARAMETER_SET_1_PC)86#define DSC_PPS0_BPC(bpc) REG_FIELD_PREP(DSC_PPS0_BPC_MASK, bpc)
109#define ICL_DSC1_PICTURE_PARAMETER_SET_1(pipe) _MMIO_PIPE((pipe) - PIPE_B, \87#define DSC_PPS0_VER_MINOR_MASK REG_GENMASK(7, 4)
110 _ICL_DSC1_PICTURE_PARAMETER_SET_1_PB, \88#define DSC_PPS0_VER_MINOR(minor) REG_FIELD_PREP(DSC_PPS0_VER_MINOR_MASK, minor)
111 _ICL_DSC1_PICTURE_PARAMETER_SET_1_PC)89#define DSC_PPS0_VER_MAJOR_MASK REG_GENMASK(3, 0)
112#define DSC_BPP(bpp) ((bpp) << 0)90#define DSC_PPS0_VER_MAJOR(major) REG_FIELD_PREP(DSC_PPS0_VER_MAJOR_MASK, major)
113 91
114#define DSCA_PICTURE_PARAMETER_SET_2 _MMIO(0x6B208)92/* PPS 1 */
115#define DSCC_PICTURE_PARAMETER_SET_2 _MMIO(0x6BA08)93#define DSC_PPS1_BPP_MASK REG_GENMASK(9, 0)
116#define _ICL_DSC0_PICTURE_PARAMETER_SET_2_PB 0x7827894#define DSC_PPS1_BPP(bpp) REG_FIELD_PREP(DSC_PPS1_BPP_MASK, bpp)
117#define _ICL_DSC1_PICTURE_PARAMETER_SET_2_PB 0x7837895
118#define _ICL_DSC0_PICTURE_PARAMETER_SET_2_PC 0x7847896/* PPS 2 */
119#define _ICL_DSC1_PICTURE_PARAMETER_SET_2_PC 0x7857897#define DSC_PPS2_PIC_WIDTH_MASK REG_GENMASK(31, 16)
120#define ICL_DSC0_PICTURE_PARAMETER_SET_2(pipe) _MMIO_PIPE((pipe) - PIPE_B, \98#define DSC_PPS2_PIC_HEIGHT_MASK REG_GENMASK(15, 0)
121 _ICL_DSC0_PICTURE_PARAMETER_SET_2_PB, \99#define DSC_PPS2_PIC_WIDTH(pic_width) REG_FIELD_PREP(DSC_PPS2_PIC_WIDTH_MASK, pic_width)
122 _ICL_DSC0_PICTURE_PARAMETER_SET_2_PC)100#define DSC_PPS2_PIC_HEIGHT(pic_height) REG_FIELD_PREP(DSC_PPS2_PIC_HEIGHT_MASK, pic_height)
123#define ICL_DSC1_PICTURE_PARAMETER_SET_2(pipe) _MMIO_PIPE((pipe) - PIPE_B, \101
124 _ICL_DSC1_PICTURE_PARAMETER_SET_2_PB, \102/* PPS 3 */
125 _ICL_DSC1_PICTURE_PARAMETER_SET_2_PC)103#define DSC_PPS3_SLICE_WIDTH_MASK REG_GENMASK(31, 16)
126#define DSC_PIC_WIDTH(pic_width) ((pic_width) << 16)104#define DSC_PPS3_SLICE_HEIGHT_MASK REG_GENMASK(15, 0)
127#define DSC_PIC_HEIGHT(pic_height) ((pic_height) << 0)105#define DSC_PPS3_SLICE_WIDTH(slice_width) REG_FIELD_PREP(DSC_PPS3_SLICE_WIDTH_MASK, slice_width)
128 106#define DSC_PPS3_SLICE_HEIGHT(slice_height) REG_FIELD_PREP(DSC_PPS3_SLICE_HEIGHT_MASK, slice_height)
129#define DSCA_PICTURE_PARAMETER_SET_3 _MMIO(0x6B20C)107
130#define DSCC_PICTURE_PARAMETER_SET_3 _MMIO(0x6BA0C)108/* PPS 4 */
131#define _ICL_DSC0_PICTURE_PARAMETER_SET_3_PB 0x7827C109#define DSC_PPS4_INITIAL_DEC_DELAY_MASK REG_GENMASK(31, 16)
132#define _ICL_DSC1_PICTURE_PARAMETER_SET_3_PB 0x7837C110#define DSC_PPS4_INITIAL_XMIT_DELAY_MASK REG_GENMASK(9, 0)
133#define _ICL_DSC0_PICTURE_PARAMETER_SET_3_PC 0x7847C111#define DSC_PPS4_INITIAL_DEC_DELAY(dec_delay) REG_FIELD_PREP(DSC_PPS4_INITIAL_DEC_DELAY_MASK, \
134#define _ICL_DSC1_PICTURE_PARAMETER_SET_3_PC 0x7857C112 dec_delay)
135#define ICL_DSC0_PICTURE_PARAMETER_SET_3(pipe) _MMIO_PIPE((pipe) - PIPE_B, \113#define DSC_PPS4_INITIAL_XMIT_DELAY(xmit_delay) REG_FIELD_PREP(DSC_PPS4_INITIAL_XMIT_DELAY_MASK, \
136 _ICL_DSC0_PICTURE_PARAMETER_SET_3_PB, \114 xmit_delay)
137 _ICL_DSC0_PICTURE_PARAMETER_SET_3_PC)115
138#define ICL_DSC1_PICTURE_PARAMETER_SET_3(pipe) _MMIO_PIPE((pipe) - PIPE_B, \116/* PPS 5 */
139 _ICL_DSC1_PICTURE_PARAMETER_SET_3_PB, \117#define DSC_PPS5_SCALE_DEC_INT_MASK REG_GENMASK(27, 16)
140 _ICL_DSC1_PICTURE_PARAMETER_SET_3_PC)118#define DSC_PPS5_SCALE_INC_INT_MASK REG_GENMASK(15, 0)
141#define DSC_SLICE_WIDTH(slice_width) ((slice_width) << 16)119#define DSC_PPS5_SCALE_DEC_INT(scale_dec) REG_FIELD_PREP(DSC_PPS5_SCALE_DEC_INT_MASK, scale_dec)
142#define DSC_SLICE_HEIGHT(slice_height) ((slice_height) << 0)120#define DSC_PPS5_SCALE_INC_INT(scale_inc) REG_FIELD_PREP(DSC_PPS5_SCALE_INC_INT_MASK, scale_inc)
143 121
144#define DSCA_PICTURE_PARAMETER_SET_4 _MMIO(0x6B210)122/* PPS 6 */
145#define DSCC_PICTURE_PARAMETER_SET_4 _MMIO(0x6BA10)123#define DSC_PPS6_FLATNESS_MAX_QP_MASK REG_GENMASK(28, 24)
146#define _ICL_DSC0_PICTURE_PARAMETER_SET_4_PB 0x78280124#define DSC_PPS6_FLATNESS_MIN_QP_MASK REG_GENMASK(20, 16)
147#define _ICL_DSC1_PICTURE_PARAMETER_SET_4_PB 0x78380125#define DSC_PPS6_FIRST_LINE_BPG_OFFSET_MASK REG_GENMASK(12, 8)
148#define _ICL_DSC0_PICTURE_PARAMETER_SET_4_PC 0x78480126#define DSC_PPS6_INITIAL_SCALE_VALUE_MASK REG_GENMASK(5, 0)
149#define _ICL_DSC1_PICTURE_PARAMETER_SET_4_PC 0x78580127#define DSC_PPS6_FLATNESS_MAX_QP(max_qp) REG_FIELD_PREP(DSC_PPS6_FLATNESS_MAX_QP_MASK, max_qp)
150#define ICL_DSC0_PICTURE_PARAMETER_SET_4(pipe) _MMIO_PIPE((pipe) - PIPE_B, \128#define DSC_PPS6_FLATNESS_MIN_QP(min_qp) REG_FIELD_PREP(DSC_PPS6_FLATNESS_MIN_QP_MASK, min_qp)
151 _ICL_DSC0_PICTURE_PARAMETER_SET_4_PB, \129#define DSC_PPS6_FIRST_LINE_BPG_OFFSET(offset) REG_FIELD_PREP(DSC_PPS6_FIRST_LINE_BPG_OFFSET_MASK, \
152 _ICL_DSC0_PICTURE_PARAMETER_SET_4_PC)130 offset)
153#define ICL_DSC1_PICTURE_PARAMETER_SET_4(pipe) _MMIO_PIPE((pipe) - PIPE_B, \131#define DSC_PPS6_INITIAL_SCALE_VALUE(value) REG_FIELD_PREP(DSC_PPS6_INITIAL_SCALE_VALUE_MASK, \
154 _ICL_DSC1_PICTURE_PARAMETER_SET_4_PB, \132 value)
155 _ICL_DSC1_PICTURE_PARAMETER_SET_4_PC)133
156#define DSC_INITIAL_DEC_DELAY(dec_delay) ((dec_delay) << 16)134/* PPS 7 */
157#define DSC_INITIAL_XMIT_DELAY(xmit_delay) ((xmit_delay) << 0)135#define DSC_PPS7_NFL_BPG_OFFSET_MASK REG_GENMASK(31, 16)
158 136#define DSC_PPS7_SLICE_BPG_OFFSET_MASK REG_GENMASK(15, 0)
159#define DSCA_PICTURE_PARAMETER_SET_5 _MMIO(0x6B214)137#define DSC_PPS7_NFL_BPG_OFFSET(bpg_offset) REG_FIELD_PREP(DSC_PPS7_NFL_BPG_OFFSET_MASK, bpg_offset)
160#define DSCC_PICTURE_PARAMETER_SET_5 _MMIO(0x6BA14)138#define DSC_PPS7_SLICE_BPG_OFFSET(bpg_offset) REG_FIELD_PREP(DSC_PPS7_SLICE_BPG_OFFSET_MASK, \
161#define _ICL_DSC0_PICTURE_PARAMETER_SET_5_PB 0x78284139 bpg_offset)
162#define _ICL_DSC1_PICTURE_PARAMETER_SET_5_PB 0x78384140/* PPS 8 */
163#define _ICL_DSC0_PICTURE_PARAMETER_SET_5_PC 0x78484141#define DSC_PPS8_INITIAL_OFFSET_MASK REG_GENMASK(31, 16)
164#define _ICL_DSC1_PICTURE_PARAMETER_SET_5_PC 0x78584142#define DSC_PPS8_FINAL_OFFSET_MASK REG_GENMASK(15, 0)
165#define ICL_DSC0_PICTURE_PARAMETER_SET_5(pipe) _MMIO_PIPE((pipe) - PIPE_B, \143#define DSC_PPS8_INITIAL_OFFSET(initial_offset) REG_FIELD_PREP(DSC_PPS8_INITIAL_OFFSET_MASK, \
166 _ICL_DSC0_PICTURE_PARAMETER_SET_5_PB, \144 initial_offset)
167 _ICL_DSC0_PICTURE_PARAMETER_SET_5_PC)145#define DSC_PPS8_FINAL_OFFSET(final_offset) REG_FIELD_PREP(DSC_PPS8_FINAL_OFFSET_MASK, \
168#define ICL_DSC1_PICTURE_PARAMETER_SET_5(pipe) _MMIO_PIPE((pipe) - PIPE_B, \146 final_offset)
169 _ICL_DSC1_PICTURE_PARAMETER_SET_5_PB, \147
170 _ICL_DSC1_PICTURE_PARAMETER_SET_5_PC)148/* PPS 9 */
171#define DSC_SCALE_DEC_INT(scale_dec) ((scale_dec) << 16)149#define DSC_PPS9_RC_EDGE_FACTOR_MASK REG_GENMASK(19, 16)
172#define DSC_SCALE_INC_INT(scale_inc) ((scale_inc) << 0)150#define DSC_PPS9_RC_MODEL_SIZE_MASK REG_GENMASK(15, 0)
173 151#define DSC_PPS9_RC_EDGE_FACTOR(rc_edge_fact) REG_FIELD_PREP(DSC_PPS9_RC_EDGE_FACTOR_MASK, \
174#define DSCA_PICTURE_PARAMETER_SET_6 _MMIO(0x6B218)152 rc_edge_fact)
175#define DSCC_PICTURE_PARAMETER_SET_6 _MMIO(0x6BA18)153#define DSC_PPS9_RC_MODEL_SIZE(rc_model_size) REG_FIELD_PREP(DSC_PPS9_RC_MODEL_SIZE_MASK, \
176#define _ICL_DSC0_PICTURE_PARAMETER_SET_6_PB 0x78288154 rc_model_size)
177#define _ICL_DSC1_PICTURE_PARAMETER_SET_6_PB 0x78388155
178#define _ICL_DSC0_PICTURE_PARAMETER_SET_6_PC 0x78488156/* PPS 10 */
179#define _ICL_DSC1_PICTURE_PARAMETER_SET_6_PC 0x78588157#define DSC_PPS10_RC_TGT_OFF_LOW_MASK REG_GENMASK(23, 20)
180#define ICL_DSC0_PICTURE_PARAMETER_SET_6(pipe) _MMIO_PIPE((pipe) - PIPE_B, \158#define DSC_PPS10_RC_TGT_OFF_HIGH_MASK REG_GENMASK(19, 16)
181 _ICL_DSC0_PICTURE_PARAMETER_SET_6_PB, \159#define DSC_PPS10_RC_QUANT_INC_LIMIT1_MASK REG_GENMASK(12, 8)
182 _ICL_DSC0_PICTURE_PARAMETER_SET_6_PC)160#define DSC_PPS10_RC_QUANT_INC_LIMIT0_MASK REG_GENMASK(4, 0)
183#define ICL_DSC1_PICTURE_PARAMETER_SET_6(pipe) _MMIO_PIPE((pipe) - PIPE_B, \161#define DSC_PPS10_RC_TARGET_OFF_LOW(rc_tgt_off_low) REG_FIELD_PREP(DSC_PPS10_RC_TGT_OFF_LOW_MASK, \
184 _ICL_DSC1_PICTURE_PARAMETER_SET_6_PB, \162 rc_tgt_off_low)
185 _ICL_DSC1_PICTURE_PARAMETER_SET_6_PC)163#define DSC_PPS10_RC_TARGET_OFF_HIGH(rc_tgt_off_high) REG_FIELD_PREP(DSC_PPS10_RC_TGT_OFF_HIGH_MASK, \
186#define DSC_FLATNESS_MAX_QP(max_qp) ((max_qp) << 24)164 rc_tgt_off_high)
187#define DSC_FLATNESS_MIN_QP(min_qp) ((min_qp) << 16)165#define DSC_PPS10_RC_QUANT_INC_LIMIT1(lim) REG_FIELD_PREP(DSC_PPS10_RC_QUANT_INC_LIMIT1_MASK, lim)
188#define DSC_FIRST_LINE_BPG_OFFSET(offset) ((offset) << 8)166#define DSC_PPS10_RC_QUANT_INC_LIMIT0(lim) REG_FIELD_PREP(DSC_PPS10_RC_QUANT_INC_LIMIT0_MASK, lim)
189#define DSC_INITIAL_SCALE_VALUE(value) ((value) << 0)167
190 168/* PPS 16 */
191#define DSCA_PICTURE_PARAMETER_SET_7 _MMIO(0x6B21C)169#define DSC_PPS16_SLICE_ROW_PR_FRME_MASK REG_GENMASK(31, 20)
192#define DSCC_PICTURE_PARAMETER_SET_7 _MMIO(0x6BA1C)170#define DSC_PPS16_SLICE_PER_LINE_MASK REG_GENMASK(18, 16)
193#define _ICL_DSC0_PICTURE_PARAMETER_SET_7_PB 0x7828C171#define DSC_PPS16_SLICE_CHUNK_SIZE_MASK REG_GENMASK(15, 0)
194#define _ICL_DSC1_PICTURE_PARAMETER_SET_7_PB 0x7838C172#define DSC_PPS16_SLICE_ROW_PER_FRAME(slice_row_per_frame) REG_FIELD_PREP(DSC_PPS16_SLICE_ROW_PR_FRME_MASK, \
195#define _ICL_DSC0_PICTURE_PARAMETER_SET_7_PC 0x7848C173 slice_row_per_frame)
196#define _ICL_DSC1_PICTURE_PARAMETER_SET_7_PC 0x7858C174#define DSC_PPS16_SLICE_PER_LINE(slice_per_line) REG_FIELD_PREP(DSC_PPS16_SLICE_PER_LINE_MASK, \
197#define ICL_DSC0_PICTURE_PARAMETER_SET_7(pipe) _MMIO_PIPE((pipe) - PIPE_B, \175 slice_per_line)
198 _ICL_DSC0_PICTURE_PARAMETER_SET_7_PB, \176#define DSC_PPS16_SLICE_CHUNK_SIZE(slice_chunk_size) REG_FIELD_PREP(DSC_PPS16_SLICE_CHUNK_SIZE_MASK, \
199 _ICL_DSC0_PICTURE_PARAMETER_SET_7_PC)177 slice_chunk_size)
200#define ICL_DSC1_PICTURE_PARAMETER_SET_7(pipe) _MMIO_PIPE((pipe) - PIPE_B, \178
201 _ICL_DSC1_PICTURE_PARAMETER_SET_7_PB, \179/* PPS 17 (MTL+) */
202 _ICL_DSC1_PICTURE_PARAMETER_SET_7_PC)180#define DSC_PPS17_SL_BPG_OFFSET_MASK REG_GENMASK(31, 27)
203#define DSC_NFL_BPG_OFFSET(bpg_offset) ((bpg_offset) << 16)181#define DSC_PPS17_SL_BPG_OFFSET(offset) REG_FIELD_PREP(DSC_PPS17_SL_BPG_OFFSET_MASK, offset)
204#define DSC_SLICE_BPG_OFFSET(bpg_offset) ((bpg_offset) << 0)182
205 183/* PPS 18 (MTL+) */
206#define DSCA_PICTURE_PARAMETER_SET_8 _MMIO(0x6B220)184#define DSC_PPS18_NSL_BPG_OFFSET_MASK REG_GENMASK(31, 16)
207#define DSCC_PICTURE_PARAMETER_SET_8 _MMIO(0x6BA20)185#define DSC_PPS18_SL_OFFSET_ADJ_MASK REG_GENMASK(15, 0)
208#define _ICL_DSC0_PICTURE_PARAMETER_SET_8_PB 0x78290186#define DSC_PPS18_NSL_BPG_OFFSET(offset) REG_FIELD_PREP(DSC_PPS18_NSL_BPG_OFFSET_MASK, offset)
209#define _ICL_DSC1_PICTURE_PARAMETER_SET_8_PB 0x78390187#define DSC_PPS18_SL_OFFSET_ADJ(offset) REG_FIELD_PREP(DSC_PPS18_SL_OFFSET_ADJ_MASK, offset)
210#define _ICL_DSC0_PICTURE_PARAMETER_SET_8_PC 0x78490
211#define _ICL_DSC1_PICTURE_PARAMETER_SET_8_PC 0x78590
212#define ICL_DSC0_PICTURE_PARAMETER_SET_8(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
213 _ICL_DSC0_PICTURE_PARAMETER_SET_8_PB, \
214 _ICL_DSC0_PICTURE_PARAMETER_SET_8_PC)
215#define ICL_DSC1_PICTURE_PARAMETER_SET_8(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
216 _ICL_DSC1_PICTURE_PARAMETER_SET_8_PB, \
217 _ICL_DSC1_PICTURE_PARAMETER_SET_8_PC)
218#define DSC_INITIAL_OFFSET(initial_offset) ((initial_offset) << 16)
219#define DSC_FINAL_OFFSET(final_offset) ((final_offset) << 0)
220
221#define DSCA_PICTURE_PARAMETER_SET_9 _MMIO(0x6B224)
222#define DSCC_PICTURE_PARAMETER_SET_9 _MMIO(0x6BA24)
223#define _ICL_DSC0_PICTURE_PARAMETER_SET_9_PB 0x78294
224#define _ICL_DSC1_PICTURE_PARAMETER_SET_9_PB 0x78394
225#define _ICL_DSC0_PICTURE_PARAMETER_SET_9_PC 0x78494
226#define _ICL_DSC1_PICTURE_PARAMETER_SET_9_PC 0x78594
227#define ICL_DSC0_PICTURE_PARAMETER_SET_9(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
228 _ICL_DSC0_PICTURE_PARAMETER_SET_9_PB, \
229 _ICL_DSC0_PICTURE_PARAMETER_SET_9_PC)
230#define ICL_DSC1_PICTURE_PARAMETER_SET_9(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
231 _ICL_DSC1_PICTURE_PARAMETER_SET_9_PB, \
232 _ICL_DSC1_PICTURE_PARAMETER_SET_9_PC)
233#define DSC_RC_EDGE_FACTOR(rc_edge_fact) ((rc_edge_fact) << 16)
234#define DSC_RC_MODEL_SIZE(rc_model_size) ((rc_model_size) << 0)
235
236#define DSCA_PICTURE_PARAMETER_SET_10 _MMIO(0x6B228)
237#define DSCC_PICTURE_PARAMETER_SET_10 _MMIO(0x6BA28)
238#define _ICL_DSC0_PICTURE_PARAMETER_SET_10_PB 0x78298
239#define _ICL_DSC1_PICTURE_PARAMETER_SET_10_PB 0x78398
240#define _ICL_DSC0_PICTURE_PARAMETER_SET_10_PC 0x78498
241#define _ICL_DSC1_PICTURE_PARAMETER_SET_10_PC 0x78598
242#define ICL_DSC0_PICTURE_PARAMETER_SET_10(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
243 _ICL_DSC0_PICTURE_PARAMETER_SET_10_PB, \
244 _ICL_DSC0_PICTURE_PARAMETER_SET_10_PC)
245#define ICL_DSC1_PICTURE_PARAMETER_SET_10(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
246 _ICL_DSC1_PICTURE_PARAMETER_SET_10_PB, \
247 _ICL_DSC1_PICTURE_PARAMETER_SET_10_PC)
248#define DSC_RC_TARGET_OFF_LOW(rc_tgt_off_low) ((rc_tgt_off_low) << 20)
249#define DSC_RC_TARGET_OFF_HIGH(rc_tgt_off_high) ((rc_tgt_off_high) << 16)
250#define DSC_RC_QUANT_INC_LIMIT1(lim) ((lim) << 8)
251#define DSC_RC_QUANT_INC_LIMIT0(lim) ((lim) << 0)
252
253#define DSCA_PICTURE_PARAMETER_SET_11 _MMIO(0x6B22C)
254#define DSCC_PICTURE_PARAMETER_SET_11 _MMIO(0x6BA2C)
255#define _ICL_DSC0_PICTURE_PARAMETER_SET_11_PB 0x7829C
256#define _ICL_DSC1_PICTURE_PARAMETER_SET_11_PB 0x7839C
257#define _ICL_DSC0_PICTURE_PARAMETER_SET_11_PC 0x7849C
258#define _ICL_DSC1_PICTURE_PARAMETER_SET_11_PC 0x7859C
259#define ICL_DSC0_PICTURE_PARAMETER_SET_11(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
260 _ICL_DSC0_PICTURE_PARAMETER_SET_11_PB, \
261 _ICL_DSC0_PICTURE_PARAMETER_SET_11_PC)
262#define ICL_DSC1_PICTURE_PARAMETER_SET_11(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
263 _ICL_DSC1_PICTURE_PARAMETER_SET_11_PB, \
264 _ICL_DSC1_PICTURE_PARAMETER_SET_11_PC)
265
266#define DSCA_PICTURE_PARAMETER_SET_12 _MMIO(0x6B260)
267#define DSCC_PICTURE_PARAMETER_SET_12 _MMIO(0x6BA60)
268#define _ICL_DSC0_PICTURE_PARAMETER_SET_12_PB 0x782A0
269#define _ICL_DSC1_PICTURE_PARAMETER_SET_12_PB 0x783A0
270#define _ICL_DSC0_PICTURE_PARAMETER_SET_12_PC 0x784A0
271#define _ICL_DSC1_PICTURE_PARAMETER_SET_12_PC 0x785A0
272#define ICL_DSC0_PICTURE_PARAMETER_SET_12(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
273 _ICL_DSC0_PICTURE_PARAMETER_SET_12_PB, \
274 _ICL_DSC0_PICTURE_PARAMETER_SET_12_PC)
275#define ICL_DSC1_PICTURE_PARAMETER_SET_12(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
276 _ICL_DSC1_PICTURE_PARAMETER_SET_12_PB, \
277 _ICL_DSC1_PICTURE_PARAMETER_SET_12_PC)
278
279#define DSCA_PICTURE_PARAMETER_SET_13 _MMIO(0x6B264)
280#define DSCC_PICTURE_PARAMETER_SET_13 _MMIO(0x6BA64)
281#define _ICL_DSC0_PICTURE_PARAMETER_SET_13_PB 0x782A4
282#define _ICL_DSC1_PICTURE_PARAMETER_SET_13_PB 0x783A4
283#define _ICL_DSC0_PICTURE_PARAMETER_SET_13_PC 0x784A4
284#define _ICL_DSC1_PICTURE_PARAMETER_SET_13_PC 0x785A4
285#define ICL_DSC0_PICTURE_PARAMETER_SET_13(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
286 _ICL_DSC0_PICTURE_PARAMETER_SET_13_PB, \
287 _ICL_DSC0_PICTURE_PARAMETER_SET_13_PC)
288#define ICL_DSC1_PICTURE_PARAMETER_SET_13(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
289 _ICL_DSC1_PICTURE_PARAMETER_SET_13_PB, \
290 _ICL_DSC1_PICTURE_PARAMETER_SET_13_PC)
291
292#define DSCA_PICTURE_PARAMETER_SET_14 _MMIO(0x6B268)
293#define DSCC_PICTURE_PARAMETER_SET_14 _MMIO(0x6BA68)
294#define _ICL_DSC0_PICTURE_PARAMETER_SET_14_PB 0x782A8
295#define _ICL_DSC1_PICTURE_PARAMETER_SET_14_PB 0x783A8
296#define _ICL_DSC0_PICTURE_PARAMETER_SET_14_PC 0x784A8
297#define _ICL_DSC1_PICTURE_PARAMETER_SET_14_PC 0x785A8
298#define ICL_DSC0_PICTURE_PARAMETER_SET_14(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
299 _ICL_DSC0_PICTURE_PARAMETER_SET_14_PB, \
300 _ICL_DSC0_PICTURE_PARAMETER_SET_14_PC)
301#define ICL_DSC1_PICTURE_PARAMETER_SET_14(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
302 _ICL_DSC1_PICTURE_PARAMETER_SET_14_PB, \
303 _ICL_DSC1_PICTURE_PARAMETER_SET_14_PC)
304
305#define DSCA_PICTURE_PARAMETER_SET_15 _MMIO(0x6B26C)
306#define DSCC_PICTURE_PARAMETER_SET_15 _MMIO(0x6BA6C)
307#define _ICL_DSC0_PICTURE_PARAMETER_SET_15_PB 0x782AC
308#define _ICL_DSC1_PICTURE_PARAMETER_SET_15_PB 0x783AC
309#define _ICL_DSC0_PICTURE_PARAMETER_SET_15_PC 0x784AC
310#define _ICL_DSC1_PICTURE_PARAMETER_SET_15_PC 0x785AC
311#define ICL_DSC0_PICTURE_PARAMETER_SET_15(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
312 _ICL_DSC0_PICTURE_PARAMETER_SET_15_PB, \
313 _ICL_DSC0_PICTURE_PARAMETER_SET_15_PC)
314#define ICL_DSC1_PICTURE_PARAMETER_SET_15(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
315 _ICL_DSC1_PICTURE_PARAMETER_SET_15_PB, \
316 _ICL_DSC1_PICTURE_PARAMETER_SET_15_PC)
317
318#define DSCA_PICTURE_PARAMETER_SET_16 _MMIO(0x6B270)
319#define DSCC_PICTURE_PARAMETER_SET_16 _MMIO(0x6BA70)
320#define _ICL_DSC0_PICTURE_PARAMETER_SET_16_PB 0x782B0
321#define _ICL_DSC1_PICTURE_PARAMETER_SET_16_PB 0x783B0
322#define _ICL_DSC0_PICTURE_PARAMETER_SET_16_PC 0x784B0
323#define _ICL_DSC1_PICTURE_PARAMETER_SET_16_PC 0x785B0
324#define ICL_DSC0_PICTURE_PARAMETER_SET_16(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
325 _ICL_DSC0_PICTURE_PARAMETER_SET_16_PB, \
326 _ICL_DSC0_PICTURE_PARAMETER_SET_16_PC)
327#define ICL_DSC1_PICTURE_PARAMETER_SET_16(pipe) _MMIO_PIPE((pipe) - PIPE_B, \
328 _ICL_DSC1_PICTURE_PARAMETER_SET_16_PB, \
329 _ICL_DSC1_PICTURE_PARAMETER_SET_16_PC)
330#define DSC_SLICE_ROW_PER_FRAME(slice_row_per_frame) ((slice_row_per_frame) << 20)
331#define DSC_SLICE_PER_LINE(slice_per_line) ((slice_per_line) << 16)
332#define DSC_SLICE_CHUNK_SIZE(slice_chunk_size) ((slice_chunk_size) << 0)
333 188
334/* Icelake Rate Control Buffer Threshold Registers */189/* Icelake Rate Control Buffer Threshold Registers */
335#define DSCA_RC_BUF_THRESH_0 _MMIO(0x6B230)190#define DSCA_RC_BUF_THRESH_0 _MMIO(0x6B230)
drivers/gpu/drm/i915/display/intel_vrr.c+16−2
@@ -42,6 +42,15 @@ bool intel_vrr_is_capable(struct intel_connector *connector) · 41 unmodified lines
42 info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;42 info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;
43}43}
44 44
45bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh)
46{
47 const struct drm_display_info *info = &connector->base.display_info;
48
49 return intel_vrr_is_capable(connector) &&
50 vrefresh >= info->monitor_range.min_vfreq &&
51 vrefresh <= info->monitor_range.max_vfreq;
52}
53
45void54void
46intel_vrr_check_modeset(struct intel_atomic_state *state)55intel_vrr_check_modeset(struct intel_atomic_state *state)
47{56{
@@ -108,12 +117,17 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, · 60 unmodified lines
108 const struct drm_display_info *info = &connector->base.display_info;117 const struct drm_display_info *info = &connector->base.display_info;
109 int vmin, vmax;118 int vmin, vmax;
110 119
111 if (!intel_vrr_is_capable(connector))120 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
112 return;121 return;
113 122
114 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)123 crtc_state->vrr.in_range =
124 intel_vrr_is_in_range(connector, drm_mode_vrefresh(adjusted_mode));
125 if (!crtc_state->vrr.in_range)
115 return;126 return;
116 127
128 if (HAS_LRR(i915))
129 crtc_state->update_lrr = true;
130
117 vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000,131 vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000,
118 adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq);132 adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq);
119 vmax = adjusted_mode->crtc_clock * 1000 /133 vmax = adjusted_mode->crtc_clock * 1000 /
drivers/gpu/drm/i915/display/intel_vrr.h+1−0
@@ -14,6 +14,7 @@ struct intel_connector; · 13 unmodified lines
14struct intel_crtc_state;14struct intel_crtc_state;
15 15
16bool intel_vrr_is_capable(struct intel_connector *connector);16bool intel_vrr_is_capable(struct intel_connector *connector);
17bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh);
17void intel_vrr_check_modeset(struct intel_atomic_state *state);18void intel_vrr_check_modeset(struct intel_atomic_state *state);
18void intel_vrr_compute_config(struct intel_crtc_state *crtc_state,19void intel_vrr_compute_config(struct intel_crtc_state *crtc_state,
19 struct drm_connector_state *conn_state);20 struct drm_connector_state *conn_state);
drivers/gpu/drm/i915/display/skl_universal_plane.c+2−5
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include "intel_display_types.h"16#include "intel_display_types.h"
17#include "intel_fb.h"17#include "intel_fb.h"
18#include "intel_fbc.h"18#include "intel_fbc.h"
19#include "intel_frontbuffer.h"
19#include "intel_psr.h"20#include "intel_psr.h"
20#include "skl_scaler.h"21#include "skl_scaler.h"
21#include "skl_universal_plane.h"22#include "skl_universal_plane.h"
@@ -1246,7 +1247,7 @@ icl_plane_update_noarm(struct intel_plane *plane, · 1224 unmodified lines
1246 }1247 }
1247 1248
1248 /* FLAT CCS doesn't need to program AUX_DIST */1249 /* FLAT CCS doesn't need to program AUX_DIST */
1249 if (!HAS_FLAT_CCS(dev_priv))1250 if (!HAS_FLAT_CCS(dev_priv) && DISPLAY_VER(dev_priv) < 20)
1250 intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),1251 intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
1251 skl_plane_aux_dist(plane_state, color_plane));1252 skl_plane_aux_dist(plane_state, color_plane));
1252 1253
@@ -2199,10 +2200,6 @@ static bool gen12_plane_has_mc_ccs(struct drm_i915_private *i915, · 946 unmodified lines
2199 if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))2200 if (IS_ALDERLAKE_P(i915) && IS_DISPLAY_STEP(i915, STEP_A0, STEP_B0))
2200 return false;2201 return false;
2201 2202
2202 /* Wa_14013215631 */
2203 if (IS_DG2_DISPLAY_STEP(i915, STEP_A0, STEP_C0))
2204 return false;
2205
2206 return plane_id < PLANE_SPRITE4;2203 return plane_id < PLANE_SPRITE4;
2207}2204}
2208 2205
drivers/gpu/drm/i915/display/skl_watermark.c+24−8
@@ -1367,7 +1367,7 @@ skl_total_relative_data_rate(const struct intel_crtc_state *crtc_state) · 1366 unmodified lines
1367 u64 data_rate = 0;1367 u64 data_rate = 0;
1368 1368
1369 for_each_plane_id_on_crtc(crtc, plane_id) {1369 for_each_plane_id_on_crtc(crtc, plane_id) {
1370 if (plane_id == PLANE_CURSOR)1370 if (plane_id == PLANE_CURSOR && DISPLAY_VER(i915) < 20)
1371 continue;1371 continue;
1372 1372
1373 data_rate += crtc_state->rel_data_rate[plane_id];1373 data_rate += crtc_state->rel_data_rate[plane_id];
@@ -1514,10 +1514,12 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, · 140 unmodified lines
1514 return 0;1514 return 0;
1515 1515
1516 /* Allocate fixed number of blocks for cursor. */1516 /* Allocate fixed number of blocks for cursor. */
1517 cursor_size = skl_cursor_allocation(crtc_state, num_active);1517 if (DISPLAY_VER(i915) < 20) {
1518 iter.size -= cursor_size;1518 cursor_size = skl_cursor_allocation(crtc_state, num_active);
1519 skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[PLANE_CURSOR],1519 iter.size -= cursor_size;
1520 alloc->end - cursor_size, alloc->end);1520 skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[PLANE_CURSOR],
1521 alloc->end - cursor_size, alloc->end);
1522 }
1521 1523
1522 iter.data_rate = skl_total_relative_data_rate(crtc_state);1524 iter.data_rate = skl_total_relative_data_rate(crtc_state);
1523 1525
@@ -1531,7 +1533,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, · 7 unmodified lines
1531 const struct skl_plane_wm *wm =1533 const struct skl_plane_wm *wm =
1532 &crtc_state->wm.skl.optimal.planes[plane_id];1534 &crtc_state->wm.skl.optimal.planes[plane_id];
1533 1535
1534 if (plane_id == PLANE_CURSOR) {1536 if (plane_id == PLANE_CURSOR && DISPLAY_VER(i915) < 20) {
1535 const struct skl_ddb_entry *ddb =1537 const struct skl_ddb_entry *ddb =
1536 &crtc_state->wm.skl.plane_ddb[plane_id];1538 &crtc_state->wm.skl.plane_ddb[plane_id];
1537 1539
@@ -1579,7 +1581,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, · 41 unmodified lines
1579 const struct skl_plane_wm *wm =1581 const struct skl_plane_wm *wm =
1580 &crtc_state->wm.skl.optimal.planes[plane_id];1582 &crtc_state->wm.skl.optimal.planes[plane_id];
1581 1583
1582 if (plane_id == PLANE_CURSOR)1584 if (plane_id == PLANE_CURSOR && DISPLAY_VER(i915) < 20)
1583 continue;1585 continue;
1584 1586
1585 if (DISPLAY_VER(i915) < 11 &&1587 if (DISPLAY_VER(i915) < 11 &&
@@ -2616,7 +2618,7 @@ skl_compute_ddb(struct intel_atomic_state *state) · 1030 unmodified lines
2616 2618
2617 if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {2619 if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
2618 /* TODO: Implement vblank synchronized MBUS joining changes */2620 /* TODO: Implement vblank synchronized MBUS joining changes */
2619 ret = intel_modeset_all_pipes(state, "MBUS joining change");2621 ret = intel_modeset_all_pipes_late(state, "MBUS joining change");
2620 if (ret)2622 if (ret)
2621 return ret;2623 return ret;
2622 }2624 }
@@ -3719,3 +3721,17 @@ void skl_watermark_debugfs_register(struct drm_i915_private *i915) · 1096 unmodified lines
3719 debugfs_create_file("i915_sagv_status", 0444, minor->debugfs_root, i915,3721 debugfs_create_file("i915_sagv_status", 0444, minor->debugfs_root, i915,
3720 &intel_sagv_status_fops);3722 &intel_sagv_status_fops);
3721}3723}
3724
3725unsigned int skl_watermark_max_latency(struct drm_i915_private *i915)
3726{
3727 int level;
3728
3729 for (level = i915->display.wm.num_levels - 1; level >= 0; level--) {
3730 unsigned int latency = skl_wm_latency(i915, level, NULL);
3731
3732 if (latency)
3733 return latency;
3734 }
3735
3736 return 0;
3737}
drivers/gpu/drm/i915/display/skl_watermark.h+2−0
@@ -46,6 +46,8 @@ void skl_watermark_ipc_update(struct drm_i915_private *i915); · 45 unmodified lines
46bool skl_watermark_ipc_enabled(struct drm_i915_private *i915);46bool skl_watermark_ipc_enabled(struct drm_i915_private *i915);
47void skl_watermark_debugfs_register(struct drm_i915_private *i915);47void skl_watermark_debugfs_register(struct drm_i915_private *i915);
48 48
49unsigned int skl_watermark_max_latency(struct drm_i915_private *i915);
50
49void skl_wm_init(struct drm_i915_private *i915);51void skl_wm_init(struct drm_i915_private *i915);
50 52
51struct intel_dbuf_state {53struct intel_dbuf_state {
drivers/gpu/drm/i915/gem/i915_gem_clflush.c+1−2
@@ -6,11 +6,10 @@ · 5 unmodified lines
6 6
7#include <drm/drm_cache.h>7#include <drm/drm_cache.h>
8 8
9#include "display/intel_frontbuffer.h"
10
11#include "i915_config.h"9#include "i915_config.h"
12#include "i915_drv.h"10#include "i915_drv.h"
13#include "i915_gem_clflush.h"11#include "i915_gem_clflush.h"
12#include "i915_gem_object_frontbuffer.h"
14#include "i915_sw_fence_work.h"13#include "i915_sw_fence_work.h"
15#include "i915_trace.h"14#include "i915_trace.h"
16 15
drivers/gpu/drm/i915/gem/i915_gem_domain.c+1−1
@@ -5,7 +5,6 @@ · 4 unmodified lines
5 */5 */
6 6
7#include "display/intel_display.h"7#include "display/intel_display.h"
8#include "display/intel_frontbuffer.h"
9#include "gt/intel_gt.h"8#include "gt/intel_gt.h"
10 9
11#include "i915_drv.h"10#include "i915_drv.h"
@@ -16,6 +15,7 @@ · 4 unmodified lines
16#include "i915_gem_lmem.h"15#include "i915_gem_lmem.h"
17#include "i915_gem_mman.h"16#include "i915_gem_mman.h"
18#include "i915_gem_object.h"17#include "i915_gem_object.h"
18#include "i915_gem_object_frontbuffer.h"
19#include "i915_vma.h"19#include "i915_vma.h"
20 20
21#define VTD_GUARD (168u * I915_GTT_PAGE_SIZE) /* 168 or tile-row PTE padding */21#define VTD_GUARD (168u * I915_GTT_PAGE_SIZE) /* 168 or tile-row PTE padding */
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c+2−2
@@ -1436,7 +1436,7 @@ eb_relocate_entry(struct i915_execbuffer *eb, · 1435 unmodified lines
1436 if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {1436 if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) {
1437 drm_dbg(&i915->drm, "reloc with multiple write domains: "1437 drm_dbg(&i915->drm, "reloc with multiple write domains: "
1438 "target %d offset %d "1438 "target %d offset %d "
1439 "read %08x write %08x",1439 "read %08x write %08x\n",
1440 reloc->target_handle,1440 reloc->target_handle,
1441 (int) reloc->offset,1441 (int) reloc->offset,
1442 reloc->read_domains,1442 reloc->read_domains,
@@ -1447,7 +1447,7 @@ eb_relocate_entry(struct i915_execbuffer *eb, · 4 unmodified lines
1447 & ~I915_GEM_GPU_DOMAINS)) {1447 & ~I915_GEM_GPU_DOMAINS)) {
1448 drm_dbg(&i915->drm, "reloc with read/write non-GPU domains: "1448 drm_dbg(&i915->drm, "reloc with read/write non-GPU domains: "
1449 "target %d offset %d "1449 "target %d offset %d "
1450 "read %08x write %08x",1450 "read %08x write %08x\n",
1451 reloc->target_handle,1451 reloc->target_handle,
1452 (int) reloc->offset,1452 (int) reloc->offset,
1453 reloc->read_domains,1453 reloc->read_domains,
drivers/gpu/drm/i915/gem/i915_gem_object.c+1−0
@@ -37,6 +37,7 @@ · 36 unmodified lines
37#include "i915_gem_dmabuf.h"37#include "i915_gem_dmabuf.h"
38#include "i915_gem_mman.h"38#include "i915_gem_mman.h"
39#include "i915_gem_object.h"39#include "i915_gem_object.h"
40#include "i915_gem_object_frontbuffer.h"
40#include "i915_gem_ttm.h"41#include "i915_gem_ttm.h"
41#include "i915_memcpy.h"42#include "i915_memcpy.h"
42#include "i915_trace.h"43#include "i915_trace.h"
drivers/gpu/drm/i915/gem/i915_gem_object.h+0−89
@@ -11,7 +11,6 @@ · 10 unmodified lines
11#include <drm/drm_file.h>11#include <drm/drm_file.h>
12#include <drm/drm_device.h>12#include <drm/drm_device.h>
13 13
14#include "display/intel_frontbuffer.h"
15#include "intel_memory_region.h"14#include "intel_memory_region.h"
16#include "i915_gem_object_types.h"15#include "i915_gem_object_types.h"
17#include "i915_gem_gtt.h"16#include "i915_gem_gtt.h"
@@ -806,27 +805,6 @@ int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, · 788 unmodified lines
806 unsigned int flags,805 unsigned int flags,
807 const struct i915_sched_attr *attr);806 const struct i915_sched_attr *attr);
808 807
809void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
810 enum fb_op_origin origin);
811void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
812 enum fb_op_origin origin);
813
814static inline void
815i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
816 enum fb_op_origin origin)
817{
818 if (unlikely(rcu_access_pointer(obj->frontbuffer)))
819 __i915_gem_object_flush_frontbuffer(obj, origin);
820}
821
822static inline void
823i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
824 enum fb_op_origin origin)
825{
826 if (unlikely(rcu_access_pointer(obj->frontbuffer)))
827 __i915_gem_object_invalidate_frontbuffer(obj, origin);
828}
829
830int i915_gem_object_read_from_page(struct drm_i915_gem_object *obj, u64 offset, void *dst, int size);808int i915_gem_object_read_from_page(struct drm_i915_gem_object *obj, u64 offset, void *dst, int size);
831 809
832bool i915_gem_object_is_shmem(const struct drm_i915_gem_object *obj);810bool i915_gem_object_is_shmem(const struct drm_i915_gem_object *obj);
@@ -887,71 +865,4 @@ static inline int i915_gem_object_userptr_validate(struct drm_i915_gem_object *o · 54 unmodified lines
887 865
888#endif866#endif
889 867
890/**
891 * i915_gem_object_get_frontbuffer - Get the object's frontbuffer
892 * @obj: The object whose frontbuffer to get.
893 *
894 * Get pointer to object's frontbuffer if such exists. Please note that RCU
895 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer.
896 *
897 * Return: pointer to object's frontbuffer is such exists or NULL
898 */
899static inline struct intel_frontbuffer *
900i915_gem_object_get_frontbuffer(const struct drm_i915_gem_object *obj)
901{
902 struct intel_frontbuffer *front;
903
904 if (likely(!rcu_access_pointer(obj->frontbuffer)))
905 return NULL;
906
907 rcu_read_lock();
908 do {
909 front = rcu_dereference(obj->frontbuffer);
910 if (!front)
911 break;
912
913 if (unlikely(!kref_get_unless_zero(&front->ref)))
914 continue;
915
916 if (likely(front == rcu_access_pointer(obj->frontbuffer)))
917 break;
918
919 intel_frontbuffer_put(front);
920 } while (1);
921 rcu_read_unlock();
922
923 return front;
924}
925
926/**
927 * i915_gem_object_set_frontbuffer - Set the object's frontbuffer
928 * @obj: The object whose frontbuffer to set.
929 * @front: The frontbuffer to set
930 *
931 * Set object's frontbuffer pointer. If frontbuffer is already set for the
932 * object keep it and return it's pointer to the caller. Please note that RCU
933 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. This
934 * function is protected by i915->display.fb_tracking.lock
935 *
936 * Return: pointer to frontbuffer which was set.
937 */
938static inline struct intel_frontbuffer *
939i915_gem_object_set_frontbuffer(struct drm_i915_gem_object *obj,
940 struct intel_frontbuffer *front)
941{
942 struct intel_frontbuffer *cur = front;
943
944 if (!front) {
945 RCU_INIT_POINTER(obj->frontbuffer, NULL);
946 } else if (rcu_access_pointer(obj->frontbuffer)) {
947 cur = rcu_dereference_protected(obj->frontbuffer, true);
948 kref_get(&cur->ref);
949 } else {
950 drm_gem_object_get(intel_bo_to_drm_bo(obj));
951 rcu_assign_pointer(obj->frontbuffer, front);
952 }
953
954 return cur;
955}
956
957#endif868#endif
drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.h+103−0
@@ -0,0 +1,103 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2023 Intel Corporation
4 */
5
6#ifndef __I915_GEM_OBJECT_FRONTBUFFER_H__
7#define __I915_GEM_OBJECT_FRONTBUFFER_H__
8
9#include <linux/kref.h>
10#include <linux/rcupdate.h>
11
12#include "display/intel_frontbuffer.h"
13#include "i915_gem_object_types.h"
14
15void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
16 enum fb_op_origin origin);
17void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
18 enum fb_op_origin origin);
19
20static inline void
21i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj,
22 enum fb_op_origin origin)
23{
24 if (unlikely(rcu_access_pointer(obj->frontbuffer)))
25 __i915_gem_object_flush_frontbuffer(obj, origin);
26}
27
28static inline void
29i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj,
30 enum fb_op_origin origin)
31{
32 if (unlikely(rcu_access_pointer(obj->frontbuffer)))
33 __i915_gem_object_invalidate_frontbuffer(obj, origin);
34}
35
36/**
37 * i915_gem_object_get_frontbuffer - Get the object's frontbuffer
38 * @obj: The object whose frontbuffer to get.
39 *
40 * Get pointer to object's frontbuffer if such exists. Please note that RCU
41 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer.
42 *
43 * Return: pointer to object's frontbuffer is such exists or NULL
44 */
45static inline struct intel_frontbuffer *
46i915_gem_object_get_frontbuffer(const struct drm_i915_gem_object *obj)
47{
48 struct intel_frontbuffer *front;
49
50 if (likely(!rcu_access_pointer(obj->frontbuffer)))
51 return NULL;
52
53 rcu_read_lock();
54 do {
55 front = rcu_dereference(obj->frontbuffer);
56 if (!front)
57 break;
58
59 if (unlikely(!kref_get_unless_zero(&front->ref)))
60 continue;
61
62 if (likely(front == rcu_access_pointer(obj->frontbuffer)))
63 break;
64
65 intel_frontbuffer_put(front);
66 } while (1);
67 rcu_read_unlock();
68
69 return front;
70}
71
72/**
73 * i915_gem_object_set_frontbuffer - Set the object's frontbuffer
74 * @obj: The object whose frontbuffer to set.
75 * @front: The frontbuffer to set
76 *
77 * Set object's frontbuffer pointer. If frontbuffer is already set for the
78 * object keep it and return it's pointer to the caller. Please note that RCU
79 * mechanism is used to handle e.g. ongoing removal of frontbuffer pointer. This
80 * function is protected by i915->display.fb_tracking.lock
81 *
82 * Return: pointer to frontbuffer which was set.
83 */
84static inline struct intel_frontbuffer *
85i915_gem_object_set_frontbuffer(struct drm_i915_gem_object *obj,
86 struct intel_frontbuffer *front)
87{
88 struct intel_frontbuffer *cur = front;
89
90 if (!front) {
91 RCU_INIT_POINTER(obj->frontbuffer, NULL);
92 } else if (rcu_access_pointer(obj->frontbuffer)) {
93 cur = rcu_dereference_protected(obj->frontbuffer, true);
94 kref_get(&cur->ref);
95 } else {
96 drm_gem_object_get(intel_bo_to_drm_bo(obj));
97 rcu_assign_pointer(obj->frontbuffer, front);
98 }
99
100 return cur;
101}
102
103#endif
drivers/gpu/drm/i915/gem/i915_gem_phys.c+1−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
13#include "gt/intel_gt.h"13#include "gt/intel_gt.h"
14#include "i915_drv.h"14#include "i915_drv.h"
15#include "i915_gem_object.h"15#include "i915_gem_object.h"
16#include "i915_gem_object_frontbuffer.h"
16#include "i915_gem_region.h"17#include "i915_gem_region.h"
17#include "i915_gem_tiling.h"18#include "i915_gem_tiling.h"
18#include "i915_scatterlist.h"19#include "i915_scatterlist.h"
drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c+15−24
@@ -83,8 +83,7 @@ static int linear_x_y_to_ftiled_pos(int x, int y, u32 stride, int bpp) · 82 unmodified lines
83enum client_tiling {83enum client_tiling {
84 CLIENT_TILING_LINEAR,84 CLIENT_TILING_LINEAR,
85 CLIENT_TILING_X,85 CLIENT_TILING_X,
86 CLIENT_TILING_Y,86 CLIENT_TILING_Y, /* Y-major, either Tile4 (Xe_HP and beyond) or legacy TileY */
87 CLIENT_TILING_4,
88 CLIENT_NUM_TILING_TYPES87 CLIENT_NUM_TILING_TYPES
89};88};
90 89
@@ -165,11 +164,10 @@ static int prepare_blit(const struct tiled_blits *t, · 74 unmodified lines
165 BLIT_CCTL_DST_MOCS(gt->mocs.uc_index));164 BLIT_CCTL_DST_MOCS(gt->mocs.uc_index));
166 165
167 src_pitch = t->width; /* in dwords */166 src_pitch = t->width; /* in dwords */
168 if (src->tiling == CLIENT_TILING_4) {167 if (src->tiling == CLIENT_TILING_Y) {
169 src_tiles = XY_FAST_COPY_BLT_D0_SRC_TILE_MODE(YMAJOR);
170 src_4t = XY_FAST_COPY_BLT_D1_SRC_TILE4;
171 } else if (src->tiling == CLIENT_TILING_Y) {
172 src_tiles = XY_FAST_COPY_BLT_D0_SRC_TILE_MODE(YMAJOR);168 src_tiles = XY_FAST_COPY_BLT_D0_SRC_TILE_MODE(YMAJOR);
169 if (GRAPHICS_VER_FULL(to_i915(batch->base.dev)) >= IP_VER(12, 50))
170 src_4t = XY_FAST_COPY_BLT_D1_SRC_TILE4;
173 } else if (src->tiling == CLIENT_TILING_X) {171 } else if (src->tiling == CLIENT_TILING_X) {
174 src_tiles = XY_FAST_COPY_BLT_D0_SRC_TILE_MODE(TILE_X);172 src_tiles = XY_FAST_COPY_BLT_D0_SRC_TILE_MODE(TILE_X);
175 } else {173 } else {
@@ -177,11 +175,10 @@ static int prepare_blit(const struct tiled_blits *t, · 1 unmodified line
177 }175 }
178 176
179 dst_pitch = t->width; /* in dwords */177 dst_pitch = t->width; /* in dwords */
180 if (dst->tiling == CLIENT_TILING_4) {178 if (dst->tiling == CLIENT_TILING_Y) {
181 dst_tiles = XY_FAST_COPY_BLT_D0_DST_TILE_MODE(YMAJOR);
182 dst_4t = XY_FAST_COPY_BLT_D1_DST_TILE4;
183 } else if (dst->tiling == CLIENT_TILING_Y) {
184 dst_tiles = XY_FAST_COPY_BLT_D0_DST_TILE_MODE(YMAJOR);179 dst_tiles = XY_FAST_COPY_BLT_D0_DST_TILE_MODE(YMAJOR);
180 if (GRAPHICS_VER_FULL(to_i915(batch->base.dev)) >= IP_VER(12, 50))
181 dst_4t = XY_FAST_COPY_BLT_D1_DST_TILE4;
185 } else if (dst->tiling == CLIENT_TILING_X) {182 } else if (dst->tiling == CLIENT_TILING_X) {
186 dst_tiles = XY_FAST_COPY_BLT_D0_DST_TILE_MODE(TILE_X);183 dst_tiles = XY_FAST_COPY_BLT_D0_DST_TILE_MODE(TILE_X);
187 } else {184 } else {
@@ -326,12 +323,6 @@ static int tiled_blits_create_buffers(struct tiled_blits *t, · 138 unmodified lines
326 t->buffers[i].vma = vma;323 t->buffers[i].vma = vma;
327 t->buffers[i].tiling =324 t->buffers[i].tiling =
328 i915_prandom_u32_max_state(CLIENT_NUM_TILING_TYPES, prng);325 i915_prandom_u32_max_state(CLIENT_NUM_TILING_TYPES, prng);
329
330 /* Platforms support either TileY or Tile4, not both */
331 if (HAS_4TILE(i915) && t->buffers[i].tiling == CLIENT_TILING_Y)
332 t->buffers[i].tiling = CLIENT_TILING_4;
333 else if (!HAS_4TILE(i915) && t->buffers[i].tiling == CLIENT_TILING_4)
334 t->buffers[i].tiling = CLIENT_TILING_Y;
335 }326 }
336 327
337 return 0;328 return 0;
@@ -367,18 +358,19 @@ static u64 tiled_offset(const struct intel_gt *gt, · 29 unmodified lines
367 358
368 y = div64_u64_rem(v, stride, &x);359 y = div64_u64_rem(v, stride, &x);
369 360
370 if (tiling == CLIENT_TILING_4) {361 if (tiling == CLIENT_TILING_X) {
371 v = linear_x_y_to_ftiled_pos(x_pos, y_pos, stride, 32);
372
373 /* no swizzling for f-tiling */
374 swizzle = I915_BIT_6_SWIZZLE_NONE;
375 } else if (tiling == CLIENT_TILING_X) {
376 v = div64_u64_rem(y, 8, &y) * stride * 8;362 v = div64_u64_rem(y, 8, &y) * stride * 8;
377 v += y * 512;363 v += y * 512;
378 v += div64_u64_rem(x, 512, &x) << 12;364 v += div64_u64_rem(x, 512, &x) << 12;
379 v += x;365 v += x;
380 366
381 swizzle = gt->ggtt->bit_6_swizzle_x;367 swizzle = gt->ggtt->bit_6_swizzle_x;
368 } else if (GRAPHICS_VER_FULL(gt->i915) >= IP_VER(12, 50)) {
369 /* Y-major tiling layout is Tile4 for Xe_HP and beyond */
370 v = linear_x_y_to_ftiled_pos(x_pos, y_pos, stride, 32);
371
372 /* no swizzling for f-tiling */
373 swizzle = I915_BIT_6_SWIZZLE_NONE;
382 } else {374 } else {
383 const unsigned int ytile_span = 16;375 const unsigned int ytile_span = 16;
384 const unsigned int ytile_height = 512;376 const unsigned int ytile_height = 512;
@@ -414,8 +406,7 @@ static const char *repr_tiling(enum client_tiling tiling) · 29 unmodified lines
414 switch (tiling) {406 switch (tiling) {
415 case CLIENT_TILING_LINEAR: return "linear";407 case CLIENT_TILING_LINEAR: return "linear";
416 case CLIENT_TILING_X: return "X";408 case CLIENT_TILING_X: return "X";
417 case CLIENT_TILING_Y: return "Y";409 case CLIENT_TILING_Y: return "Y / 4";
418 case CLIENT_TILING_4: return "F";
419 default: return "unknown";410 default: return "unknown";
420 }411 }
421}412}
drivers/gpu/drm/i915/gt/gen8_ppgtt.c+18−18
@@ -242,9 +242,9 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space * const vm, · 241 unmodified lines
242 GEM_BUG_ON(end > vm->total >> GEN8_PTE_SHIFT);242 GEM_BUG_ON(end > vm->total >> GEN8_PTE_SHIFT);
243 243
244 len = gen8_pd_range(start, end, lvl--, &idx);244 len = gen8_pd_range(start, end, lvl--, &idx);
245 DBG("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d }\n",245 GTT_TRACE("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d }\n",
246 __func__, vm, lvl + 1, start, end,246 __func__, vm, lvl + 1, start, end,
247 idx, len, atomic_read(px_used(pd)));247 idx, len, atomic_read(px_used(pd)));
248 GEM_BUG_ON(!len || len >= atomic_read(px_used(pd)));248 GEM_BUG_ON(!len || len >= atomic_read(px_used(pd)));
249 249
250 do {250 do {
@@ -252,8 +252,8 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space * const vm, · 1 unmodified line
252 252
253 if (atomic_fetch_inc(&pt->used) >> gen8_pd_shift(1) &&253 if (atomic_fetch_inc(&pt->used) >> gen8_pd_shift(1) &&
254 gen8_pd_contains(start, end, lvl)) {254 gen8_pd_contains(start, end, lvl)) {
255 DBG("%s(%p):{ lvl:%d, idx:%d, start:%llx, end:%llx } removing pd\n",255 GTT_TRACE("%s(%p):{ lvl:%d, idx:%d, start:%llx, end:%llx } removing pd\n",
256 __func__, vm, lvl + 1, idx, start, end);256 __func__, vm, lvl + 1, idx, start, end);
257 clear_pd_entry(pd, idx, scratch);257 clear_pd_entry(pd, idx, scratch);
258 __gen8_ppgtt_cleanup(vm, as_pd(pt), I915_PDES, lvl);258 __gen8_ppgtt_cleanup(vm, as_pd(pt), I915_PDES, lvl);
259 start += (u64)I915_PDES << gen8_pd_shift(lvl);259 start += (u64)I915_PDES << gen8_pd_shift(lvl);
@@ -270,10 +270,10 @@ static u64 __gen8_ppgtt_clear(struct i915_address_space * const vm, · 10 unmodified lines
270 u64 *vaddr;270 u64 *vaddr;
271 271
272 count = gen8_pt_count(start, end);272 count = gen8_pt_count(start, end);
273 DBG("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d } removing pte\n",273 GTT_TRACE("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d } removing pte\n",
274 __func__, vm, lvl, start, end,274 __func__, vm, lvl, start, end,
275 gen8_pd_index(start, 0), count,275 gen8_pd_index(start, 0), count,
276 atomic_read(&pt->used));276 atomic_read(&pt->used));
277 GEM_BUG_ON(!count || count >= atomic_read(&pt->used));277 GEM_BUG_ON(!count || count >= atomic_read(&pt->used));
278 278
279 num_ptes = count;279 num_ptes = count;
@@ -325,9 +325,9 @@ static void __gen8_ppgtt_alloc(struct i915_address_space * const vm, · 45 unmodified lines
325 GEM_BUG_ON(end > vm->total >> GEN8_PTE_SHIFT);325 GEM_BUG_ON(end > vm->total >> GEN8_PTE_SHIFT);
326 326
327 len = gen8_pd_range(*start, end, lvl--, &idx);327 len = gen8_pd_range(*start, end, lvl--, &idx);
328 DBG("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d }\n",328 GTT_TRACE("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d }\n",
329 __func__, vm, lvl + 1, *start, end,329 __func__, vm, lvl + 1, *start, end,
330 idx, len, atomic_read(px_used(pd)));330 idx, len, atomic_read(px_used(pd)));
331 GEM_BUG_ON(!len || (idx + len - 1) >> gen8_pd_shift(1));331 GEM_BUG_ON(!len || (idx + len - 1) >> gen8_pd_shift(1));
332 332
333 spin_lock(&pd->lock);333 spin_lock(&pd->lock);
@@ -338,8 +338,8 @@ static void __gen8_ppgtt_alloc(struct i915_address_space * const vm, · 4 unmodified lines
338 if (!pt) {338 if (!pt) {
339 spin_unlock(&pd->lock);339 spin_unlock(&pd->lock);
340 340
341 DBG("%s(%p):{ lvl:%d, idx:%d } allocating new tree\n",341 GTT_TRACE("%s(%p):{ lvl:%d, idx:%d } allocating new tree\n",
342 __func__, vm, lvl + 1, idx);342 __func__, vm, lvl + 1, idx);
343 343
344 pt = stash->pt[!!lvl];344 pt = stash->pt[!!lvl];
345 __i915_gem_object_pin_pages(pt->base);345 __i915_gem_object_pin_pages(pt->base);
@@ -369,10 +369,10 @@ static void __gen8_ppgtt_alloc(struct i915_address_space * const vm, · 23 unmodified lines
369 } else {369 } else {
370 unsigned int count = gen8_pt_count(*start, end);370 unsigned int count = gen8_pt_count(*start, end);
371 371
372 DBG("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d } inserting pte\n",372 GTT_TRACE("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d } inserting pte\n",
373 __func__, vm, lvl, *start, end,373 __func__, vm, lvl, *start, end,
374 gen8_pd_index(*start, 0), count,374 gen8_pd_index(*start, 0), count,
375 atomic_read(&pt->used));375 atomic_read(&pt->used));
376 376
377 atomic_add(count, &pt->used);377 atomic_add(count, &pt->used);
378 /* All other pdes may be simultaneously removed */378 /* All other pdes may be simultaneously removed */
drivers/gpu/drm/i915/gt/intel_gtt.h+2−2
@@ -35,9 +35,9 @@ · 34 unmodified lines
35#define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)35#define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
36 36
37#if IS_ENABLED(CONFIG_DRM_I915_TRACE_GTT)37#if IS_ENABLED(CONFIG_DRM_I915_TRACE_GTT)
38#define DBG(...) trace_printk(__VA_ARGS__)38#define GTT_TRACE(...) trace_printk(__VA_ARGS__)
39#else39#else
40#define DBG(...)40#define GTT_TRACE(...)
41#endif41#endif
42 42
43#define NALLOC 3 /* 1 normal, 1 for concurrent threads, 1 for preallocation */43#define NALLOC 3 /* 1 normal, 1 for concurrent threads, 1 for preallocation */
drivers/gpu/drm/i915/i915_driver.c+5−5
@@ -183,6 +183,9 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv) · 182 unmodified lines
183 pre |= IS_ICELAKE(dev_priv) && INTEL_REVID(dev_priv) < 0x7;183 pre |= IS_ICELAKE(dev_priv) && INTEL_REVID(dev_priv) < 0x7;
184 pre |= IS_TIGERLAKE(dev_priv) && INTEL_REVID(dev_priv) < 0x1;184 pre |= IS_TIGERLAKE(dev_priv) && INTEL_REVID(dev_priv) < 0x1;
185 pre |= IS_DG1(dev_priv) && INTEL_REVID(dev_priv) < 0x1;185 pre |= IS_DG1(dev_priv) && INTEL_REVID(dev_priv) < 0x1;
186 pre |= IS_DG2_G10(dev_priv) && INTEL_REVID(dev_priv) < 0x8;
187 pre |= IS_DG2_G11(dev_priv) && INTEL_REVID(dev_priv) < 0x5;
188 pre |= IS_DG2_G12(dev_priv) && INTEL_REVID(dev_priv) < 0x1;
186 189
187 if (pre) {190 if (pre) {
188 drm_err(&dev_priv->drm, "This is a pre-production stepping. "191 drm_err(&dev_priv->drm, "This is a pre-production stepping. "
@@ -696,8 +699,6 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) · 507 unmodified lines
696 699
697 intel_device_info_print(INTEL_INFO(dev_priv),700 intel_device_info_print(INTEL_INFO(dev_priv),
698 RUNTIME_INFO(dev_priv), &p);701 RUNTIME_INFO(dev_priv), &p);
699 intel_display_device_info_print(DISPLAY_INFO(dev_priv),
700 DISPLAY_RUNTIME_INFO(dev_priv), &p);
701 i915_print_iommu_status(dev_priv, &p);702 i915_print_iommu_status(dev_priv, &p);
702 for_each_gt(gt, dev_priv, i)703 for_each_gt(gt, dev_priv, i)
703 intel_gt_info_print(&gt->info, &p);704 intel_gt_info_print(&gt->info, &p);
@@ -732,6 +733,8 @@ i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent) · 28 unmodified lines
732 /* Set up device info and initial runtime info. */733 /* Set up device info and initial runtime info. */
733 intel_device_info_driver_create(i915, pdev->device, match_info);734 intel_device_info_driver_create(i915, pdev->device, match_info);
734 735
736 intel_display_device_probe(i915);
737
735 return i915;738 return i915;
736}739}
737 740
@@ -1566,8 +1569,6 @@ static int intel_runtime_suspend(struct device *kdev) · 828 unmodified lines
1566 if (root_pdev)1569 if (root_pdev)
1567 pci_d3cold_disable(root_pdev);1570 pci_d3cold_disable(root_pdev);
1568 1571
1569 rpm->suspended = true;
1570
1571 /*1572 /*
1572 * FIXME: We really should find a document that references the arguments1573 * FIXME: We really should find a document that references the arguments
1573 * used below!1574 * used below!
@@ -1618,7 +1619,6 @@ static int intel_runtime_resume(struct device *kdev) · 44 unmodified lines
1618 disable_rpm_wakeref_asserts(rpm);1619 disable_rpm_wakeref_asserts(rpm);
1619 1620
1620 intel_opregion_notify_adapter(dev_priv, PCI_D0);1621 intel_opregion_notify_adapter(dev_priv, PCI_D0);
1621 rpm->suspended = false;
1622 1622
1623 root_pdev = pcie_find_root_port(pdev);1623 root_pdev = pcie_find_root_port(pdev);
1624 if (root_pdev)1624 if (root_pdev)
drivers/gpu/drm/i915/i915_driver.h+2−2
@@ -15,8 +15,8 @@ struct drm_printer; · 14 unmodified lines
15 15
16#define DRIVER_NAME "i915"16#define DRIVER_NAME "i915"
17#define DRIVER_DESC "Intel Graphics"17#define DRIVER_DESC "Intel Graphics"
18#define DRIVER_DATE "20201103"18#define DRIVER_DATE "20230929"
19#define DRIVER_TIMESTAMP 160440608519#define DRIVER_TIMESTAMP 1695980603
20 20
21extern const struct dev_pm_ops i915_pm_ops;21extern const struct dev_pm_ops i915_pm_ops;
22 22
drivers/gpu/drm/i915/i915_drv.h+2−16
@@ -437,6 +437,8 @@ static inline struct intel_gt *to_gt(struct drm_i915_private *i915) · 436 unmodified lines
437 (MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until))437 (MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until))
438 438
439#define DISPLAY_VER(i915) (DISPLAY_RUNTIME_INFO(i915)->ip.ver)439#define DISPLAY_VER(i915) (DISPLAY_RUNTIME_INFO(i915)->ip.ver)
440#define DISPLAY_VER_FULL(i915) IP_VER(DISPLAY_RUNTIME_INFO(i915)->ip.ver, \
441 DISPLAY_RUNTIME_INFO(i915)->ip.rel)
440#define IS_DISPLAY_VER(i915, from, until) \442#define IS_DISPLAY_VER(i915, from, until) \
441 (DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))443 (DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until))
442 444
@@ -644,24 +646,9 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, · 201 unmodified lines
644#define IS_TIGERLAKE_UY(i915) \646#define IS_TIGERLAKE_UY(i915) \
645 IS_SUBPLATFORM(i915, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_UY)647 IS_SUBPLATFORM(i915, INTEL_TIGERLAKE, INTEL_SUBPLATFORM_UY)
646 648
647
648
649
650
651
652
653
654#define IS_XEHPSDV_GRAPHICS_STEP(__i915, since, until) \649#define IS_XEHPSDV_GRAPHICS_STEP(__i915, since, until) \
655 (IS_XEHPSDV(__i915) && IS_GRAPHICS_STEP(__i915, since, until))650 (IS_XEHPSDV(__i915) && IS_GRAPHICS_STEP(__i915, since, until))
656 651
657#define IS_MTL_DISPLAY_STEP(__i915, since, until) \
658 (IS_METEORLAKE(__i915) && \
659 IS_DISPLAY_STEP(__i915, since, until))
660
661#define IS_DG2_DISPLAY_STEP(__i915, since, until) \
662 (IS_DG2(__i915) && \
663 IS_DISPLAY_STEP(__i915, since, until))
664
665#define IS_PVC_BD_STEP(__i915, since, until) \652#define IS_PVC_BD_STEP(__i915, since, until) \
666 (IS_PONTEVECCHIO(__i915) && \653 (IS_PONTEVECCHIO(__i915) && \
667 IS_BASEDIE_STEP(__i915, since, until))654 IS_BASEDIE_STEP(__i915, since, until))
@@ -706,7 +693,6 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, · 38 unmodified lines
706#define CMDPARSER_USES_GGTT(i915) (GRAPHICS_VER(i915) == 7)693#define CMDPARSER_USES_GGTT(i915) (GRAPHICS_VER(i915) == 7)
707 694
708#define HAS_LLC(i915) (INTEL_INFO(i915)->has_llc)695#define HAS_LLC(i915) (INTEL_INFO(i915)->has_llc)
709#define HAS_4TILE(i915) (INTEL_INFO(i915)->has_4tile)
710#define HAS_SNOOP(i915) (INTEL_INFO(i915)->has_snoop)696#define HAS_SNOOP(i915) (INTEL_INFO(i915)->has_snoop)
711#define HAS_EDRAM(i915) ((i915)->edram_size_mb)697#define HAS_EDRAM(i915) ((i915)->edram_size_mb)
712#define HAS_SECURE_BATCHES(i915) (GRAPHICS_VER(i915) < 6)698#define HAS_SECURE_BATCHES(i915) (GRAPHICS_VER(i915) < 6)
drivers/gpu/drm/i915/i915_gem.c+1−1
@@ -40,12 +40,12 @@ · 39 unmodified lines
40#include <drm/drm_vma_manager.h>40#include <drm/drm_vma_manager.h>
41 41
42#include "display/intel_display.h"42#include "display/intel_display.h"
43#include "display/intel_frontbuffer.h"
44 43
45#include "gem/i915_gem_clflush.h"44#include "gem/i915_gem_clflush.h"
46#include "gem/i915_gem_context.h"45#include "gem/i915_gem_context.h"
47#include "gem/i915_gem_ioctls.h"46#include "gem/i915_gem_ioctls.h"
48#include "gem/i915_gem_mman.h"47#include "gem/i915_gem_mman.h"
48#include "gem/i915_gem_object_frontbuffer.h"
49#include "gem/i915_gem_pm.h"49#include "gem/i915_gem_pm.h"
50#include "gem/i915_gem_region.h"50#include "gem/i915_gem_region.h"
51#include "gem/i915_gem_userptr.h"51#include "gem/i915_gem_userptr.h"
drivers/gpu/drm/i915/i915_getparam.c+1−1
@@ -109,7 +109,7 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data, · 108 unmodified lines
109 return value;109 return value;
110 break;110 break;
111 case I915_PARAM_PXP_STATUS:111 case I915_PARAM_PXP_STATUS:
112 value = intel_pxp_get_readiness_status(i915->pxp);112 value = intel_pxp_get_readiness_status(i915->pxp, 0);
113 if (value < 0)113 if (value < 0)
114 return value;114 return value;
115 break;115 break;
drivers/gpu/drm/i915/i915_gpu_error.c+2−2
@@ -1757,7 +1757,7 @@ static void gt_record_display_regs(struct intel_gt_coredump *gt) · 1756 unmodified lines
1757 struct intel_uncore *uncore = gt->_gt->uncore;1757 struct intel_uncore *uncore = gt->_gt->uncore;
1758 struct drm_i915_private *i915 = uncore->i915;1758 struct drm_i915_private *i915 = uncore->i915;
1759 1759
1760 if (GRAPHICS_VER(i915) >= 6)1760 if (DISPLAY_VER(i915) >= 6 && DISPLAY_VER(i915) < 20)
1761 gt->derrmr = intel_uncore_read(uncore, DERRMR);1761 gt->derrmr = intel_uncore_read(uncore, DERRMR);
1762 1762
1763 if (GRAPHICS_VER(i915) >= 8)1763 if (GRAPHICS_VER(i915) >= 8)
@@ -1972,7 +1972,7 @@ static void capture_gen(struct i915_gpu_coredump *error) · 208 unmodified lines
1972 struct drm_i915_private *i915 = error->i915;1972 struct drm_i915_private *i915 = error->i915;
1973 1973
1974 error->wakelock = atomic_read(&i915->runtime_pm.wakeref_count);1974 error->wakelock = atomic_read(&i915->runtime_pm.wakeref_count);
1975 error->suspended = i915->runtime_pm.suspended;1975 error->suspended = pm_runtime_suspended(i915->drm.dev);
1976 1976
1977 error->iommu = i915_vtd_active(i915);1977 error->iommu = i915_vtd_active(i915);
1978 error->reset_count = i915_reset_count(&i915->gpu_error);1978 error->reset_count = i915_reset_count(&i915->gpu_error);
drivers/gpu/drm/i915/i915_irq.c+2−0
@@ -751,6 +751,8 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv) · 750 unmodified lines
751 751
752 GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_);752 GEN3_IRQ_RESET(uncore, GEN11_GU_MISC_);
753 GEN3_IRQ_RESET(uncore, GEN8_PCU_);753 GEN3_IRQ_RESET(uncore, GEN8_PCU_);
754
755 intel_uncore_write(uncore, GEN11_GFX_MSTR_IRQ, ~0);
754}756}
755 757
756static void cherryview_irq_reset(struct drm_i915_private *dev_priv)758static void cherryview_irq_reset(struct drm_i915_private *dev_priv)
drivers/gpu/drm/i915/i915_pci.c+0−1
@@ -713,7 +713,6 @@ static const struct intel_device_info adl_p_info = { · 712 unmodified lines
713 .has_3d_pipeline = 1, \713 .has_3d_pipeline = 1, \
714 .has_64bit_reloc = 1, \714 .has_64bit_reloc = 1, \
715 .has_flat_ccs = 1, \715 .has_flat_ccs = 1, \
716 .has_4tile = 1, \
717 .has_global_mocs = 1, \716 .has_global_mocs = 1, \
718 .has_gt_uc = 1, \717 .has_gt_uc = 1, \
719 .has_llc = 1, \718 .has_llc = 1, \
drivers/gpu/drm/i915/i915_reg.h+4−277
@@ -2693,13 +2693,6 @@ · 2692 unmodified lines
2693#define PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id) REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))2693#define PIPE_MISC2_FLIP_INFO_PLANE_SEL(plane_id) REG_FIELD_PREP(PIPE_MISC2_FLIP_INFO_PLANE_SEL_MASK, (plane_id))
2694#define PIPE_MISC2(pipe) _MMIO_PIPE(pipe, _PIPE_MISC2_A, _PIPE_MISC2_B)2694#define PIPE_MISC2(pipe) _MMIO_PIPE(pipe, _PIPE_MISC2_A, _PIPE_MISC2_B)
2695 2695
2696/* Skylake+ pipe bottom (background) color */
2697#define _SKL_BOTTOM_COLOR_A 0x70034
2698#define _SKL_BOTTOM_COLOR_B 0x71034
2699#define SKL_BOTTOM_COLOR_GAMMA_ENABLE REG_BIT(31)
2700#define SKL_BOTTOM_COLOR_CSC_ENABLE REG_BIT(30)
2701#define SKL_BOTTOM_COLOR(pipe) _MMIO_PIPE(pipe, _SKL_BOTTOM_COLOR_A, _SKL_BOTTOM_COLOR_B)
2702
2703#define _ICL_PIPE_A_STATUS 0x700582696#define _ICL_PIPE_A_STATUS 0x70058
2704#define ICL_PIPESTATUS(pipe) _MMIO_PIPE2(pipe, _ICL_PIPE_A_STATUS)2697#define ICL_PIPESTATUS(pipe) _MMIO_PIPE2(pipe, _ICL_PIPE_A_STATUS)
2705#define PIPE_STATUS_UNDERRUN REG_BIT(31)2698#define PIPE_STATUS_UNDERRUN REG_BIT(31)
@@ -4213,45 +4206,6 @@ · 1507 unmodified lines
4213#define GLK_PS_COEF_DATA_SET(pipe, id, set) _MMIO_PIPE(pipe, \4206#define GLK_PS_COEF_DATA_SET(pipe, id, set) _MMIO_PIPE(pipe, \
4214 _ID(id, _PS_COEF_SET0_DATA_1A, _PS_COEF_SET0_DATA_2A) + (set) * 8, \4207 _ID(id, _PS_COEF_SET0_DATA_1A, _PS_COEF_SET0_DATA_2A) + (set) * 8, \
4215 _ID(id, _PS_COEF_SET0_DATA_1B, _PS_COEF_SET0_DATA_2B) + (set) * 8)4208 _ID(id, _PS_COEF_SET0_DATA_1B, _PS_COEF_SET0_DATA_2B) + (set) * 8)
4216/* legacy palette */
4217#define _LGC_PALETTE_A 0x4a000
4218#define _LGC_PALETTE_B 0x4a800
4219/* see PALETTE_* for the bits */
4220#define LGC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + (i) * 4)
4221
4222/* ilk/snb precision palette */
4223#define _PREC_PALETTE_A 0x4b000
4224#define _PREC_PALETTE_B 0x4c000
4225/* 10bit mode */
4226#define PREC_PALETTE_10_RED_MASK REG_GENMASK(29, 20)
4227#define PREC_PALETTE_10_GREEN_MASK REG_GENMASK(19, 10)
4228#define PREC_PALETTE_10_BLUE_MASK REG_GENMASK(9, 0)
4229/* 12.4 interpolated mode ldw */
4230#define PREC_PALETTE_12P4_RED_LDW_MASK REG_GENMASK(29, 24)
4231#define PREC_PALETTE_12P4_GREEN_LDW_MASK REG_GENMASK(19, 14)
4232#define PREC_PALETTE_12P4_BLUE_LDW_MASK REG_GENMASK(9, 4)
4233/* 12.4 interpolated mode udw */
4234#define PREC_PALETTE_12P4_RED_UDW_MASK REG_GENMASK(29, 20)
4235#define PREC_PALETTE_12P4_GREEN_UDW_MASK REG_GENMASK(19, 10)
4236#define PREC_PALETTE_12P4_BLUE_UDW_MASK REG_GENMASK(9, 0)
4237#define PREC_PALETTE(pipe, i) _MMIO(_PIPE(pipe, _PREC_PALETTE_A, _PREC_PALETTE_B) + (i) * 4)
4238
4239#define _PREC_PIPEAGCMAX 0x4d000
4240#define _PREC_PIPEBGCMAX 0x4d010
4241#define PREC_PIPEGCMAX(pipe, i) _MMIO(_PIPE(pipe, _PIPEAGCMAX, _PIPEBGCMAX) + (i) * 4) /* u1.16 */
4242
4243#define _GAMMA_MODE_A 0x4a480
4244#define _GAMMA_MODE_B 0x4ac80
4245#define GAMMA_MODE(pipe) _MMIO_PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B)
4246#define PRE_CSC_GAMMA_ENABLE REG_BIT(31) /* icl+ */
4247#define POST_CSC_GAMMA_ENABLE REG_BIT(30) /* icl+ */
4248#define PALETTE_ANTICOL_DISABLE REG_BIT(15) /* skl+ */
4249#define GAMMA_MODE_MODE_MASK REG_GENMASK(1, 0)
4250#define GAMMA_MODE_MODE_8BIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 0)
4251#define GAMMA_MODE_MODE_10BIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 1)
4252#define GAMMA_MODE_MODE_12BIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 2)
4253#define GAMMA_MODE_MODE_SPLIT REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 3) /* ivb-bdw */
4254#define GAMMA_MODE_MODE_12BIT_MULTI_SEG REG_FIELD_PREP(GAMMA_MODE_MODE_MASK, 3) /* icl-tgl */
4255 4209
4256/* Display Internal Timeout Register */4210/* Display Internal Timeout Register */
4257#define RM_TIMEOUT _MMIO(0x42060)4211#define RM_TIMEOUT _MMIO(0x42060)
@@ -4513,13 +4467,12 @@ · 255 unmodified lines
4513#define PICAINTERRUPT_IMR _MMIO(0x16FE54)4467#define PICAINTERRUPT_IMR _MMIO(0x16FE54)
4514#define PICAINTERRUPT_IIR _MMIO(0x16FE58)4468#define PICAINTERRUPT_IIR _MMIO(0x16FE58)
4515#define PICAINTERRUPT_IER _MMIO(0x16FE5C)4469#define PICAINTERRUPT_IER _MMIO(0x16FE5C)
4516
4517#define XELPDP_DP_ALT_HOTPLUG(hpd_pin) REG_BIT(16 + _HPD_PIN_TC(hpd_pin))4470#define XELPDP_DP_ALT_HOTPLUG(hpd_pin) REG_BIT(16 + _HPD_PIN_TC(hpd_pin))
4518#define XELPDP_DP_ALT_HOTPLUG_MASK REG_GENMASK(19, 16)4471#define XELPDP_DP_ALT_HOTPLUG_MASK REG_GENMASK(19, 16)
4519
4520#define XELPDP_AUX_TC(hpd_pin) REG_BIT(8 + _HPD_PIN_TC(hpd_pin))4472#define XELPDP_AUX_TC(hpd_pin) REG_BIT(8 + _HPD_PIN_TC(hpd_pin))
4521#define XELPDP_AUX_TC_MASK REG_GENMASK(11, 8)4473#define XELPDP_AUX_TC_MASK REG_GENMASK(11, 8)
4522 4474#define XE2LPD_AUX_DDI(hpd_pin) REG_BIT(6 + _HPD_PIN_DDI(hpd_pin))
4475#define XE2LPD_AUX_DDI_MASK REG_GENMASK(7, 6)
4523#define XELPDP_TBT_HOTPLUG(hpd_pin) REG_BIT(_HPD_PIN_TC(hpd_pin))4476#define XELPDP_TBT_HOTPLUG(hpd_pin) REG_BIT(_HPD_PIN_TC(hpd_pin))
4524#define XELPDP_TBT_HOTPLUG_MASK REG_GENMASK(3, 0)4477#define XELPDP_TBT_HOTPLUG_MASK REG_GENMASK(3, 0)
4525 4478
@@ -5929,6 +5882,7 @@ enum skl_power_gate { · 1403 unmodified lines
5929#define CDCLK_FREQ_540 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 1)5882#define CDCLK_FREQ_540 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 1)
5930#define CDCLK_FREQ_337_308 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 2)5883#define CDCLK_FREQ_337_308 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 2)
5931#define CDCLK_FREQ_675_617 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 3)5884#define CDCLK_FREQ_675_617 REG_FIELD_PREP(CDCLK_FREQ_SEL_MASK, 3)
5885#define MDCLK_SOURCE_SEL_CDCLK_PLL REG_BIT(25)
5932#define BXT_CDCLK_CD2X_DIV_SEL_MASK REG_GENMASK(23, 22)5886#define BXT_CDCLK_CD2X_DIV_SEL_MASK REG_GENMASK(23, 22)
5933#define BXT_CDCLK_CD2X_DIV_SEL_1 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 0)5887#define BXT_CDCLK_CD2X_DIV_SEL_1 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 0)
5934#define BXT_CDCLK_CD2X_DIV_SEL_1_5 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 1)5888#define BXT_CDCLK_CD2X_DIV_SEL_1_5 REG_FIELD_PREP(BXT_CDCLK_CD2X_DIV_SEL_MASK, 1)
@@ -6269,179 +6223,6 @@ enum skl_power_gate { · 334 unmodified lines
6269#define WM_DBG_DISALLOW_MAXFIFO (1 << 1)6223#define WM_DBG_DISALLOW_MAXFIFO (1 << 1)
6270#define WM_DBG_DISALLOW_SPRITE (1 << 2)6224#define WM_DBG_DISALLOW_SPRITE (1 << 2)
6271 6225
6272/* pipe CSC */
6273#define _PIPE_A_CSC_COEFF_RY_GY 0x49010
6274#define _PIPE_A_CSC_COEFF_BY 0x49014
6275#define _PIPE_A_CSC_COEFF_RU_GU 0x49018
6276#define _PIPE_A_CSC_COEFF_BU 0x4901c
6277#define _PIPE_A_CSC_COEFF_RV_GV 0x49020
6278#define _PIPE_A_CSC_COEFF_BV 0x49024
6279
6280#define _PIPE_A_CSC_MODE 0x49028
6281#define ICL_CSC_ENABLE (1 << 31) /* icl+ */
6282#define ICL_OUTPUT_CSC_ENABLE (1 << 30) /* icl+ */
6283#define CSC_BLACK_SCREEN_OFFSET (1 << 2) /* ilk/snb */
6284#define CSC_POSITION_BEFORE_GAMMA (1 << 1) /* pre-glk */
6285#define CSC_MODE_YUV_TO_RGB (1 << 0) /* ilk/snb */
6286
6287#define _PIPE_A_CSC_PREOFF_HI 0x49030
6288#define _PIPE_A_CSC_PREOFF_ME 0x49034
6289#define _PIPE_A_CSC_PREOFF_LO 0x49038
6290#define _PIPE_A_CSC_POSTOFF_HI 0x49040
6291#define _PIPE_A_CSC_POSTOFF_ME 0x49044
6292#define _PIPE_A_CSC_POSTOFF_LO 0x49048
6293
6294#define _PIPE_B_CSC_COEFF_RY_GY 0x49110
6295#define _PIPE_B_CSC_COEFF_BY 0x49114
6296#define _PIPE_B_CSC_COEFF_RU_GU 0x49118
6297#define _PIPE_B_CSC_COEFF_BU 0x4911c
6298#define _PIPE_B_CSC_COEFF_RV_GV 0x49120
6299#define _PIPE_B_CSC_COEFF_BV 0x49124
6300#define _PIPE_B_CSC_MODE 0x49128
6301#define _PIPE_B_CSC_PREOFF_HI 0x49130
6302#define _PIPE_B_CSC_PREOFF_ME 0x49134
6303#define _PIPE_B_CSC_PREOFF_LO 0x49138
6304#define _PIPE_B_CSC_POSTOFF_HI 0x49140
6305#define _PIPE_B_CSC_POSTOFF_ME 0x49144
6306#define _PIPE_B_CSC_POSTOFF_LO 0x49148
6307
6308#define PIPE_CSC_COEFF_RY_GY(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RY_GY, _PIPE_B_CSC_COEFF_RY_GY)
6309#define PIPE_CSC_COEFF_BY(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BY, _PIPE_B_CSC_COEFF_BY)
6310#define PIPE_CSC_COEFF_RU_GU(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RU_GU, _PIPE_B_CSC_COEFF_RU_GU)
6311#define PIPE_CSC_COEFF_BU(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BU, _PIPE_B_CSC_COEFF_BU)
6312#define PIPE_CSC_COEFF_RV_GV(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_RV_GV, _PIPE_B_CSC_COEFF_RV_GV)
6313#define PIPE_CSC_COEFF_BV(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_COEFF_BV, _PIPE_B_CSC_COEFF_BV)
6314#define PIPE_CSC_MODE(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_MODE, _PIPE_B_CSC_MODE)
6315#define PIPE_CSC_PREOFF_HI(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_HI, _PIPE_B_CSC_PREOFF_HI)
6316#define PIPE_CSC_PREOFF_ME(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_ME, _PIPE_B_CSC_PREOFF_ME)
6317#define PIPE_CSC_PREOFF_LO(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_PREOFF_LO, _PIPE_B_CSC_PREOFF_LO)
6318#define PIPE_CSC_POSTOFF_HI(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_HI, _PIPE_B_CSC_POSTOFF_HI)
6319#define PIPE_CSC_POSTOFF_ME(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
6320#define PIPE_CSC_POSTOFF_LO(pipe) _MMIO_PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
6321
6322/* Pipe Output CSC */
6323#define _PIPE_A_OUTPUT_CSC_COEFF_RY_GY 0x49050
6324#define _PIPE_A_OUTPUT_CSC_COEFF_BY 0x49054
6325#define _PIPE_A_OUTPUT_CSC_COEFF_RU_GU 0x49058
6326#define _PIPE_A_OUTPUT_CSC_COEFF_BU 0x4905c
6327#define _PIPE_A_OUTPUT_CSC_COEFF_RV_GV 0x49060
6328#define _PIPE_A_OUTPUT_CSC_COEFF_BV 0x49064
6329#define _PIPE_A_OUTPUT_CSC_PREOFF_HI 0x49068
6330#define _PIPE_A_OUTPUT_CSC_PREOFF_ME 0x4906c
6331#define _PIPE_A_OUTPUT_CSC_PREOFF_LO 0x49070
6332#define _PIPE_A_OUTPUT_CSC_POSTOFF_HI 0x49074
6333#define _PIPE_A_OUTPUT_CSC_POSTOFF_ME 0x49078
6334#define _PIPE_A_OUTPUT_CSC_POSTOFF_LO 0x4907c
6335
6336#define _PIPE_B_OUTPUT_CSC_COEFF_RY_GY 0x49150
6337#define _PIPE_B_OUTPUT_CSC_COEFF_BY 0x49154
6338#define _PIPE_B_OUTPUT_CSC_COEFF_RU_GU 0x49158
6339#define _PIPE_B_OUTPUT_CSC_COEFF_BU 0x4915c
6340#define _PIPE_B_OUTPUT_CSC_COEFF_RV_GV 0x49160
6341#define _PIPE_B_OUTPUT_CSC_COEFF_BV 0x49164
6342#define _PIPE_B_OUTPUT_CSC_PREOFF_HI 0x49168
6343#define _PIPE_B_OUTPUT_CSC_PREOFF_ME 0x4916c
6344#define _PIPE_B_OUTPUT_CSC_PREOFF_LO 0x49170
6345#define _PIPE_B_OUTPUT_CSC_POSTOFF_HI 0x49174
6346#define _PIPE_B_OUTPUT_CSC_POSTOFF_ME 0x49178
6347#define _PIPE_B_OUTPUT_CSC_POSTOFF_LO 0x4917c
6348
6349#define PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe) _MMIO_PIPE(pipe,\
6350 _PIPE_A_OUTPUT_CSC_COEFF_RY_GY,\
6351 _PIPE_B_OUTPUT_CSC_COEFF_RY_GY)
6352#define PIPE_CSC_OUTPUT_COEFF_BY(pipe) _MMIO_PIPE(pipe, \
6353 _PIPE_A_OUTPUT_CSC_COEFF_BY, \
6354 _PIPE_B_OUTPUT_CSC_COEFF_BY)
6355#define PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe) _MMIO_PIPE(pipe, \
6356 _PIPE_A_OUTPUT_CSC_COEFF_RU_GU, \
6357 _PIPE_B_OUTPUT_CSC_COEFF_RU_GU)
6358#define PIPE_CSC_OUTPUT_COEFF_BU(pipe) _MMIO_PIPE(pipe, \
6359 _PIPE_A_OUTPUT_CSC_COEFF_BU, \
6360 _PIPE_B_OUTPUT_CSC_COEFF_BU)
6361#define PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe) _MMIO_PIPE(pipe, \
6362 _PIPE_A_OUTPUT_CSC_COEFF_RV_GV, \
6363 _PIPE_B_OUTPUT_CSC_COEFF_RV_GV)
6364#define PIPE_CSC_OUTPUT_COEFF_BV(pipe) _MMIO_PIPE(pipe, \
6365 _PIPE_A_OUTPUT_CSC_COEFF_BV, \
6366 _PIPE_B_OUTPUT_CSC_COEFF_BV)
6367#define PIPE_CSC_OUTPUT_PREOFF_HI(pipe) _MMIO_PIPE(pipe, \
6368 _PIPE_A_OUTPUT_CSC_PREOFF_HI, \
6369 _PIPE_B_OUTPUT_CSC_PREOFF_HI)
6370#define PIPE_CSC_OUTPUT_PREOFF_ME(pipe) _MMIO_PIPE(pipe, \
6371 _PIPE_A_OUTPUT_CSC_PREOFF_ME, \
6372 _PIPE_B_OUTPUT_CSC_PREOFF_ME)
6373#define PIPE_CSC_OUTPUT_PREOFF_LO(pipe) _MMIO_PIPE(pipe, \
6374 _PIPE_A_OUTPUT_CSC_PREOFF_LO, \
6375 _PIPE_B_OUTPUT_CSC_PREOFF_LO)
6376#define PIPE_CSC_OUTPUT_POSTOFF_HI(pipe) _MMIO_PIPE(pipe, \
6377 _PIPE_A_OUTPUT_CSC_POSTOFF_HI, \
6378 _PIPE_B_OUTPUT_CSC_POSTOFF_HI)
6379#define PIPE_CSC_OUTPUT_POSTOFF_ME(pipe) _MMIO_PIPE(pipe, \
6380 _PIPE_A_OUTPUT_CSC_POSTOFF_ME, \
6381 _PIPE_B_OUTPUT_CSC_POSTOFF_ME)
6382#define PIPE_CSC_OUTPUT_POSTOFF_LO(pipe) _MMIO_PIPE(pipe, \
6383 _PIPE_A_OUTPUT_CSC_POSTOFF_LO, \
6384 _PIPE_B_OUTPUT_CSC_POSTOFF_LO)
6385
6386/* pipe degamma/gamma LUTs on IVB+ */
6387#define _PAL_PREC_INDEX_A 0x4A400
6388#define _PAL_PREC_INDEX_B 0x4AC00
6389#define _PAL_PREC_INDEX_C 0x4B400
6390#define PAL_PREC_SPLIT_MODE REG_BIT(31)
6391#define PAL_PREC_AUTO_INCREMENT REG_BIT(15)
6392#define PAL_PREC_INDEX_VALUE_MASK REG_GENMASK(9, 0)
6393#define PAL_PREC_INDEX_VALUE(x) REG_FIELD_PREP(PAL_PREC_INDEX_VALUE_MASK, (x))
6394#define _PAL_PREC_DATA_A 0x4A404
6395#define _PAL_PREC_DATA_B 0x4AC04
6396#define _PAL_PREC_DATA_C 0x4B404
6397/* see PREC_PALETTE_* for the bits */
6398#define _PAL_PREC_GC_MAX_A 0x4A410
6399#define _PAL_PREC_GC_MAX_B 0x4AC10
6400#define _PAL_PREC_GC_MAX_C 0x4B410
6401#define _PAL_PREC_EXT_GC_MAX_A 0x4A420
6402#define _PAL_PREC_EXT_GC_MAX_B 0x4AC20
6403#define _PAL_PREC_EXT_GC_MAX_C 0x4B420
6404#define _PAL_PREC_EXT2_GC_MAX_A 0x4A430
6405#define _PAL_PREC_EXT2_GC_MAX_B 0x4AC30
6406#define _PAL_PREC_EXT2_GC_MAX_C 0x4B430
6407
6408#define PREC_PAL_INDEX(pipe) _MMIO_PIPE(pipe, _PAL_PREC_INDEX_A, _PAL_PREC_INDEX_B)
6409#define PREC_PAL_DATA(pipe) _MMIO_PIPE(pipe, _PAL_PREC_DATA_A, _PAL_PREC_DATA_B)
6410#define PREC_PAL_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_GC_MAX_A, _PAL_PREC_GC_MAX_B) + (i) * 4) /* u1.16 */
6411#define PREC_PAL_EXT_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT_GC_MAX_A, _PAL_PREC_EXT_GC_MAX_B) + (i) * 4) /* u3.16 */
6412#define PREC_PAL_EXT2_GC_MAX(pipe, i) _MMIO(_PIPE(pipe, _PAL_PREC_EXT2_GC_MAX_A, _PAL_PREC_EXT2_GC_MAX_B) + (i) * 4) /* glk+, u3.16 */
6413
6414#define _PRE_CSC_GAMC_INDEX_A 0x4A484
6415#define _PRE_CSC_GAMC_INDEX_B 0x4AC84
6416#define _PRE_CSC_GAMC_INDEX_C 0x4B484
6417#define PRE_CSC_GAMC_AUTO_INCREMENT REG_BIT(10)
6418#define PRE_CSC_GAMC_INDEX_VALUE_MASK REG_GENMASK(7, 0)
6419#define PRE_CSC_GAMC_INDEX_VALUE(x) REG_FIELD_PREP(PRE_CSC_GAMC_INDEX_VALUE_MASK, (x))
6420#define _PRE_CSC_GAMC_DATA_A 0x4A488
6421#define _PRE_CSC_GAMC_DATA_B 0x4AC88
6422#define _PRE_CSC_GAMC_DATA_C 0x4B488
6423
6424#define PRE_CSC_GAMC_INDEX(pipe) _MMIO_PIPE(pipe, _PRE_CSC_GAMC_INDEX_A, _PRE_CSC_GAMC_INDEX_B)
6425#define PRE_CSC_GAMC_DATA(pipe) _MMIO_PIPE(pipe, _PRE_CSC_GAMC_DATA_A, _PRE_CSC_GAMC_DATA_B)
6426
6427/* ICL Multi segmented gamma */
6428#define _PAL_PREC_MULTI_SEG_INDEX_A 0x4A408
6429#define _PAL_PREC_MULTI_SEG_INDEX_B 0x4AC08
6430#define PAL_PREC_MULTI_SEG_AUTO_INCREMENT REG_BIT(15)
6431#define PAL_PREC_MULTI_SEG_INDEX_VALUE_MASK REG_GENMASK(4, 0)
6432#define PAL_PREC_MULTI_SEG_INDEX_VALUE(x) REG_FIELD_PREP(PAL_PREC_MULTI_SEG_INDEX_VALUE_MASK, (x))
6433
6434#define _PAL_PREC_MULTI_SEG_DATA_A 0x4A40C
6435#define _PAL_PREC_MULTI_SEG_DATA_B 0x4AC0C
6436/* see PREC_PALETTE_12P4_* for the bits */
6437
6438#define PREC_PAL_MULTI_SEG_INDEX(pipe) _MMIO_PIPE(pipe, \
6439 _PAL_PREC_MULTI_SEG_INDEX_A, \
6440 _PAL_PREC_MULTI_SEG_INDEX_B)
6441#define PREC_PAL_MULTI_SEG_DATA(pipe) _MMIO_PIPE(pipe, \
6442 _PAL_PREC_MULTI_SEG_DATA_A, \
6443 _PAL_PREC_MULTI_SEG_DATA_B)
6444
6445#define _MMIO_PLANE_GAMC(plane, i, a, b) _MMIO(_PIPE(plane, a, b) + (i) * 4)6226#define _MMIO_PLANE_GAMC(plane, i, a, b) _MMIO(_PIPE(plane, a, b) + (i) * 4)
6446 6227
6447/* Plane CSC Registers */6228/* Plane CSC Registers */
@@ -6487,61 +6268,6 @@ enum skl_power_gate { · 39 unmodified lines
6487 (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \6268 (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
6488 (index) * 4)6269 (index) * 4)
6489 6270
6490#define _PIPE_A_WGC_C01_C00 0x600B0 /* s2.10 */
6491#define _PIPE_A_WGC_C02 0x600B4 /* s2.10 */
6492#define _PIPE_A_WGC_C11_C10 0x600B8 /* s2.10 */
6493#define _PIPE_A_WGC_C12 0x600BC /* s2.10 */
6494#define _PIPE_A_WGC_C21_C20 0x600C0 /* s2.10 */
6495#define _PIPE_A_WGC_C22 0x600C4 /* s2.10 */
6496
6497#define PIPE_WGC_C01_C00(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C01_C00)
6498#define PIPE_WGC_C02(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C02)
6499#define PIPE_WGC_C11_C10(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C11_C10)
6500#define PIPE_WGC_C12(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C12)
6501#define PIPE_WGC_C21_C20(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C21_C20)
6502#define PIPE_WGC_C22(pipe) _MMIO_TRANS2(pipe, _PIPE_A_WGC_C22)
6503
6504/* pipe CSC & degamma/gamma LUTs on CHV */
6505#define _CGM_PIPE_A_CSC_COEFF01 (VLV_DISPLAY_BASE + 0x67900)
6506#define _CGM_PIPE_A_CSC_COEFF23 (VLV_DISPLAY_BASE + 0x67904)
6507#define _CGM_PIPE_A_CSC_COEFF45 (VLV_DISPLAY_BASE + 0x67908)
6508#define _CGM_PIPE_A_CSC_COEFF67 (VLV_DISPLAY_BASE + 0x6790C)
6509#define _CGM_PIPE_A_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x67910)
6510#define _CGM_PIPE_A_DEGAMMA (VLV_DISPLAY_BASE + 0x66000)
6511/* cgm degamma ldw */
6512#define CGM_PIPE_DEGAMMA_GREEN_LDW_MASK REG_GENMASK(29, 16)
6513#define CGM_PIPE_DEGAMMA_BLUE_LDW_MASK REG_GENMASK(13, 0)
6514/* cgm degamma udw */
6515#define CGM_PIPE_DEGAMMA_RED_UDW_MASK REG_GENMASK(13, 0)
6516#define _CGM_PIPE_A_GAMMA (VLV_DISPLAY_BASE + 0x67000)
6517/* cgm gamma ldw */
6518#define CGM_PIPE_GAMMA_GREEN_LDW_MASK REG_GENMASK(25, 16)
6519#define CGM_PIPE_GAMMA_BLUE_LDW_MASK REG_GENMASK(9, 0)
6520/* cgm gamma udw */
6521#define CGM_PIPE_GAMMA_RED_UDW_MASK REG_GENMASK(9, 0)
6522#define _CGM_PIPE_A_MODE (VLV_DISPLAY_BASE + 0x67A00)
6523#define CGM_PIPE_MODE_GAMMA (1 << 2)
6524#define CGM_PIPE_MODE_CSC (1 << 1)
6525#define CGM_PIPE_MODE_DEGAMMA (1 << 0)
6526
6527#define _CGM_PIPE_B_CSC_COEFF01 (VLV_DISPLAY_BASE + 0x69900)
6528#define _CGM_PIPE_B_CSC_COEFF23 (VLV_DISPLAY_BASE + 0x69904)
6529#define _CGM_PIPE_B_CSC_COEFF45 (VLV_DISPLAY_BASE + 0x69908)
6530#define _CGM_PIPE_B_CSC_COEFF67 (VLV_DISPLAY_BASE + 0x6990C)
6531#define _CGM_PIPE_B_CSC_COEFF8 (VLV_DISPLAY_BASE + 0x69910)
6532#define _CGM_PIPE_B_DEGAMMA (VLV_DISPLAY_BASE + 0x68000)
6533#define _CGM_PIPE_B_GAMMA (VLV_DISPLAY_BASE + 0x69000)
6534#define _CGM_PIPE_B_MODE (VLV_DISPLAY_BASE + 0x69A00)
6535
6536#define CGM_PIPE_CSC_COEFF01(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF01, _CGM_PIPE_B_CSC_COEFF01)
6537#define CGM_PIPE_CSC_COEFF23(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF23, _CGM_PIPE_B_CSC_COEFF23)
6538#define CGM_PIPE_CSC_COEFF45(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF45, _CGM_PIPE_B_CSC_COEFF45)
6539#define CGM_PIPE_CSC_COEFF67(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF67, _CGM_PIPE_B_CSC_COEFF67)
6540#define CGM_PIPE_CSC_COEFF8(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_CSC_COEFF8, _CGM_PIPE_B_CSC_COEFF8)
6541#define CGM_PIPE_DEGAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_DEGAMMA, _CGM_PIPE_B_DEGAMMA) + (i) * 8 + (w) * 4)
6542#define CGM_PIPE_GAMMA(pipe, i, w) _MMIO(_PIPE(pipe, _CGM_PIPE_A_GAMMA, _CGM_PIPE_B_GAMMA) + (i) * 8 + (w) * 4)
6543#define CGM_PIPE_MODE(pipe) _MMIO_PIPE(pipe, _CGM_PIPE_A_MODE, _CGM_PIPE_B_MODE)
6544
6545/* Gen4+ Timestamp and Pipe Frame time stamp registers */6271/* Gen4+ Timestamp and Pipe Frame time stamp registers */
6546#define GEN4_TIMESTAMP _MMIO(0x2358)6272#define GEN4_TIMESTAMP _MMIO(0x2358)
6547#define ILK_TIMESTAMP_HI _MMIO(0x70070)6273#define ILK_TIMESTAMP_HI _MMIO(0x70070)
@@ -6624,6 +6350,7 @@ enum skl_power_gate { · 76 unmodified lines
6624#define TCSS_DDI_STATUS(tc) _MMIO(_PICK_EVEN(tc, \6350#define TCSS_DDI_STATUS(tc) _MMIO(_PICK_EVEN(tc, \
6625 _TCSS_DDI_STATUS_1, \6351 _TCSS_DDI_STATUS_1, \
6626 _TCSS_DDI_STATUS_2))6352 _TCSS_DDI_STATUS_2))
6353#define TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK REG_GENMASK(28, 25)
6627#define TCSS_DDI_STATUS_READY REG_BIT(2)6354#define TCSS_DDI_STATUS_READY REG_BIT(2)
6628#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT REG_BIT(1)6355#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT REG_BIT(1)
6629#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT REG_BIT(0)6356#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT REG_BIT(0)
drivers/gpu/drm/i915/i915_vma.c+1−0
@@ -29,6 +29,7 @@ · 28 unmodified lines
29#include "display/intel_display.h"29#include "display/intel_display.h"
30#include "display/intel_frontbuffer.h"30#include "display/intel_frontbuffer.h"
31#include "gem/i915_gem_lmem.h"31#include "gem/i915_gem_lmem.h"
32#include "gem/i915_gem_object_frontbuffer.h"
32#include "gem/i915_gem_tiling.h"33#include "gem/i915_gem_tiling.h"
33#include "gt/intel_engine.h"34#include "gt/intel_engine.h"
34#include "gt/intel_engine_heartbeat.h"35#include "gt/intel_engine_heartbeat.h"
drivers/gpu/drm/i915/i915_vma_resource.c+1−1
@@ -94,7 +94,7 @@ static void unbind_fence_release(struct dma_fence *fence) · 93 unmodified lines
94 call_rcu(&fence->rcu, unbind_fence_free_rcu);94 call_rcu(&fence->rcu, unbind_fence_free_rcu);
95}95}
96 96
97static struct dma_fence_ops unbind_fence_ops = {97static const struct dma_fence_ops unbind_fence_ops = {
98 .get_driver_name = get_driver_name,98 .get_driver_name = get_driver_name,
99 .get_timeline_name = get_timeline_name,99 .get_timeline_name = get_timeline_name,
100 .release = unbind_fence_release,100 .release = unbind_fence_release,
drivers/gpu/drm/i915/intel_clock_gating.c+2−50
@@ -349,41 +349,6 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *i915, · 348 unmodified lines
349 intel_uncore_write(&i915->uncore, GEN7_MISCCPCTL, misccpctl);349 intel_uncore_write(&i915->uncore, GEN7_MISCCPCTL, misccpctl);
350}350}
351 351
352static void icl_init_clock_gating(struct drm_i915_private *i915)
353{
354 /* Wa_1409120013:icl,ehl */
355 intel_uncore_write(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A),
356 DPFC_CHICKEN_COMP_DUMMY_PIXEL);
357
358 /*Wa_14010594013:icl, ehl */
359 intel_uncore_rmw(&i915->uncore, GEN8_CHICKEN_DCPR_1,
360 0, ICL_DELAY_PMRSP);
361}
362
363static void gen12lp_init_clock_gating(struct drm_i915_private *i915)
364{
365 /* Wa_1409120013 */
366 if (DISPLAY_VER(i915) == 12)
367 intel_uncore_write(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A),
368 DPFC_CHICKEN_COMP_DUMMY_PIXEL);
369
370 /* Wa_14013723622:tgl,rkl,dg1,adl-s */
371 if (DISPLAY_VER(i915) == 12)
372 intel_uncore_rmw(&i915->uncore, CLKREQ_POLICY,
373 CLKREQ_POLICY_MEM_UP_OVRD, 0);
374}
375
376static void adlp_init_clock_gating(struct drm_i915_private *i915)
377{
378 gen12lp_init_clock_gating(i915);
379
380 /* Wa_22011091694:adlp */
381 intel_de_rmw(i915, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS);
382
383 /* Bspec/49189 Initialize Sequence */
384 intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0);
385}
386
387static void xehpsdv_init_clock_gating(struct drm_i915_private *i915)352static void xehpsdv_init_clock_gating(struct drm_i915_private *i915)
388{353{
389 /* Wa_22010146351:xehpsdv */354 /* Wa_22010146351:xehpsdv */
@@ -800,9 +765,6 @@ static const struct drm_i915_clock_gating_funcs platform##_clock_gating_funcs = · 410 unmodified lines
800CG_FUNCS(pvc);765CG_FUNCS(pvc);
801CG_FUNCS(dg2);766CG_FUNCS(dg2);
802CG_FUNCS(xehpsdv);767CG_FUNCS(xehpsdv);
803CG_FUNCS(adlp);
804CG_FUNCS(gen12lp);
805CG_FUNCS(icl);
806CG_FUNCS(cfl);768CG_FUNCS(cfl);
807CG_FUNCS(skl);769CG_FUNCS(skl);
808CG_FUNCS(kbl);770CG_FUNCS(kbl);
@@ -835,20 +797,12 @@ CG_FUNCS(nop); · 26 unmodified lines
835 */797 */
836void intel_clock_gating_hooks_init(struct drm_i915_private *i915)798void intel_clock_gating_hooks_init(struct drm_i915_private *i915)
837{799{
838 if (IS_METEORLAKE(i915))800 if (IS_PONTEVECCHIO(i915))
839 i915->clock_gating_funcs = &nop_clock_gating_funcs;
840 else if (IS_PONTEVECCHIO(i915))
841 i915->clock_gating_funcs = &pvc_clock_gating_funcs;801 i915->clock_gating_funcs = &pvc_clock_gating_funcs;
842 else if (IS_DG2(i915))802 else if (IS_DG2(i915))
843 i915->clock_gating_funcs = &dg2_clock_gating_funcs;803 i915->clock_gating_funcs = &dg2_clock_gating_funcs;
844 else if (IS_XEHPSDV(i915))804 else if (IS_XEHPSDV(i915))
845 i915->clock_gating_funcs = &xehpsdv_clock_gating_funcs;805 i915->clock_gating_funcs = &xehpsdv_clock_gating_funcs;
846 else if (IS_ALDERLAKE_P(i915))
847 i915->clock_gating_funcs = &adlp_clock_gating_funcs;
848 else if (GRAPHICS_VER(i915) == 12)
849 i915->clock_gating_funcs = &gen12lp_clock_gating_funcs;
850 else if (GRAPHICS_VER(i915) == 11)
851 i915->clock_gating_funcs = &icl_clock_gating_funcs;
852 else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))806 else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
853 i915->clock_gating_funcs = &cfl_clock_gating_funcs;807 i915->clock_gating_funcs = &cfl_clock_gating_funcs;
854 else if (IS_SKYLAKE(i915))808 else if (IS_SKYLAKE(i915))
@@ -885,8 +839,6 @@ void intel_clock_gating_hooks_init(struct drm_i915_private *i915) · 30 unmodified lines
885 i915->clock_gating_funcs = &i85x_clock_gating_funcs;839 i915->clock_gating_funcs = &i85x_clock_gating_funcs;
886 else if (GRAPHICS_VER(i915) == 2)840 else if (GRAPHICS_VER(i915) == 2)
887 i915->clock_gating_funcs = &i830_clock_gating_funcs;841 i915->clock_gating_funcs = &i830_clock_gating_funcs;
888 else {842 else
889 MISSING_CASE(INTEL_DEVID(i915));
890 i915->clock_gating_funcs = &nop_clock_gating_funcs;843 i915->clock_gating_funcs = &nop_clock_gating_funcs;
891 }
892}844}
drivers/gpu/drm/i915/intel_device_info.c+0−14
@@ -410,7 +410,6 @@ void intel_device_info_driver_create(struct drm_i915_private *i915, · 409 unmodified lines
410 const struct intel_device_info *match_info)410 const struct intel_device_info *match_info)
411{411{
412 struct intel_runtime_info *runtime;412 struct intel_runtime_info *runtime;
413 u16 ver, rel, step;
414 413
415 /* Setup INTEL_INFO() */414 /* Setup INTEL_INFO() */
416 i915->__info = match_info;415 i915->__info = match_info;
@@ -419,19 +418,6 @@ void intel_device_info_driver_create(struct drm_i915_private *i915, · 2 unmodified lines
419 runtime = RUNTIME_INFO(i915);418 runtime = RUNTIME_INFO(i915);
420 memcpy(runtime, &INTEL_INFO(i915)->__runtime, sizeof(*runtime));419 memcpy(runtime, &INTEL_INFO(i915)->__runtime, sizeof(*runtime));
421 420
422 /* Probe display support */
423 i915->display.info.__device_info = intel_display_device_probe(i915, HAS_GMD_ID(i915),
424 &ver, &rel, &step);
425 memcpy(DISPLAY_RUNTIME_INFO(i915),
426 &DISPLAY_INFO(i915)->__runtime_defaults,
427 sizeof(*DISPLAY_RUNTIME_INFO(i915)));
428
429 if (HAS_GMD_ID(i915)) {
430 DISPLAY_RUNTIME_INFO(i915)->ip.ver = ver;
431 DISPLAY_RUNTIME_INFO(i915)->ip.rel = rel;
432 DISPLAY_RUNTIME_INFO(i915)->ip.step = step;
433 }
434
435 runtime->device_id = device_id;421 runtime->device_id = device_id;
436}422}
437 423
drivers/gpu/drm/i915/intel_device_info.h+0−1
@@ -146,7 +146,6 @@ enum intel_ppgtt_type { · 145 unmodified lines
146 func(gpu_reset_clobbers_display); \146 func(gpu_reset_clobbers_display); \
147 func(has_reset_engine); \147 func(has_reset_engine); \
148 func(has_3d_pipeline); \148 func(has_3d_pipeline); \
149 func(has_4tile); \
150 func(has_flat_ccs); \149 func(has_flat_ccs); \
151 func(has_global_mocs); \150 func(has_global_mocs); \
152 func(has_gmd_id); \151 func(has_gmd_id); \
drivers/gpu/drm/i915/intel_gvt_mmio_table.c+1−0
@@ -5,6 +5,7 @@ · 4 unmodified lines
5 5
6#include "display/intel_audio_regs.h"6#include "display/intel_audio_regs.h"
7#include "display/intel_backlight_regs.h"7#include "display/intel_backlight_regs.h"
8#include "display/intel_color_regs.h"
8#include "display/intel_display_types.h"9#include "display/intel_display_types.h"
9#include "display/intel_dmc_regs.h"10#include "display/intel_dmc_regs.h"
10#include "display/intel_dp_aux_regs.h"11#include "display/intel_dp_aux_regs.h"
drivers/gpu/drm/i915/intel_runtime_pm.c+0−1
@@ -652,7 +652,6 @@ void intel_runtime_pm_init_early(struct intel_runtime_pm *rpm) · 651 unmodified lines
652 652
653 rpm->kdev = kdev;653 rpm->kdev = kdev;
654 rpm->available = HAS_RUNTIME_PM(i915);654 rpm->available = HAS_RUNTIME_PM(i915);
655 rpm->suspended = false;
656 atomic_set(&rpm->wakeref_count, 0);655 atomic_set(&rpm->wakeref_count, 0);
657 656
658 init_intel_runtime_pm_wakeref(rpm);657 init_intel_runtime_pm_wakeref(rpm);
drivers/gpu/drm/i915/intel_runtime_pm.h+2−2
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#ifndef __INTEL_RUNTIME_PM_H__6#ifndef __INTEL_RUNTIME_PM_H__
7#define __INTEL_RUNTIME_PM_H__7#define __INTEL_RUNTIME_PM_H__
8 8
9#include <linux/pm_runtime.h>
9#include <linux/types.h>10#include <linux/types.h>
10 11
11#include "intel_wakeref.h"12#include "intel_wakeref.h"
@@ -43,7 +44,6 @@ struct intel_runtime_pm { · 31 unmodified lines
43 atomic_t wakeref_count;44 atomic_t wakeref_count;
44 struct device *kdev; /* points to i915->drm.dev */45 struct device *kdev; /* points to i915->drm.dev */
45 bool available;46 bool available;
46 bool suspended;
47 bool irqs_enabled;47 bool irqs_enabled;
48 bool no_wakeref_tracking;48 bool no_wakeref_tracking;
49 49
@@ -110,7 +110,7 @@ intel_rpm_wakelock_count(int wakeref_count) · 60 unmodified lines
110static inline void110static inline void
111assert_rpm_device_not_suspended(struct intel_runtime_pm *rpm)111assert_rpm_device_not_suspended(struct intel_runtime_pm *rpm)
112{112{
113 WARN_ONCE(rpm->suspended,113 WARN_ONCE(pm_runtime_suspended(rpm->kdev),
114 "Device suspended during HW access\n");114 "Device suspended during HW access\n");
115}115}
116 116
drivers/gpu/drm/i915/intel_step.c+1−0
@@ -124,6 +124,7 @@ static const struct intel_step_info dg2_g11_revid_step_tbl[] = { · 123 unmodified lines
124 124
125static const struct intel_step_info dg2_g12_revid_step_tbl[] = {125static const struct intel_step_info dg2_g12_revid_step_tbl[] = {
126 [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_C0 },126 [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_C0 },
127 [0x1] = { COMMON_GT_MEDIA_STEP(A1), .display_step = STEP_C0 },
127};128};
128 129
129static const struct intel_step_info adls_rpls_revids[] = {130static const struct intel_step_info adls_rpls_revids[] = {
drivers/gpu/drm/i915/pxp/intel_pxp.c+33−7
@@ -359,22 +359,46 @@ void intel_pxp_end(struct intel_pxp *pxp) · 358 unmodified lines
359 intel_runtime_pm_put(&i915->runtime_pm, wakeref);359 intel_runtime_pm_put(&i915->runtime_pm, wakeref);
360}360}
361 361
362static bool pxp_required_fw_failed(struct intel_pxp *pxp)
363{
364 if (__intel_uc_fw_status(&pxp->ctrl_gt->uc.huc.fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)
365 return true;
366 if (HAS_ENGINE(pxp->ctrl_gt, GSC0) &&
367 __intel_uc_fw_status(&pxp->ctrl_gt->uc.gsc.fw) == INTEL_UC_FIRMWARE_LOAD_FAIL)
368 return true;
369
370 return false;
371}
372
373static bool pxp_fw_dependencies_completed(struct intel_pxp *pxp)
374{
375 if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
376 return intel_pxp_gsccs_is_ready_for_sessions(pxp);
377
378 return pxp_component_bound(pxp);
379}
380
362/*381/*
363 * this helper is used by both intel_pxp_start and by382 * this helper is used by both intel_pxp_start and by
364 * the GET_PARAM IOCTL that user space calls. Thus, the383 * the GET_PARAM IOCTL that user space calls. Thus, the
365 * return values here should match the UAPI spec.384 * return values here should match the UAPI spec.
366 */385 */
367int intel_pxp_get_readiness_status(struct intel_pxp *pxp)386int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms)
368{387{
369 if (!intel_pxp_is_enabled(pxp))388 if (!intel_pxp_is_enabled(pxp))
370 return -ENODEV;389 return -ENODEV;
371 390
372 if (HAS_ENGINE(pxp->ctrl_gt, GSC0)) {391 if (pxp_required_fw_failed(pxp))
373 if (wait_for(intel_pxp_gsccs_is_ready_for_sessions(pxp), 250))392 return -ENODEV;
374 return 2;393
375 } else {394 if (pxp->platform_cfg_is_bad)
376 if (wait_for(pxp_component_bound(pxp), 250))395 return -ENODEV;
396
397 if (timeout_ms) {
398 if (wait_for(pxp_fw_dependencies_completed(pxp), timeout_ms))
377 return 2;399 return 2;
400 } else if (!pxp_fw_dependencies_completed(pxp)) {
401 return 2;
378 }402 }
379 return 1;403 return 1;
380}404}
@@ -383,11 +407,13 @@ int intel_pxp_get_readiness_status(struct intel_pxp *pxp) · 2 unmodified lines
383 * the arb session is restarted from the irq work when we receive the407 * the arb session is restarted from the irq work when we receive the
384 * termination completion interrupt408 * termination completion interrupt
385 */409 */
410#define PXP_READINESS_TIMEOUT 250
411
386int intel_pxp_start(struct intel_pxp *pxp)412int intel_pxp_start(struct intel_pxp *pxp)
387{413{
388 int ret = 0;414 int ret = 0;
389 415
390 ret = intel_pxp_get_readiness_status(pxp);416 ret = intel_pxp_get_readiness_status(pxp, PXP_READINESS_TIMEOUT);
391 if (ret < 0)417 if (ret < 0)
392 return ret;418 return ret;
393 else if (ret > 1)419 else if (ret > 1)
drivers/gpu/drm/i915/pxp/intel_pxp.h+1−1
@@ -26,7 +26,7 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp); · 25 unmodified lines
26void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);26void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
27void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);27void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id);
28 28
29int intel_pxp_get_readiness_status(struct intel_pxp *pxp);29int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms);
30int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp);30int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp);
31int intel_pxp_start(struct intel_pxp *pxp);31int intel_pxp_start(struct intel_pxp *pxp);
32void intel_pxp_end(struct intel_pxp *pxp);32void intel_pxp_end(struct intel_pxp *pxp);
drivers/gpu/drm/i915/pxp/intel_pxp_gsccs.c+4−3
@@ -18,12 +18,13 @@ · 17 unmodified lines
18#include "intel_pxp_types.h"18#include "intel_pxp_types.h"
19 19
20static bool20static bool
21is_fw_err_platform_config(u32 type)21is_fw_err_platform_config(struct intel_pxp *pxp, u32 type)
22{22{
23 switch (type) {23 switch (type) {
24 case PXP_STATUS_ERROR_API_VERSION:24 case PXP_STATUS_ERROR_API_VERSION:
25 case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:25 case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
26 case PXP_STATUS_PLATFCONFIG_KF1_BAD:26 case PXP_STATUS_PLATFCONFIG_KF1_BAD:
27 pxp->platform_cfg_is_bad = true;
27 return true;28 return true;
28 default:29 default:
29 break;30 break;
@@ -226,7 +227,7 @@ int intel_pxp_gsccs_create_session(struct intel_pxp *pxp, · 196 unmodified lines
226 if (ret) {227 if (ret) {
227 drm_err(&i915->drm, "Failed to init session %d, ret=[%d]\n", arb_session_id, ret);228 drm_err(&i915->drm, "Failed to init session %d, ret=[%d]\n", arb_session_id, ret);
228 } else if (msg_out.header.status != 0) {229 } else if (msg_out.header.status != 0) {
229 if (is_fw_err_platform_config(msg_out.header.status)) {230 if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
230 drm_info_once(&i915->drm,231 drm_info_once(&i915->drm,
231 "PXP init-session-%d failed due to BIOS/SOC:0x%08x:%s\n",232 "PXP init-session-%d failed due to BIOS/SOC:0x%08x:%s\n",
232 arb_session_id, msg_out.header.status,233 arb_session_id, msg_out.header.status,
@@ -269,7 +270,7 @@ void intel_pxp_gsccs_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id) · 36 unmodified lines
269 drm_err(&i915->drm, "Failed to inv-stream-key-%u, ret=[%d]\n",270 drm_err(&i915->drm, "Failed to inv-stream-key-%u, ret=[%d]\n",
270 session_id, ret);271 session_id, ret);
271 } else if (msg_out.header.status != 0) {272 } else if (msg_out.header.status != 0) {
272 if (is_fw_err_platform_config(msg_out.header.status)) {273 if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
273 drm_info_once(&i915->drm,274 drm_info_once(&i915->drm,
274 "PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",275 "PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",
275 session_id, msg_out.header.status,276 session_id, msg_out.header.status,
drivers/gpu/drm/i915/pxp/intel_pxp_pm.c+17−1
@@ -34,8 +34,10 @@ void intel_pxp_suspend(struct intel_pxp *pxp) · 33 unmodified lines
34 }34 }
35}35}
36 36
37void intel_pxp_resume_complete(struct intel_pxp *pxp)37static void _pxp_resume(struct intel_pxp *pxp, bool take_wakeref)
38{38{
39 intel_wakeref_t wakeref;
40
39 if (!intel_pxp_is_enabled(pxp))41 if (!intel_pxp_is_enabled(pxp))
40 return;42 return;
41 43
@@ -48,7 +50,21 @@ void intel_pxp_resume_complete(struct intel_pxp *pxp) · 6 unmodified lines
48 if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)50 if (!HAS_ENGINE(pxp->ctrl_gt, GSC0) && !pxp->pxp_component)
49 return;51 return;
50 52
53 if (take_wakeref)
54 wakeref = intel_runtime_pm_get(&pxp->ctrl_gt->i915->runtime_pm);
51 intel_pxp_init_hw(pxp);55 intel_pxp_init_hw(pxp);
56 if (take_wakeref)
57 intel_runtime_pm_put(&pxp->ctrl_gt->i915->runtime_pm, wakeref);
58}
59
60void intel_pxp_resume_complete(struct intel_pxp *pxp)
61{
62 _pxp_resume(pxp, true);
63}
64
65void intel_pxp_runtime_resume(struct intel_pxp *pxp)
66{
67 _pxp_resume(pxp, false);
52}68}
53 69
54void intel_pxp_runtime_suspend(struct intel_pxp *pxp)70void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
drivers/gpu/drm/i915/pxp/intel_pxp_pm.h+3−2
@@ -13,6 +13,7 @@ void intel_pxp_suspend_prepare(struct intel_pxp *pxp); · 12 unmodified lines
13void intel_pxp_suspend(struct intel_pxp *pxp);13void intel_pxp_suspend(struct intel_pxp *pxp);
14void intel_pxp_resume_complete(struct intel_pxp *pxp);14void intel_pxp_resume_complete(struct intel_pxp *pxp);
15void intel_pxp_runtime_suspend(struct intel_pxp *pxp);15void intel_pxp_runtime_suspend(struct intel_pxp *pxp);
16void intel_pxp_runtime_resume(struct intel_pxp *pxp);
16#else17#else
17static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp)18static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
18{19{
@@ -29,9 +30,9 @@ static inline void intel_pxp_resume_complete(struct intel_pxp *pxp) · 10 unmodified lines
29static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp)30static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
30{31{
31}32}
32#endif33
33static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp)34static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp)
34{35{
35 intel_pxp_resume_complete(pxp);
36}36}
37#endif
37#endif /* __INTEL_PXP_PM_H__ */38#endif /* __INTEL_PXP_PM_H__ */
drivers/gpu/drm/i915/pxp/intel_pxp_tee.c+4−3
@@ -22,12 +22,13 @@ · 21 unmodified lines
22#include "intel_pxp_types.h"22#include "intel_pxp_types.h"
23 23
24static bool24static bool
25is_fw_err_platform_config(u32 type)25is_fw_err_platform_config(struct intel_pxp *pxp, u32 type)
26{26{
27 switch (type) {27 switch (type) {
28 case PXP_STATUS_ERROR_API_VERSION:28 case PXP_STATUS_ERROR_API_VERSION:
29 case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:29 case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF:
30 case PXP_STATUS_PLATFCONFIG_KF1_BAD:30 case PXP_STATUS_PLATFCONFIG_KF1_BAD:
31 pxp->platform_cfg_is_bad = true;
31 return true;32 return true;
32 default:33 default:
33 break;34 break;
@@ -344,7 +345,7 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp, · 310 unmodified lines
344 if (ret) {345 if (ret) {
345 drm_err(&i915->drm, "Failed to send tee msg init arb session, ret=[%d]\n", ret);346 drm_err(&i915->drm, "Failed to send tee msg init arb session, ret=[%d]\n", ret);
346 } else if (msg_out.header.status != 0) {347 } else if (msg_out.header.status != 0) {
347 if (is_fw_err_platform_config(msg_out.header.status)) {348 if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
348 drm_info_once(&i915->drm,349 drm_info_once(&i915->drm,
349 "PXP init-arb-session-%d failed due to BIOS/SOC:0x%08x:%s\n",350 "PXP init-arb-session-%d failed due to BIOS/SOC:0x%08x:%s\n",
350 arb_session_id, msg_out.header.status,351 arb_session_id, msg_out.header.status,
@@ -392,7 +393,7 @@ try_again: · 41 unmodified lines
392 drm_err(&i915->drm, "Failed to send tee msg for inv-stream-key-%u, ret=[%d]\n",393 drm_err(&i915->drm, "Failed to send tee msg for inv-stream-key-%u, ret=[%d]\n",
393 session_id, ret);394 session_id, ret);
394 } else if (msg_out.header.status != 0) {395 } else if (msg_out.header.status != 0) {
395 if (is_fw_err_platform_config(msg_out.header.status)) {396 if (is_fw_err_platform_config(pxp, msg_out.header.status)) {
396 drm_info_once(&i915->drm,397 drm_info_once(&i915->drm,
397 "PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",398 "PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n",
398 session_id, msg_out.header.status,399 session_id, msg_out.header.status,
drivers/gpu/drm/i915/pxp/intel_pxp_types.h+9−0
@@ -26,6 +26,15 @@ struct intel_pxp { · 25 unmodified lines
26 */26 */
27 struct intel_gt *ctrl_gt;27 struct intel_gt *ctrl_gt;
28 28
29 /**
30 * @platform_cfg_is_bad: used to track if any prior arb session creation resulted
31 * in a failure that was caused by a platform configuration issue, meaning that
32 * failure will not get resolved without a change to the platform (not kernel)
33 * such as BIOS configuration, firwmware update, etc. This bool gets reflected when
34 * GET_PARAM:I915_PARAM_PXP_STATUS is called.
35 */
36 bool platform_cfg_is_bad;
37
29 /**38 /**
30 * @kcr_base: base mmio offset for the KCR engine which is different on legacy platforms39 * @kcr_base: base mmio offset for the KCR engine which is different on legacy platforms
31 * vs newer platforms where the KCR is inside the media-tile.40 * vs newer platforms where the KCR is inside the media-tile.
drivers/gpu/drm/i915/selftests/mock_gem_device.c+2−0
@@ -181,6 +181,8 @@ struct drm_i915_private *mock_gem_device(void) · 180 unmodified lines
181 /* Set up device info and initial runtime info. */181 /* Set up device info and initial runtime info. */
182 intel_device_info_driver_create(i915, pdev->device, &mock_info);182 intel_device_info_driver_create(i915, pdev->device, &mock_info);
183 183
184 intel_display_device_probe(i915);
185
184 dev_pm_domain_set(&pdev->dev, &pm_domain);186 dev_pm_domain_set(&pdev->dev, &pm_domain);
185 pm_runtime_enable(&pdev->dev);187 pm_runtime_enable(&pdev->dev);
186 pm_runtime_dont_use_autosuspend(&pdev->dev);188 pm_runtime_dont_use_autosuspend(&pdev->dev);
drivers/gpu/drm/i915/soc/intel_pch.c+9−3
@@ -218,13 +218,19 @@ void intel_detect_pch(struct drm_i915_private *dev_priv) · 217 unmodified lines
218 unsigned short id;218 unsigned short id;
219 enum intel_pch pch_type;219 enum intel_pch pch_type;
220 220
221 /* DG1 has south engine display on the same PCI device */221 /*
222 if (IS_DG1(dev_priv)) {222 * South display engine on the same PCI device: just assign the fake
223 dev_priv->pch_type = PCH_DG1;223 * PCH.
224 */
225 if (DISPLAY_VER(dev_priv) >= 20) {
226 dev_priv->pch_type = PCH_LNL;
224 return;227 return;
225 } else if (IS_DG2(dev_priv)) {228 } else if (IS_DG2(dev_priv)) {
226 dev_priv->pch_type = PCH_DG2;229 dev_priv->pch_type = PCH_DG2;
227 return;230 return;
231 } else if (IS_DG1(dev_priv)) {
232 dev_priv->pch_type = PCH_DG1;
233 return;
228 }234 }
229 235
230 /*236 /*
drivers/gpu/drm/i915/soc/intel_pch.h+2−0
@@ -30,6 +30,7 @@ enum intel_pch { · 29 unmodified lines
30 /* Fake PCHs, functionality handled on the same PCI dev */30 /* Fake PCHs, functionality handled on the same PCI dev */
31 PCH_DG1 = 1024,31 PCH_DG1 = 1024,
32 PCH_DG2,32 PCH_DG2,
33 PCH_LNL,
33};34};
34 35
35#define INTEL_PCH_DEVICE_ID_MASK 0xff8036#define INTEL_PCH_DEVICE_ID_MASK 0xff80
@@ -66,6 +67,7 @@ enum intel_pch { · 30 unmodified lines
66 67
67#define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type)68#define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type)
68#define INTEL_PCH_ID(dev_priv) ((dev_priv)->pch_id)69#define INTEL_PCH_ID(dev_priv) ((dev_priv)->pch_id)
70#define HAS_PCH_LNL(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LNL)
69#define HAS_PCH_MTP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_MTP)71#define HAS_PCH_MTP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_MTP)
70#define HAS_PCH_DG2(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG2)72#define HAS_PCH_DG2(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG2)
71#define HAS_PCH_ADP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ADP)73#define HAS_PCH_ADP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ADP)
drivers/media/cec/core/cec-adap.c+5−0
@@ -1688,6 +1688,11 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) · 1687 unmodified lines
1688}1688}
1689EXPORT_SYMBOL_GPL(cec_s_phys_addr);1689EXPORT_SYMBOL_GPL(cec_s_phys_addr);
1690 1690
1691/*
1692 * Note: In the drm subsystem, prefer calling (if possible):
1693 *
1694 * cec_s_phys_addr(adap, connector->display_info.source_physical_address, false);
1695 */
1691void cec_s_phys_addr_from_edid(struct cec_adapter *adap,1696void cec_s_phys_addr_from_edid(struct cec_adapter *adap,
1692 const struct edid *edid)1697 const struct edid *edid)
1693{1698{
drivers/media/cec/core/cec-notifier.c+5−0
@@ -196,6 +196,11 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa) · 195 unmodified lines
196}196}
197EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);197EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr);
198 198
199/*
200 * Note: In the drm subsystem, prefer calling (if possible):
201 *
202 * cec_notifier_set_phys_addr(n, connector->display_info.source_physical_address);
203 */
199void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,204void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n,
200 const struct edid *edid)205 const struct edid *edid)
201{206{
include/drm/display/drm_dp_helper.h+6−0
@@ -699,6 +699,7 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux); · 698 unmodified lines
699void drm_dp_cec_register_connector(struct drm_dp_aux *aux,699void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
700 struct drm_connector *connector);700 struct drm_connector *connector);
701void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux);701void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux);
702void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address);
702void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid);703void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid);
703void drm_dp_cec_unset_edid(struct drm_dp_aux *aux);704void drm_dp_cec_unset_edid(struct drm_dp_aux *aux);
704#else705#else
@@ -716,6 +717,11 @@ static inline void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux) · 11 unmodified lines
716{717{
717}718}
718 719
720static inline void drm_dp_cec_attach(struct drm_dp_aux *aux,
721 u16 source_physical_address)
722{
723}
724
719static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,725static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,
720 const struct edid *edid)726 const struct edid *edid)
721{727{
include/drm/drm_connector.h+8−0
@@ -817,6 +817,14 @@ struct drm_display_info { · 816 unmodified lines
817 * @quirks: EDID based quirks. Internal to EDID parsing.817 * @quirks: EDID based quirks. Internal to EDID parsing.
818 */818 */
819 u32 quirks;819 u32 quirks;
820
821 /**
822 * @source_physical_address: Source Physical Address from HDMI
823 * Vendor-Specific Data Block, for CEC usage.
824 *
825 * Defaults to CEC_PHYS_ADDR_INVALID (0xffff).
826 */
827 u16 source_physical_address;
820};828};
821 829
822int drm_display_info_set_bus_formats(struct drm_display_info *info,830int drm_display_info_set_bus_formats(struct drm_display_info *info,
include/drm/drm_edid.h+1−0
@@ -612,6 +612,7 @@ const struct drm_edid *drm_edid_read_switcheroo(struct drm_connector *connector, · 611 unmodified lines
612int drm_edid_connector_update(struct drm_connector *connector,612int drm_edid_connector_update(struct drm_connector *connector,
613 const struct drm_edid *edid);613 const struct drm_edid *edid);
614int drm_edid_connector_add_modes(struct drm_connector *connector);614int drm_edid_connector_add_modes(struct drm_connector *connector);
615bool drm_edid_is_digital(const struct drm_edid *drm_edid);
615 616
616const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,617const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid,
617 int ext_id, int *ext_index);618 int ext_id, int *ext_index);
include/drm/i915_pciids.h+6−2
@@ -689,14 +689,18 @@ · 688 unmodified lines
689#define INTEL_RPLU_IDS(info) \689#define INTEL_RPLU_IDS(info) \
690 INTEL_VGA_DEVICE(0xA721, info), \690 INTEL_VGA_DEVICE(0xA721, info), \
691 INTEL_VGA_DEVICE(0xA7A1, info), \691 INTEL_VGA_DEVICE(0xA7A1, info), \
692 INTEL_VGA_DEVICE(0xA7A9, info)692 INTEL_VGA_DEVICE(0xA7A9, info), \
693 INTEL_VGA_DEVICE(0xA7AC, info), \
694 INTEL_VGA_DEVICE(0xA7AD, info)
693 695
694/* RPL-P */696/* RPL-P */
695#define INTEL_RPLP_IDS(info) \697#define INTEL_RPLP_IDS(info) \
696 INTEL_RPLU_IDS(info), \698 INTEL_RPLU_IDS(info), \
697 INTEL_VGA_DEVICE(0xA720, info), \699 INTEL_VGA_DEVICE(0xA720, info), \
698 INTEL_VGA_DEVICE(0xA7A0, info), \700 INTEL_VGA_DEVICE(0xA7A0, info), \
699 INTEL_VGA_DEVICE(0xA7A8, info)701 INTEL_VGA_DEVICE(0xA7A8, info), \
702 INTEL_VGA_DEVICE(0xA7AA, info), \
703 INTEL_VGA_DEVICE(0xA7AB, info)
700 704
701/* DG2 */705/* DG2 */
702#define INTEL_DG2_G10_IDS(info) \706#define INTEL_DG2_G10_IDS(info) \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t