0001
0002
0003
0004
0005 #include <linux/workqueue.h>
0006 #include "intel_pxp.h"
0007 #include "intel_pxp_irq.h"
0008 #include "intel_pxp_session.h"
0009 #include "gt/intel_gt_irq.h"
0010 #include "gt/intel_gt_regs.h"
0011 #include "gt/intel_gt_types.h"
0012 #include "i915_irq.h"
0013 #include "i915_reg.h"
0014 #include "intel_runtime_pm.h"
0015
0016
0017
0018
0019
0020
0021 void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
0022 {
0023 struct intel_gt *gt = pxp_to_gt(pxp);
0024
0025 if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp)))
0026 return;
0027
0028 lockdep_assert_held(>->irq_lock);
0029
0030 if (unlikely(!iir))
0031 return;
0032
0033 if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
0034 GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
0035
0036 intel_pxp_mark_termination_in_progress(pxp);
0037 pxp->session_events |= PXP_TERMINATION_REQUEST | PXP_INVAL_REQUIRED;
0038 }
0039
0040 if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
0041 pxp->session_events |= PXP_TERMINATION_COMPLETE;
0042
0043 if (pxp->session_events)
0044 queue_work(system_unbound_wq, &pxp->session_work);
0045 }
0046
0047 static inline void __pxp_set_interrupts(struct intel_gt *gt, u32 interrupts)
0048 {
0049 struct intel_uncore *uncore = gt->uncore;
0050 const u32 mask = interrupts << 16;
0051
0052 intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, mask);
0053 intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK, ~mask);
0054 }
0055
0056 static inline void pxp_irq_reset(struct intel_gt *gt)
0057 {
0058 spin_lock_irq(>->irq_lock);
0059 gen11_gt_reset_one_iir(gt, 0, GEN11_KCR);
0060 spin_unlock_irq(>->irq_lock);
0061 }
0062
0063 void intel_pxp_irq_enable(struct intel_pxp *pxp)
0064 {
0065 struct intel_gt *gt = pxp_to_gt(pxp);
0066
0067 spin_lock_irq(>->irq_lock);
0068
0069 if (!pxp->irq_enabled)
0070 WARN_ON_ONCE(gen11_gt_reset_one_iir(gt, 0, GEN11_KCR));
0071
0072 __pxp_set_interrupts(gt, GEN12_PXP_INTERRUPTS);
0073 pxp->irq_enabled = true;
0074
0075 spin_unlock_irq(>->irq_lock);
0076 }
0077
0078 void intel_pxp_irq_disable(struct intel_pxp *pxp)
0079 {
0080 struct intel_gt *gt = pxp_to_gt(pxp);
0081
0082
0083
0084
0085
0086
0087
0088
0089 GEM_WARN_ON(intel_pxp_is_active(pxp));
0090
0091 spin_lock_irq(>->irq_lock);
0092
0093 pxp->irq_enabled = false;
0094 __pxp_set_interrupts(gt, 0);
0095
0096 spin_unlock_irq(>->irq_lock);
0097 intel_synchronize_irq(gt->i915);
0098
0099 pxp_irq_reset(gt);
0100
0101 flush_work(&pxp->session_work);
0102 }