1
2
3
4
5
6
7
8
9#include <linux/mmu_notifier.h>
10#include <linux/mmu_context.h>
11#include <linux/of.h>
12#include <linux/pci.h>
13#include <linux/memblock.h>
14#include <linux/sizes.h>
15
16#include <asm/debugfs.h>
17#include <asm/powernv.h>
18#include <asm/ppc-pci.h>
19#include <asm/opal.h>
20
21#include "pci.h"
22
23static struct pci_dev *get_pci_dev(struct device_node *dn)
24{
25 struct pci_dn *pdn = PCI_DN(dn);
26 struct pci_dev *pdev;
27
28 pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pdn->phb->bus),
29 pdn->busno, pdn->devfn);
30
31
32
33
34
35
36
37
38 if (pdev)
39 pci_dev_put(pdev);
40
41 return pdev;
42}
43
44
45struct pci_dev *pnv_pci_get_gpu_dev(struct pci_dev *npdev)
46{
47 struct device_node *dn;
48 struct pci_dev *gpdev;
49
50 if (WARN_ON(!npdev))
51 return NULL;
52
53 if (WARN_ON(!npdev->dev.of_node))
54 return NULL;
55
56
57 dn = of_parse_phandle(npdev->dev.of_node, "ibm,gpu", 0);
58 if (!dn)
59 return NULL;
60
61 gpdev = get_pci_dev(dn);
62 of_node_put(dn);
63
64 return gpdev;
65}
66EXPORT_SYMBOL(pnv_pci_get_gpu_dev);
67
68
69struct pci_dev *pnv_pci_get_npu_dev(struct pci_dev *gpdev, int index)
70{
71 struct device_node *dn;
72 struct pci_dev *npdev;
73
74 if (WARN_ON(!gpdev))
75 return NULL;
76
77
78 if (!gpdev->dev.of_node)
79 return NULL;
80
81
82 dn = of_parse_phandle(gpdev->dev.of_node, "ibm,npu", index);
83 if (!dn)
84 return NULL;
85
86 npdev = get_pci_dev(dn);
87 of_node_put(dn);
88
89 return npdev;
90}
91EXPORT_SYMBOL(pnv_pci_get_npu_dev);
92
93#ifdef CONFIG_IOMMU_API
94
95
96
97
98static struct pnv_ioda_pe *get_gpu_pci_dev_and_pe(struct pnv_ioda_pe *npe,
99 struct pci_dev **gpdev)
100{
101 struct pnv_phb *phb;
102 struct pci_controller *hose;
103 struct pci_dev *pdev;
104 struct pnv_ioda_pe *pe;
105 struct pci_dn *pdn;
106
107 pdev = pnv_pci_get_gpu_dev(npe->pdev);
108 if (!pdev)
109 return NULL;
110
111 pdn = pci_get_pdn(pdev);
112 if (WARN_ON(!pdn || pdn->pe_number == IODA_INVALID_PE))
113 return NULL;
114
115 hose = pci_bus_to_host(pdev->bus);
116 phb = hose->private_data;
117 pe = &phb->ioda.pe_array[pdn->pe_number];
118
119 if (gpdev)
120 *gpdev = pdev;
121
122 return pe;
123}
124
125static long pnv_npu_unset_window(struct iommu_table_group *table_group,
126 int num);
127
128static long pnv_npu_set_window(struct iommu_table_group *table_group, int num,
129 struct iommu_table *tbl)
130{
131 struct pnv_ioda_pe *npe = container_of(table_group, struct pnv_ioda_pe,
132 table_group);
133 struct pnv_phb *phb = npe->phb;
134 int64_t rc;
135 const unsigned long size = tbl->it_indirect_levels ?
136 tbl->it_level_size : tbl->it_size;
137 const __u64 start_addr = tbl->it_offset << tbl->it_page_shift;
138 const __u64 win_size = tbl->it_size << tbl->it_page_shift;
139 int num2 = (num == 0) ? 1 : 0;
140
141
142 if (npe->table_group.tables[num2])
143 pnv_npu_unset_window(&npe->table_group, num2);
144
145 pe_info(npe, "Setting up window %llx..%llx pg=%lx\n",
146 start_addr, start_addr + win_size - 1,
147 IOMMU_PAGE_SIZE(tbl));
148
149 rc = opal_pci_map_pe_dma_window(phb->opal_id,
150 npe->pe_number,
151 npe->pe_number,
152 tbl->it_indirect_levels + 1,
153 __pa(tbl->it_base),
154 size << 3,
155 IOMMU_PAGE_SIZE(tbl));
156 if (rc) {
157 pe_err(npe, "Failed to configure TCE table, err %lld\n", rc);
158 return rc;
159 }
160 pnv_pci_ioda2_tce_invalidate_entire(phb, false);
161
162
163 pnv_pci_link_table_and_group(phb->hose->node, num,
164 tbl, &npe->table_group);
165
166 return 0;
167}
168
169static long pnv_npu_unset_window(struct iommu_table_group *table_group, int num)
170{
171 struct pnv_ioda_pe *npe = container_of(table_group, struct pnv_ioda_pe,
172 table_group);
173 struct pnv_phb *phb = npe->phb;
174 int64_t rc;
175
176 if (!npe->table_group.tables[num])
177 return 0;
178
179 pe_info(npe, "Removing DMA window\n");
180
181 rc = opal_pci_map_pe_dma_window(phb->opal_id, npe->pe_number,
182 npe->pe_number,
183 0, 0,
184 0, 0);
185 if (rc) {
186 pe_err(npe, "Unmapping failed, ret = %lld\n", rc);
187 return rc;
188 }
189 pnv_pci_ioda2_tce_invalidate_entire(phb, false);
190
191 pnv_pci_unlink_table_and_group(npe->table_group.tables[num],
192 &npe->table_group);
193
194 return 0;
195}
196
197
198static void pnv_npu_take_ownership(struct iommu_table_group *table_group)
199{
200 struct pnv_ioda_pe *npe = container_of(table_group, struct pnv_ioda_pe,
201 table_group);
202 struct pnv_phb *phb = npe->phb;
203 int64_t rc;
204 struct pci_dev *gpdev = NULL;
205
206
207
208
209
210
211
212 if (npe->table_group.tables[0]) {
213 pnv_npu_unset_window(&npe->table_group, 0);
214 return;
215 }
216
217
218 rc = opal_pci_map_pe_dma_window_real(phb->opal_id,
219 npe->pe_number, npe->pe_number,
220 0 , 0);
221 if (rc) {
222 pe_err(npe, "Failed to disable bypass, err %lld\n", rc);
223 return;
224 }
225 pnv_pci_ioda2_tce_invalidate_entire(npe->phb, false);
226
227 get_gpu_pci_dev_and_pe(npe, &gpdev);
228 if (gpdev)
229 pnv_npu2_unmap_lpar_dev(gpdev);
230}
231
232static void pnv_npu_release_ownership(struct iommu_table_group *table_group)
233{
234 struct pnv_ioda_pe *npe = container_of(table_group, struct pnv_ioda_pe,
235 table_group);
236 struct pci_dev *gpdev = NULL;
237
238 get_gpu_pci_dev_and_pe(npe, &gpdev);
239 if (gpdev)
240 pnv_npu2_map_lpar_dev(gpdev, 0, MSR_DR | MSR_PR | MSR_HV);
241}
242
243static struct iommu_table_group_ops pnv_pci_npu_ops = {
244 .set_window = pnv_npu_set_window,
245 .unset_window = pnv_npu_unset_window,
246 .take_ownership = pnv_npu_take_ownership,
247 .release_ownership = pnv_npu_release_ownership,
248};
249#endif
250
251
252
253
254
255#define NV_NMMU_ATSD_REGS 8
256#define NV_NPU_MAX_PE_NUM 16
257
258
259
260
261
262struct npu_comp {
263 struct iommu_table_group table_group;
264 int pe_num;
265 struct pnv_ioda_pe *pe[NV_NPU_MAX_PE_NUM];
266};
267
268
269struct npu {
270 int index;
271 struct npu_comp npucomp;
272};
273
274#ifdef CONFIG_IOMMU_API
275static long pnv_npu_peers_create_table_userspace(
276 struct iommu_table_group *table_group,
277 int num, __u32 page_shift, __u64 window_size, __u32 levels,
278 struct iommu_table **ptbl)
279{
280 struct npu_comp *npucomp = container_of(table_group, struct npu_comp,
281 table_group);
282
283 if (!npucomp->pe_num || !npucomp->pe[0] ||
284 !npucomp->pe[0]->table_group.ops ||
285 !npucomp->pe[0]->table_group.ops->create_table)
286 return -EFAULT;
287
288 return npucomp->pe[0]->table_group.ops->create_table(
289 &npucomp->pe[0]->table_group, num, page_shift,
290 window_size, levels, ptbl);
291}
292
293static long pnv_npu_peers_set_window(struct iommu_table_group *table_group,
294 int num, struct iommu_table *tbl)
295{
296 int i, j;
297 long ret = 0;
298 struct npu_comp *npucomp = container_of(table_group, struct npu_comp,
299 table_group);
300
301 for (i = 0; i < npucomp->pe_num; ++i) {
302 struct pnv_ioda_pe *pe = npucomp->pe[i];
303
304 if (!pe->table_group.ops->set_window)
305 continue;
306
307 ret = pe->table_group.ops->set_window(&pe->table_group,
308 num, tbl);
309 if (ret)
310 break;
311 }
312
313 if (ret) {
314 for (j = 0; j < i; ++j) {
315 struct pnv_ioda_pe *pe = npucomp->pe[j];
316
317 if (!pe->table_group.ops->unset_window)
318 continue;
319
320 ret = pe->table_group.ops->unset_window(
321 &pe->table_group, num);
322 if (ret)
323 break;
324 }
325 } else {
326 table_group->tables[num] = iommu_tce_table_get(tbl);
327 }
328
329 return ret;
330}
331
332static long pnv_npu_peers_unset_window(struct iommu_table_group *table_group,
333 int num)
334{
335 int i, j;
336 long ret = 0;
337 struct npu_comp *npucomp = container_of(table_group, struct npu_comp,
338 table_group);
339
340 for (i = 0; i < npucomp->pe_num; ++i) {
341 struct pnv_ioda_pe *pe = npucomp->pe[i];
342
343 WARN_ON(npucomp->table_group.tables[num] !=
344 table_group->tables[num]);
345 if (!npucomp->table_group.tables[num])
346 continue;
347
348 if (!pe->table_group.ops->unset_window)
349 continue;
350
351 ret = pe->table_group.ops->unset_window(&pe->table_group, num);
352 if (ret)
353 break;
354 }
355
356 if (ret) {
357 for (j = 0; j < i; ++j) {
358 struct pnv_ioda_pe *pe = npucomp->pe[j];
359
360 if (!npucomp->table_group.tables[num])
361 continue;
362
363 if (!pe->table_group.ops->set_window)
364 continue;
365
366 ret = pe->table_group.ops->set_window(&pe->table_group,
367 num, table_group->tables[num]);
368 if (ret)
369 break;
370 }
371 } else if (table_group->tables[num]) {
372 iommu_tce_table_put(table_group->tables[num]);
373 table_group->tables[num] = NULL;
374 }
375
376 return ret;
377}
378
379static void pnv_npu_peers_take_ownership(struct iommu_table_group *table_group)
380{
381 int i;
382 struct npu_comp *npucomp = container_of(table_group, struct npu_comp,
383 table_group);
384
385 for (i = 0; i < npucomp->pe_num; ++i) {
386 struct pnv_ioda_pe *pe = npucomp->pe[i];
387
388 if (!pe->table_group.ops->take_ownership)
389 continue;
390 pe->table_group.ops->take_ownership(&pe->table_group);
391 }
392}
393
394static void pnv_npu_peers_release_ownership(
395 struct iommu_table_group *table_group)
396{
397 int i;
398 struct npu_comp *npucomp = container_of(table_group, struct npu_comp,
399 table_group);
400
401 for (i = 0; i < npucomp->pe_num; ++i) {
402 struct pnv_ioda_pe *pe = npucomp->pe[i];
403
404 if (!pe->table_group.ops->release_ownership)
405 continue;
406 pe->table_group.ops->release_ownership(&pe->table_group);
407 }
408}
409
410static struct iommu_table_group_ops pnv_npu_peers_ops = {
411 .get_table_size = pnv_pci_ioda2_get_table_size,
412 .create_table = pnv_npu_peers_create_table_userspace,
413 .set_window = pnv_npu_peers_set_window,
414 .unset_window = pnv_npu_peers_unset_window,
415 .take_ownership = pnv_npu_peers_take_ownership,
416 .release_ownership = pnv_npu_peers_release_ownership,
417};
418
419static void pnv_comp_attach_table_group(struct npu_comp *npucomp,
420 struct pnv_ioda_pe *pe)
421{
422 if (WARN_ON(npucomp->pe_num == NV_NPU_MAX_PE_NUM))
423 return;
424
425 npucomp->pe[npucomp->pe_num] = pe;
426 ++npucomp->pe_num;
427}
428
429static struct iommu_table_group *
430 pnv_try_setup_npu_table_group(struct pnv_ioda_pe *pe)
431{
432 struct iommu_table_group *compound_group;
433 struct npu_comp *npucomp;
434 struct pci_dev *gpdev = NULL;
435 struct pci_controller *hose;
436 struct pci_dev *npdev = NULL;
437
438 list_for_each_entry(gpdev, &pe->pbus->devices, bus_list) {
439 npdev = pnv_pci_get_npu_dev(gpdev, 0);
440 if (npdev)
441 break;
442 }
443
444 if (!npdev)
445
446 return NULL;
447
448 hose = pci_bus_to_host(npdev->bus);
449
450 if (hose->npu) {
451
452 npucomp = &hose->npu->npucomp;
453 } else {
454
455 npucomp = pe->npucomp = kzalloc(sizeof(*npucomp), GFP_KERNEL);
456 }
457
458 compound_group = &npucomp->table_group;
459 if (!compound_group->group) {
460 compound_group->ops = &pnv_npu_peers_ops;
461 iommu_register_group(compound_group, hose->global_number,
462 pe->pe_number);
463
464
465 compound_group->max_dynamic_windows_supported =
466 pe->table_group.max_dynamic_windows_supported;
467 compound_group->tce32_start = pe->table_group.tce32_start;
468 compound_group->tce32_size = pe->table_group.tce32_size;
469 compound_group->max_levels = pe->table_group.max_levels;
470 if (!compound_group->pgsizes)
471 compound_group->pgsizes = pe->table_group.pgsizes;
472 }
473
474
475
476
477
478 iommu_del_device(&gpdev->dev);
479
480
481
482
483
484
485
486
487 iommu_group_put(pe->table_group.group);
488
489
490 pnv_comp_attach_table_group(npucomp, pe);
491 iommu_add_device(compound_group, &gpdev->dev);
492
493 return compound_group;
494}
495
496static struct iommu_table_group *pnv_npu_compound_attach(struct pnv_ioda_pe *pe)
497{
498 struct iommu_table_group *table_group;
499 struct npu_comp *npucomp;
500 struct pci_dev *gpdev = NULL;
501 struct pci_dev *npdev;
502 struct pnv_ioda_pe *gpe = get_gpu_pci_dev_and_pe(pe, &gpdev);
503
504 WARN_ON(!(pe->flags & PNV_IODA_PE_DEV));
505 if (!gpe)
506 return NULL;
507
508
509
510
511
512
513
514 pe->table_group.ops = &pnv_pci_npu_ops;
515
516 table_group = iommu_group_get_iommudata(
517 iommu_group_get(&gpdev->dev));
518
519
520
521
522
523
524 table_group->pgsizes &= pe->table_group.pgsizes;
525 npucomp = container_of(table_group, struct npu_comp, table_group);
526 pnv_comp_attach_table_group(npucomp, pe);
527
528 list_for_each_entry(npdev, &pe->phb->hose->bus->devices, bus_list) {
529 struct pci_dev *gpdevtmp = pnv_pci_get_gpu_dev(npdev);
530
531 if (gpdevtmp != gpdev)
532 continue;
533
534 iommu_add_device(table_group, &npdev->dev);
535 }
536
537 return table_group;
538}
539
540void pnv_pci_npu_setup_iommu_groups(void)
541{
542 struct pci_controller *hose;
543 struct pnv_phb *phb;
544 struct pnv_ioda_pe *pe;
545
546
547
548
549
550
551
552
553
554
555 list_for_each_entry(hose, &hose_list, list_node) {
556 phb = hose->private_data;
557
558 if (phb->type == PNV_PHB_IODA2)
559 list_for_each_entry(pe, &phb->ioda.pe_list, list)
560 pnv_try_setup_npu_table_group(pe);
561 }
562
563
564
565
566
567 list_for_each_entry(hose, &hose_list, list_node) {
568 unsigned long pgsizes;
569
570 phb = hose->private_data;
571
572 if (phb->type != PNV_PHB_NPU_NVLINK)
573 continue;
574
575 pgsizes = pnv_ioda_parse_tce_sizes(phb);
576 list_for_each_entry(pe, &phb->ioda.pe_list, list) {
577
578
579
580
581
582 pe->table_group.pgsizes = pgsizes;
583 pnv_npu_compound_attach(pe);
584 }
585 }
586}
587#endif
588
589int pnv_npu2_init(struct pci_controller *hose)
590{
591 static int npu_index;
592 struct npu *npu;
593 int ret;
594
595 npu = kzalloc(sizeof(*npu), GFP_KERNEL);
596 if (!npu)
597 return -ENOMEM;
598
599 npu_index++;
600 if (WARN_ON(npu_index >= NV_MAX_NPUS)) {
601 ret = -ENOSPC;
602 goto fail_exit;
603 }
604 npu->index = npu_index;
605 hose->npu = npu;
606
607 return 0;
608
609fail_exit:
610 kfree(npu);
611 return ret;
612}
613
614int pnv_npu2_map_lpar_dev(struct pci_dev *gpdev, unsigned int lparid,
615 unsigned long msr)
616{
617 int ret;
618 struct pci_dev *npdev = pnv_pci_get_npu_dev(gpdev, 0);
619 struct pci_controller *hose;
620 struct pnv_phb *nphb;
621
622 if (!npdev)
623 return -ENODEV;
624
625 hose = pci_bus_to_host(npdev->bus);
626 nphb = hose->private_data;
627
628 dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=%u\n",
629 nphb->opal_id, lparid);
630
631
632
633
634 ret = opal_npu_map_lpar(nphb->opal_id, pci_dev_id(gpdev), lparid,
635 0 );
636 if (ret) {
637 dev_err(&gpdev->dev, "Error %d mapping device to LPAR\n", ret);
638 return ret;
639 }
640
641 dev_dbg(&gpdev->dev, "init context opalid=%llu msr=%lx\n",
642 nphb->opal_id, msr);
643 ret = opal_npu_init_context(nphb->opal_id, 0, msr,
644 pci_dev_id(gpdev));
645 if (ret < 0)
646 dev_err(&gpdev->dev, "Failed to init context: %d\n", ret);
647 else
648 ret = 0;
649
650 return 0;
651}
652EXPORT_SYMBOL_GPL(pnv_npu2_map_lpar_dev);
653
654void pnv_npu2_map_lpar(struct pnv_ioda_pe *gpe, unsigned long msr)
655{
656 struct pci_dev *gpdev;
657
658 list_for_each_entry(gpdev, &gpe->pbus->devices, bus_list)
659 pnv_npu2_map_lpar_dev(gpdev, 0, msr);
660}
661
662int pnv_npu2_unmap_lpar_dev(struct pci_dev *gpdev)
663{
664 int ret;
665 struct pci_dev *npdev = pnv_pci_get_npu_dev(gpdev, 0);
666 struct pci_controller *hose;
667 struct pnv_phb *nphb;
668
669 if (!npdev)
670 return -ENODEV;
671
672 hose = pci_bus_to_host(npdev->bus);
673 nphb = hose->private_data;
674
675 dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n",
676 nphb->opal_id);
677 ret = opal_npu_destroy_context(nphb->opal_id, 0,
678 pci_dev_id(gpdev));
679 if (ret < 0) {
680 dev_err(&gpdev->dev, "Failed to destroy context: %d\n", ret);
681 return ret;
682 }
683
684
685 dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=0\n", nphb->opal_id);
686 ret = opal_npu_map_lpar(nphb->opal_id, pci_dev_id(gpdev), 0 ,
687 0 );
688 if (ret)
689 dev_err(&gpdev->dev, "Error %d mapping device to LPAR\n", ret);
690
691 return ret;
692}
693EXPORT_SYMBOL_GPL(pnv_npu2_unmap_lpar_dev);
694