1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Copyright(c) 2020 Intel Corporation. */ 3 /* Copyright(c) 2026 Advanced Micro Devices, Inc. */ 4 5 #ifndef __CXL_CXL_H__ 6 #define __CXL_CXL_H__ 7 8 #include <linux/node.h> 9 #include <linux/ioport.h> 10 #include <cxl/mailbox.h> 11 12 /** 13 * enum cxl_devtype - delineate type-2 from a generic type-3 device 14 * @CXL_DEVTYPE_DEVMEM: Vendor specific CXL Type-2 device implementing HDM-D or 15 * HDM-DB, no requirement that this device implements a 16 * mailbox, or other memory-device-standard manageability 17 * flows. 18 * @CXL_DEVTYPE_CLASSMEM: Common class definition of a CXL Type-3 device with 19 * HDM-H and class-mandatory memory device registers 20 */ 21 enum cxl_devtype { 22 CXL_DEVTYPE_DEVMEM, 23 CXL_DEVTYPE_CLASSMEM, 24 }; 25 26 struct device; 27 28 /* 29 * Using struct_group() allows for per register-block-type helper routines, 30 * without requiring block-type agnostic code to include the prefix. 31 */ 32 struct cxl_regs { 33 /* 34 * Common set of CXL Component register block base pointers 35 * @hdm_decoder: CXL 2.0 8.2.5.12 CXL HDM Decoder Capability Structure 36 * @ras: CXL 2.0 8.2.5.9 CXL RAS Capability Structure 37 */ 38 struct_group_tagged(cxl_component_regs, component, 39 void __iomem *hdm_decoder; 40 void __iomem *ras; 41 ); 42 /* 43 * Common set of CXL Device register block base pointers 44 * @status: CXL 2.0 8.2.8.3 Device Status Registers 45 * @mbox: CXL 2.0 8.2.8.4 Mailbox Registers 46 * @memdev: CXL 2.0 8.2.8.5 Memory Device Registers 47 */ 48 struct_group_tagged(cxl_device_regs, device_regs, 49 void __iomem *status, *mbox, *memdev; 50 ); 51 52 struct_group_tagged(cxl_pmu_regs, pmu_regs, 53 void __iomem *pmu; 54 ); 55 56 /* 57 * RCH downstream port specific RAS register 58 * @aer: CXL 3.0 8.2.1.1 RCH Downstream Port RCRB 59 */ 60 struct_group_tagged(cxl_rch_regs, rch_regs, 61 void __iomem *dport_aer; 62 ); 63 64 /* 65 * RCD upstream port specific PCIe cap register 66 * @pcie_cap: CXL 3.0 8.2.1.2 RCD Upstream Port RCRB 67 */ 68 struct_group_tagged(cxl_rcd_regs, rcd_regs, 69 void __iomem *rcd_pcie_cap; 70 ); 71 }; 72 73 struct cxl_reg_map { 74 bool valid; 75 int id; 76 unsigned long offset; 77 unsigned long size; 78 }; 79 80 struct cxl_component_reg_map { 81 struct cxl_reg_map hdm_decoder; 82 struct cxl_reg_map ras; 83 }; 84 85 struct cxl_device_reg_map { 86 struct cxl_reg_map status; 87 struct cxl_reg_map mbox; 88 struct cxl_reg_map memdev; 89 }; 90 91 struct cxl_pmu_reg_map { 92 struct cxl_reg_map pmu; 93 }; 94 95 /** 96 * struct cxl_register_map - DVSEC harvested register block mapping parameters 97 * @host: device for devm operations and logging 98 * @base: virtual base of the register-block-BAR + @block_offset 99 * @resource: physical resource base of the register block 100 * @max_size: maximum mapping size to perform register search 101 * @reg_type: see enum cxl_regloc_type 102 * @component_map: cxl_reg_map for component registers 103 * @device_map: cxl_reg_maps for device registers 104 * @pmu_map: cxl_reg_maps for CXL Performance Monitoring Units 105 */ 106 struct cxl_register_map { 107 struct device *host; 108 void __iomem *base; 109 resource_size_t resource; 110 resource_size_t max_size; 111 u8 reg_type; 112 union { 113 struct cxl_component_reg_map component_map; 114 struct cxl_device_reg_map device_map; 115 struct cxl_pmu_reg_map pmu_map; 116 }; 117 }; 118 119 /** 120 * struct cxl_dpa_perf - DPA performance property entry 121 * @dpa_range: range for DPA address 122 * @coord: QoS performance data (i.e. latency, bandwidth) 123 * @cdat_coord: raw QoS performance data from CDAT 124 * @qos_class: QoS Class cookies 125 */ 126 struct cxl_dpa_perf { 127 struct range dpa_range; 128 struct access_coordinate coord[ACCESS_COORDINATE_MAX]; 129 struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX]; 130 int qos_class; 131 }; 132 133 enum cxl_partition_mode { 134 CXL_PARTMODE_RAM, 135 CXL_PARTMODE_PMEM, 136 }; 137 138 /** 139 * struct cxl_dpa_partition - DPA partition descriptor 140 * @res: shortcut to the partition in the DPA resource tree (cxlds->dpa_res) 141 * @perf: performance attributes of the partition from CDAT 142 * @mode: operation mode for the DPA capacity, e.g. ram, pmem, dynamic... 143 */ 144 struct cxl_dpa_partition { 145 struct resource res; 146 struct cxl_dpa_perf perf; 147 enum cxl_partition_mode mode; 148 }; 149 150 #define CXL_NR_PARTITIONS_MAX 2 151 152 /** 153 * struct cxl_dev_state - The driver device state 154 * 155 * cxl_dev_state represents the CXL driver/device state. It provides an 156 * interface to mailbox commands as well as some cached data about the device. 157 * Currently only memory devices are represented. 158 * 159 * @dev: The device associated with this CXL state 160 * @cxlmd: The device representing the CXL.mem capabilities of @dev 161 * @reg_map: component and ras register mapping parameters 162 * @regs: Parsed register blocks 163 * @cxl_dvsec: Offset to the PCIe device DVSEC 164 * @rcd: operating in RCD mode (CXL 3.0 9.11.8 CXL Devices Attached to an RCH) 165 * @media_ready: Indicate whether the device media is usable 166 * @dpa_res: Overall DPA resource tree for the device 167 * @part: DPA partition array 168 * @nr_partitions: Number of DPA partitions 169 * @serial: PCIe Device Serial Number 170 * @type: Generic Memory Class device or Vendor Specific Memory device 171 * @cxl_mbox: CXL mailbox context 172 * @cxlfs: CXL features context 173 */ 174 struct cxl_dev_state { 175 /* public for Type2 drivers */ 176 struct device *dev; 177 struct cxl_memdev *cxlmd; 178 179 /* private for Type2 drivers */ 180 struct cxl_register_map reg_map; 181 struct cxl_device_regs regs; 182 int cxl_dvsec; 183 bool rcd; 184 bool media_ready; 185 struct resource dpa_res; 186 struct cxl_dpa_partition part[CXL_NR_PARTITIONS_MAX]; 187 unsigned int nr_partitions; 188 u64 serial; 189 enum cxl_devtype type; 190 struct cxl_mailbox cxl_mbox; 191 #ifdef CONFIG_CXL_FEATURES 192 struct cxl_features_state *cxlfs; 193 #endif 194 }; 195 196 struct cxl_dev_state *_devm_cxl_dev_state_create(struct device *dev, 197 enum cxl_devtype type, 198 u64 serial, u16 dvsec, 199 size_t size, bool has_mbox); 200 201 /** 202 * cxl_dev_state_create - safely create and cast a cxl dev state embedded in a 203 * driver specific struct. 204 * 205 * @parent: device behind the request 206 * @type: CXL device type 207 * @serial: device identification 208 * @dvsec: dvsec capability offset 209 * @drv_struct: driver struct embedding a cxl_dev_state struct 210 * @member: name of the struct cxl_dev_state member in drv_struct 211 * @mbox: true if mailbox supported 212 * 213 * Returns a pointer to the drv_struct allocated and embedding a cxl_dev_state 214 * struct initialized. 215 * 216 * Introduced for Type2 driver support. 217 */ 218 #define devm_cxl_dev_state_create(parent, type, serial, dvsec, drv_struct, member, mbox) \ 219 ({ \ 220 static_assert(__same_type(struct cxl_dev_state, \ 221 ((drv_struct *)NULL)->member)); \ 222 static_assert(offsetof(drv_struct, member) == 0); \ 223 (drv_struct *)_devm_cxl_dev_state_create(parent, type, serial, dvsec, \ 224 sizeof(drv_struct), mbox); \ 225 }) 226 #endif /* __CXL_CXL_H__ */ 227