diff options
Diffstat (limited to 'drivers')
| -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) |
