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