hdm.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Copyright(c) 2022 Intel Corporation. All rights reserved. */
  3. #include <linux/seq_file.h>
  4. #include <linux/device.h>
  5. #include <linux/delay.h>
  6. #include "cxlmem.h"
  7. #include "core.h"
  8. /**
  9. * DOC: cxl core hdm
  10. *
  11. * Compute Express Link Host Managed Device Memory, starting with the
  12. * CXL 2.0 specification, is managed by an array of HDM Decoder register
  13. * instances per CXL port and per CXL endpoint. Define common helpers
  14. * for enumerating these registers and capabilities.
  15. */
  16. DECLARE_RWSEM(cxl_dpa_rwsem);
  17. static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
  18. int *target_map)
  19. {
  20. int rc;
  21. rc = cxl_decoder_add_locked(cxld, target_map);
  22. if (rc) {
  23. put_device(&cxld->dev);
  24. dev_err(&port->dev, "Failed to add decoder\n");
  25. return rc;
  26. }
  27. rc = cxl_decoder_autoremove(&port->dev, cxld);
  28. if (rc)
  29. return rc;
  30. dev_dbg(&cxld->dev, "Added to port %s\n", dev_name(&port->dev));
  31. return 0;
  32. }
  33. /*
  34. * Per the CXL specification (8.2.5.12 CXL HDM Decoder Capability Structure)
  35. * single ported host-bridges need not publish a decoder capability when a
  36. * passthrough decode can be assumed, i.e. all transactions that the uport sees
  37. * are claimed and passed to the single dport. Disable the range until the first
  38. * CXL region is enumerated / activated.
  39. */
  40. int devm_cxl_add_passthrough_decoder(struct cxl_port *port)
  41. {
  42. struct cxl_switch_decoder *cxlsd;
  43. struct cxl_dport *dport = NULL;
  44. int single_port_map[1];
  45. unsigned long index;
  46. struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
  47. /*
  48. * Capability checks are moot for passthrough decoders, support
  49. * any and all possibilities.
  50. */
  51. cxlhdm->interleave_mask = ~0U;
  52. cxlhdm->iw_cap_mask = ~0UL;
  53. cxlsd = cxl_switch_decoder_alloc(port, 1);
  54. if (IS_ERR(cxlsd))
  55. return PTR_ERR(cxlsd);
  56. device_lock_assert(&port->dev);
  57. xa_for_each(&port->dports, index, dport)
  58. break;
  59. single_port_map[0] = dport->port_id;
  60. return add_hdm_decoder(port, &cxlsd->cxld, single_port_map);
  61. }
  62. EXPORT_SYMBOL_NS_GPL(devm_cxl_add_passthrough_decoder, CXL);
  63. static void parse_hdm_decoder_caps(struct cxl_hdm *cxlhdm)
  64. {
  65. u32 hdm_cap;
  66. hdm_cap = readl(cxlhdm->regs.hdm_decoder + CXL_HDM_DECODER_CAP_OFFSET);
  67. cxlhdm->decoder_count = cxl_hdm_decoder_count(hdm_cap);
  68. cxlhdm->target_count =
  69. FIELD_GET(CXL_HDM_DECODER_TARGET_COUNT_MASK, hdm_cap);
  70. if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_11_8, hdm_cap))
  71. cxlhdm->interleave_mask |= GENMASK(11, 8);
  72. if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_14_12, hdm_cap))
  73. cxlhdm->interleave_mask |= GENMASK(14, 12);
  74. cxlhdm->iw_cap_mask = BIT(1) | BIT(2) | BIT(4) | BIT(8);
  75. if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_3_6_12_WAY, hdm_cap))
  76. cxlhdm->iw_cap_mask |= BIT(3) | BIT(6) | BIT(12);
  77. if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_16_WAY, hdm_cap))
  78. cxlhdm->iw_cap_mask |= BIT(16);
  79. }
  80. static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
  81. {
  82. struct cxl_hdm *cxlhdm;
  83. void __iomem *hdm;
  84. u32 ctrl;
  85. int i;
  86. if (!info)
  87. return false;
  88. cxlhdm = dev_get_drvdata(&info->port->dev);
  89. hdm = cxlhdm->regs.hdm_decoder;
  90. if (!hdm)
  91. return true;
  92. /*
  93. * If HDM decoders are present and the driver is in control of
  94. * Mem_Enable skip DVSEC based emulation
  95. */
  96. if (!info->mem_enabled)
  97. return false;
  98. /*
  99. * If any decoders are committed already, there should not be any
  100. * emulated DVSEC decoders.
  101. */
  102. for (i = 0; i < cxlhdm->decoder_count; i++) {
  103. ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
  104. dev_dbg(&info->port->dev,
  105. "decoder%d.%d: committed: %ld base: %#x_%.8x size: %#x_%.8x\n",
  106. info->port->id, i,
  107. FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl),
  108. readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(i)),
  109. readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(i)),
  110. readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(i)),
  111. readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(i)));
  112. if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
  113. return false;
  114. }
  115. return true;
  116. }
  117. /**
  118. * devm_cxl_setup_hdm - map HDM decoder component registers
  119. * @port: cxl_port to map
  120. * @info: cached DVSEC range register info
  121. */
  122. struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port,
  123. struct cxl_endpoint_dvsec_info *info)
  124. {
  125. struct cxl_register_map *reg_map = &port->reg_map;
  126. struct device *dev = &port->dev;
  127. struct cxl_hdm *cxlhdm;
  128. int rc;
  129. cxlhdm = devm_kzalloc(dev, sizeof(*cxlhdm), GFP_KERNEL);
  130. if (!cxlhdm)
  131. return ERR_PTR(-ENOMEM);
  132. cxlhdm->port = port;
  133. dev_set_drvdata(dev, cxlhdm);
  134. /* Memory devices can configure device HDM using DVSEC range regs. */
  135. if (reg_map->resource == CXL_RESOURCE_NONE) {
  136. if (!info || !info->mem_enabled) {
  137. dev_err(dev, "No component registers mapped\n");
  138. return ERR_PTR(-ENXIO);
  139. }
  140. cxlhdm->decoder_count = info->ranges;
  141. return cxlhdm;
  142. }
  143. if (!reg_map->component_map.hdm_decoder.valid) {
  144. dev_dbg(&port->dev, "HDM decoder registers not implemented\n");
  145. /* unique error code to indicate no HDM decoder capability */
  146. return ERR_PTR(-ENODEV);
  147. }
  148. rc = cxl_map_component_regs(reg_map, &cxlhdm->regs,
  149. BIT(CXL_CM_CAP_CAP_ID_HDM));
  150. if (rc) {
  151. dev_err(dev, "Failed to map HDM capability.\n");
  152. return ERR_PTR(rc);
  153. }
  154. parse_hdm_decoder_caps(cxlhdm);
  155. if (cxlhdm->decoder_count == 0) {
  156. dev_err(dev, "Spec violation. Caps invalid\n");
  157. return ERR_PTR(-ENXIO);
  158. }
  159. /*
  160. * Now that the hdm capability is parsed, decide if range
  161. * register emulation is needed and fixup cxlhdm accordingly.
  162. */
  163. if (should_emulate_decoders(info)) {
  164. dev_dbg(dev, "Fallback map %d range register%s\n", info->ranges,
  165. info->ranges > 1 ? "s" : "");
  166. cxlhdm->decoder_count = info->ranges;
  167. }
  168. return cxlhdm;
  169. }
  170. EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, CXL);
  171. static void __cxl_dpa_debug(struct seq_file *file, struct resource *r, int depth)
  172. {
  173. unsigned long long start = r->start, end = r->end;
  174. seq_printf(file, "%*s%08llx-%08llx : %s\n", depth * 2, "", start, end,
  175. r->name);
  176. }
  177. void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds)
  178. {
  179. struct resource *p1, *p2;
  180. down_read(&cxl_dpa_rwsem);
  181. for (p1 = cxlds->dpa_res.child; p1; p1 = p1->sibling) {
  182. __cxl_dpa_debug(file, p1, 0);
  183. for (p2 = p1->child; p2; p2 = p2->sibling)
  184. __cxl_dpa_debug(file, p2, 1);
  185. }
  186. up_read(&cxl_dpa_rwsem);
  187. }
  188. EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, CXL);
  189. /*
  190. * Must be called in a context that synchronizes against this decoder's
  191. * port ->remove() callback (like an endpoint decoder sysfs attribute)
  192. */
  193. static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
  194. {
  195. struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
  196. struct cxl_port *port = cxled_to_port(cxled);
  197. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  198. struct resource *res = cxled->dpa_res;
  199. resource_size_t skip_start;
  200. lockdep_assert_held_write(&cxl_dpa_rwsem);
  201. /* save @skip_start, before @res is released */
  202. skip_start = res->start - cxled->skip;
  203. __release_region(&cxlds->dpa_res, res->start, resource_size(res));
  204. if (cxled->skip)
  205. __release_region(&cxlds->dpa_res, skip_start, cxled->skip);
  206. cxled->skip = 0;
  207. cxled->dpa_res = NULL;
  208. put_device(&cxled->cxld.dev);
  209. port->hdm_end--;
  210. }
  211. static void cxl_dpa_release(void *cxled)
  212. {
  213. down_write(&cxl_dpa_rwsem);
  214. __cxl_dpa_release(cxled);
  215. up_write(&cxl_dpa_rwsem);
  216. }
  217. /*
  218. * Must be called from context that will not race port device
  219. * unregistration, like decoder sysfs attribute methods
  220. */
  221. static void devm_cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
  222. {
  223. struct cxl_port *port = cxled_to_port(cxled);
  224. lockdep_assert_held_write(&cxl_dpa_rwsem);
  225. devm_remove_action(&port->dev, cxl_dpa_release, cxled);
  226. __cxl_dpa_release(cxled);
  227. }
  228. static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
  229. resource_size_t base, resource_size_t len,
  230. resource_size_t skipped)
  231. {
  232. struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
  233. struct cxl_port *port = cxled_to_port(cxled);
  234. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  235. struct device *dev = &port->dev;
  236. struct resource *res;
  237. lockdep_assert_held_write(&cxl_dpa_rwsem);
  238. if (!len) {
  239. dev_warn(dev, "decoder%d.%d: empty reservation attempted\n",
  240. port->id, cxled->cxld.id);
  241. return -EINVAL;
  242. }
  243. if (cxled->dpa_res) {
  244. dev_dbg(dev, "decoder%d.%d: existing allocation %pr assigned\n",
  245. port->id, cxled->cxld.id, cxled->dpa_res);
  246. return -EBUSY;
  247. }
  248. if (port->hdm_end + 1 != cxled->cxld.id) {
  249. /*
  250. * Assumes alloc and commit order is always in hardware instance
  251. * order per expectations from 8.2.5.12.20 Committing Decoder
  252. * Programming that enforce decoder[m] committed before
  253. * decoder[m+1] commit start.
  254. */
  255. dev_dbg(dev, "decoder%d.%d: expected decoder%d.%d\n", port->id,
  256. cxled->cxld.id, port->id, port->hdm_end + 1);
  257. return -EBUSY;
  258. }
  259. if (skipped) {
  260. res = __request_region(&cxlds->dpa_res, base - skipped, skipped,
  261. dev_name(&cxled->cxld.dev), 0);
  262. if (!res) {
  263. dev_dbg(dev,
  264. "decoder%d.%d: failed to reserve skipped space\n",
  265. port->id, cxled->cxld.id);
  266. return -EBUSY;
  267. }
  268. }
  269. res = __request_region(&cxlds->dpa_res, base, len,
  270. dev_name(&cxled->cxld.dev), 0);
  271. if (!res) {
  272. dev_dbg(dev, "decoder%d.%d: failed to reserve allocation\n",
  273. port->id, cxled->cxld.id);
  274. if (skipped)
  275. __release_region(&cxlds->dpa_res, base - skipped,
  276. skipped);
  277. return -EBUSY;
  278. }
  279. cxled->dpa_res = res;
  280. cxled->skip = skipped;
  281. if (resource_contains(&cxlds->pmem_res, res))
  282. cxled->mode = CXL_DECODER_PMEM;
  283. else if (resource_contains(&cxlds->ram_res, res))
  284. cxled->mode = CXL_DECODER_RAM;
  285. else {
  286. dev_warn(dev, "decoder%d.%d: %pr mixed mode not supported\n",
  287. port->id, cxled->cxld.id, cxled->dpa_res);
  288. cxled->mode = CXL_DECODER_MIXED;
  289. }
  290. port->hdm_end++;
  291. get_device(&cxled->cxld.dev);
  292. return 0;
  293. }
  294. int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
  295. resource_size_t base, resource_size_t len,
  296. resource_size_t skipped)
  297. {
  298. struct cxl_port *port = cxled_to_port(cxled);
  299. int rc;
  300. down_write(&cxl_dpa_rwsem);
  301. rc = __cxl_dpa_reserve(cxled, base, len, skipped);
  302. up_write(&cxl_dpa_rwsem);
  303. if (rc)
  304. return rc;
  305. return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
  306. }
  307. EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, CXL);
  308. resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled)
  309. {
  310. resource_size_t size = 0;
  311. down_read(&cxl_dpa_rwsem);
  312. if (cxled->dpa_res)
  313. size = resource_size(cxled->dpa_res);
  314. up_read(&cxl_dpa_rwsem);
  315. return size;
  316. }
  317. resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled)
  318. {
  319. resource_size_t base = -1;
  320. lockdep_assert_held(&cxl_dpa_rwsem);
  321. if (cxled->dpa_res)
  322. base = cxled->dpa_res->start;
  323. return base;
  324. }
  325. int cxl_dpa_free(struct cxl_endpoint_decoder *cxled)
  326. {
  327. struct cxl_port *port = cxled_to_port(cxled);
  328. struct device *dev = &cxled->cxld.dev;
  329. int rc;
  330. down_write(&cxl_dpa_rwsem);
  331. if (!cxled->dpa_res) {
  332. rc = 0;
  333. goto out;
  334. }
  335. if (cxled->cxld.region) {
  336. dev_dbg(dev, "decoder assigned to: %s\n",
  337. dev_name(&cxled->cxld.region->dev));
  338. rc = -EBUSY;
  339. goto out;
  340. }
  341. if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
  342. dev_dbg(dev, "decoder enabled\n");
  343. rc = -EBUSY;
  344. goto out;
  345. }
  346. if (cxled->cxld.id != port->hdm_end) {
  347. dev_dbg(dev, "expected decoder%d.%d\n", port->id,
  348. port->hdm_end);
  349. rc = -EBUSY;
  350. goto out;
  351. }
  352. devm_cxl_dpa_release(cxled);
  353. rc = 0;
  354. out:
  355. up_write(&cxl_dpa_rwsem);
  356. return rc;
  357. }
  358. int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
  359. enum cxl_decoder_mode mode)
  360. {
  361. struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
  362. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  363. struct device *dev = &cxled->cxld.dev;
  364. int rc;
  365. switch (mode) {
  366. case CXL_DECODER_RAM:
  367. case CXL_DECODER_PMEM:
  368. break;
  369. default:
  370. dev_dbg(dev, "unsupported mode: %d\n", mode);
  371. return -EINVAL;
  372. }
  373. down_write(&cxl_dpa_rwsem);
  374. if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
  375. rc = -EBUSY;
  376. goto out;
  377. }
  378. /*
  379. * Only allow modes that are supported by the current partition
  380. * configuration
  381. */
  382. if (mode == CXL_DECODER_PMEM && !resource_size(&cxlds->pmem_res)) {
  383. dev_dbg(dev, "no available pmem capacity\n");
  384. rc = -ENXIO;
  385. goto out;
  386. }
  387. if (mode == CXL_DECODER_RAM && !resource_size(&cxlds->ram_res)) {
  388. dev_dbg(dev, "no available ram capacity\n");
  389. rc = -ENXIO;
  390. goto out;
  391. }
  392. cxled->mode = mode;
  393. rc = 0;
  394. out:
  395. up_write(&cxl_dpa_rwsem);
  396. return rc;
  397. }
  398. int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
  399. {
  400. struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
  401. resource_size_t free_ram_start, free_pmem_start;
  402. struct cxl_port *port = cxled_to_port(cxled);
  403. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  404. struct device *dev = &cxled->cxld.dev;
  405. resource_size_t start, avail, skip;
  406. struct resource *p, *last;
  407. int rc;
  408. down_write(&cxl_dpa_rwsem);
  409. if (cxled->cxld.region) {
  410. dev_dbg(dev, "decoder attached to %s\n",
  411. dev_name(&cxled->cxld.region->dev));
  412. rc = -EBUSY;
  413. goto out;
  414. }
  415. if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) {
  416. dev_dbg(dev, "decoder enabled\n");
  417. rc = -EBUSY;
  418. goto out;
  419. }
  420. for (p = cxlds->ram_res.child, last = NULL; p; p = p->sibling)
  421. last = p;
  422. if (last)
  423. free_ram_start = last->end + 1;
  424. else
  425. free_ram_start = cxlds->ram_res.start;
  426. for (p = cxlds->pmem_res.child, last = NULL; p; p = p->sibling)
  427. last = p;
  428. if (last)
  429. free_pmem_start = last->end + 1;
  430. else
  431. free_pmem_start = cxlds->pmem_res.start;
  432. if (cxled->mode == CXL_DECODER_RAM) {
  433. start = free_ram_start;
  434. avail = cxlds->ram_res.end - start + 1;
  435. skip = 0;
  436. } else if (cxled->mode == CXL_DECODER_PMEM) {
  437. resource_size_t skip_start, skip_end;
  438. start = free_pmem_start;
  439. avail = cxlds->pmem_res.end - start + 1;
  440. skip_start = free_ram_start;
  441. /*
  442. * If some pmem is already allocated, then that allocation
  443. * already handled the skip.
  444. */
  445. if (cxlds->pmem_res.child &&
  446. skip_start == cxlds->pmem_res.child->start)
  447. skip_end = skip_start - 1;
  448. else
  449. skip_end = start - 1;
  450. skip = skip_end - skip_start + 1;
  451. } else {
  452. dev_dbg(dev, "mode not set\n");
  453. rc = -EINVAL;
  454. goto out;
  455. }
  456. if (size > avail) {
  457. dev_dbg(dev, "%pa exceeds available %s capacity: %pa\n", &size,
  458. cxl_decoder_mode_name(cxled->mode), &avail);
  459. rc = -ENOSPC;
  460. goto out;
  461. }
  462. rc = __cxl_dpa_reserve(cxled, start, size, skip);
  463. out:
  464. up_write(&cxl_dpa_rwsem);
  465. if (rc)
  466. return rc;
  467. return devm_add_action_or_reset(&port->dev, cxl_dpa_release, cxled);
  468. }
  469. static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
  470. {
  471. u16 eig;
  472. u8 eiw;
  473. /*
  474. * Input validation ensures these warns never fire, but otherwise
  475. * suppress unititalized variable usage warnings.
  476. */
  477. if (WARN_ONCE(ways_to_eiw(cxld->interleave_ways, &eiw),
  478. "invalid interleave_ways: %d\n", cxld->interleave_ways))
  479. return;
  480. if (WARN_ONCE(granularity_to_eig(cxld->interleave_granularity, &eig),
  481. "invalid interleave_granularity: %d\n",
  482. cxld->interleave_granularity))
  483. return;
  484. u32p_replace_bits(ctrl, eig, CXL_HDM_DECODER0_CTRL_IG_MASK);
  485. u32p_replace_bits(ctrl, eiw, CXL_HDM_DECODER0_CTRL_IW_MASK);
  486. *ctrl |= CXL_HDM_DECODER0_CTRL_COMMIT;
  487. }
  488. static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl)
  489. {
  490. u32p_replace_bits(ctrl,
  491. !!(cxld->target_type == CXL_DECODER_HOSTONLYMEM),
  492. CXL_HDM_DECODER0_CTRL_HOSTONLY);
  493. }
  494. static void cxlsd_set_targets(struct cxl_switch_decoder *cxlsd, u64 *tgt)
  495. {
  496. struct cxl_dport **t = &cxlsd->target[0];
  497. int ways = cxlsd->cxld.interleave_ways;
  498. *tgt = FIELD_PREP(GENMASK(7, 0), t[0]->port_id);
  499. if (ways > 1)
  500. *tgt |= FIELD_PREP(GENMASK(15, 8), t[1]->port_id);
  501. if (ways > 2)
  502. *tgt |= FIELD_PREP(GENMASK(23, 16), t[2]->port_id);
  503. if (ways > 3)
  504. *tgt |= FIELD_PREP(GENMASK(31, 24), t[3]->port_id);
  505. if (ways > 4)
  506. *tgt |= FIELD_PREP(GENMASK_ULL(39, 32), t[4]->port_id);
  507. if (ways > 5)
  508. *tgt |= FIELD_PREP(GENMASK_ULL(47, 40), t[5]->port_id);
  509. if (ways > 6)
  510. *tgt |= FIELD_PREP(GENMASK_ULL(55, 48), t[6]->port_id);
  511. if (ways > 7)
  512. *tgt |= FIELD_PREP(GENMASK_ULL(63, 56), t[7]->port_id);
  513. }
  514. /*
  515. * Per CXL 2.0 8.2.5.12.20 Committing Decoder Programming, hardware must set
  516. * committed or error within 10ms, but just be generous with 20ms to account for
  517. * clock skew and other marginal behavior
  518. */
  519. #define COMMIT_TIMEOUT_MS 20
  520. static int cxld_await_commit(void __iomem *hdm, int id)
  521. {
  522. u32 ctrl;
  523. int i;
  524. for (i = 0; i < COMMIT_TIMEOUT_MS; i++) {
  525. ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
  526. if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMIT_ERROR, ctrl)) {
  527. ctrl &= ~CXL_HDM_DECODER0_CTRL_COMMIT;
  528. writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
  529. return -EIO;
  530. }
  531. if (FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl))
  532. return 0;
  533. fsleep(1000);
  534. }
  535. return -ETIMEDOUT;
  536. }
  537. static int cxl_decoder_commit(struct cxl_decoder *cxld)
  538. {
  539. struct cxl_port *port = to_cxl_port(cxld->dev.parent);
  540. struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
  541. void __iomem *hdm = cxlhdm->regs.hdm_decoder;
  542. int id = cxld->id, rc;
  543. u64 base, size;
  544. u32 ctrl;
  545. if (cxld->flags & CXL_DECODER_F_ENABLE)
  546. return 0;
  547. if (cxl_num_decoders_committed(port) != id) {
  548. dev_dbg(&port->dev,
  549. "%s: out of order commit, expected decoder%d.%d\n",
  550. dev_name(&cxld->dev), port->id,
  551. cxl_num_decoders_committed(port));
  552. return -EBUSY;
  553. }
  554. /*
  555. * For endpoint decoders hosted on CXL memory devices that
  556. * support the sanitize operation, make sure sanitize is not in-flight.
  557. */
  558. if (is_endpoint_decoder(&cxld->dev)) {
  559. struct cxl_endpoint_decoder *cxled =
  560. to_cxl_endpoint_decoder(&cxld->dev);
  561. struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
  562. struct cxl_memdev_state *mds =
  563. to_cxl_memdev_state(cxlmd->cxlds);
  564. if (mds && mds->security.sanitize_active) {
  565. dev_dbg(&cxlmd->dev,
  566. "attempted to commit %s during sanitize\n",
  567. dev_name(&cxld->dev));
  568. return -EBUSY;
  569. }
  570. }
  571. down_read(&cxl_dpa_rwsem);
  572. /* common decoder settings */
  573. ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id));
  574. cxld_set_interleave(cxld, &ctrl);
  575. cxld_set_type(cxld, &ctrl);
  576. base = cxld->hpa_range.start;
  577. size = range_len(&cxld->hpa_range);
  578. writel(upper_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(id));
  579. writel(lower_32_bits(base), hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id));
  580. writel(upper_32_bits(size), hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(id));
  581. writel(lower_32_bits(size), hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(id));
  582. if (is_switch_decoder(&cxld->dev)) {
  583. struct cxl_switch_decoder *cxlsd =
  584. to_cxl_switch_decoder(&cxld->dev);
  585. void __iomem *tl_hi = hdm + CXL_HDM_DECODER0_TL_HIGH(id);
  586. void __iomem *tl_lo = hdm + CXL_HDM_DECODER0_TL_LOW(id);
  587. u64 targets;
  588. cxlsd_set_targets(cxlsd, &targets);
  589. writel(upper_32_bits(targets), tl_hi);
  590. writel(lower_32_bits(targets), tl_lo);
  591. } else {
  592. struct cxl_endpoint_decoder *cxled =
  593. to_cxl_endpoint_decoder(&cxld->dev);
  594. void __iomem *sk_hi = hdm + CXL_HDM_DECODER0_SKIP_HIGH(id);
  595. void __iomem *sk_lo = hdm + CXL_HDM_DECODER0_SKIP_LOW(id);
  596. writel(upper_32_bits(cxled->skip), sk_hi);
  597. writel(lower_32_bits(cxled->skip), sk_lo);
  598. }
  599. writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
  600. up_read(&cxl_dpa_rwsem);
  601. port->commit_end++;
  602. rc = cxld_await_commit(hdm, cxld->id);
  603. if (rc) {
  604. dev_dbg(&port->dev, "%s: error %d committing decoder\n",
  605. dev_name(&cxld->dev), rc);
  606. cxld->reset(cxld);
  607. return rc;
  608. }
  609. cxld->flags |= CXL_DECODER_F_ENABLE;
  610. return 0;
  611. }
  612. static int commit_reap(struct device *dev, const void *data)
  613. {
  614. struct cxl_port *port = to_cxl_port(dev->parent);
  615. struct cxl_decoder *cxld;
  616. if (!is_switch_decoder(dev) && !is_endpoint_decoder(dev))
  617. return 0;
  618. cxld = to_cxl_decoder(dev);
  619. if (port->commit_end == cxld->id &&
  620. ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
  621. port->commit_end--;
  622. dev_dbg(&port->dev, "reap: %s commit_end: %d\n",
  623. dev_name(&cxld->dev), port->commit_end);
  624. }
  625. return 0;
  626. }
  627. void cxl_port_commit_reap(struct cxl_decoder *cxld)
  628. {
  629. struct cxl_port *port = to_cxl_port(cxld->dev.parent);
  630. lockdep_assert_held_write(&cxl_region_rwsem);
  631. /*
  632. * Once the highest committed decoder is disabled, free any other
  633. * decoders that were pinned allocated by out-of-order release.
  634. */
  635. port->commit_end--;
  636. dev_dbg(&port->dev, "reap: %s commit_end: %d\n", dev_name(&cxld->dev),
  637. port->commit_end);
  638. device_for_each_child_reverse_from(&port->dev, &cxld->dev, NULL,
  639. commit_reap);
  640. }
  641. EXPORT_SYMBOL_NS_GPL(cxl_port_commit_reap, CXL);
  642. static void cxl_decoder_reset(struct cxl_decoder *cxld)
  643. {
  644. struct cxl_port *port = to_cxl_port(cxld->dev.parent);
  645. struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
  646. void __iomem *hdm = cxlhdm->regs.hdm_decoder;
  647. int id = cxld->id;
  648. u32 ctrl;
  649. if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
  650. return;
  651. if (port->commit_end == id)
  652. cxl_port_commit_reap(cxld);
  653. else
  654. dev_dbg(&port->dev,
  655. "%s: out of order reset, expected decoder%d.%d\n",
  656. dev_name(&cxld->dev), port->id, port->commit_end);
  657. down_read(&cxl_dpa_rwsem);
  658. ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
  659. ctrl &= ~CXL_HDM_DECODER0_CTRL_COMMIT;
  660. writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
  661. writel(0, hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(id));
  662. writel(0, hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(id));
  663. writel(0, hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(id));
  664. writel(0, hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id));
  665. up_read(&cxl_dpa_rwsem);
  666. cxld->flags &= ~CXL_DECODER_F_ENABLE;
  667. /* Userspace is now responsible for reconfiguring this decoder */
  668. if (is_endpoint_decoder(&cxld->dev)) {
  669. struct cxl_endpoint_decoder *cxled;
  670. cxled = to_cxl_endpoint_decoder(&cxld->dev);
  671. cxled->state = CXL_DECODER_STATE_MANUAL;
  672. }
  673. }
  674. static int cxl_setup_hdm_decoder_from_dvsec(
  675. struct cxl_port *port, struct cxl_decoder *cxld, u64 *dpa_base,
  676. int which, struct cxl_endpoint_dvsec_info *info)
  677. {
  678. struct cxl_endpoint_decoder *cxled;
  679. u64 len;
  680. int rc;
  681. if (!is_cxl_endpoint(port))
  682. return -EOPNOTSUPP;
  683. cxled = to_cxl_endpoint_decoder(&cxld->dev);
  684. len = range_len(&info->dvsec_range[which]);
  685. if (!len)
  686. return -ENOENT;
  687. cxld->target_type = CXL_DECODER_HOSTONLYMEM;
  688. cxld->commit = NULL;
  689. cxld->reset = NULL;
  690. cxld->hpa_range = info->dvsec_range[which];
  691. /*
  692. * Set the emulated decoder as locked pending additional support to
  693. * change the range registers at run time.
  694. */
  695. cxld->flags |= CXL_DECODER_F_ENABLE | CXL_DECODER_F_LOCK;
  696. port->commit_end = cxld->id;
  697. rc = devm_cxl_dpa_reserve(cxled, *dpa_base, len, 0);
  698. if (rc) {
  699. dev_err(&port->dev,
  700. "decoder%d.%d: Failed to reserve DPA range %#llx - %#llx\n (%d)",
  701. port->id, cxld->id, *dpa_base, *dpa_base + len - 1, rc);
  702. return rc;
  703. }
  704. *dpa_base += len;
  705. cxled->state = CXL_DECODER_STATE_AUTO;
  706. return 0;
  707. }
  708. static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
  709. int *target_map, void __iomem *hdm, int which,
  710. u64 *dpa_base, struct cxl_endpoint_dvsec_info *info)
  711. {
  712. struct cxl_endpoint_decoder *cxled = NULL;
  713. u64 size, base, skip, dpa_size, lo, hi;
  714. bool committed;
  715. u32 remainder;
  716. int i, rc;
  717. u32 ctrl;
  718. union {
  719. u64 value;
  720. unsigned char target_id[8];
  721. } target_list;
  722. if (should_emulate_decoders(info))
  723. return cxl_setup_hdm_decoder_from_dvsec(port, cxld, dpa_base,
  724. which, info);
  725. ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
  726. lo = readl(hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(which));
  727. hi = readl(hdm + CXL_HDM_DECODER0_BASE_HIGH_OFFSET(which));
  728. base = (hi << 32) + lo;
  729. lo = readl(hdm + CXL_HDM_DECODER0_SIZE_LOW_OFFSET(which));
  730. hi = readl(hdm + CXL_HDM_DECODER0_SIZE_HIGH_OFFSET(which));
  731. size = (hi << 32) + lo;
  732. committed = !!(ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED);
  733. cxld->commit = cxl_decoder_commit;
  734. cxld->reset = cxl_decoder_reset;
  735. if (!committed)
  736. size = 0;
  737. if (base == U64_MAX || size == U64_MAX) {
  738. dev_warn(&port->dev, "decoder%d.%d: Invalid resource range\n",
  739. port->id, cxld->id);
  740. return -ENXIO;
  741. }
  742. if (info)
  743. cxled = to_cxl_endpoint_decoder(&cxld->dev);
  744. cxld->hpa_range = (struct range) {
  745. .start = base,
  746. .end = base + size - 1,
  747. };
  748. /* decoders are enabled if committed */
  749. if (committed) {
  750. cxld->flags |= CXL_DECODER_F_ENABLE;
  751. if (ctrl & CXL_HDM_DECODER0_CTRL_LOCK)
  752. cxld->flags |= CXL_DECODER_F_LOCK;
  753. if (FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl))
  754. cxld->target_type = CXL_DECODER_HOSTONLYMEM;
  755. else
  756. cxld->target_type = CXL_DECODER_DEVMEM;
  757. guard(rwsem_write)(&cxl_region_rwsem);
  758. if (cxld->id != cxl_num_decoders_committed(port)) {
  759. dev_warn(&port->dev,
  760. "decoder%d.%d: Committed out of order\n",
  761. port->id, cxld->id);
  762. return -ENXIO;
  763. }
  764. if (size == 0) {
  765. dev_warn(&port->dev,
  766. "decoder%d.%d: Committed with zero size\n",
  767. port->id, cxld->id);
  768. return -ENXIO;
  769. }
  770. port->commit_end = cxld->id;
  771. } else {
  772. if (cxled) {
  773. struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
  774. struct cxl_dev_state *cxlds = cxlmd->cxlds;
  775. /*
  776. * Default by devtype until a device arrives that needs
  777. * more precision.
  778. */
  779. if (cxlds->type == CXL_DEVTYPE_CLASSMEM)
  780. cxld->target_type = CXL_DECODER_HOSTONLYMEM;
  781. else
  782. cxld->target_type = CXL_DECODER_DEVMEM;
  783. } else {
  784. /* To be overridden by region type at commit time */
  785. cxld->target_type = CXL_DECODER_HOSTONLYMEM;
  786. }
  787. if (!FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl) &&
  788. cxld->target_type == CXL_DECODER_HOSTONLYMEM) {
  789. ctrl |= CXL_HDM_DECODER0_CTRL_HOSTONLY;
  790. writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
  791. }
  792. }
  793. rc = eiw_to_ways(FIELD_GET(CXL_HDM_DECODER0_CTRL_IW_MASK, ctrl),
  794. &cxld->interleave_ways);
  795. if (rc) {
  796. dev_warn(&port->dev,
  797. "decoder%d.%d: Invalid interleave ways (ctrl: %#x)\n",
  798. port->id, cxld->id, ctrl);
  799. return rc;
  800. }
  801. rc = eig_to_granularity(FIELD_GET(CXL_HDM_DECODER0_CTRL_IG_MASK, ctrl),
  802. &cxld->interleave_granularity);
  803. if (rc) {
  804. dev_warn(&port->dev,
  805. "decoder%d.%d: Invalid interleave granularity (ctrl: %#x)\n",
  806. port->id, cxld->id, ctrl);
  807. return rc;
  808. }
  809. dev_dbg(&port->dev, "decoder%d.%d: range: %#llx-%#llx iw: %d ig: %d\n",
  810. port->id, cxld->id, cxld->hpa_range.start, cxld->hpa_range.end,
  811. cxld->interleave_ways, cxld->interleave_granularity);
  812. if (!cxled) {
  813. lo = readl(hdm + CXL_HDM_DECODER0_TL_LOW(which));
  814. hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which));
  815. target_list.value = (hi << 32) + lo;
  816. for (i = 0; i < cxld->interleave_ways; i++)
  817. target_map[i] = target_list.target_id[i];
  818. return 0;
  819. }
  820. if (!committed)
  821. return 0;
  822. dpa_size = div_u64_rem(size, cxld->interleave_ways, &remainder);
  823. if (remainder) {
  824. dev_err(&port->dev,
  825. "decoder%d.%d: invalid committed configuration size: %#llx ways: %d\n",
  826. port->id, cxld->id, size, cxld->interleave_ways);
  827. return -ENXIO;
  828. }
  829. lo = readl(hdm + CXL_HDM_DECODER0_SKIP_LOW(which));
  830. hi = readl(hdm + CXL_HDM_DECODER0_SKIP_HIGH(which));
  831. skip = (hi << 32) + lo;
  832. rc = devm_cxl_dpa_reserve(cxled, *dpa_base + skip, dpa_size, skip);
  833. if (rc) {
  834. dev_err(&port->dev,
  835. "decoder%d.%d: Failed to reserve DPA range %#llx - %#llx\n (%d)",
  836. port->id, cxld->id, *dpa_base,
  837. *dpa_base + dpa_size + skip - 1, rc);
  838. return rc;
  839. }
  840. *dpa_base += dpa_size + skip;
  841. cxled->state = CXL_DECODER_STATE_AUTO;
  842. return 0;
  843. }
  844. static void cxl_settle_decoders(struct cxl_hdm *cxlhdm)
  845. {
  846. void __iomem *hdm = cxlhdm->regs.hdm_decoder;
  847. int committed, i;
  848. u32 ctrl;
  849. if (!hdm)
  850. return;
  851. /*
  852. * Since the register resource was recently claimed via request_region()
  853. * be careful about trusting the "not-committed" status until the commit
  854. * timeout has elapsed. The commit timeout is 10ms (CXL 2.0
  855. * 8.2.5.12.20), but double it to be tolerant of any clock skew between
  856. * host and target.
  857. */
  858. for (i = 0, committed = 0; i < cxlhdm->decoder_count; i++) {
  859. ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(i));
  860. if (ctrl & CXL_HDM_DECODER0_CTRL_COMMITTED)
  861. committed++;
  862. }
  863. /* ensure that future checks of committed can be trusted */
  864. if (committed != cxlhdm->decoder_count)
  865. msleep(20);
  866. }
  867. /**
  868. * devm_cxl_enumerate_decoders - add decoder objects per HDM register set
  869. * @cxlhdm: Structure to populate with HDM capabilities
  870. * @info: cached DVSEC range register info
  871. */
  872. int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
  873. struct cxl_endpoint_dvsec_info *info)
  874. {
  875. void __iomem *hdm = cxlhdm->regs.hdm_decoder;
  876. struct cxl_port *port = cxlhdm->port;
  877. int i;
  878. u64 dpa_base = 0;
  879. cxl_settle_decoders(cxlhdm);
  880. for (i = 0; i < cxlhdm->decoder_count; i++) {
  881. int target_map[CXL_DECODER_MAX_INTERLEAVE] = { 0 };
  882. int rc, target_count = cxlhdm->target_count;
  883. struct cxl_decoder *cxld;
  884. if (is_cxl_endpoint(port)) {
  885. struct cxl_endpoint_decoder *cxled;
  886. cxled = cxl_endpoint_decoder_alloc(port);
  887. if (IS_ERR(cxled)) {
  888. dev_warn(&port->dev,
  889. "Failed to allocate decoder%d.%d\n",
  890. port->id, i);
  891. return PTR_ERR(cxled);
  892. }
  893. cxld = &cxled->cxld;
  894. } else {
  895. struct cxl_switch_decoder *cxlsd;
  896. cxlsd = cxl_switch_decoder_alloc(port, target_count);
  897. if (IS_ERR(cxlsd)) {
  898. dev_warn(&port->dev,
  899. "Failed to allocate decoder%d.%d\n",
  900. port->id, i);
  901. return PTR_ERR(cxlsd);
  902. }
  903. cxld = &cxlsd->cxld;
  904. }
  905. rc = init_hdm_decoder(port, cxld, target_map, hdm, i,
  906. &dpa_base, info);
  907. if (rc) {
  908. dev_warn(&port->dev,
  909. "Failed to initialize decoder%d.%d\n",
  910. port->id, i);
  911. put_device(&cxld->dev);
  912. return rc;
  913. }
  914. rc = add_hdm_decoder(port, cxld, target_map);
  915. if (rc) {
  916. dev_warn(&port->dev,
  917. "Failed to add decoder%d.%d\n", port->id, i);
  918. return rc;
  919. }
  920. }
  921. return 0;
  922. }
  923. EXPORT_SYMBOL_NS_GPL(devm_cxl_enumerate_decoders, CXL);