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
Unified · Split
| @@ -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 situation | 20 | * 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. Otherwise | 298 | * 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 | */ |
| 300 | void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid) | 301 | void 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 in | 371 | * 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 | } |
| 375 | unlock: | 376 | unlock: |
| 376 | mutex_unlock(&aux->cec.lock); | 377 | mutex_unlock(&aux->cec.lock); |
| 377 | } | 378 | } |
| 379 | EXPORT_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 | */ | ||
| 385 | void 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 | } | ||
| 378 | EXPORT_SYMBOL(drm_dp_cec_set_edid); | 395 | EXPORT_SYMBOL(drm_dp_cec_set_edid); |
| 379 | 396 | ||
| 380 | /* | 397 | /* |
| @@ -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 | } |
| @@ -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 | ||
| 654 | err_late_register: | ||
| 655 | if (connector->funcs->early_unregister) | ||
| 656 | connector->funcs->early_unregister(connector); | ||
| 650 | err_debugfs: | 657 | err_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); |
| @@ -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 | ||
| 3116 | static void | 3117 | static 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 | ||
| 6483 | static void update_displayid_info(struct drm_connector *connector, | 6488 | static 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 | */ | ||
| 7358 | bool 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 | } | ||
| 7363 | EXPORT_SYMBOL(drm_edid_is_digital); | ||
| @@ -153,6 +153,8 @@ int drm_sysfs_init(void); · 152 unmodified lines | |||
| 153 | void drm_sysfs_destroy(void); | 153 | void drm_sysfs_destroy(void); |
| 154 | struct device *drm_sysfs_minor_alloc(struct drm_minor *minor); | 154 | struct device *drm_sysfs_minor_alloc(struct drm_minor *minor); |
| 155 | int drm_sysfs_connector_add(struct drm_connector *connector); | 155 | int drm_sysfs_connector_add(struct drm_connector *connector); |
| 156 | int drm_sysfs_connector_add_late(struct drm_connector *connector); | ||
| 157 | void drm_sysfs_connector_remove_early(struct drm_connector *connector); | ||
| 156 | void drm_sysfs_connector_remove(struct drm_connector *connector); | 158 | void drm_sysfs_connector_remove(struct drm_connector *connector); |
| 157 | 159 | ||
| 158 | void drm_sysfs_lease_event(struct drm_device *dev); | 160 | void drm_sysfs_lease_event(struct drm_device *dev); |
| @@ -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 | ||
| 409 | err_free: | 405 | err_free: |
| @@ -411,13 +407,25 @@ err_free: · 1 unmodified line | |||
| 411 | return r; | 407 | return r; |
| 412 | } | 408 | } |
| 413 | 409 | ||
| 414 | void drm_sysfs_connector_remove(struct drm_connector *connector) | 410 | int 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 | ||
| 419 | void 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 | |||
| 425 | void 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); |
| @@ -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 \ |
| @@ -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 | else | 359 | else |
| @@ -361,6 +364,9 @@ static void intel_dp_get_config(struct intel_encoder *encoder, · 4 unmodified lines | |||
| 361 | else | 364 | 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 | else | 372 | else |
| @@ -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); |
| @@ -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" |
| @@ -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 */ |
| @@ -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 | ||
| @@ -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; |
| @@ -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; |
| @@ -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 | ||
| 762 | void intel_audio_sdp_split_update(struct intel_encoder *encoder, | 762 | void 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)) |
| @@ -29,7 +29,6 @@ void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv); · 28 unmodified lines | |||
| 29 | void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv); | 29 | void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv); |
| 30 | void intel_audio_init(struct drm_i915_private *dev_priv); | 30 | void intel_audio_init(struct drm_i915_private *dev_priv); |
| 31 | void intel_audio_deinit(struct drm_i915_private *dev_priv); | 31 | void intel_audio_deinit(struct drm_i915_private *dev_priv); |
| 32 | void intel_audio_sdp_split_update(struct intel_encoder *encoder, | 32 | void 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__ */ |
| @@ -521,7 +521,8 @@ static void init_bdb_blocks(struct drm_i915_private *i915, · 520 unmodified lines | |||
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | static void | 523 | static void |
| 524 | fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | 524 | fill_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)) { |
| @@ -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 | ||
| 1385 | static 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 | |||
| 1384 | static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk) | 1410 | static 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 | ||
| 1841 | static bool pll_enable_wa_needed(struct drm_i915_private *dev_priv) | 1867 | static 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 | ||
| 1848 | static void _bxt_set_cdclk(struct drm_i915_private *dev_priv, | 1875 | static 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 | ||
| 2568 | static 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 | |||
| 2536 | int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) | 2610 | int 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, since | 2682 | 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 calculate | 2685 | * 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 | */ |
| 3560 | void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv) | 3622 | void 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)) { |
| @@ -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 | ||
| 1021 | static 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 | |||
| 1028 | static 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 | |||
| 1035 | static 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 | |||
| 1052 | static 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 | |||
| 1062 | static 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 | |||
| 1016 | static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state) | 1080 | static 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 | ||
| 1273 | static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state, | 1348 | static 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 | ||
| 1688 | static void vlv_load_luts(const struct intel_crtc_state *crtc_state) | 1757 | static 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 | ||
| 1810 | void intel_color_post_update(const struct intel_crtc_state *crtc_state) | 1885 | void 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 | |||
| 1818 | void intel_color_prepare_commit(struct intel_crtc_state *crtc_state) | 1893 | void 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 | ||
| 1831 | void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state) | 1917 | void 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 | ||
| 1926 | void 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 | |||
| 1932 | bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state) | ||
| 1933 | { | ||
| 1934 | return crtc_state->dsb; | ||
| 1935 | } | ||
| 1936 | |||
| 1840 | static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state) | 1937 | static 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 | ||
| 2868 | static bool err_check(struct drm_color_lut *lut1, | 2968 | static 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 | ||
| 2876 | static bool intel_lut_entries_equal(struct drm_color_lut *lut1, | 2976 | static 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 | ||
| 3307 | static 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 | |||
| 3207 | static void chv_read_luts(struct intel_crtc_state *crtc_state) | 3317 | static 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 | ||
| 3380 | static 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 | |||
| 3270 | static void ilk_read_luts(struct intel_crtc_state *crtc_state) | 3389 | static 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 | ||
| 3578 | static const struct intel_color_funcs vlv_color_funcs = { | 3698 | static 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 | ||
| 3595 | static const struct intel_color_funcs i9xx_color_funcs = { | 3716 | static 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 | ||
| 3603 | static const struct intel_color_funcs tgl_color_funcs = { | 3725 | static 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 | ||
| 3613 | static const struct intel_color_funcs icl_color_funcs = { | 3736 | static 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 | ||
| 3624 | static const struct intel_color_funcs glk_color_funcs = { | 3748 | static 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 | ||
| 3634 | static const struct intel_color_funcs skl_color_funcs = { | 3759 | static 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 | ||
| 3644 | static const struct intel_color_funcs bdw_color_funcs = { | 3770 | static 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 | ||
| 3654 | static const struct intel_color_funcs hsw_color_funcs = { | 3781 | static 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 | ||
| 3664 | static const struct intel_color_funcs ivb_color_funcs = { | 3792 | static 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 | ||
| 3674 | static const struct intel_color_funcs ilk_color_funcs = { | 3803 | static 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 | ||
| 3684 | void intel_color_crtc_init(struct intel_crtc *crtc) | 3814 | void intel_color_crtc_init(struct intel_crtc *crtc) |
| @@ -19,6 +19,8 @@ void intel_color_crtc_init(struct intel_crtc *crtc); · 18 unmodified lines | |||
| 19 | int intel_color_check(struct intel_crtc_state *crtc_state); | 19 | int intel_color_check(struct intel_crtc_state *crtc_state); |
| 20 | void intel_color_prepare_commit(struct intel_crtc_state *crtc_state); | 20 | void intel_color_prepare_commit(struct intel_crtc_state *crtc_state); |
| 21 | void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state); | 21 | void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state); |
| 22 | bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state); | ||
| 23 | void intel_color_wait_commit(const struct intel_crtc_state *crtc_state); | ||
| 22 | void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state); | 24 | void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state); |
| 23 | void intel_color_commit_arm(const struct intel_crtc_state *crtc_state); | 25 | void intel_color_commit_arm(const struct intel_crtc_state *crtc_state); |
| 24 | void intel_color_post_update(const struct intel_crtc_state *crtc_state); | 26 | void intel_color_post_update(const struct intel_crtc_state *crtc_state); |
| @@ -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__ */ | ||
| @@ -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; |
| @@ -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 monitor | 193 | * intel_ddc_get_modes - get modelist from monitor |
| 194 | * @connector: DRM connector device to use | 194 | * @connector: DRM connector device to use |
| 195 | * @adapter: i2c adapter | 195 | * @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 | */ |
| 199 | int intel_ddc_get_modes(struct drm_connector *connector, | 199 | int 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 | ||
| @@ -26,7 +26,7 @@ bool intel_connector_get_hw_state(struct intel_connector *connector); · 25 unmodified lines | |||
| 26 | enum pipe intel_connector_get_pipe(struct intel_connector *connector); | 26 | enum pipe intel_connector_get_pipe(struct intel_connector *connector); |
| 27 | int intel_connector_update_modes(struct drm_connector *connector, | 27 | int intel_connector_update_modes(struct drm_connector *connector, |
| 28 | const struct drm_edid *drm_edid); | 28 | const struct drm_edid *drm_edid); |
| 29 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 29 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *ddc); |
| 30 | void intel_attach_force_audio_property(struct drm_connector *connector); | 30 | void intel_attach_force_audio_property(struct drm_connector *connector); |
| 31 | void intel_attach_broadcast_rgb_property(struct drm_connector *connector); | 31 | void intel_attach_broadcast_rgb_property(struct drm_connector *connector); |
| 32 | void intel_attach_aspect_ratio_property(struct drm_connector *connector); | 32 | void intel_attach_aspect_ratio_property(struct drm_connector *connector); |
| @@ -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 | ||
| 612 | static const struct drm_edid *intel_crt_get_edid(struct drm_connector *connector, | 621 | static 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() */ |
| 631 | static int intel_crt_ddc_get_modes(struct drm_connector *connector, | 640 | static 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 DDC | 668 | * This may be a DVI-I connector with a shared DDC |
| 665 | * link between analog and digital outputs, so we | 669 | * 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 | |||
| 907 | out: | 911 | out: |
| 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 | ||
| 941 | out: | 938 | out: |
| 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"); |
| @@ -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 | ||
| 180 | static struct intel_crtc *intel_crtc_alloc(void) | 182 | static 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 | ||
| 400 | static void intel_crtc_vblank_work(struct kthread_work *base) | 403 | static 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 | ||
| 474 | static 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 registers | 529 | * intel_pipe_update_start() - start update of a set of display registers |
| 473 | * @new_crtc_state: the new crtc state | 530 | * @state: the atomic state |
| 531 | * @crtc: the crtc | ||
| 474 | * | 532 | * |
| 475 | * Mark the start of an update to pipe registers that should be updated | 533 | * Mark the start of an update to pipe registers that should be updated |
| 476 | * atomically regarding vblank. If the next vblank will happens within | 534 | * 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 to | 538 | * until a subsequent call to intel_pipe_update_end(). That is done to |
| 481 | * avoid random delays. | 539 | * avoid random delays. |
| 482 | */ | 540 | */ |
| 483 | void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state) | 541 | void 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 registers | 672 | * intel_pipe_update_end() - end update of a set of display registers |
| 634 | * @new_crtc_state: the new crtc state | 673 | * @state: the atomic state |
| 674 | * @crtc: the crtc | ||
| 635 | * | 675 | * |
| 636 | * Mark the end of an update started with intel_pipe_update_start(). This | 676 | * Mark the end of an update started with intel_pipe_update_start(). This |
| 637 | * re-enables interrupts and verifies the update was actually completed | 677 | * re-enables interrupts and verifies the update was actually completed |
| 638 | * before a vblank. | 678 | * before a vblank. |
| 639 | */ | 679 | */ |
| 640 | void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) | 680 | void 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 | |||
| 759 | out: | ||
| 760 | intel_psr_unlock(new_crtc_state); | ||
| 727 | } | 761 | } |
| @@ -36,8 +36,10 @@ void intel_crtc_state_reset(struct intel_crtc_state *crtc_state, · 35 unmodified lines | |||
| 36 | u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc); | 36 | u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc); |
| 37 | void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state); | 37 | void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state); |
| 38 | void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state); | 38 | void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state); |
| 39 | void intel_pipe_update_start(struct intel_crtc_state *new_crtc_state); | 39 | void intel_pipe_update_start(struct intel_atomic_state *state, |
| 40 | void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state); | 40 | struct intel_crtc *crtc); |
| 41 | void intel_pipe_update_end(struct intel_atomic_state *state, | ||
| 42 | struct intel_crtc *crtc); | ||
| 41 | void intel_wait_for_vblank_workers(struct intel_atomic_state *state); | 43 | void intel_wait_for_vblank_workers(struct intel_atomic_state *state); |
| 42 | struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915); | 44 | struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915); |
| 43 | struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915, | 45 | struct intel_crtc *intel_crtc_for_pipe(struct drm_i915_private *i915, |
| @@ -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", |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | bool intel_is_c10phy(struct drm_i915_private *i915, enum phy phy) | 32 | bool 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 | ||
| 49 | static 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 | |||
| 49 | static void | 65 | static void |
| 50 | assert_dc_off(struct drm_i915_private *i915) | 66 | assert_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 | ||
| 74 | static 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 message | 89 | * 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 | */ |
| 64 | static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *encoder) | 95 | static 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 | ||
| 73 | static void intel_cx0_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref) | 108 | static 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 | else | 2736 | 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 lane | 2740 | * 6. Program the enabled and disabled owned PHY lane |
| 2732 | * transmitters over message bus | 2741 | * 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 - Sequence | 2746 | * 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 DDI | 2751 | * 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 Request | 2758 | * 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 After | 2774 | * 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 | ||
| @@ -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 | |||
| 16 | struct drm_i915_private; | ||
| 17 | struct intel_encoder; | ||
| 18 | struct intel_crtc_state; | ||
| 19 | enum icl_port_dpll_id; | 13 | enum icl_port_dpll_id; |
| 20 | enum phy; | 14 | enum phy; |
| 15 | struct drm_i915_private; | ||
| 16 | struct intel_atomic_state; | ||
| 17 | struct intel_c10pll_state; | ||
| 18 | struct intel_c20pll_state; | ||
| 19 | struct intel_crtc_state; | ||
| 20 | struct intel_encoder; | ||
| 21 | struct intel_hdmi; | ||
| 21 | 22 | ||
| 22 | bool intel_is_c10phy(struct drm_i915_private *dev_priv, enum phy phy); | 23 | bool intel_is_c10phy(struct drm_i915_private *dev_priv, enum phy phy); |
| 23 | void intel_mtl_pll_enable(struct intel_encoder *encoder, | 24 | void 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); |
| 45 | int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock); | 46 | int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock); |
| 46 | int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder); | 47 | int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder); |
| 48 | |||
| 47 | #endif /* __INTEL_CX0_PHY_H__ */ | 49 | #endif /* __INTEL_CX0_PHY_H__ */ |
| @@ -110,6 +110,19 @@ · 109 unmodified lines | |||
| 110 | #define CX0_P4PG_STATE_DISABLE 0xC | 110 | #define CX0_P4PG_STATE_DISABLE 0xC |
| 111 | #define CX0_P2_STATE_RESET 0x2 | 111 | #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 0x640E0 | 126 | #define _XELPDP_PORT_CLOCK_CTL_A 0x640E0 |
| 114 | #define _XELPDP_PORT_CLOCK_CTL_B 0x641E0 | 127 | #define _XELPDP_PORT_CLOCK_CTL_B 0x641E0 |
| 115 | #define _XELPDP_PORT_CLOCK_CTL_USBC1 0x16F260 | 128 | #define _XELPDP_PORT_CLOCK_CTL_USBC1 0x16F260 |
| @@ -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); |
| @@ -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 | ||
| 918 | static 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 | |||
| 916 | static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state, | 928 | static 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 | ||
| 922 | static bool vrr_disabling(const struct intel_crtc_state *old_crtc_state, | 937 | static 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_disabling | 946 | #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 | ||
| 2591 | static 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 | |||
| 2573 | static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state) | 2622 | static 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 | ||
| 2872 | static 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 | |||
| 2890 | static bool i9xx_get_pipe_config(struct intel_crtc *crtc, | 2921 | static 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 | ||
| 4642 | static int | 4646 | static int |
| 4643 | intel_modeset_pipe_config(struct intel_atomic_state *state, | 4647 | intel_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 | ||
| 4717 | encoder_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_X | 5433 | #undef PIPE_CONF_CHECK_X |
| 5397 | #undef PIPE_CONF_CHECK_I | 5434 | #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 | ||
| 5423 | int intel_modeset_all_pipes(struct intel_atomic_state *state, | 5460 | static 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 | */ | ||
| 5501 | int 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 | */ | ||
| 5538 | int 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 | ||
| 6285 | static 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 | |||
| 6341 | static 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 object | 6381 | * intel_atomic_check - validate state object |
| 6176 | * @dev: drm device | 6382 | * @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 | ||
| 6490 | static void commit_pipe_pre_planes(struct intel_atomic_state *state, | 6674 | static 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 | ||
| 6537 | static void intel_enable_crtc(struct intel_atomic_state *state, | 6726 | static 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 the | 6814 | * 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 | /* |
| @@ -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 | |||
| 195 | enum phy { | 193 | enum 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 | |||
| 513 | void intel_update_watermarks(struct drm_i915_private *i915); | 511 | void intel_update_watermarks(struct drm_i915_private *i915); |
| 514 | 512 | ||
| 515 | /* modesetting */ | 513 | /* modesetting */ |
| 516 | int intel_modeset_all_pipes(struct intel_atomic_state *state, | 514 | int intel_modeset_pipes_in_mask_early(struct intel_atomic_state *state, |
| 517 | const char *reason); | 515 | const char *reason, u8 pipe_mask); |
| 516 | int intel_modeset_all_pipes_late(struct intel_atomic_state *state, | ||
| 517 | const char *reason); | ||
| 518 | void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state, | 518 | void 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); |
| 520 | void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc, | 520 | void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc, |
| @@ -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 | ||
| @@ -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 | |||
| 713 | static const struct intel_display_device_info xe_lpdp_display = { | 758 | static 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, | 762 | static 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 | ||
| 808 | static const struct intel_display_device_info * | 852 | static 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 | ||
| 853 | const struct intel_display_device_info * | 897 | static const struct intel_display_device_info * |
| 854 | intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid, | 898 | probe_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 | ||
| 919 | void 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 | |||
| 879 | void intel_display_device_info_runtime_init(struct drm_i915_private *i915) | 942 | void 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) |
| @@ -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 | |||
| 74 | struct intel_display_runtime_info { | 101 | struct 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 | ||
| 126 | const struct intel_display_device_info * | 153 | void intel_display_device_probe(struct drm_i915_private *i915); |
| 127 | intel_display_device_probe(struct drm_i915_private *i915, bool has_gmdid, | ||
| 128 | u16 *ver, u16 *rel, u16 *step); | ||
| 129 | void intel_display_device_info_runtime_init(struct drm_i915_private *i915); | 154 | void intel_display_device_info_runtime_init(struct drm_i915_private *i915); |
| 130 | 155 | ||
| 131 | void intel_display_device_info_print(const struct intel_display_device_info *info, | 156 | void intel_display_device_info_print(const struct intel_display_device_info *info, |
| @@ -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 | ||
| 93 | static const struct drm_mode_config_funcs intel_mode_funcs = { | 96 | static 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 | ||
| 378 | void intel_display_driver_register(struct drm_i915_private *i915) | 381 | void 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 */ |
| @@ -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) |
| @@ -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 | |||
| 343 | static void __async_put_domains_mask(struct i915_power_domains *power_domains, | 339 | static 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; |
| @@ -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, |
| @@ -332,7 +332,6 @@ I915_DECL_PW_DOMAINS(skl_pwdoms_pw_2, · 331 unmodified lines | |||
| 332 | I915_DECL_PW_DOMAINS(skl_pwdoms_dc_off, | 332 | I915_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 | |||
| 685 | I915_DECL_PW_DOMAINS(icl_pwdoms_dc_off, | 682 | I915_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 | ||
| 1539 | I915_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 | |||
| 1554 | static 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 | |||
| 1564 | I915_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 | |||
| 1571 | static 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 | |||
| 1581 | static 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 | |||
| 1548 | static void init_power_well_domains(const struct i915_power_well_instance *inst, | 1589 | static 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); |
| @@ -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 | ||
| 1836 | static 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 | |||
| 1850 | static 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 | |||
| 1863 | static 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 | |||
| 1831 | const struct i915_power_well_ops i9xx_always_on_power_well_ops = { | 1870 | const 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 | |||
| 1990 | const 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 | }; | ||
| @@ -176,5 +176,6 @@ extern const struct i915_power_well_ops icl_aux_power_well_ops; · 175 unmodified lines | |||
| 176 | extern const struct i915_power_well_ops icl_ddi_power_well_ops; | 176 | extern const struct i915_power_well_ops icl_ddi_power_well_ops; |
| 177 | extern const struct i915_power_well_ops tgl_tc_cold_off_ops; | 177 | extern const struct i915_power_well_ops tgl_tc_cold_off_ops; |
| 178 | extern const struct i915_power_well_ops xelpdp_aux_power_well_ops; | 178 | extern const struct i915_power_well_ops xelpdp_aux_power_well_ops; |
| 179 | extern const struct i915_power_well_ops xe2lpd_pica_power_well_ops; | ||
| 179 | 180 | ||
| 180 | #endif | 181 | #endif |
| @@ -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 to | 516 | * 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 | ||
| 1582 | struct intel_hdmi { | 1591 | struct 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 | ||
| 2119 | static inline int to_bpp_int(int bpp_x16) | ||
| 2120 | { | ||
| 2121 | return bpp_x16 >> 4; | ||
| 2122 | } | ||
| 2123 | |||
| 2124 | static 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 | |||
| 2132 | static inline int to_bpp_int_roundup(int bpp_x16) | ||
| 2133 | { | ||
| 2134 | return (bpp_x16 + 0xf) >> 4; | ||
| 2135 | } | ||
| 2136 | |||
| 2137 | static 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__ */ |
| @@ -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 | |||
| 11 | static 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 | |||
| 21 | static 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 | |||
| 31 | static 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 | |||
| 40 | void 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 | } | ||
| @@ -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 | |||
| 9 | struct drm_i915_private; | ||
| 10 | |||
| 11 | void intel_display_wa_apply(struct drm_i915_private *i915); | ||
| 12 | |||
| 13 | #endif | ||
| @@ -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)) { |
| @@ -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 | ||
| 318 | int intel_dp_max_lane_count(struct intel_dp *intel_dp) | 318 | int 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 | ||
| 743 | u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, | 743 | static |
| 744 | u32 link_clock, u32 lane_count, | 744 | u32 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 | |||
| 769 | u16 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 | ||
| 807 | u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, | 826 | u8 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 | ||
| 938 | static bool | ||
| 939 | dfp_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 | |||
| 919 | static enum intel_output_format | 956 | static enum intel_output_format |
| 920 | intel_dp_output_format(struct intel_connector *connector, | 957 | intel_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 | ||
| 954 | static int intel_dp_output_bpp(enum intel_output_format output_format, int bpp) | 999 | int 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 output | 1002 | * 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 picked | 1216 | * 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 the | 1221 | * 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 | |||
| 1306 | static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp, | 1357 | static 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 | ||
| 1515 | int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 max_req_bpc) | 1568 | static |
| 1569 | u8 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 | |||
| 1580 | int 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 | else | 1590 | 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 | ||
| 1720 | static 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 | |||
| 1733 | static 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 | |||
| 1767 | static | ||
| 1768 | u16 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 | |||
| 1794 | static 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 | |||
| 1811 | static 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 | |||
| 1819 | static int dsc_src_min_compressed_bpp(void) | ||
| 1820 | { | ||
| 1821 | /* Min Compressed bpp supported by source is 8 */ | ||
| 1822 | return 8; | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | static 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 | */ | ||
| 1843 | static int | ||
| 1844 | icl_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 | */ | ||
| 1882 | static int | ||
| 1883 | xelpd_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 | |||
| 1913 | static 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 | |||
| 1947 | static | ||
| 1948 | u8 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 | |||
| 1954 | static | ||
| 1955 | bool 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 | |||
| 1972 | static | ||
| 1973 | int 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 | |||
| 1996 | static 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 | |||
| 2053 | static 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 | |||
| 1654 | int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, | 2101 | int 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 count | 2125 | * 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 rate | 2170 | * 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 | ||
| 1799 | static int | 2197 | /** |
| 1800 | intel_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 | */ | ||
| 2209 | bool | ||
| 2210 | intel_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 | |||
| 2257 | static bool | ||
| 2258 | intel_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 these | 2280 | * 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 | |||
| 2295 | static int | ||
| 2296 | intel_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 some | 2323 | !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 | |||
| 2136 | static void | 2622 | static void |
| 2137 | intel_dp_drrs_compute_config(struct intel_connector *connector, | 2623 | intel_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 | ||
| 2173 | static bool intel_dp_has_audio(struct intel_encoder *encoder, | 2659 | static 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 | ||
| 2235 | static void | 2723 | void |
| 2236 | intel_dp_audio_compute_config(struct intel_encoder *encoder, | 2724 | intel_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 | else | 2803 | 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 | ||
| 4835 | static void | 5322 | static 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 | ||
| 4999 | static int intel_dp_get_modes(struct drm_connector *connector) | 5473 | static 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)) |
| @@ -26,7 +26,14 @@ struct intel_encoder; · 25 unmodified lines | |||
| 26 | struct link_config_limits { | 26 | struct 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 | ||
| 32 | void intel_edp_fixup_vbt_bpp(struct intel_encoder *encoder, int pipe_bpp); | 39 | void 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); |
| 75 | void intel_dp_audio_compute_config(struct intel_encoder *encoder, | ||
| 76 | struct intel_crtc_state *pipe_config, | ||
| 77 | struct drm_connector_state *conn_state); | ||
| 68 | bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp); | 78 | bool intel_dp_has_hdmi_sink(struct intel_dp *intel_dp); |
| 69 | bool intel_dp_is_edp(struct intel_dp *intel_dp); | 79 | bool intel_dp_is_edp(struct intel_dp *intel_dp); |
| 70 | bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state); | 80 | bool 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); |
| 108 | bool intel_digital_port_connected(struct intel_encoder *encoder); | 118 | bool intel_digital_port_connected(struct intel_encoder *encoder); |
| 109 | int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); | 119 | int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc); |
| 110 | u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, | 120 | u16 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); | ||
| 116 | u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, | 127 | u8 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 | |||
| 143 | void intel_dp_phy_test(struct intel_encoder *encoder); | 154 | void intel_dp_phy_test(struct intel_encoder *encoder); |
| 144 | 155 | ||
| 145 | void intel_dp_wait_source_oui(struct intel_dp *intel_dp); | 156 | void intel_dp_wait_source_oui(struct intel_dp *intel_dp); |
| 157 | int intel_dp_output_bpp(enum intel_output_format output_format, int bpp); | ||
| 158 | |||
| 159 | bool | ||
| 160 | intel_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__ */ |
| @@ -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 | |||
| 19 | static 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 | |||
| 17 | u32 intel_dp_aux_pack(const u8 *src, int src_bytes) | 32 | u32 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 | } |
| @@ -13,48 +13,34 @@ · 12 unmodified lines | |||
| 13 | * packet size supported is 20 bytes in each direction, hence the 5 fixed data | 13 | * packet size supported is 20 bytes in each direction, hence the 5 fixed data |
| 14 | * registers | 14 | * 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__ */ |
| @@ -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 | ||
| 333 | static struct drm_dp_aux * | ||
| 334 | intel_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 | |||
| 333 | static int | 344 | static int |
| 334 | intel_dp_hdcp2_read_rx_status(struct intel_digital_port *dig_port, | 345 | intel_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 | ||
| 352 | static | 364 | static |
| 353 | int hdcp2_detect_msg_availability(struct intel_digital_port *dig_port, | 365 | int 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 | ||
| 385 | static ssize_t | 397 | static ssize_t |
| 386 | intel_dp_hdcp2_wait_for_msg(struct intel_digital_port *dig_port, | 398 | intel_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 | ||
| 439 | static | 450 | static |
| 440 | int intel_dp_hdcp2_write_msg(struct intel_digital_port *dig_port, | 451 | int 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 | ||
| 475 | static | 489 | static |
| 476 | ssize_t get_receiver_id_list_rx_info(struct intel_digital_port *dig_port, u32 *dev_cnt, u8 *byte) | 490 | ssize_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 | ||
| 496 | static | 512 | static |
| 497 | int intel_dp_hdcp2_read_msg(struct intel_digital_port *dig_port, | 513 | int 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 | ||
| 576 | static | 601 | static |
| 577 | int intel_dp_hdcp2_config_stream_type(struct intel_digital_port *dig_port, | 602 | int 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 | ||
| 624 | static | 650 | static |
| 625 | int intel_dp_hdcp2_capable(struct intel_digital_port *dig_port, | 651 | int 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) |
| @@ -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 write | 1390 | * Default value of bit 31 is '0' hence discarding the write |
| 1391 | * TODO: Corrective actions on SDP corruption yet to be defined | 1391 | * 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 | } |
| @@ -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 | else | 209 | 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 | ||
| 293 | static bool intel_dp_mst_has_audio(const struct drm_connector_state *conn_state) | 305 | static bool |
| 306 | intel_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 | else | 320 | |
| 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 | ||
| 306 | static int intel_dp_mst_compute_config(struct intel_encoder *encoder, | 340 | static 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't | 367 | 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, if | 395 | * 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 of | 775 | * 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 picked | 1007 | * 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 | /* |
| @@ -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 | ||
| @@ -29,7 +29,7 @@ static inline struct i915_dpt * · 28 unmodified lines | |||
| 29 | i915_vm_to_dpt(struct i915_address_space *vm) | 29 | i915_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 | ||
| @@ -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 | /** |
| @@ -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 | ||
| 16 | struct i915_vma; | 21 | struct 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 24 | 77 | #define DSB_OPCODE_SHIFT 24 |
| 71 | #define DSB_OPCODE_NOOP 0x0 | 78 | #define DSB_OPCODE_NOOP 0x0 |
| 72 | #define DSB_OPCODE_MMIO_WRITE 0x1 | 79 | #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 0x2 | 83 | #define DSB_OPCODE_WAIT_USEC 0x2 |
| 74 | #define DSB_OPCODE_WAIT_LINES 0x3 | 84 | #define DSB_OPCODE_WAIT_SCANLINE 0x3 |
| 75 | #define DSB_OPCODE_WAIT_VBLANKS 0x4 | 85 | #define DSB_OPCODE_WAIT_VBLANKS 0x4 |
| 76 | #define DSB_OPCODE_WAIT_DSL_IN 0x5 | 86 | #define DSB_OPCODE_WAIT_DSL_IN 0x5 |
| 77 | #define DSB_OPCODE_WAIT_DSL_OUT 0x6 | 87 | #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 0x7 | 90 | #define DSB_OPCODE_INTERRUPT 0x7 |
| 79 | #define DSB_OPCODE_INDEXED_WRITE 0x9 | 91 | #define DSB_OPCODE_INDEXED_WRITE 0x9 |
| 92 | /* see DSB_REG_VALUE_MASK */ | ||
| 80 | #define DSB_OPCODE_POLL 0xA | 93 | #define DSB_OPCODE_POLL 0xA |
| 81 | #define DSB_BYTE_EN 0xF | 94 | /* see DSB_REG_VALUE_MASK */ |
| 82 | #define DSB_BYTE_EN_SHIFT 20 | ||
| 83 | #define DSB_REG_VALUE_MASK 0xfffff | ||
| 84 | 95 | ||
| 85 | static bool assert_dsb_has_room(struct intel_dsb *dsb) | 96 | static 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 | ||
| 107 | static 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 | |||
| 96 | static bool is_dsb_busy(struct drm_i915_private *i915, enum pipe pipe, | 123 | static 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 | ||
| 102 | static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw) | 129 | static 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 | ||
| 130 | static bool intel_dsb_prev_ins_is_mmio_write(struct intel_dsb *dsb, i915_reg_t reg) | 165 | static 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 | ||
| 135 | static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb, i915_reg_t reg) | 174 | static 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 | ||
| 244 | static 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! */ | ||
| 253 | void 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 | |||
| 262 | void 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 | |||
| 271 | void 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 | |||
| 281 | void 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 | |||
| 203 | static void intel_dsb_align_tail(struct intel_dsb *dsb) | 291 | static 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 | ||
| 217 | void intel_dsb_finish(struct intel_dsb *dsb) | 305 | void 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 | /** | 320 | static 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 context | 322 | struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); |
| 225 | * @wait_for_vblank: wait for vblank before executing | 323 | 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 | |
| 229 | void 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 | |||
| 339 | static 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 | */ | ||
| 393 | void 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 | ||
| 255 | void intel_dsb_wait(struct intel_dsb *dsb) | 401 | void 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 CRTC | 431 | * @crtc_state: the CRTC state |
| 275 | * @max_cmds: number of commands we need to fit into command buffer | 432 | * @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 dsb | 434 | * 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 failure | 438 | * DSB context, NULL on failure |
| 282 | */ | 439 | */ |
| 283 | struct intel_dsb *intel_dsb_prepare(struct intel_crtc *crtc, | 440 | struct 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 | ||
| @@ -11,14 +11,21 @@ · 10 unmodified lines | |||
| 11 | #include "i915_reg_defs.h" | 11 | #include "i915_reg_defs.h" |
| 12 | 12 | ||
| 13 | struct intel_crtc; | 13 | struct intel_crtc; |
| 14 | struct intel_crtc_state; | ||
| 14 | struct intel_dsb; | 15 | struct intel_dsb; |
| 15 | 16 | ||
| 16 | struct intel_dsb *intel_dsb_prepare(struct intel_crtc *crtc, | 17 | struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state, |
| 17 | unsigned int max_cmds); | 18 | unsigned int max_cmds); |
| 18 | void intel_dsb_finish(struct intel_dsb *dsb); | 19 | void intel_dsb_finish(struct intel_dsb *dsb); |
| 19 | void intel_dsb_cleanup(struct intel_dsb *dsb); | 20 | void intel_dsb_cleanup(struct intel_dsb *dsb); |
| 20 | void intel_dsb_reg_write(struct intel_dsb *dsb, | 21 | void intel_dsb_reg_write(struct intel_dsb *dsb, |
| 21 | i915_reg_t reg, u32 val); | 22 | i915_reg_t reg, u32 val); |
| 23 | void intel_dsb_reg_write_masked(struct intel_dsb *dsb, | ||
| 24 | i915_reg_t reg, u32 mask, u32 val); | ||
| 25 | void intel_dsb_noop(struct intel_dsb *dsb, int count); | ||
| 26 | void intel_dsb_nonpost_start(struct intel_dsb *dsb); | ||
| 27 | void intel_dsb_nonpost_end(struct intel_dsb *dsb); | ||
| 28 | |||
| 22 | void intel_dsb_commit(struct intel_dsb *dsb, | 29 | void intel_dsb_commit(struct intel_dsb *dsb, |
| 23 | bool wait_for_vblank); | 30 | bool wait_for_vblank); |
| 24 | void intel_dsb_wait(struct intel_dsb *dsb); | 31 | void intel_dsb_wait(struct intel_dsb *dsb); |
| @@ -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__ */ |
| @@ -328,7 +328,6 @@ intel_dvo_detect(struct drm_connector *_connector, bool force) · 327 unmodified lines | |||
| 328 | static int intel_dvo_get_modes(struct drm_connector *_connector) | 328 | static 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); |
| @@ -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 | ||
| 1903 | struct frontbuffer_fence_cb { | ||
| 1904 | struct dma_fence_cb base; | ||
| 1905 | struct intel_frontbuffer *front; | ||
| 1906 | }; | ||
| 1907 | |||
| 1908 | static 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 | |||
| 1899 | static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, | 1918 | static 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 | |||
| 1962 | flush: | ||
| 1963 | i915_gem_object_flush_if_display(obj); | ||
| 1964 | intel_frontbuffer_flush(front, ORIGIN_DIRTYFB); | ||
| 1965 | return ret; | ||
| 1911 | } | 1966 | } |
| 1912 | 1967 | ||
| 1913 | static const struct drm_framebuffer_funcs intel_fb_funcs = { | 1968 | static const struct drm_framebuffer_funcs intel_fb_funcs = { |
| @@ -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); |
| @@ -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 | ||
| 1316 | void intel_fbc_post_update(struct intel_atomic_state *state, | 1317 | void intel_fbc_post_update(struct intel_atomic_state *state, |
| @@ -20,6 +20,8 @@ struct intel_plane_state; · 19 unmodified lines | |||
| 20 | enum intel_fbc_id { | 20 | enum 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 | }; |
| @@ -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 | ||
| 17 | struct intel_fdi_funcs { | 18 | struct 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 | */ | ||
| 134 | int 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 */ |
| 123 | static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state) | 171 | static 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 | ||
| 131 | static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, | 179 | static 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 | */ | ||
| 302 | bool 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 | |||
| 235 | int ilk_fdi_compute_config(struct intel_crtc *crtc, | 317 | int 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 | ||
| 244 | retry: | ||
| 245 | /* FDI is a binary signal running at ~2.7GHz, encoding | 325 | /* FDI is a binary signal running at ~2.7GHz, encoding |
| 246 | * each output octet as 10 bits. The actual frequency | 326 | * each output octet as 10 bits. The actual frequency |
| 247 | * is stored as a divider into a 100MHz clock, and the | 327 | * 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 | |||
| 347 | static 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 | */ | ||
| 386 | int 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 | ||
| 285 | static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable) | 409 | static 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:hsw | 890 | * 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 the | 926 | * 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); |
| @@ -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 | |||
| 9 | enum pipe; | 11 | enum pipe; |
| 10 | struct drm_i915_private; | 12 | struct drm_i915_private; |
| 13 | struct intel_atomic_state; | ||
| 11 | struct intel_crtc; | 14 | struct intel_crtc; |
| 12 | struct intel_crtc_state; | 15 | struct intel_crtc_state; |
| 13 | struct intel_encoder; | 16 | struct intel_encoder; |
| 17 | struct intel_link_bw_limits; | ||
| 14 | 18 | ||
| 19 | int intel_fdi_add_affected_crtcs(struct intel_atomic_state *state); | ||
| 15 | int intel_fdi_link_freq(struct drm_i915_private *i915, | 20 | int 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); |
| 22 | bool intel_fdi_compute_pipe_bpp(struct intel_crtc_state *crtc_state); | ||
| 17 | int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, | 23 | int ilk_fdi_compute_config(struct intel_crtc *intel_crtc, |
| 18 | struct intel_crtc_state *pipe_config); | 24 | struct intel_crtc_state *pipe_config); |
| 25 | int intel_fdi_atomic_check_link(struct intel_atomic_state *state, | ||
| 26 | struct intel_link_bw_limits *limits); | ||
| 19 | void intel_fdi_normal_train(struct intel_crtc *crtc); | 27 | void intel_fdi_normal_train(struct intel_crtc *crtc); |
| 20 | void ilk_fdi_disable(struct intel_crtc *crtc); | 28 | void ilk_fdi_disable(struct intel_crtc *crtc); |
| 21 | void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc); | 29 | void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc); |
| @@ -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 | ||
| 206 | static 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 | */ | ||
| 223 | void 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 | |||
| 205 | static int frontbuffer_active(struct i915_active *ref) | 233 | static 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 | |||
| 223 | static void frontbuffer_release(struct kref *ref) | 251 | static 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); |
| @@ -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 | ||
| 140 | void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front); | ||
| 141 | |||
| 138 | void intel_frontbuffer_track(struct intel_frontbuffer *old, | 142 | void 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); |
| @@ -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) { |
| @@ -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 */ |
| 164 | bool intel_hdcp2_capable(struct intel_connector *connector) | 164 | bool 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 */ |
| 1416 | static int hdcp2_authentication_key_exchange(struct intel_connector *connector) | 1415 | static 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 | ||
| 1505 | static int hdcp2_locality_check(struct intel_connector *connector) | 1503 | static 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 | ||
| 1541 | static int hdcp2_session_key_exchange(struct intel_connector *connector) | 1538 | static 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 | ||
| 1686 | static int hdcp2_authenticate_sink(struct intel_connector *connector) | 1682 | static 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) |
| @@ -1240,26 +1240,23 @@ static void hsw_set_infoframes(struct intel_encoder *encoder, · 1239 unmodified lines | |||
| 1240 | void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable) | 1240 | void 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 | ||
| 1256 | static int intel_hdmi_hdcp_read(struct intel_digital_port *dig_port, | 1255 | static 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 = buffer | 1273 | .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 | |||
| 1285 | static int intel_hdmi_hdcp_write(struct intel_digital_port *dig_port, | 1282 | static 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 | ||
| 1667 | static | 1661 | static |
| 1668 | int intel_hdmi_hdcp2_write_msg(struct intel_digital_port *dig_port, | 1662 | int 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 | ||
| 1677 | static | 1672 | static |
| 1678 | int intel_hdmi_hdcp2_read_msg(struct intel_digital_port *dig_port, | 1673 | int 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 | ||
| 1735 | static | 1731 | static |
| 1736 | int intel_hdmi_hdcp2_capable(struct intel_digital_port *dig_port, | 1732 | int 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 any | 2406 | * 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 | ||
| 2556 | static struct i2c_adapter * | ||
| 2557 | intel_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 | |||
| 2565 | static 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 | |||
| 2578 | static 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 | |||
| 2587 | static int | 2544 | static int |
| 2588 | intel_hdmi_connector_register(struct drm_connector *connector) | 2545 | intel_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) |
| @@ -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 | ||
| 262 | enum intel_hotplug_state | 263 | static enum intel_hotplug_state |
| 263 | intel_encoder_hotplug(struct intel_encoder *encoder, | 264 | intel_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 | ||
| 296 | enum intel_hotplug_state | ||
| 297 | intel_encoder_hotplug(struct intel_encoder *encoder, | ||
| 298 | struct intel_connector *connector) | ||
| 299 | { | ||
| 300 | return intel_hotplug_detect_connector(connector); | ||
| 301 | } | ||
| 302 | |||
| 294 | static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder) | 303 | static 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 | ||
| 643 | static 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 | |||
| 672 | out: | ||
| 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 | |||
| 634 | static void i915_hpd_poll_init_work(struct work_struct *work) | 686 | static 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 were | 735 | * We might have missed any hotplugs that happened while we were |
| 670 | * in the middle of disabling polling | 736 | * 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 | /** |
| @@ -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 | ||
| 1068 | static 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 | |||
| 1063 | static bool is_xelpdp_pica_hpd_pin(enum hpd_pin hpd_pin) | 1081 | static 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 | ||
| @@ -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 | */ | ||
| 20 | void 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 | */ | ||
| 48 | int 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 | */ | ||
| 114 | bool | ||
| 115 | intel_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 | |||
| 140 | static 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 | |||
| 153 | static bool | ||
| 154 | assert_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 | */ | ||
| 197 | int 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 | } | ||
| @@ -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 | |||
| 13 | struct drm_i915_private; | ||
| 14 | |||
| 15 | struct intel_atomic_state; | ||
| 16 | struct intel_crtc_state; | ||
| 17 | |||
| 18 | struct 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 | |||
| 24 | void intel_link_bw_init_limits(struct drm_i915_private *i915, | ||
| 25 | struct intel_link_bw_limits *limits); | ||
| 26 | int 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); | ||
| 30 | bool 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); | ||
| 34 | int intel_link_bw_atomic_check(struct intel_atomic_state *state, | ||
| 35 | struct intel_link_bw_limits *new_limits); | ||
| 36 | |||
| 37 | #endif | ||
| @@ -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, ¤t_mode)) { | 149 | if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, ¤t_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, ¤t_mode); | 190 | err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, ¤t_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 | } |
| @@ -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 | else | 436 | 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)) { |
| @@ -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" |
| @@ -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 | ||
| 62 | static 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 | |||
| 71 | static bool is_best_fixed_mode(struct intel_connector *connector, | 62 | static 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 requested | 72 | * 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 the | 215 | * 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 | /* |
| @@ -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 | ||
| 14 | static bool | 15 | static bool |
| @@ -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 | ||
| @@ -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 may | 1448 | * 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 | else | 3180 | 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 | } |
| 3180 | DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status); | 3202 | DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status); |
| 3181 | 3203 | ||
| @@ -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 | ||
| 70 | static const char * const tv_format_names[] = { | 72 | static 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 | ||
| 84 | struct intel_sdvo; | ||
| 85 | |||
| 86 | struct intel_sdvo_ddc { | ||
| 87 | struct i2c_adapter ddc; | ||
| 88 | struct intel_sdvo *sdvo; | ||
| 89 | u8 ddc_bus; | ||
| 90 | }; | ||
| 91 | |||
| 82 | struct intel_sdvo { | 92 | struct 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 by | 104 | * 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 device | 115 | * 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->dtd | 120 | * 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 | else | 234 | 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 | ||
| 415 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, | 411 | static 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 | ||
| 1225 | static bool | 1221 | static bool |
| 1226 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, | 1222 | intel_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 | ||
| 1273 | static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_state *pipe_config) | 1270 | static 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 | ||
| 1303 | static bool intel_has_hdmi_sink(struct intel_sdvo_connector *intel_sdvo_connector, | 1303 | static 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 our | 1368 | * We need to construct preferred input timings based on our |
| 1365 | * output timings. To do that, we have to set the output | 1369 | * 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 input | 1534 | * 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 | else | 1616 | 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 | ||
| 2032 | static bool | ||
| 2033 | intel_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 | |||
| 2039 | static const struct drm_edid * | 2047 | static const struct drm_edid * |
| 2040 | intel_sdvo_get_edid(struct drm_connector *connector) | 2048 | intel_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 | |||
| 2048 | intel_sdvo_get_analog_edid(struct drm_connector *connector) | 2060 | intel_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 | ||
| 2058 | static enum drm_connector_status | 2072 | static enum drm_connector_status |
| 2059 | intel_sdvo_tmds_sink_detect(struct drm_connector *connector) | 2073 | intel_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 VGA | 2081 | * 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 | else | 2092 | else |
| 2103 | status = connector_status_disconnected; | 2093 | status = connector_status_disconnected; |
| @@ -2111,8 +2101,7 @@ static bool · 7 unmodified lines | |||
| 2111 | intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo, | 2101 | intel_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 | |||
| 2276 | static int intel_sdvo_get_tv_modes(struct drm_connector *connector) | 2267 | static 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 | ||
| 2461 | static int | ||
| 2462 | intel_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 | |||
| 2476 | static void | ||
| 2477 | intel_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 | |||
| 2486 | static struct drm_connector_state * | 2454 | static struct drm_connector_state * |
| 2487 | intel_sdvo_connector_duplicate_state(struct drm_connector *connector) | 2455 | intel_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 | ||
| 2542 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 2510 | static 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 | ||
| 2550 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | 2525 | static 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 | ||
| 2554 | static void | 2529 | static int |
| 2555 | intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo) | 2530 | intel_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 the | 2537 | * 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 TMDS | 2576 | * 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 | */ |
| 2603 | static void | 2579 | static struct intel_sdvo_ddc * |
| 2604 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | 2580 | intel_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 | else | 2589 | 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 | else | 2594 | 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 | ||
| 2620 | static void | 2603 | static void |
| 2621 | intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, | 2604 | intel_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 | else | 2612 | 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 | else | 2618 | 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 | ||
| 2661 | static u8 | 2648 | static u8 |
| 2662 | intel_sdvo_get_slave_addr(struct drm_i915_private *dev_priv, | 2649 | intel_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 | else | 2683 | else |
| 2697 | return 0x72; | 2684 | return 0x72; |
| 2698 | } | 2685 | } |
| 2699 | 2686 | ||
| 2687 | static int | ||
| 2688 | intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc, | ||
| 2689 | struct intel_sdvo *sdvo, int bit); | ||
| 2690 | |||
| 2700 | static int | 2691 | static int |
| 2701 | intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | 2692 | intel_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 | ||
| 3261 | static u32 intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter) | 3257 | static 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 | |||
| 3272 | static void proxy_lock_bus(struct i2c_adapter *adapter, | 3270 | static 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 | ||
| 3279 | static int proxy_trylock_bus(struct i2c_adapter *adapter, | 3279 | static 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 | ||
| 3286 | static void proxy_unlock_bus(struct i2c_adapter *adapter, | 3288 | static 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 | ||
| 3299 | static bool | 3303 | static int |
| 3300 | intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo, | 3304 | intel_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 | ||
| 3316 | static bool is_sdvo_port_valid(struct drm_i915_private *dev_priv, enum port port) | 3325 | static 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 | else | 3427 | 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 | ||
| 3455 | err_output: | 3470 | err_output: |
| 3456 | intel_sdvo_output_cleanup(intel_sdvo); | 3471 | intel_sdvo_output_cleanup(intel_sdvo); |
| 3457 | |||
| 3458 | err: | 3472 | err: |
| 3459 | drm_encoder_cleanup(&intel_encoder->base); | ||
| 3460 | i2c_del_adapter(&intel_sdvo->ddc); | ||
| 3461 | err_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 | } |
| @@ -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; |
| @@ -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 | ||
| 50 | static void i9xx_plane_linear_gamma(u16 gamma[8]) | 51 | static void i9xx_plane_linear_gamma(u16 gamma[8]) |
| @@ -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 | ||
| 263 | u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port) | 263 | static 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 | ||
| 293 | static int mtl_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port) | 293 | static 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 | |||
| 318 | static 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 | ||
| 314 | int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port) | 339 | static 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 | ||
| 365 | int 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 | |||
| 351 | void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, | 385 | void 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; |
| @@ -19,9 +19,8 @@ bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port); · 18 unmodified lines | |||
| 19 | bool intel_tc_port_connected(struct intel_encoder *encoder); | 19 | bool intel_tc_port_connected(struct intel_encoder *encoder); |
| 20 | bool intel_tc_port_connected_locked(struct intel_encoder *encoder); | 20 | bool intel_tc_port_connected_locked(struct intel_encoder *encoder); |
| 21 | 21 | ||
| 22 | u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port); | ||
| 23 | u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port); | 22 | u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port); |
| 24 | int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port); | 23 | int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port); |
| 25 | void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, | 24 | void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, |
| 26 | int required_lanes); | 25 | int required_lanes); |
| 27 | 26 | ||
| @@ -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 | ||
| 254 | int 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 | |||
| 254 | static bool i915_get_crtc_scanoutpos(struct drm_crtc *_crtc, | 268 | static 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, |
| @@ -22,5 +22,6 @@ void intel_wait_for_pipe_scanline_stopped(struct intel_crtc *crtc); · 21 unmodified lines | |||
| 22 | void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc); | 22 | void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc); |
| 23 | void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state, | 23 | void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state, |
| 24 | bool vrr_enable); | 24 | bool vrr_enable); |
| 25 | int intel_crtc_scanline_to_hw(struct intel_crtc *crtc, int scanline); | ||
| 25 | 26 | ||
| 26 | #endif /* __INTEL_VBLANK_H__ */ | 27 | #endif /* __INTEL_VBLANK_H__ */ |
| @@ -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 | else | 90 | 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 | ||
| 359 | static 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 | |||
| 353 | int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state) | 364 | int 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 | ||
| 374 | static 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 | |||
| 392 | static 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 | |||
| 363 | static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) | 411 | static 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 second | 513 | DSC_PPS16_SLICE_PER_LINE((vdsc_cfg->pic_width / num_vdsc_instances) / |
| 655 | * VDSC | 514 | 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 | ||
| 799 | static 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 | |||
| 836 | static 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 | |||
| 849 | static 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 | |||
| 990 | void intel_dsc_get_config(struct intel_crtc_state *crtc_state) | 953 | void 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; | ||
| 1038 | out: | 982 | out: |
| 1039 | intel_display_power_put(dev_priv, power_domain, wakeref); | 983 | intel_display_power_put(dev_priv, power_domain, wakeref); |
| 1040 | } | 984 | } |
| @@ -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 0x78270 | 56 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PB 0x78270 |
| 79 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB 0x78370 | 57 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB 0x78370 |
| 80 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_0_PC 0x78470 | 58 | #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 12 | 73 | #define ICL_DSC1_PPS(pipe, pps) _MMIO(_ICL_DSC1_PPS_0(pipe) + ((pps) * 4)) |
| 96 | #define DSC_BPC_SHIFT 8 | 74 | |
| 97 | #define DSC_VER_MIN_SHIFT 4 | 75 | /* 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 0x78274 | 80 | #define DSC_PPS0_422_ENABLE REG_BIT(18) |
| 103 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_1_PB 0x78374 | 81 | #define DSC_PPS0_COLOR_SPACE_CONVERSION REG_BIT(17) |
| 104 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_1_PC 0x78474 | 82 | #define DSC_PPS0_BLOCK_PREDICTION REG_BIT(16) |
| 105 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_1_PC 0x78574 | 83 | #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 0x78278 | 94 | #define DSC_PPS1_BPP(bpp) REG_FIELD_PREP(DSC_PPS1_BPP_MASK, bpp) |
| 117 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_2_PB 0x78378 | 95 | |
| 118 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_2_PC 0x78478 | 96 | /* PPS 2 */ |
| 119 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_2_PC 0x78578 | 97 | #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 0x7827C | 109 | #define DSC_PPS4_INITIAL_DEC_DELAY_MASK REG_GENMASK(31, 16) |
| 132 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_3_PB 0x7837C | 110 | #define DSC_PPS4_INITIAL_XMIT_DELAY_MASK REG_GENMASK(9, 0) |
| 133 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_3_PC 0x7847C | 111 | #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 0x7857C | 112 | 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 0x78280 | 124 | #define DSC_PPS6_FLATNESS_MIN_QP_MASK REG_GENMASK(20, 16) |
| 147 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_4_PB 0x78380 | 125 | #define DSC_PPS6_FIRST_LINE_BPG_OFFSET_MASK REG_GENMASK(12, 8) |
| 148 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_4_PC 0x78480 | 126 | #define DSC_PPS6_INITIAL_SCALE_VALUE_MASK REG_GENMASK(5, 0) |
| 149 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_4_PC 0x78580 | 127 | #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 0x78284 | 139 | bpg_offset) |
| 162 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_5_PB 0x78384 | 140 | /* PPS 8 */ |
| 163 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_5_PC 0x78484 | 141 | #define DSC_PPS8_INITIAL_OFFSET_MASK REG_GENMASK(31, 16) |
| 164 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_5_PC 0x78584 | 142 | #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 0x78288 | 154 | rc_model_size) |
| 177 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_6_PB 0x78388 | 155 | |
| 178 | #define _ICL_DSC0_PICTURE_PARAMETER_SET_6_PC 0x78488 | 156 | /* PPS 10 */ |
| 179 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_6_PC 0x78588 | 157 | #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 0x7828C | 171 | #define DSC_PPS16_SLICE_CHUNK_SIZE_MASK REG_GENMASK(15, 0) |
| 194 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_7_PB 0x7838C | 172 | #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 0x7848C | 173 | slice_row_per_frame) |
| 196 | #define _ICL_DSC1_PICTURE_PARAMETER_SET_7_PC 0x7858C | 174 | #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 0x78290 | 186 | #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 0x78390 | 187 | #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) |
| @@ -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 | ||
| 45 | bool 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 | |||
| 45 | void | 54 | void |
| 46 | intel_vrr_check_modeset(struct intel_atomic_state *state) | 55 | intel_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 / |
| @@ -14,6 +14,7 @@ struct intel_connector; · 13 unmodified lines | |||
| 14 | struct intel_crtc_state; | 14 | struct intel_crtc_state; |
| 15 | 15 | ||
| 16 | bool intel_vrr_is_capable(struct intel_connector *connector); | 16 | bool intel_vrr_is_capable(struct intel_connector *connector); |
| 17 | bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh); | ||
| 17 | void intel_vrr_check_modeset(struct intel_atomic_state *state); | 18 | void intel_vrr_check_modeset(struct intel_atomic_state *state); |
| 18 | void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, | 19 | void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, |
| 19 | struct drm_connector_state *conn_state); | 20 | struct drm_connector_state *conn_state); |
| @@ -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 | ||
| @@ -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 | |||
| 3725 | unsigned 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 | } | ||
| @@ -46,6 +46,8 @@ void skl_watermark_ipc_update(struct drm_i915_private *i915); · 45 unmodified lines | |||
| 46 | bool skl_watermark_ipc_enabled(struct drm_i915_private *i915); | 46 | bool skl_watermark_ipc_enabled(struct drm_i915_private *i915); |
| 47 | void skl_watermark_debugfs_register(struct drm_i915_private *i915); | 47 | void skl_watermark_debugfs_register(struct drm_i915_private *i915); |
| 48 | 48 | ||
| 49 | unsigned int skl_watermark_max_latency(struct drm_i915_private *i915); | ||
| 50 | |||
| 49 | void skl_wm_init(struct drm_i915_private *i915); | 51 | void skl_wm_init(struct drm_i915_private *i915); |
| 50 | 52 | ||
| 51 | struct intel_dbuf_state { | 53 | struct intel_dbuf_state { |
| @@ -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 | ||
| @@ -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 */ |
| @@ -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, |
| @@ -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" |
| @@ -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 | ||
| 809 | void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 810 | enum fb_op_origin origin); | ||
| 811 | void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 812 | enum fb_op_origin origin); | ||
| 813 | |||
| 814 | static inline void | ||
| 815 | i915_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 | |||
| 822 | static inline void | ||
| 823 | i915_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 | |||
| 830 | int i915_gem_object_read_from_page(struct drm_i915_gem_object *obj, u64 offset, void *dst, int size); | 808 | int i915_gem_object_read_from_page(struct drm_i915_gem_object *obj, u64 offset, void *dst, int size); |
| 831 | 809 | ||
| 832 | bool i915_gem_object_is_shmem(const struct drm_i915_gem_object *obj); | 810 | bool 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 | #endif | 866 | #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 | */ | ||
| 899 | static inline struct intel_frontbuffer * | ||
| 900 | i915_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 | */ | ||
| 938 | static inline struct intel_frontbuffer * | ||
| 939 | i915_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 | #endif | 868 | #endif |
| @@ -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 | |||
| 15 | void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 16 | enum fb_op_origin origin); | ||
| 17 | void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, | ||
| 18 | enum fb_op_origin origin); | ||
| 19 | |||
| 20 | static inline void | ||
| 21 | i915_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 | |||
| 28 | static inline void | ||
| 29 | i915_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 | */ | ||
| 45 | static inline struct intel_frontbuffer * | ||
| 46 | i915_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 | */ | ||
| 84 | static inline struct intel_frontbuffer * | ||
| 85 | i915_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 | ||
| @@ -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" |
| @@ -83,8 +83,7 @@ static int linear_x_y_to_ftiled_pos(int x, int y, u32 stride, int bpp) · 82 unmodified lines | |||
| 83 | enum client_tiling { | 83 | enum 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_TYPES | 87 | 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 | } |
| @@ -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 */ |
| @@ -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 | #else | 39 | #else |
| 40 | #define DBG(...) | 40 | #define GTT_TRACE(...) |
| 41 | #endif | 41 | #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 */ |
| @@ -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(>->info, &p); | 704 | intel_gt_info_print(>->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 arguments | 1573 | * 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) |
| @@ -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 1604406085 | 19 | #define DRIVER_TIMESTAMP 1695980603 |
| 20 | 20 | ||
| 21 | extern const struct dev_pm_ops i915_pm_ops; | 21 | extern const struct dev_pm_ops i915_pm_ops; |
| 22 | 22 | ||
| @@ -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) |
| @@ -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" |
| @@ -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; |
| @@ -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); |
| @@ -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 | ||
| 756 | static void cherryview_irq_reset(struct drm_i915_private *dev_priv) | 758 | static void cherryview_irq_reset(struct drm_i915_private *dev_priv) |
| @@ -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, \ |
| @@ -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 0x70058 | 2696 | #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) |
| @@ -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" |
| @@ -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 | ||
| 97 | static struct dma_fence_ops unbind_fence_ops = { | 97 | static 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, |
| @@ -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 | ||
| 352 | static 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 | |||
| 363 | static 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 | |||
| 376 | static 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 | |||
| 387 | static void xehpsdv_init_clock_gating(struct drm_i915_private *i915) | 352 | static 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 | |||
| 800 | CG_FUNCS(pvc); | 765 | CG_FUNCS(pvc); |
| 801 | CG_FUNCS(dg2); | 766 | CG_FUNCS(dg2); |
| 802 | CG_FUNCS(xehpsdv); | 767 | CG_FUNCS(xehpsdv); |
| 803 | CG_FUNCS(adlp); | ||
| 804 | CG_FUNCS(gen12lp); | ||
| 805 | CG_FUNCS(icl); | ||
| 806 | CG_FUNCS(cfl); | 768 | CG_FUNCS(cfl); |
| 807 | CG_FUNCS(skl); | 769 | CG_FUNCS(skl); |
| 808 | CG_FUNCS(kbl); | 770 | CG_FUNCS(kbl); |
| @@ -835,20 +797,12 @@ CG_FUNCS(nop); · 26 unmodified lines | |||
| 835 | */ | 797 | */ |
| 836 | void intel_clock_gating_hooks_init(struct drm_i915_private *i915) | 798 | void 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 | } |
| @@ -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 | ||
| @@ -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); \ |
| @@ -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" |
| @@ -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); |
| @@ -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 | |||
| 110 | static inline void | 110 | static inline void |
| 111 | assert_rpm_device_not_suspended(struct intel_runtime_pm *rpm) | 111 | assert_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 | ||
| @@ -124,6 +124,7 @@ static const struct intel_step_info dg2_g11_revid_step_tbl[] = { · 123 unmodified lines | |||
| 124 | 124 | ||
| 125 | static const struct intel_step_info dg2_g12_revid_step_tbl[] = { | 125 | static 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 | ||
| 129 | static const struct intel_step_info adls_rpls_revids[] = { | 130 | static const struct intel_step_info adls_rpls_revids[] = { |
| @@ -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 | ||
| 362 | static 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 | |||
| 373 | static 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 by | 382 | * this helper is used by both intel_pxp_start and by |
| 364 | * the GET_PARAM IOCTL that user space calls. Thus, the | 383 | * 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 | */ |
| 367 | int intel_pxp_get_readiness_status(struct intel_pxp *pxp) | 386 | int 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 the | 407 | * the arb session is restarted from the irq work when we receive the |
| 384 | * termination completion interrupt | 408 | * termination completion interrupt |
| 385 | */ | 409 | */ |
| 410 | #define PXP_READINESS_TIMEOUT 250 | ||
| 411 | |||
| 386 | int intel_pxp_start(struct intel_pxp *pxp) | 412 | int 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) |
| @@ -26,7 +26,7 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp); · 25 unmodified lines | |||
| 26 | void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp); | 26 | void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp); |
| 27 | void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id); | 27 | void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 arb_session_id); |
| 28 | 28 | ||
| 29 | int intel_pxp_get_readiness_status(struct intel_pxp *pxp); | 29 | int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms); |
| 30 | int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp); | 30 | int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp); |
| 31 | int intel_pxp_start(struct intel_pxp *pxp); | 31 | int intel_pxp_start(struct intel_pxp *pxp); |
| 32 | void intel_pxp_end(struct intel_pxp *pxp); | 32 | void intel_pxp_end(struct intel_pxp *pxp); |
| @@ -18,12 +18,13 @@ · 17 unmodified lines | |||
| 18 | #include "intel_pxp_types.h" | 18 | #include "intel_pxp_types.h" |
| 19 | 19 | ||
| 20 | static bool | 20 | static bool |
| 21 | is_fw_err_platform_config(u32 type) | 21 | is_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, |
| @@ -34,8 +34,10 @@ void intel_pxp_suspend(struct intel_pxp *pxp) · 33 unmodified lines | |||
| 34 | } | 34 | } |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | void intel_pxp_resume_complete(struct intel_pxp *pxp) | 37 | static 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 | |||
| 60 | void intel_pxp_resume_complete(struct intel_pxp *pxp) | ||
| 61 | { | ||
| 62 | _pxp_resume(pxp, true); | ||
| 63 | } | ||
| 64 | |||
| 65 | void intel_pxp_runtime_resume(struct intel_pxp *pxp) | ||
| 66 | { | ||
| 67 | _pxp_resume(pxp, false); | ||
| 52 | } | 68 | } |
| 53 | 69 | ||
| 54 | void intel_pxp_runtime_suspend(struct intel_pxp *pxp) | 70 | void intel_pxp_runtime_suspend(struct intel_pxp *pxp) |
| @@ -13,6 +13,7 @@ void intel_pxp_suspend_prepare(struct intel_pxp *pxp); · 12 unmodified lines | |||
| 13 | void intel_pxp_suspend(struct intel_pxp *pxp); | 13 | void intel_pxp_suspend(struct intel_pxp *pxp); |
| 14 | void intel_pxp_resume_complete(struct intel_pxp *pxp); | 14 | void intel_pxp_resume_complete(struct intel_pxp *pxp); |
| 15 | void intel_pxp_runtime_suspend(struct intel_pxp *pxp); | 15 | void intel_pxp_runtime_suspend(struct intel_pxp *pxp); |
| 16 | void intel_pxp_runtime_resume(struct intel_pxp *pxp); | ||
| 16 | #else | 17 | #else |
| 17 | static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp) | 18 | static 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 | |||
| 29 | static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp) | 30 | static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp) |
| 30 | { | 31 | { |
| 31 | } | 32 | } |
| 32 | #endif | 33 | |
| 33 | static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp) | 34 | static 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__ */ |
| @@ -22,12 +22,13 @@ · 21 unmodified lines | |||
| 22 | #include "intel_pxp_types.h" | 22 | #include "intel_pxp_types.h" |
| 23 | 23 | ||
| 24 | static bool | 24 | static bool |
| 25 | is_fw_err_platform_config(u32 type) | 25 | is_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, |
| @@ -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 platforms | 39 | * @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. |
| @@ -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); |
| @@ -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 | /* |
| @@ -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 0xff80 | 36 | #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) |
| @@ -1688,6 +1688,11 @@ void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) · 1687 unmodified lines | |||
| 1688 | } | 1688 | } |
| 1689 | EXPORT_SYMBOL_GPL(cec_s_phys_addr); | 1689 | EXPORT_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 | */ | ||
| 1691 | void cec_s_phys_addr_from_edid(struct cec_adapter *adap, | 1696 | void cec_s_phys_addr_from_edid(struct cec_adapter *adap, |
| 1692 | const struct edid *edid) | 1697 | const struct edid *edid) |
| 1693 | { | 1698 | { |
| @@ -196,6 +196,11 @@ void cec_notifier_set_phys_addr(struct cec_notifier *n, u16 pa) · 195 unmodified lines | |||
| 196 | } | 196 | } |
| 197 | EXPORT_SYMBOL_GPL(cec_notifier_set_phys_addr); | 197 | EXPORT_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 | */ | ||
| 199 | void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, | 204 | void cec_notifier_set_phys_addr_from_edid(struct cec_notifier *n, |
| 200 | const struct edid *edid) | 205 | const struct edid *edid) |
| 201 | { | 206 | { |
| @@ -699,6 +699,7 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux); · 698 unmodified lines | |||
| 699 | void drm_dp_cec_register_connector(struct drm_dp_aux *aux, | 699 | void drm_dp_cec_register_connector(struct drm_dp_aux *aux, |
| 700 | struct drm_connector *connector); | 700 | struct drm_connector *connector); |
| 701 | void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux); | 701 | void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux); |
| 702 | void drm_dp_cec_attach(struct drm_dp_aux *aux, u16 source_physical_address); | ||
| 702 | void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid); | 703 | void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid); |
| 703 | void drm_dp_cec_unset_edid(struct drm_dp_aux *aux); | 704 | void drm_dp_cec_unset_edid(struct drm_dp_aux *aux); |
| 704 | #else | 705 | #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 | ||
| 720 | static inline void drm_dp_cec_attach(struct drm_dp_aux *aux, | ||
| 721 | u16 source_physical_address) | ||
| 722 | { | ||
| 723 | } | ||
| 724 | |||
| 719 | static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux, | 725 | static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux, |
| 720 | const struct edid *edid) | 726 | const struct edid *edid) |
| 721 | { | 727 | { |
| @@ -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 | ||
| 822 | int drm_display_info_set_bus_formats(struct drm_display_info *info, | 830 | int drm_display_info_set_bus_formats(struct drm_display_info *info, |
| @@ -612,6 +612,7 @@ const struct drm_edid *drm_edid_read_switcheroo(struct drm_connector *connector, · 611 unmodified lines | |||
| 612 | int drm_edid_connector_update(struct drm_connector *connector, | 612 | int drm_edid_connector_update(struct drm_connector *connector, |
| 613 | const struct drm_edid *edid); | 613 | const struct drm_edid *edid); |
| 614 | int drm_edid_connector_add_modes(struct drm_connector *connector); | 614 | int drm_edid_connector_add_modes(struct drm_connector *connector); |
| 615 | bool drm_edid_is_digital(const struct drm_edid *drm_edid); | ||
| 615 | 616 | ||
| 616 | const u8 *drm_find_edid_extension(const struct drm_edid *drm_edid, | 617 | const 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); |
| @@ -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) \ |