@@ -764,14 +764,53 @@ static int cxld_await_commit(void __iomem *hdm, int id)
764
764
return - ETIMEDOUT ;
765
765
}
766
766
767
+ static void setup_hw_decoder (struct cxl_decoder * cxld , void __iomem * hdm )
768
+ {
769
+ int id = cxld -> id ;
770
+ u64 base , size ;
771
+ u32 ctrl ;
772
+
773
+ /* common decoder settings */
774
+ ctrl = readl (hdm + CXL_HDM_DECODER0_CTRL_OFFSET (cxld -> id ));
775
+ cxld_set_interleave (cxld , & ctrl );
776
+ cxld_set_type (cxld , & ctrl );
777
+ base = cxld -> hpa_range .start ;
778
+ size = range_len (& cxld -> hpa_range );
779
+
780
+ writel (upper_32_bits (base ), hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET (id ));
781
+ writel (lower_32_bits (base ), hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET (id ));
782
+ writel (upper_32_bits (size ), hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET (id ));
783
+ writel (lower_32_bits (size ), hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET (id ));
784
+
785
+ if (is_switch_decoder (& cxld -> dev )) {
786
+ struct cxl_switch_decoder * cxlsd =
787
+ to_cxl_switch_decoder (& cxld -> dev );
788
+ void __iomem * tl_hi = hdm + CXL_HDM_DECODER0_TL_HIGH (id );
789
+ void __iomem * tl_lo = hdm + CXL_HDM_DECODER0_TL_LOW (id );
790
+ u64 targets ;
791
+
792
+ cxlsd_set_targets (cxlsd , & targets );
793
+ writel (upper_32_bits (targets ), tl_hi );
794
+ writel (lower_32_bits (targets ), tl_lo );
795
+ } else {
796
+ struct cxl_endpoint_decoder * cxled =
797
+ to_cxl_endpoint_decoder (& cxld -> dev );
798
+ void __iomem * sk_hi = hdm + CXL_HDM_DECODER0_SKIP_HIGH (id );
799
+ void __iomem * sk_lo = hdm + CXL_HDM_DECODER0_SKIP_LOW (id );
800
+
801
+ writel (upper_32_bits (cxled -> skip ), sk_hi );
802
+ writel (lower_32_bits (cxled -> skip ), sk_lo );
803
+ }
804
+
805
+ writel (ctrl , hdm + CXL_HDM_DECODER0_CTRL_OFFSET (id ));
806
+ }
807
+
767
808
static int cxl_decoder_commit (struct cxl_decoder * cxld )
768
809
{
769
810
struct cxl_port * port = to_cxl_port (cxld -> dev .parent );
770
811
struct cxl_hdm * cxlhdm = dev_get_drvdata (& port -> dev );
771
812
void __iomem * hdm = cxlhdm -> regs .hdm_decoder ;
772
813
int id = cxld -> id , rc ;
773
- u64 base , size ;
774
- u32 ctrl ;
775
814
776
815
if (cxld -> flags & CXL_DECODER_F_ENABLE )
777
816
return 0 ;
@@ -804,39 +843,7 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
804
843
}
805
844
806
845
down_read (& cxl_dpa_rwsem );
807
- /* common decoder settings */
808
- ctrl = readl (hdm + CXL_HDM_DECODER0_CTRL_OFFSET (cxld -> id ));
809
- cxld_set_interleave (cxld , & ctrl );
810
- cxld_set_type (cxld , & ctrl );
811
- base = cxld -> hpa_range .start ;
812
- size = range_len (& cxld -> hpa_range );
813
-
814
- writel (upper_32_bits (base ), hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET (id ));
815
- writel (lower_32_bits (base ), hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET (id ));
816
- writel (upper_32_bits (size ), hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET (id ));
817
- writel (lower_32_bits (size ), hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET (id ));
818
-
819
- if (is_switch_decoder (& cxld -> dev )) {
820
- struct cxl_switch_decoder * cxlsd =
821
- to_cxl_switch_decoder (& cxld -> dev );
822
- void __iomem * tl_hi = hdm + CXL_HDM_DECODER0_TL_HIGH (id );
823
- void __iomem * tl_lo = hdm + CXL_HDM_DECODER0_TL_LOW (id );
824
- u64 targets ;
825
-
826
- cxlsd_set_targets (cxlsd , & targets );
827
- writel (upper_32_bits (targets ), tl_hi );
828
- writel (lower_32_bits (targets ), tl_lo );
829
- } else {
830
- struct cxl_endpoint_decoder * cxled =
831
- to_cxl_endpoint_decoder (& cxld -> dev );
832
- void __iomem * sk_hi = hdm + CXL_HDM_DECODER0_SKIP_HIGH (id );
833
- void __iomem * sk_lo = hdm + CXL_HDM_DECODER0_SKIP_LOW (id );
834
-
835
- writel (upper_32_bits (cxled -> skip ), sk_hi );
836
- writel (lower_32_bits (cxled -> skip ), sk_lo );
837
- }
838
-
839
- writel (ctrl , hdm + CXL_HDM_DECODER0_CTRL_OFFSET (id ));
846
+ setup_hw_decoder (cxld , hdm );
840
847
up_read (& cxl_dpa_rwsem );
841
848
842
849
port -> commit_end ++ ;
0 commit comments