xref: /linux/include/cxl/cxl.h (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
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