@@ -730,6 +730,32 @@ static int cxl_setup_hdm_decoder_from_dvsec(struct cxl_port *port,
730
730
return 0 ;
731
731
}
732
732
733
+ static bool should_emulate_decoders (struct cxl_port * port )
734
+ {
735
+ struct cxl_hdm * cxlhdm = dev_get_drvdata (& port -> dev );
736
+ void __iomem * hdm = cxlhdm -> regs .hdm_decoder ;
737
+ u32 ctrl ;
738
+ int i ;
739
+
740
+ if (!is_cxl_endpoint (cxlhdm -> port ))
741
+ return false;
742
+
743
+ if (!hdm )
744
+ return true;
745
+
746
+ /*
747
+ * If any decoders are committed already, there should not be any
748
+ * emulated DVSEC decoders.
749
+ */
750
+ for (i = 0 ; i < cxlhdm -> decoder_count ; i ++ ) {
751
+ ctrl = readl (hdm + CXL_HDM_DECODER0_CTRL_OFFSET (i ));
752
+ if (FIELD_GET (CXL_HDM_DECODER0_CTRL_COMMITTED , ctrl ))
753
+ return false;
754
+ }
755
+
756
+ return true;
757
+ }
758
+
733
759
static int init_hdm_decoder (struct cxl_port * port , struct cxl_decoder * cxld ,
734
760
int * target_map , void __iomem * hdm , int which ,
735
761
u64 * dpa_base , struct cxl_endpoint_dvsec_info * info )
@@ -745,6 +771,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
745
771
unsigned char target_id [8 ];
746
772
} target_list ;
747
773
774
+ if (should_emulate_decoders (port ))
775
+ return cxl_setup_hdm_decoder_from_dvsec (port , cxld , which , info );
776
+
748
777
if (is_endpoint_decoder (& cxld -> dev ))
749
778
cxled = to_cxl_endpoint_decoder (& cxld -> dev );
750
779
0 commit comments