Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/msm/dp: Support only IRQ_HPD and REPLUG interrupts for eDP

The panel-edp enables the eDP panel power during probe, get_modes
and pre-enable. The eDP connect and disconnect interrupts for the eDP/DP
controller are directly dependent on panel power. As eDP display can be
assumed as always connected, the controller driver can skip the eDP
connect and disconnect interrupts. Any disruption in the link status
will be indicated via the IRQ_HPD interrupts.

So, the eDP controller driver can just enable the IRQ_HPD and replug
interrupts. The DP controller driver still needs to enable all the
interrupts.

Signed-off-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Patchwork: https://patchwork.freedesktop.org/patch/483310/
Link: https://lore.kernel.org/r/1650887072-16652-3-git-send-email-quic_sbillaka@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

authored by

Sankeerth Billakanti and committed by
Dmitry Baryshkov
391c96ff f5d01644

+31 -7
+10 -6
drivers/gpu/drm/msm/dp/dp_catalog.c
··· 589 589 590 590 u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); 591 591 592 - /* enable HPD plug and unplug interrupts */ 593 - dp_catalog_hpd_config_intr(dp_catalog, 594 - DP_DP_HPD_PLUG_INT_MASK | DP_DP_HPD_UNPLUG_INT_MASK, true); 595 - 596 592 /* Configure REFTIMER and enable it */ 597 593 reftimer |= DP_DP_HPD_REFTIMER_ENABLE; 598 594 dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); ··· 615 619 { 616 620 struct dp_catalog_private *catalog = container_of(dp_catalog, 617 621 struct dp_catalog_private, dp_catalog); 618 - int isr = 0; 622 + int isr, mask; 619 623 620 624 isr = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS); 621 625 dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK, 622 626 (isr & DP_DP_HPD_INT_MASK)); 627 + mask = dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK); 623 628 624 - return isr; 629 + /* 630 + * We only want to return interrupts that are unmasked to the caller. 631 + * However, the interrupt status field also contains other 632 + * informational bits about the HPD state status, so we only mask 633 + * out the part of the register that tells us about which interrupts 634 + * are pending. 635 + */ 636 + return isr & (mask | ~DP_DP_HPD_INT_MASK); 625 637 } 626 638 627 639 int dp_catalog_ctrl_get_interrupt(struct dp_catalog *dp_catalog)
+21 -1
drivers/gpu/drm/msm/dp/dp_display.c
··· 685 685 dp_display_handle_plugged_change(&dp->dp_display, false); 686 686 687 687 /* enable HDP plug interrupt to prepare for next plugin */ 688 - dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); 688 + if (!dp->dp_display.is_edp) 689 + dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); 689 690 690 691 drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", 691 692 dp->dp_display.connector_type, state); ··· 1072 1071 dp_display_host_init(dp); 1073 1072 dp_catalog_ctrl_hpd_config(dp->catalog); 1074 1073 1074 + /* Enable plug and unplug interrupts only for external DisplayPort */ 1075 + if (!dp->dp_display.is_edp) 1076 + dp_catalog_hpd_config_intr(dp->catalog, 1077 + DP_DP_HPD_PLUG_INT_MASK | 1078 + DP_DP_HPD_UNPLUG_INT_MASK, 1079 + true); 1080 + 1075 1081 /* Enable interrupt first time 1076 1082 * we are leaving dp clocks on during disconnect 1077 1083 * and never disable interrupt ··· 1362 1354 1363 1355 dp_catalog_ctrl_hpd_config(dp->catalog); 1364 1356 1357 + 1358 + if (!dp->dp_display.is_edp) 1359 + dp_catalog_hpd_config_intr(dp->catalog, 1360 + DP_DP_HPD_PLUG_INT_MASK | 1361 + DP_DP_HPD_UNPLUG_INT_MASK, 1362 + true); 1365 1363 1366 1364 if (dp_catalog_link_is_connected(dp->catalog)) { 1367 1365 /* ··· 1653 1639 return; 1654 1640 } 1655 1641 1642 + if (dp->is_edp) 1643 + dp_hpd_plug_handle(dp_display, 0); 1644 + 1656 1645 mutex_lock(&dp_display->event_mutex); 1657 1646 1658 1647 state = dp_display->hpd_state; ··· 1723 1706 struct dp_display_private *dp_display; 1724 1707 1725 1708 dp_display = container_of(dp, struct dp_display_private, dp_display); 1709 + 1710 + if (dp->is_edp) 1711 + dp_hpd_unplug_handle(dp_display, 0); 1726 1712 1727 1713 mutex_lock(&dp_display->event_mutex); 1728 1714