of.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright 2015 IBM Corp.
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/module.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/slab.h>
  9. #include <linux/of.h>
  10. #include <linux/of_address.h>
  11. #include <linux/of_platform.h>
  12. #include "cxl.h"
  13. static int read_phys_addr(struct device_node *np, char *prop_name,
  14. struct cxl_afu *afu)
  15. {
  16. int i, len, entry_size, naddr, nsize, type;
  17. u64 addr, size;
  18. const __be32 *prop;
  19. naddr = of_n_addr_cells(np);
  20. nsize = of_n_size_cells(np);
  21. prop = of_get_property(np, prop_name, &len);
  22. if (prop) {
  23. entry_size = naddr + nsize;
  24. for (i = 0; i < (len / 4); i += entry_size, prop += entry_size) {
  25. type = be32_to_cpu(prop[0]);
  26. addr = of_read_number(prop, naddr);
  27. size = of_read_number(&prop[naddr], nsize);
  28. switch (type) {
  29. case 0: /* unit address */
  30. afu->guest->handle = addr;
  31. break;
  32. case 1: /* p2 area */
  33. afu->guest->p2n_phys += addr;
  34. afu->guest->p2n_size = size;
  35. break;
  36. case 2: /* problem state area */
  37. afu->psn_phys += addr;
  38. afu->adapter->ps_size = size;
  39. break;
  40. default:
  41. pr_err("Invalid address type %d found in %s property of AFU\n",
  42. type, prop_name);
  43. return -EINVAL;
  44. }
  45. }
  46. }
  47. return 0;
  48. }
  49. static int read_vpd(struct cxl *adapter, struct cxl_afu *afu)
  50. {
  51. char vpd[256];
  52. int rc;
  53. size_t len = sizeof(vpd);
  54. memset(vpd, 0, len);
  55. if (adapter)
  56. rc = cxl_guest_read_adapter_vpd(adapter, vpd, len);
  57. else
  58. rc = cxl_guest_read_afu_vpd(afu, vpd, len);
  59. if (rc > 0) {
  60. cxl_dump_debug_buffer(vpd, rc);
  61. rc = 0;
  62. }
  63. return rc;
  64. }
  65. int cxl_of_read_afu_handle(struct cxl_afu *afu, struct device_node *afu_np)
  66. {
  67. return of_property_read_reg(afu_np, 0, &afu->guest->handle, NULL);
  68. }
  69. int cxl_of_read_afu_properties(struct cxl_afu *afu, struct device_node *np)
  70. {
  71. int i, rc;
  72. u16 device_id, vendor_id;
  73. u32 val = 0, class_code;
  74. /* Properties are read in the same order as listed in PAPR */
  75. rc = read_phys_addr(np, "reg", afu);
  76. if (rc)
  77. return rc;
  78. rc = read_phys_addr(np, "assigned-addresses", afu);
  79. if (rc)
  80. return rc;
  81. if (afu->psn_phys == 0)
  82. afu->psa = false;
  83. else
  84. afu->psa = true;
  85. of_property_read_u32(np, "ibm,#processes", &afu->max_procs_virtualised);
  86. if (cxl_verbose)
  87. read_vpd(NULL, afu);
  88. of_property_read_u32(np, "ibm,max-ints-per-process", &afu->guest->max_ints);
  89. afu->irqs_max = afu->guest->max_ints;
  90. if (!of_property_read_u32(np, "ibm,min-ints-per-process", &afu->pp_irqs)) {
  91. /* One extra interrupt for the PSL interrupt is already
  92. * included. Remove it now to keep only AFU interrupts and
  93. * match the native case.
  94. */
  95. afu->pp_irqs--;
  96. }
  97. of_property_read_u64(np, "ibm,error-buffer-size", &afu->eb_len);
  98. afu->eb_offset = 0;
  99. of_property_read_u64(np, "ibm,config-record-size", &afu->crs_len);
  100. afu->crs_offset = 0;
  101. of_property_read_u32(np, "ibm,#config-records", &afu->crs_num);
  102. if (cxl_verbose) {
  103. for (i = 0; i < afu->crs_num; i++) {
  104. rc = cxl_ops->afu_cr_read16(afu, i, PCI_DEVICE_ID,
  105. &device_id);
  106. if (!rc)
  107. pr_info("record %d - device-id: %#x\n",
  108. i, device_id);
  109. rc = cxl_ops->afu_cr_read16(afu, i, PCI_VENDOR_ID,
  110. &vendor_id);
  111. if (!rc)
  112. pr_info("record %d - vendor-id: %#x\n",
  113. i, vendor_id);
  114. rc = cxl_ops->afu_cr_read32(afu, i, PCI_CLASS_REVISION,
  115. &class_code);
  116. if (!rc) {
  117. class_code >>= 8;
  118. pr_info("record %d - class-code: %#x\n",
  119. i, class_code);
  120. }
  121. }
  122. }
  123. /*
  124. * if "ibm,process-mmio" doesn't exist then per-process mmio is
  125. * not supported
  126. */
  127. val = 0;
  128. if (!of_property_read_u32(np, "ibm,process-mmio", &val) && val == 1)
  129. afu->pp_psa = true;
  130. else
  131. afu->pp_psa = false;
  132. if (!of_property_read_u32(np, "ibm,function-error-interrupt", &val))
  133. afu->serr_hwirq = val;
  134. pr_devel("AFU handle: %#llx\n", afu->guest->handle);
  135. pr_devel("p2n_phys: %#llx (size %#llx)\n",
  136. afu->guest->p2n_phys, afu->guest->p2n_size);
  137. pr_devel("psn_phys: %#llx (size %#llx)\n",
  138. afu->psn_phys, afu->adapter->ps_size);
  139. pr_devel("Max number of processes virtualised=%i\n",
  140. afu->max_procs_virtualised);
  141. pr_devel("Per-process irqs min=%i, max=%i\n", afu->pp_irqs,
  142. afu->irqs_max);
  143. pr_devel("Slice error interrupt=%#lx\n", afu->serr_hwirq);
  144. return 0;
  145. }
  146. static int read_adapter_irq_config(struct cxl *adapter, struct device_node *np)
  147. {
  148. const __be32 *ranges;
  149. int len, nranges, i;
  150. struct irq_avail *cur;
  151. ranges = of_get_property(np, "interrupt-ranges", &len);
  152. if (ranges == NULL || len < (2 * sizeof(int)))
  153. return -EINVAL;
  154. /*
  155. * encoded array of two cells per entry, each cell encoded as
  156. * with encode-int
  157. */
  158. nranges = len / (2 * sizeof(int));
  159. if (nranges == 0 || (nranges * 2 * sizeof(int)) != len)
  160. return -EINVAL;
  161. adapter->guest->irq_avail = kcalloc(nranges, sizeof(struct irq_avail),
  162. GFP_KERNEL);
  163. if (adapter->guest->irq_avail == NULL)
  164. return -ENOMEM;
  165. adapter->guest->irq_base_offset = be32_to_cpu(ranges[0]);
  166. for (i = 0; i < nranges; i++) {
  167. cur = &adapter->guest->irq_avail[i];
  168. cur->offset = be32_to_cpu(ranges[i * 2]);
  169. cur->range = be32_to_cpu(ranges[i * 2 + 1]);
  170. cur->bitmap = bitmap_zalloc(cur->range, GFP_KERNEL);
  171. if (cur->bitmap == NULL)
  172. goto err;
  173. if (cur->offset < adapter->guest->irq_base_offset)
  174. adapter->guest->irq_base_offset = cur->offset;
  175. if (cxl_verbose)
  176. pr_info("available IRQ range: %#lx-%#lx (%lu)\n",
  177. cur->offset, cur->offset + cur->range - 1,
  178. cur->range);
  179. }
  180. adapter->guest->irq_nranges = nranges;
  181. spin_lock_init(&adapter->guest->irq_alloc_lock);
  182. return 0;
  183. err:
  184. for (i--; i >= 0; i--) {
  185. cur = &adapter->guest->irq_avail[i];
  186. bitmap_free(cur->bitmap);
  187. }
  188. kfree(adapter->guest->irq_avail);
  189. adapter->guest->irq_avail = NULL;
  190. return -ENOMEM;
  191. }
  192. int cxl_of_read_adapter_handle(struct cxl *adapter, struct device_node *np)
  193. {
  194. return of_property_read_reg(np, 0, &adapter->guest->handle, NULL);
  195. }
  196. int cxl_of_read_adapter_properties(struct cxl *adapter, struct device_node *np)
  197. {
  198. int rc;
  199. const char *p;
  200. u32 val = 0;
  201. /* Properties are read in the same order as listed in PAPR */
  202. if ((rc = read_adapter_irq_config(adapter, np)))
  203. return rc;
  204. if (!of_property_read_u32(np, "ibm,caia-version", &val)) {
  205. adapter->caia_major = (val & 0xFF00) >> 8;
  206. adapter->caia_minor = val & 0xFF;
  207. }
  208. if (!of_property_read_u32(np, "ibm,psl-revision", &val))
  209. adapter->psl_rev = val;
  210. if (!of_property_read_string(np, "status", &p)) {
  211. adapter->guest->status = kasprintf(GFP_KERNEL, "%s", p);
  212. if (adapter->guest->status == NULL)
  213. return -ENOMEM;
  214. }
  215. if (!of_property_read_u32(np, "vendor-id", &val))
  216. adapter->guest->vendor = val;
  217. if (!of_property_read_u32(np, "device-id", &val))
  218. adapter->guest->device = val;
  219. if (!of_property_read_u32(np, "subsystem-vendor-id", &val))
  220. adapter->guest->subsystem_vendor = val;
  221. if (!of_property_read_u32(np, "subsystem-id", &val))
  222. adapter->guest->subsystem = val;
  223. if (cxl_verbose)
  224. read_vpd(adapter, NULL);
  225. return 0;
  226. }
  227. static void cxl_of_remove(struct platform_device *pdev)
  228. {
  229. struct cxl *adapter;
  230. int afu;
  231. adapter = dev_get_drvdata(&pdev->dev);
  232. for (afu = 0; afu < adapter->slices; afu++)
  233. cxl_guest_remove_afu(adapter->afu[afu]);
  234. cxl_guest_remove_adapter(adapter);
  235. }
  236. static void cxl_of_shutdown(struct platform_device *pdev)
  237. {
  238. cxl_of_remove(pdev);
  239. }
  240. int cxl_of_probe(struct platform_device *pdev)
  241. {
  242. struct device_node *np = NULL;
  243. struct device_node *afu_np = NULL;
  244. struct cxl *adapter = NULL;
  245. int ret;
  246. int slice = 0, slice_ok = 0;
  247. pr_devel("in %s\n", __func__);
  248. np = pdev->dev.of_node;
  249. if (np == NULL)
  250. return -ENODEV;
  251. /* init adapter */
  252. adapter = cxl_guest_init_adapter(np, pdev);
  253. if (IS_ERR(adapter)) {
  254. dev_err(&pdev->dev, "guest_init_adapter failed: %li\n", PTR_ERR(adapter));
  255. return PTR_ERR(adapter);
  256. }
  257. /* init afu */
  258. for_each_child_of_node(np, afu_np) {
  259. if ((ret = cxl_guest_init_afu(adapter, slice, afu_np)))
  260. dev_err(&pdev->dev, "AFU %i failed to initialise: %i\n",
  261. slice, ret);
  262. else
  263. slice_ok++;
  264. slice++;
  265. }
  266. if (slice_ok == 0) {
  267. dev_info(&pdev->dev, "No active AFU");
  268. adapter->slices = 0;
  269. }
  270. return 0;
  271. }
  272. static const struct of_device_id cxl_of_match[] = {
  273. { .compatible = "ibm,coherent-platform-facility",},
  274. {},
  275. };
  276. MODULE_DEVICE_TABLE(of, cxl_of_match);
  277. struct platform_driver cxl_of_driver = {
  278. .driver = {
  279. .name = "cxl_of",
  280. .of_match_table = cxl_of_match,
  281. .owner = THIS_MODULE
  282. },
  283. .probe = cxl_of_probe,
  284. .remove_new = cxl_of_remove,
  285. .shutdown = cxl_of_shutdown,
  286. };