@@ -546,6 +546,36 @@ static bool is_event_handler(struct intel_display *display,
546546 REG_FIELD_GET (DMC_EVT_CTL_EVENT_ID_MASK , data ) == event_id ;
547547}
548548
549+ static bool fixup_dmc_evt (struct intel_display * display ,
550+ enum intel_dmc_id dmc_id ,
551+ i915_reg_t reg_ctl , u32 * data_ctl ,
552+ i915_reg_t reg_htp , u32 * data_htp )
553+ {
554+ if (!is_dmc_evt_ctl_reg (display , dmc_id , reg_ctl ))
555+ return false;
556+
557+ if (!is_dmc_evt_htp_reg (display , dmc_id , reg_htp ))
558+ return false;
559+
560+ /* make sure reg_ctl and reg_htp are for the same event */
561+ if (i915_mmio_reg_offset (reg_ctl ) - i915_mmio_reg_offset (DMC_EVT_CTL (display , dmc_id , 0 )) !=
562+ i915_mmio_reg_offset (reg_htp ) - i915_mmio_reg_offset (DMC_EVT_HTP (display , dmc_id , 0 )))
563+ return false;
564+
565+ /*
566+ * On ADL-S the HRR event handler is not restored after DC6.
567+ * Clear it to zero from the beginning to avoid mismatches later.
568+ */
569+ if (display -> platform .alderlake_s && dmc_id == DMC_FW_MAIN &&
570+ is_event_handler (display , dmc_id , MAINDMC_EVENT_VBLANK_A , reg_ctl , * data_ctl )) {
571+ * data_ctl = 0 ;
572+ * data_htp = 0 ;
573+ return true;
574+ }
575+
576+ return false;
577+ }
578+
549579static bool disable_dmc_evt (struct intel_display * display ,
550580 enum intel_dmc_id dmc_id ,
551581 i915_reg_t reg , u32 data )
@@ -1064,9 +1094,32 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
10641094 for (i = 0 ; i < mmio_count ; i ++ ) {
10651095 dmc_info -> mmioaddr [i ] = _MMIO (mmioaddr [i ]);
10661096 dmc_info -> mmiodata [i ] = mmiodata [i ];
1097+ }
1098+
1099+ for (i = 0 ; i < mmio_count - 1 ; i ++ ) {
1100+ u32 orig_mmiodata [2 ] = {
1101+ dmc_info -> mmiodata [i ],
1102+ dmc_info -> mmiodata [i + 1 ],
1103+ };
1104+
1105+ if (!fixup_dmc_evt (display , dmc_id ,
1106+ dmc_info -> mmioaddr [i ], & dmc_info -> mmiodata [i ],
1107+ dmc_info -> mmioaddr [i + 1 ], & dmc_info -> mmiodata [i + 1 ]))
1108+ continue ;
1109+
1110+ drm_dbg_kms (display -> drm ,
1111+ " mmio[%d]: 0x%x = 0x%x->0x%x (EVT_CTL)\n" ,
1112+ i , i915_mmio_reg_offset (dmc_info -> mmioaddr [i ]),
1113+ orig_mmiodata [0 ], dmc_info -> mmiodata [i ]);
1114+ drm_dbg_kms (display -> drm ,
1115+ " mmio[%d]: 0x%x = 0x%x->0x%x (EVT_HTP)\n" ,
1116+ i + 1 , i915_mmio_reg_offset (dmc_info -> mmioaddr [i + 1 ]),
1117+ orig_mmiodata [1 ], dmc_info -> mmiodata [i + 1 ]);
1118+ }
10671119
1120+ for (i = 0 ; i < mmio_count ; i ++ ) {
10681121 drm_dbg_kms (display -> drm , " mmio[%d]: 0x%x = 0x%x%s%s\n" ,
1069- i , mmioaddr [i ], mmiodata [i ],
1122+ i , i915_mmio_reg_offset ( dmc_info -> mmioaddr [i ]), dmc_info -> mmiodata [i ],
10701123 is_dmc_evt_ctl_reg (display , dmc_id , dmc_info -> mmioaddr [i ]) ? " (EVT_CTL)" :
10711124 is_dmc_evt_htp_reg (display , dmc_id , dmc_info -> mmioaddr [i ]) ? " (EVT_HTP)" : "" ,
10721125 disable_dmc_evt (display , dmc_id , dmc_info -> mmioaddr [i ],
0 commit comments