.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * MPC83xx/85xx/86xx PCI/PCIE support routing. |
---|
3 | 4 | * |
---|
.. | .. |
---|
11 | 12 | * MPC83xx PCI-Express support: |
---|
12 | 13 | * Tony Li <tony.li@freescale.com> |
---|
13 | 14 | * Anton Vorontsov <avorontsov@ru.mvista.com> |
---|
14 | | - * |
---|
15 | | - * This program is free software; you can redistribute it and/or modify it |
---|
16 | | - * under the terms of the GNU General Public License as published by the |
---|
17 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
18 | | - * option) any later version. |
---|
19 | 15 | */ |
---|
20 | 16 | #include <linux/kernel.h> |
---|
21 | 17 | #include <linux/pci.h> |
---|
.. | .. |
---|
40 | 36 | #include <asm/mpc85xx.h> |
---|
41 | 37 | #include <asm/disassemble.h> |
---|
42 | 38 | #include <asm/ppc-opcode.h> |
---|
| 39 | +#include <asm/swiotlb.h> |
---|
43 | 40 | #include <sysdev/fsl_soc.h> |
---|
44 | 41 | #include <sysdev/fsl_pci.h> |
---|
45 | 42 | |
---|
.. | .. |
---|
114 | 111 | static u64 pci64_dma_offset; |
---|
115 | 112 | |
---|
116 | 113 | #ifdef CONFIG_SWIOTLB |
---|
| 114 | +static void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev) |
---|
| 115 | +{ |
---|
| 116 | + struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
---|
| 117 | + |
---|
| 118 | + pdev->dev.bus_dma_limit = |
---|
| 119 | + hose->dma_window_base_cur + hose->dma_window_size - 1; |
---|
| 120 | +} |
---|
| 121 | + |
---|
117 | 122 | static void setup_swiotlb_ops(struct pci_controller *hose) |
---|
118 | 123 | { |
---|
119 | | - if (ppc_swiotlb_enable) { |
---|
| 124 | + if (ppc_swiotlb_enable) |
---|
120 | 125 | hose->controller_ops.dma_dev_setup = pci_dma_dev_setup_swiotlb; |
---|
121 | | - set_pci_dma_ops(&powerpc_swiotlb_dma_ops); |
---|
122 | | - } |
---|
123 | 126 | } |
---|
124 | 127 | #else |
---|
125 | 128 | static inline void setup_swiotlb_ops(struct pci_controller *hose) {} |
---|
126 | 129 | #endif |
---|
127 | 130 | |
---|
128 | | -static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask) |
---|
| 131 | +static void fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask) |
---|
129 | 132 | { |
---|
130 | | - if (!dev->dma_mask || !dma_supported(dev, dma_mask)) |
---|
131 | | - return -EIO; |
---|
132 | | - |
---|
133 | 133 | /* |
---|
134 | 134 | * Fix up PCI devices that are able to DMA to the large inbound |
---|
135 | 135 | * mapping that allows addressing any RAM address from across PCI. |
---|
136 | 136 | */ |
---|
137 | 137 | if (dev_is_pci(dev) && dma_mask >= pci64_dma_offset * 2 - 1) { |
---|
138 | | - set_dma_ops(dev, &dma_nommu_ops); |
---|
139 | | - set_dma_offset(dev, pci64_dma_offset); |
---|
| 138 | + dev->bus_dma_limit = 0; |
---|
| 139 | + dev->archdata.dma_offset = pci64_dma_offset; |
---|
140 | 140 | } |
---|
141 | | - |
---|
142 | | - *dev->dma_mask = dma_mask; |
---|
143 | | - return 0; |
---|
144 | 141 | } |
---|
145 | 142 | |
---|
146 | 143 | static int setup_one_atmu(struct ccsr_pci __iomem *pci, |
---|
.. | .. |
---|
523 | 520 | struct resource rsrc; |
---|
524 | 521 | const int *bus_range; |
---|
525 | 522 | u8 hdr_type, progif; |
---|
| 523 | + u32 class_code; |
---|
526 | 524 | struct device_node *dev; |
---|
527 | 525 | struct ccsr_pci __iomem *pci; |
---|
528 | 526 | u16 temp; |
---|
.. | .. |
---|
596 | 594 | PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS; |
---|
597 | 595 | if (fsl_pcie_check_link(hose)) |
---|
598 | 596 | hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; |
---|
| 597 | + /* Fix Class Code to PCI_CLASS_BRIDGE_PCI_NORMAL for pre-3.0 controller */ |
---|
| 598 | + if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) { |
---|
| 599 | + early_read_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, &class_code); |
---|
| 600 | + class_code &= 0xff; |
---|
| 601 | + class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8; |
---|
| 602 | + early_write_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, class_code); |
---|
| 603 | + } |
---|
599 | 604 | } else { |
---|
600 | 605 | /* |
---|
601 | 606 | * Set PBFR(PCI Bus Function Register)[10] = 1 to |
---|
.. | .. |
---|
1068 | 1073 | addr += mfspr(SPRN_MCAR); |
---|
1069 | 1074 | |
---|
1070 | 1075 | if (is_in_pci_mem_space(addr)) { |
---|
1071 | | - if (user_mode(regs)) { |
---|
1072 | | - pagefault_disable(); |
---|
1073 | | - ret = get_user(inst, (__u32 __user *)regs->nip); |
---|
1074 | | - pagefault_enable(); |
---|
1075 | | - } else { |
---|
1076 | | - ret = probe_kernel_address((void *)regs->nip, inst); |
---|
1077 | | - } |
---|
| 1076 | + if (user_mode(regs)) |
---|
| 1077 | + ret = copy_from_user_nofault(&inst, |
---|
| 1078 | + (void __user *)regs->nip, sizeof(inst)); |
---|
| 1079 | + else |
---|
| 1080 | + ret = get_kernel_nofault(inst, (void *)regs->nip); |
---|
1078 | 1081 | |
---|
1079 | 1082 | if (!ret && mcheck_handle_load(regs, inst)) { |
---|
1080 | 1083 | regs->nip += 4; |
---|