| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | ** ccio-dma.c: |
|---|
| 3 | 4 | ** DMA management routines for first generation cache-coherent machines. |
|---|
| .. | .. |
|---|
| 7 | 8 | ** (c) Copyright 2000 Ryan Bradetich |
|---|
| 8 | 9 | ** (c) Copyright 2000 Hewlett-Packard Company |
|---|
| 9 | 10 | ** |
|---|
| 10 | | -** This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | -** it under the terms of the GNU General Public License as published by |
|---|
| 12 | | -** the Free Software Foundation; either version 2 of the License, or |
|---|
| 13 | | -** (at your option) any later version. |
|---|
| 14 | 11 | ** |
|---|
| 15 | 12 | ** |
|---|
| 16 | 13 | ** "Real Mode" operation refers to U2/Uturn chip operation. |
|---|
| .. | .. |
|---|
| 42 | 39 | #include <linux/reboot.h> |
|---|
| 43 | 40 | #include <linux/proc_fs.h> |
|---|
| 44 | 41 | #include <linux/seq_file.h> |
|---|
| 42 | +#include <linux/dma-map-ops.h> |
|---|
| 45 | 43 | #include <linux/scatterlist.h> |
|---|
| 46 | 44 | #include <linux/iommu-helper.h> |
|---|
| 47 | 45 | #include <linux/export.h> |
|---|
| .. | .. |
|---|
| 54 | 52 | #include <asm/io.h> |
|---|
| 55 | 53 | #include <asm/hardware.h> /* for register_module() */ |
|---|
| 56 | 54 | #include <asm/parisc-device.h> |
|---|
| 55 | + |
|---|
| 56 | +#include "iommu.h" |
|---|
| 57 | 57 | |
|---|
| 58 | 58 | /* |
|---|
| 59 | 59 | ** Choose "ccio" since that's what HP-UX calls it. |
|---|
| .. | .. |
|---|
| 109 | 109 | #define IOA_NORMAL_MODE 0x00020080 /* IO_CONTROL to turn on CCIO */ |
|---|
| 110 | 110 | #define CMD_TLB_DIRECT_WRITE 35 /* IO_COMMAND for I/O TLB Writes */ |
|---|
| 111 | 111 | #define CMD_TLB_PURGE 33 /* IO_COMMAND to Purge I/O TLB entry */ |
|---|
| 112 | | - |
|---|
| 113 | | -#define CCIO_MAPPING_ERROR (~(dma_addr_t)0) |
|---|
| 114 | 112 | |
|---|
| 115 | 113 | struct ioa_registers { |
|---|
| 116 | 114 | /* Runway Supervisory Set */ |
|---|
| .. | .. |
|---|
| 359 | 357 | ** ggg sacrifices another 710 to the computer gods. |
|---|
| 360 | 358 | */ |
|---|
| 361 | 359 | |
|---|
| 362 | | - boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1, |
|---|
| 363 | | - 1ULL << IOVP_SHIFT) >> IOVP_SHIFT; |
|---|
| 360 | + boundary_size = dma_get_seg_boundary_nr_pages(dev, IOVP_SHIFT); |
|---|
| 364 | 361 | |
|---|
| 365 | 362 | if (pages_needed <= 8) { |
|---|
| 366 | 363 | /* |
|---|
| .. | .. |
|---|
| 570 | 567 | ** "hints" parm includes the VALID bit! |
|---|
| 571 | 568 | ** "dep" clobbers the physical address offset bits as well. |
|---|
| 572 | 569 | */ |
|---|
| 573 | | - pa = virt_to_phys(vba); |
|---|
| 570 | + pa = lpa(vba); |
|---|
| 574 | 571 | asm volatile("depw %1,31,12,%0" : "+r" (pa) : "r" (hints)); |
|---|
| 575 | 572 | ((u32 *)pdir_ptr)[1] = (u32) pa; |
|---|
| 576 | 573 | |
|---|
| .. | .. |
|---|
| 607 | 604 | ** PCX-T'? Don't know. (eg C110 or similar K-class) |
|---|
| 608 | 605 | ** |
|---|
| 609 | 606 | ** See PDC_MODEL/option 0/SW_CAP word for "Non-coherent IO-PDIR bit". |
|---|
| 610 | | - ** Hopefully we can patch (NOP) these out at boot time somehow. |
|---|
| 611 | 607 | ** |
|---|
| 612 | 608 | ** "Since PCX-U employs an offset hash that is incompatible with |
|---|
| 613 | 609 | ** the real mode coherence index generation of U2, the PDIR entry |
|---|
| 614 | 610 | ** must be flushed to memory to retain coherence." |
|---|
| 615 | 611 | */ |
|---|
| 616 | | - asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr)); |
|---|
| 617 | | - asm volatile("sync"); |
|---|
| 612 | + asm_io_fdc(pdir_ptr); |
|---|
| 613 | + asm_io_sync(); |
|---|
| 618 | 614 | } |
|---|
| 619 | 615 | |
|---|
| 620 | 616 | /** |
|---|
| .. | .. |
|---|
| 680 | 676 | ** FIXME: PCX_W platforms don't need FDC/SYNC. (eg C360) |
|---|
| 681 | 677 | ** PCX-U/U+ do. (eg C200/C240) |
|---|
| 682 | 678 | ** See PDC_MODEL/option 0/SW_CAP for "Non-coherent IO-PDIR bit". |
|---|
| 683 | | - ** |
|---|
| 684 | | - ** Hopefully someone figures out how to patch (NOP) the |
|---|
| 685 | | - ** FDC/SYNC out at boot time. |
|---|
| 686 | 679 | */ |
|---|
| 687 | | - asm volatile("fdc %%r0(%0)" : : "r" (pdir_ptr[7])); |
|---|
| 680 | + asm_io_fdc(pdir_ptr); |
|---|
| 688 | 681 | |
|---|
| 689 | 682 | iovp += IOVP_SIZE; |
|---|
| 690 | 683 | byte_cnt -= IOVP_SIZE; |
|---|
| 691 | 684 | } |
|---|
| 692 | 685 | |
|---|
| 693 | | - asm volatile("sync"); |
|---|
| 686 | + asm_io_sync(); |
|---|
| 694 | 687 | ccio_clear_io_tlb(ioc, CCIO_IOVP(iova), saved_byte_cnt); |
|---|
| 695 | 688 | } |
|---|
| 696 | 689 | |
|---|
| .. | .. |
|---|
| 714 | 707 | return 0; |
|---|
| 715 | 708 | } |
|---|
| 716 | 709 | |
|---|
| 717 | | - /* only support 32-bit devices (ie PCI/GSC) */ |
|---|
| 718 | | - return (int)(mask == 0xffffffffUL); |
|---|
| 710 | + /* only support 32-bit or better devices (ie PCI/GSC) */ |
|---|
| 711 | + return (int)(mask >= 0xffffffffUL); |
|---|
| 719 | 712 | } |
|---|
| 720 | 713 | |
|---|
| 721 | 714 | /** |
|---|
| .. | .. |
|---|
| 742 | 735 | BUG_ON(!dev); |
|---|
| 743 | 736 | ioc = GET_IOC(dev); |
|---|
| 744 | 737 | if (!ioc) |
|---|
| 745 | | - return CCIO_MAPPING_ERROR; |
|---|
| 738 | + return DMA_MAPPING_ERROR; |
|---|
| 746 | 739 | |
|---|
| 747 | 740 | BUG_ON(size <= 0); |
|---|
| 748 | 741 | |
|---|
| .. | .. |
|---|
| 1024 | 1017 | DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents); |
|---|
| 1025 | 1018 | } |
|---|
| 1026 | 1019 | |
|---|
| 1027 | | -static int ccio_mapping_error(struct device *dev, dma_addr_t dma_addr) |
|---|
| 1028 | | -{ |
|---|
| 1029 | | - return dma_addr == CCIO_MAPPING_ERROR; |
|---|
| 1030 | | -} |
|---|
| 1031 | | - |
|---|
| 1032 | 1020 | static const struct dma_map_ops ccio_ops = { |
|---|
| 1033 | 1021 | .dma_supported = ccio_dma_supported, |
|---|
| 1034 | 1022 | .alloc = ccio_alloc, |
|---|
| .. | .. |
|---|
| 1037 | 1025 | .unmap_page = ccio_unmap_page, |
|---|
| 1038 | 1026 | .map_sg = ccio_map_sg, |
|---|
| 1039 | 1027 | .unmap_sg = ccio_unmap_sg, |
|---|
| 1040 | | - .mapping_error = ccio_mapping_error, |
|---|
| 1028 | + .get_sgtable = dma_common_get_sgtable, |
|---|
| 1029 | + .alloc_pages = dma_common_alloc_pages, |
|---|
| 1030 | + .free_pages = dma_common_free_pages, |
|---|
| 1041 | 1031 | }; |
|---|
| 1042 | 1032 | |
|---|
| 1043 | 1033 | #ifdef CONFIG_PROC_FS |
|---|
| .. | .. |
|---|
| 1254 | 1244 | ** Hot-Plug/Removal of PCI cards. (aka PCI OLARD). |
|---|
| 1255 | 1245 | */ |
|---|
| 1256 | 1246 | |
|---|
| 1257 | | - iova_space_size = (u32) (totalram_pages / count_parisc_driver(&ccio_driver)); |
|---|
| 1247 | + iova_space_size = (u32) (totalram_pages() / count_parisc_driver(&ccio_driver)); |
|---|
| 1258 | 1248 | |
|---|
| 1259 | 1249 | /* limit IOVA space size to 1MB-1GB */ |
|---|
| 1260 | 1250 | |
|---|
| .. | .. |
|---|
| 1293 | 1283 | |
|---|
| 1294 | 1284 | DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n", |
|---|
| 1295 | 1285 | __func__, ioc->ioc_regs, |
|---|
| 1296 | | - (unsigned long) totalram_pages >> (20 - PAGE_SHIFT), |
|---|
| 1286 | + (unsigned long) totalram_pages() >> (20 - PAGE_SHIFT), |
|---|
| 1297 | 1287 | iova_space_size>>20, |
|---|
| 1298 | 1288 | iov_order + PAGE_SHIFT); |
|---|
| 1299 | 1289 | |
|---|
| .. | .. |
|---|
| 1390 | 1380 | } |
|---|
| 1391 | 1381 | } |
|---|
| 1392 | 1382 | |
|---|
| 1393 | | -static void __init ccio_init_resources(struct ioc *ioc) |
|---|
| 1383 | +static int __init ccio_init_resources(struct ioc *ioc) |
|---|
| 1394 | 1384 | { |
|---|
| 1395 | 1385 | struct resource *res = ioc->mmio_region; |
|---|
| 1396 | 1386 | char *name = kmalloc(14, GFP_KERNEL); |
|---|
| 1397 | | - |
|---|
| 1387 | + if (unlikely(!name)) |
|---|
| 1388 | + return -ENOMEM; |
|---|
| 1398 | 1389 | snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path); |
|---|
| 1399 | 1390 | |
|---|
| 1400 | 1391 | ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); |
|---|
| 1401 | 1392 | ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); |
|---|
| 1393 | + return 0; |
|---|
| 1402 | 1394 | } |
|---|
| 1403 | 1395 | |
|---|
| 1404 | 1396 | static int new_ioc_area(struct resource *res, unsigned long size, |
|---|
| .. | .. |
|---|
| 1528 | 1520 | { |
|---|
| 1529 | 1521 | int i; |
|---|
| 1530 | 1522 | struct ioc *ioc, **ioc_p = &ioc_list; |
|---|
| 1523 | + struct pci_hba_data *hba; |
|---|
| 1531 | 1524 | |
|---|
| 1532 | 1525 | ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL); |
|---|
| 1533 | 1526 | if (ioc == NULL) { |
|---|
| .. | .. |
|---|
| 1546 | 1539 | *ioc_p = ioc; |
|---|
| 1547 | 1540 | |
|---|
| 1548 | 1541 | ioc->hw_path = dev->hw_path; |
|---|
| 1549 | | - ioc->ioc_regs = ioremap_nocache(dev->hpa.start, 4096); |
|---|
| 1542 | + ioc->ioc_regs = ioremap(dev->hpa.start, 4096); |
|---|
| 1550 | 1543 | if (!ioc->ioc_regs) { |
|---|
| 1551 | 1544 | kfree(ioc); |
|---|
| 1552 | 1545 | return -ENOMEM; |
|---|
| 1553 | 1546 | } |
|---|
| 1554 | 1547 | ccio_ioc_init(ioc); |
|---|
| 1555 | | - ccio_init_resources(ioc); |
|---|
| 1548 | + if (ccio_init_resources(ioc)) { |
|---|
| 1549 | + iounmap(ioc->ioc_regs); |
|---|
| 1550 | + kfree(ioc); |
|---|
| 1551 | + return -ENOMEM; |
|---|
| 1552 | + } |
|---|
| 1556 | 1553 | hppa_dma_ops = &ccio_ops; |
|---|
| 1557 | | - dev->dev.platform_data = kzalloc(sizeof(struct pci_hba_data), GFP_KERNEL); |
|---|
| 1558 | 1554 | |
|---|
| 1555 | + hba = kzalloc(sizeof(*hba), GFP_KERNEL); |
|---|
| 1559 | 1556 | /* if this fails, no I/O cards will work, so may as well bug */ |
|---|
| 1560 | | - BUG_ON(dev->dev.platform_data == NULL); |
|---|
| 1561 | | - HBA_DATA(dev->dev.platform_data)->iommu = ioc; |
|---|
| 1557 | + BUG_ON(hba == NULL); |
|---|
| 1558 | + |
|---|
| 1559 | + hba->iommu = ioc; |
|---|
| 1560 | + dev->dev.platform_data = hba; |
|---|
| 1562 | 1561 | |
|---|
| 1563 | 1562 | #ifdef CONFIG_PROC_FS |
|---|
| 1564 | 1563 | if (ioc_count == 0) { |
|---|