diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 134 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 41 |
2 files changed, 172 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 46aaef5c1851..7a7c4a2bd778 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -122,6 +122,15 @@ static const u32 hpd_gen11[HPD_NUM_PINS] = { | |||
122 | [HPD_PORT_F] = GEN11_TC4_HOTPLUG | GEN11_TBT4_HOTPLUG | 122 | [HPD_PORT_F] = GEN11_TC4_HOTPLUG | GEN11_TBT4_HOTPLUG |
123 | }; | 123 | }; |
124 | 124 | ||
125 | static const u32 hpd_icp[HPD_NUM_PINS] = { | ||
126 | [HPD_PORT_A] = SDE_DDIA_HOTPLUG_ICP, | ||
127 | [HPD_PORT_B] = SDE_DDIB_HOTPLUG_ICP, | ||
128 | [HPD_PORT_C] = SDE_TC1_HOTPLUG_ICP, | ||
129 | [HPD_PORT_D] = SDE_TC2_HOTPLUG_ICP, | ||
130 | [HPD_PORT_E] = SDE_TC3_HOTPLUG_ICP, | ||
131 | [HPD_PORT_F] = SDE_TC4_HOTPLUG_ICP | ||
132 | }; | ||
133 | |||
125 | /* IIR can theoretically queue up two events. Be paranoid. */ | 134 | /* IIR can theoretically queue up two events. Be paranoid. */ |
126 | #define GEN8_IRQ_RESET_NDX(type, which) do { \ | 135 | #define GEN8_IRQ_RESET_NDX(type, which) do { \ |
127 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ | 136 | I915_WRITE(GEN8_##type##_IMR(which), 0xffffffff); \ |
@@ -1586,6 +1595,34 @@ static bool bxt_port_hotplug_long_detect(enum port port, u32 val) | |||
1586 | } | 1595 | } |
1587 | } | 1596 | } |
1588 | 1597 | ||
1598 | static bool icp_ddi_port_hotplug_long_detect(enum port port, u32 val) | ||
1599 | { | ||
1600 | switch (port) { | ||
1601 | case PORT_A: | ||
1602 | return val & ICP_DDIA_HPD_LONG_DETECT; | ||
1603 | case PORT_B: | ||
1604 | return val & ICP_DDIB_HPD_LONG_DETECT; | ||
1605 | default: | ||
1606 | return false; | ||
1607 | } | ||
1608 | } | ||
1609 | |||
1610 | static bool icp_tc_port_hotplug_long_detect(enum port port, u32 val) | ||
1611 | { | ||
1612 | switch (port) { | ||
1613 | case PORT_C: | ||
1614 | return val & ICP_TC_HPD_LONG_DETECT(PORT_TC1); | ||
1615 | case PORT_D: | ||
1616 | return val & ICP_TC_HPD_LONG_DETECT(PORT_TC2); | ||
1617 | case PORT_E: | ||
1618 | return val & ICP_TC_HPD_LONG_DETECT(PORT_TC3); | ||
1619 | case PORT_F: | ||
1620 | return val & ICP_TC_HPD_LONG_DETECT(PORT_TC4); | ||
1621 | default: | ||
1622 | return false; | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1589 | static bool spt_port_hotplug2_long_detect(enum port port, u32 val) | 1626 | static bool spt_port_hotplug2_long_detect(enum port port, u32 val) |
1590 | { | 1627 | { |
1591 | switch (port) { | 1628 | switch (port) { |
@@ -2385,6 +2422,43 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) | |||
2385 | cpt_serr_int_handler(dev_priv); | 2422 | cpt_serr_int_handler(dev_priv); |
2386 | } | 2423 | } |
2387 | 2424 | ||
2425 | static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) | ||
2426 | { | ||
2427 | u32 ddi_hotplug_trigger = pch_iir & SDE_DDI_MASK_ICP; | ||
2428 | u32 tc_hotplug_trigger = pch_iir & SDE_TC_MASK_ICP; | ||
2429 | u32 pin_mask = 0, long_mask = 0; | ||
2430 | |||
2431 | if (ddi_hotplug_trigger) { | ||
2432 | u32 dig_hotplug_reg; | ||
2433 | |||
2434 | dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_DDI); | ||
2435 | I915_WRITE(SHOTPLUG_CTL_DDI, dig_hotplug_reg); | ||
2436 | |||
2437 | intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, | ||
2438 | ddi_hotplug_trigger, | ||
2439 | dig_hotplug_reg, hpd_icp, | ||
2440 | icp_ddi_port_hotplug_long_detect); | ||
2441 | } | ||
2442 | |||
2443 | if (tc_hotplug_trigger) { | ||
2444 | u32 dig_hotplug_reg; | ||
2445 | |||
2446 | dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_TC); | ||
2447 | I915_WRITE(SHOTPLUG_CTL_TC, dig_hotplug_reg); | ||
2448 | |||
2449 | intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, | ||
2450 | tc_hotplug_trigger, | ||
2451 | dig_hotplug_reg, hpd_icp, | ||
2452 | icp_tc_port_hotplug_long_detect); | ||
2453 | } | ||
2454 | |||
2455 | if (pin_mask) | ||
2456 | intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); | ||
2457 | |||
2458 | if (pch_iir & SDE_GMBUS_ICP) | ||
2459 | gmbus_irq_handler(dev_priv); | ||
2460 | } | ||
2461 | |||
2388 | static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) | 2462 | static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) |
2389 | { | 2463 | { |
2390 | u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT & | 2464 | u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT & |
@@ -2804,8 +2878,11 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) | |||
2804 | I915_WRITE(SDEIIR, iir); | 2878 | I915_WRITE(SDEIIR, iir); |
2805 | ret = IRQ_HANDLED; | 2879 | ret = IRQ_HANDLED; |
2806 | 2880 | ||
2807 | if (HAS_PCH_SPT(dev_priv) || HAS_PCH_KBP(dev_priv) || | 2881 | if (HAS_PCH_ICP(dev_priv)) |
2808 | HAS_PCH_CNP(dev_priv)) | 2882 | icp_irq_handler(dev_priv, iir); |
2883 | else if (HAS_PCH_SPT(dev_priv) || | ||
2884 | HAS_PCH_KBP(dev_priv) || | ||
2885 | HAS_PCH_CNP(dev_priv)) | ||
2809 | spt_irq_handler(dev_priv, iir); | 2886 | spt_irq_handler(dev_priv, iir); |
2810 | else | 2887 | else |
2811 | cpt_irq_handler(dev_priv, iir); | 2888 | cpt_irq_handler(dev_priv, iir); |
@@ -3584,6 +3661,9 @@ static void gen11_irq_reset(struct drm_device *dev) | |||
3584 | GEN3_IRQ_RESET(GEN11_DE_HPD_); | 3661 | GEN3_IRQ_RESET(GEN11_DE_HPD_); |
3585 | GEN3_IRQ_RESET(GEN11_GU_MISC_); | 3662 | GEN3_IRQ_RESET(GEN11_GU_MISC_); |
3586 | GEN3_IRQ_RESET(GEN8_PCU_); | 3663 | GEN3_IRQ_RESET(GEN8_PCU_); |
3664 | |||
3665 | if (HAS_PCH_ICP(dev_priv)) | ||
3666 | GEN3_IRQ_RESET(SDE); | ||
3587 | } | 3667 | } |
3588 | 3668 | ||
3589 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, | 3669 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, |
@@ -3700,6 +3780,35 @@ static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) | |||
3700 | ibx_hpd_detection_setup(dev_priv); | 3780 | ibx_hpd_detection_setup(dev_priv); |
3701 | } | 3781 | } |
3702 | 3782 | ||
3783 | static void icp_hpd_detection_setup(struct drm_i915_private *dev_priv) | ||
3784 | { | ||
3785 | u32 hotplug; | ||
3786 | |||
3787 | hotplug = I915_READ(SHOTPLUG_CTL_DDI); | ||
3788 | hotplug |= ICP_DDIA_HPD_ENABLE | | ||
3789 | ICP_DDIB_HPD_ENABLE; | ||
3790 | I915_WRITE(SHOTPLUG_CTL_DDI, hotplug); | ||
3791 | |||
3792 | hotplug = I915_READ(SHOTPLUG_CTL_TC); | ||
3793 | hotplug |= ICP_TC_HPD_ENABLE(PORT_TC1) | | ||
3794 | ICP_TC_HPD_ENABLE(PORT_TC2) | | ||
3795 | ICP_TC_HPD_ENABLE(PORT_TC3) | | ||
3796 | ICP_TC_HPD_ENABLE(PORT_TC4); | ||
3797 | I915_WRITE(SHOTPLUG_CTL_TC, hotplug); | ||
3798 | } | ||
3799 | |||
3800 | static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv) | ||
3801 | { | ||
3802 | u32 hotplug_irqs, enabled_irqs; | ||
3803 | |||
3804 | hotplug_irqs = SDE_DDI_MASK_ICP | SDE_TC_MASK_ICP; | ||
3805 | enabled_irqs = intel_hpd_enabled_irqs(dev_priv, hpd_icp); | ||
3806 | |||
3807 | ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); | ||
3808 | |||
3809 | icp_hpd_detection_setup(dev_priv); | ||
3810 | } | ||
3811 | |||
3703 | static void gen11_hpd_detection_setup(struct drm_i915_private *dev_priv) | 3812 | static void gen11_hpd_detection_setup(struct drm_i915_private *dev_priv) |
3704 | { | 3813 | { |
3705 | u32 hotplug; | 3814 | u32 hotplug; |
@@ -3733,6 +3842,9 @@ static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv) | |||
3733 | POSTING_READ(GEN11_DE_HPD_IMR); | 3842 | POSTING_READ(GEN11_DE_HPD_IMR); |
3734 | 3843 | ||
3735 | gen11_hpd_detection_setup(dev_priv); | 3844 | gen11_hpd_detection_setup(dev_priv); |
3845 | |||
3846 | if (HAS_PCH_ICP(dev_priv)) | ||
3847 | icp_hpd_irq_setup(dev_priv); | ||
3736 | } | 3848 | } |
3737 | 3849 | ||
3738 | static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) | 3850 | static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) |
@@ -4168,11 +4280,29 @@ static void gen11_gt_irq_postinstall(struct drm_i915_private *dev_priv) | |||
4168 | I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_MASK, ~0); | 4280 | I915_WRITE(GEN11_GPM_WGBOXPERF_INTR_MASK, ~0); |
4169 | } | 4281 | } |
4170 | 4282 | ||
4283 | static void icp_irq_postinstall(struct drm_device *dev) | ||
4284 | { | ||
4285 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
4286 | u32 mask = SDE_GMBUS_ICP; | ||
4287 | |||
4288 | WARN_ON(I915_READ(SDEIER) != 0); | ||
4289 | I915_WRITE(SDEIER, 0xffffffff); | ||
4290 | POSTING_READ(SDEIER); | ||
4291 | |||
4292 | gen3_assert_iir_is_zero(dev_priv, SDEIIR); | ||
4293 | I915_WRITE(SDEIMR, ~mask); | ||
4294 | |||
4295 | icp_hpd_detection_setup(dev_priv); | ||
4296 | } | ||
4297 | |||
4171 | static int gen11_irq_postinstall(struct drm_device *dev) | 4298 | static int gen11_irq_postinstall(struct drm_device *dev) |
4172 | { | 4299 | { |
4173 | struct drm_i915_private *dev_priv = dev->dev_private; | 4300 | struct drm_i915_private *dev_priv = dev->dev_private; |
4174 | u32 gu_misc_masked = GEN11_GU_MISC_GSE; | 4301 | u32 gu_misc_masked = GEN11_GU_MISC_GSE; |
4175 | 4302 | ||
4303 | if (HAS_PCH_ICP(dev_priv)) | ||
4304 | icp_irq_postinstall(dev); | ||
4305 | |||
4176 | gen11_gt_irq_postinstall(dev_priv); | 4306 | gen11_gt_irq_postinstall(dev_priv); |
4177 | gen8_de_irq_postinstall(dev_priv); | 4307 | gen8_de_irq_postinstall(dev_priv); |
4178 | 4308 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2c20dc0db648..c30cfcd90754 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -7462,7 +7462,7 @@ enum { | |||
7462 | #define SDE_TRANSA_FIFO_UNDER (1 << 0) | 7462 | #define SDE_TRANSA_FIFO_UNDER (1 << 0) |
7463 | #define SDE_TRANS_MASK (0x3f) | 7463 | #define SDE_TRANS_MASK (0x3f) |
7464 | 7464 | ||
7465 | /* south display engine interrupt: CPT/PPT */ | 7465 | /* south display engine interrupt: CPT - CNP */ |
7466 | #define SDE_AUDIO_POWER_D_CPT (1 << 31) | 7466 | #define SDE_AUDIO_POWER_D_CPT (1 << 31) |
7467 | #define SDE_AUDIO_POWER_C_CPT (1 << 30) | 7467 | #define SDE_AUDIO_POWER_C_CPT (1 << 30) |
7468 | #define SDE_AUDIO_POWER_B_CPT (1 << 29) | 7468 | #define SDE_AUDIO_POWER_B_CPT (1 << 29) |
@@ -7510,6 +7510,21 @@ enum { | |||
7510 | SDE_FDI_RXB_CPT | \ | 7510 | SDE_FDI_RXB_CPT | \ |
7511 | SDE_FDI_RXA_CPT) | 7511 | SDE_FDI_RXA_CPT) |
7512 | 7512 | ||
7513 | /* south display engine interrupt: ICP */ | ||
7514 | #define SDE_TC4_HOTPLUG_ICP (1 << 27) | ||
7515 | #define SDE_TC3_HOTPLUG_ICP (1 << 26) | ||
7516 | #define SDE_TC2_HOTPLUG_ICP (1 << 25) | ||
7517 | #define SDE_TC1_HOTPLUG_ICP (1 << 24) | ||
7518 | #define SDE_GMBUS_ICP (1 << 23) | ||
7519 | #define SDE_DDIB_HOTPLUG_ICP (1 << 17) | ||
7520 | #define SDE_DDIA_HOTPLUG_ICP (1 << 16) | ||
7521 | #define SDE_DDI_MASK_ICP (SDE_DDIB_HOTPLUG_ICP | \ | ||
7522 | SDE_DDIA_HOTPLUG_ICP) | ||
7523 | #define SDE_TC_MASK_ICP (SDE_TC4_HOTPLUG_ICP | \ | ||
7524 | SDE_TC3_HOTPLUG_ICP | \ | ||
7525 | SDE_TC2_HOTPLUG_ICP | \ | ||
7526 | SDE_TC1_HOTPLUG_ICP) | ||
7527 | |||
7513 | #define SDEISR _MMIO(0xc4000) | 7528 | #define SDEISR _MMIO(0xc4000) |
7514 | #define SDEIMR _MMIO(0xc4004) | 7529 | #define SDEIMR _MMIO(0xc4004) |
7515 | #define SDEIIR _MMIO(0xc4008) | 7530 | #define SDEIIR _MMIO(0xc4008) |
@@ -7570,6 +7585,30 @@ enum { | |||
7570 | #define PORTE_HOTPLUG_SHORT_DETECT (1 << 0) | 7585 | #define PORTE_HOTPLUG_SHORT_DETECT (1 << 0) |
7571 | #define PORTE_HOTPLUG_LONG_DETECT (2 << 0) | 7586 | #define PORTE_HOTPLUG_LONG_DETECT (2 << 0) |
7572 | 7587 | ||
7588 | /* This register is a reuse of PCH_PORT_HOTPLUG register. The | ||
7589 | * functionality covered in PCH_PORT_HOTPLUG is split into | ||
7590 | * SHOTPLUG_CTL_DDI and SHOTPLUG_CTL_TC. | ||
7591 | */ | ||
7592 | |||
7593 | #define SHOTPLUG_CTL_DDI _MMIO(0xc4030) | ||
7594 | #define ICP_DDIB_HPD_ENABLE (1 << 7) | ||
7595 | #define ICP_DDIB_HPD_STATUS_MASK (3 << 4) | ||
7596 | #define ICP_DDIB_HPD_NO_DETECT (0 << 4) | ||
7597 | #define ICP_DDIB_HPD_SHORT_DETECT (1 << 4) | ||
7598 | #define ICP_DDIB_HPD_LONG_DETECT (2 << 4) | ||
7599 | #define ICP_DDIB_HPD_SHORT_LONG_DETECT (3 << 4) | ||
7600 | #define ICP_DDIA_HPD_ENABLE (1 << 3) | ||
7601 | #define ICP_DDIA_HPD_STATUS_MASK (3 << 0) | ||
7602 | #define ICP_DDIA_HPD_NO_DETECT (0 << 0) | ||
7603 | #define ICP_DDIA_HPD_SHORT_DETECT (1 << 0) | ||
7604 | #define ICP_DDIA_HPD_LONG_DETECT (2 << 0) | ||
7605 | #define ICP_DDIA_HPD_SHORT_LONG_DETECT (3 << 0) | ||
7606 | |||
7607 | #define SHOTPLUG_CTL_TC _MMIO(0xc4034) | ||
7608 | #define ICP_TC_HPD_ENABLE(tc_port) (8 << (tc_port) * 4) | ||
7609 | #define ICP_TC_HPD_LONG_DETECT(tc_port) (2 << (tc_port) * 4) | ||
7610 | #define ICP_TC_HPD_SHORT_DETECT(tc_port) (1 << (tc_port) * 4) | ||
7611 | |||
7573 | #define PCH_GPIOA _MMIO(0xc5010) | 7612 | #define PCH_GPIOA _MMIO(0xc5010) |
7574 | #define PCH_GPIOB _MMIO(0xc5014) | 7613 | #define PCH_GPIOB _MMIO(0xc5014) |
7575 | #define PCH_GPIOC _MMIO(0xc5018) | 7614 | #define PCH_GPIOC _MMIO(0xc5018) |