11// SPDX-License-Identifier: GPL-2.0-only
22/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
3- #include <linux/io-64-nonatomic-hi-lo.h>
43#include <linux/seq_file.h>
54#include <linux/device.h>
65#include <linux/delay.h>
@@ -93,8 +92,9 @@ static int map_hdm_decoder_regs(struct cxl_port *port, void __iomem *crb,
9392
9493 cxl_probe_component_regs (& port -> dev , crb , & map .component_map );
9594 if (!map .component_map .hdm_decoder .valid ) {
96- dev_err (& port -> dev , "HDM decoder registers invalid\n" );
97- return - ENXIO ;
95+ dev_dbg (& port -> dev , "HDM decoder registers not implemented\n" );
96+ /* unique error code to indicate no HDM decoder capability */
97+ return - ENODEV ;
9898 }
9999
100100 return cxl_map_component_regs (& port -> dev , regs , & map ,
@@ -130,6 +130,14 @@ static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
130130 */
131131 for (i = 0 ; i < cxlhdm -> decoder_count ; i ++ ) {
132132 ctrl = readl (hdm + CXL_HDM_DECODER0_CTRL_OFFSET (i ));
133+ dev_dbg (& info -> port -> dev ,
134+ "decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n" ,
135+ info -> port -> id , i ,
136+ FIELD_GET (CXL_HDM_DECODER0_CTRL_COMMITTED , ctrl ),
137+ readl (hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET (i )),
138+ readl (hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET (i )),
139+ readl (hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET (i )),
140+ readl (hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET (i )));
133141 if (FIELD_GET (CXL_HDM_DECODER0_CTRL_COMMITTED , ctrl ))
134142 return false;
135143 }
@@ -269,8 +277,11 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
269277
270278 lockdep_assert_held_write (& cxl_dpa_rwsem );
271279
272- if (!len )
273- goto success ;
280+ if (!len ) {
281+ dev_warn (dev , "decoder%d.%d: empty reservation attempted\n" ,
282+ port -> id , cxled -> cxld .id );
283+ return - EINVAL ;
284+ }
274285
275286 if (cxled -> dpa_res ) {
276287 dev_dbg (dev , "decoder%d.%d: existing allocation %pr assigned\n" ,
@@ -323,7 +334,6 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
323334 cxled -> mode = CXL_DECODER_MIXED ;
324335 }
325336
326- success :
327337 port -> hdm_end ++ ;
328338 get_device (& cxled -> cxld .dev );
329339 return 0 ;
@@ -783,8 +793,8 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
783793 int * target_map , void __iomem * hdm , int which ,
784794 u64 * dpa_base , struct cxl_endpoint_dvsec_info * info )
785795{
796+ u64 size , base , skip , dpa_size , lo , hi ;
786797 struct cxl_endpoint_decoder * cxled ;
787- u64 size , base , skip , dpa_size ;
788798 bool committed ;
789799 u32 remainder ;
790800 int i , rc ;
@@ -799,8 +809,12 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
799809 which , info );
800810
801811 ctrl = readl (hdm + CXL_HDM_DECODER0_CTRL_OFFSET (which ));
802- base = ioread64_hi_lo (hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET (which ));
803- size = ioread64_hi_lo (hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET (which ));
812+ lo = readl (hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET (which ));
813+ hi = readl (hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET (which ));
814+ base = (hi << 32 ) + lo ;
815+ lo = readl (hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET (which ));
816+ hi = readl (hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET (which ));
817+ size = (hi << 32 ) + lo ;
804818 committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED );
805819 cxld -> commit = cxl_decoder_commit ;
806820 cxld -> reset = cxl_decoder_reset ;
@@ -833,6 +847,13 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
833847 port -> id , cxld -> id );
834848 return - ENXIO ;
835849 }
850+
851+ if (size == 0 ) {
852+ dev_warn (& port -> dev ,
853+ "decoder%d.%d: Committed with zero size\n" ,
854+ port -> id , cxld -> id );
855+ return - ENXIO ;
856+ }
836857 port -> commit_end = cxld -> id ;
837858 } else {
838859 /* unless / until type-2 drivers arrive, assume type-3 */
@@ -855,9 +876,14 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
855876 if (rc )
856877 return rc ;
857878
879+ dev_dbg (& port -> dev , "decoder%d.%d: range: %#llx-%#llx iw: %d ig: %d\n" ,
880+ port -> id , cxld -> id , cxld -> hpa_range .start , cxld -> hpa_range .end ,
881+ cxld -> interleave_ways , cxld -> interleave_granularity );
882+
858883 if (!info ) {
859- target_list .value =
860- ioread64_hi_lo (hdm + CXL_HDM_DECODER0_TL_LOW (which ));
884+ lo = readl (hdm + CXL_HDM_DECODER0_TL_LOW (which ));
885+ hi = readl (hdm + CXL_HDM_DECODER0_TL_HIGH (which ));
886+ target_list .value = (hi << 32 ) + lo ;
861887 for (i = 0 ; i < cxld -> interleave_ways ; i ++ )
862888 target_map [i ] = target_list .target_id [i ];
863889
@@ -874,7 +900,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
874900 port -> id , cxld -> id , size , cxld -> interleave_ways );
875901 return - ENXIO ;
876902 }
877- skip = ioread64_hi_lo (hdm + CXL_HDM_DECODER0_SKIP_LOW (which ));
903+ lo = readl (hdm + CXL_HDM_DECODER0_SKIP_LOW (which ));
904+ hi = readl (hdm + CXL_HDM_DECODER0_SKIP_HIGH (which ));
905+ skip = (hi << 32 ) + lo ;
878906 cxled = to_cxl_endpoint_decoder (& cxld -> dev );
879907 rc = devm_cxl_dpa_reserve (cxled , * dpa_base + skip , dpa_size , skip );
880908 if (rc ) {
0 commit comments