| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | | - * arch/x86/pci/sta2x11-fixup.c |
|---|
| 3 | | - * glue code for lib/swiotlb.c and DMA translation between STA2x11 |
|---|
| 4 | | - * AMBA memory mapping and the X86 memory mapping |
|---|
| 3 | + * DMA translation between STA2x11 AMBA memory mapping and the x86 memory mapping |
|---|
| 5 | 4 | * |
|---|
| 6 | 5 | * ST Microelectronics ConneXt (STA2X11/STA2X10) |
|---|
| 7 | 6 | * |
|---|
| 8 | 7 | * Copyright (c) 2010-2011 Wind River Systems, Inc. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 12 | | - * published by the Free Software Foundation. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 15 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|---|
| 17 | | - * See the GNU General Public License for more details. |
|---|
| 18 | | - * |
|---|
| 19 | | - * You should have received a copy of the GNU General Public License |
|---|
| 20 | | - * along with this program; if not, write to the Free Software |
|---|
| 21 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 22 | | - * |
|---|
| 23 | 8 | */ |
|---|
| 24 | 9 | |
|---|
| 25 | 10 | #include <linux/pci.h> |
|---|
| .. | .. |
|---|
| 30 | 15 | #include <asm/iommu.h> |
|---|
| 31 | 16 | |
|---|
| 32 | 17 | #define STA2X11_SWIOTLB_SIZE (4*1024*1024) |
|---|
| 33 | | -extern int swiotlb_late_init_with_default_size(size_t default_size); |
|---|
| 34 | 18 | |
|---|
| 35 | 19 | /* |
|---|
| 36 | 20 | * We build a list of bus numbers that are under the ConneXt. The |
|---|
| .. | .. |
|---|
| 45 | 29 | }; |
|---|
| 46 | 30 | |
|---|
| 47 | 31 | struct sta2x11_mapping { |
|---|
| 48 | | - u32 amba_base; |
|---|
| 49 | 32 | int is_suspended; |
|---|
| 50 | 33 | struct sta2x11_ahb_regs regs[STA2X11_NR_FUNCS]; |
|---|
| 51 | 34 | }; |
|---|
| .. | .. |
|---|
| 107 | 90 | return pdev->bus->number - instance->bus0; |
|---|
| 108 | 91 | } |
|---|
| 109 | 92 | |
|---|
| 110 | | -static struct sta2x11_mapping *sta2x11_pdev_to_mapping(struct pci_dev *pdev) |
|---|
| 111 | | -{ |
|---|
| 112 | | - struct sta2x11_instance *instance; |
|---|
| 113 | | - int ep; |
|---|
| 114 | | - |
|---|
| 115 | | - instance = sta2x11_pdev_to_instance(pdev); |
|---|
| 116 | | - if (!instance) |
|---|
| 117 | | - return NULL; |
|---|
| 118 | | - ep = sta2x11_pdev_to_ep(pdev); |
|---|
| 119 | | - return instance->map + ep; |
|---|
| 120 | | -} |
|---|
| 121 | | - |
|---|
| 122 | 93 | /* This is exported, as some devices need to access the MFD registers */ |
|---|
| 123 | 94 | struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev) |
|---|
| 124 | 95 | { |
|---|
| 125 | 96 | return sta2x11_pdev_to_instance(pdev); |
|---|
| 126 | 97 | } |
|---|
| 127 | 98 | EXPORT_SYMBOL(sta2x11_get_instance); |
|---|
| 128 | | - |
|---|
| 129 | | - |
|---|
| 130 | | -/** |
|---|
| 131 | | - * p2a - Translate physical address to STA2x11 AMBA address, |
|---|
| 132 | | - * used for DMA transfers to STA2x11 |
|---|
| 133 | | - * @p: Physical address |
|---|
| 134 | | - * @pdev: PCI device (must be hosted within the connext) |
|---|
| 135 | | - */ |
|---|
| 136 | | -static dma_addr_t p2a(dma_addr_t p, struct pci_dev *pdev) |
|---|
| 137 | | -{ |
|---|
| 138 | | - struct sta2x11_mapping *map; |
|---|
| 139 | | - dma_addr_t a; |
|---|
| 140 | | - |
|---|
| 141 | | - map = sta2x11_pdev_to_mapping(pdev); |
|---|
| 142 | | - a = p + map->amba_base; |
|---|
| 143 | | - return a; |
|---|
| 144 | | -} |
|---|
| 145 | | - |
|---|
| 146 | | -/** |
|---|
| 147 | | - * a2p - Translate STA2x11 AMBA address to physical address |
|---|
| 148 | | - * used for DMA transfers from STA2x11 |
|---|
| 149 | | - * @a: STA2x11 AMBA address |
|---|
| 150 | | - * @pdev: PCI device (must be hosted within the connext) |
|---|
| 151 | | - */ |
|---|
| 152 | | -static dma_addr_t a2p(dma_addr_t a, struct pci_dev *pdev) |
|---|
| 153 | | -{ |
|---|
| 154 | | - struct sta2x11_mapping *map; |
|---|
| 155 | | - dma_addr_t p; |
|---|
| 156 | | - |
|---|
| 157 | | - map = sta2x11_pdev_to_mapping(pdev); |
|---|
| 158 | | - p = a - map->amba_base; |
|---|
| 159 | | - return p; |
|---|
| 160 | | -} |
|---|
| 161 | 99 | |
|---|
| 162 | 100 | /* At setup time, we use our own ops if the device is a ConneXt one */ |
|---|
| 163 | 101 | static void sta2x11_setup_pdev(struct pci_dev *pdev) |
|---|
| .. | .. |
|---|
| 166 | 104 | |
|---|
| 167 | 105 | if (!instance) /* either a sta2x11 bridge or another ST device */ |
|---|
| 168 | 106 | return; |
|---|
| 169 | | - pci_set_consistent_dma_mask(pdev, STA2X11_AMBA_SIZE - 1); |
|---|
| 170 | | - pci_set_dma_mask(pdev, STA2X11_AMBA_SIZE - 1); |
|---|
| 171 | | - pdev->dev.dma_ops = &swiotlb_dma_ops; |
|---|
| 172 | | - pdev->dev.archdata.is_sta2x11 = true; |
|---|
| 173 | 107 | |
|---|
| 174 | 108 | /* We must enable all devices as master, for audio DMA to work */ |
|---|
| 175 | 109 | pci_set_master(pdev); |
|---|
| 176 | 110 | } |
|---|
| 177 | 111 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_setup_pdev); |
|---|
| 178 | | - |
|---|
| 179 | | -/* |
|---|
| 180 | | - * The following three functions are exported (used in swiotlb: FIXME) |
|---|
| 181 | | - */ |
|---|
| 182 | | -/** |
|---|
| 183 | | - * dma_capable - Check if device can manage DMA transfers (FIXME: kill it) |
|---|
| 184 | | - * @dev: device for a PCI device |
|---|
| 185 | | - * @addr: DMA address |
|---|
| 186 | | - * @size: DMA size |
|---|
| 187 | | - */ |
|---|
| 188 | | -bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) |
|---|
| 189 | | -{ |
|---|
| 190 | | - struct sta2x11_mapping *map; |
|---|
| 191 | | - |
|---|
| 192 | | - if (!dev->archdata.is_sta2x11) { |
|---|
| 193 | | - if (!dev->dma_mask) |
|---|
| 194 | | - return false; |
|---|
| 195 | | - return addr + size - 1 <= *dev->dma_mask; |
|---|
| 196 | | - } |
|---|
| 197 | | - |
|---|
| 198 | | - map = sta2x11_pdev_to_mapping(to_pci_dev(dev)); |
|---|
| 199 | | - |
|---|
| 200 | | - if (!map || (addr < map->amba_base)) |
|---|
| 201 | | - return false; |
|---|
| 202 | | - if (addr + size >= map->amba_base + STA2X11_AMBA_SIZE) { |
|---|
| 203 | | - return false; |
|---|
| 204 | | - } |
|---|
| 205 | | - |
|---|
| 206 | | - return true; |
|---|
| 207 | | -} |
|---|
| 208 | | - |
|---|
| 209 | | -/** |
|---|
| 210 | | - * __phys_to_dma - Return the DMA AMBA address used for this STA2x11 device |
|---|
| 211 | | - * @dev: device for a PCI device |
|---|
| 212 | | - * @paddr: Physical address |
|---|
| 213 | | - */ |
|---|
| 214 | | -dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) |
|---|
| 215 | | -{ |
|---|
| 216 | | - if (!dev->archdata.is_sta2x11) |
|---|
| 217 | | - return paddr; |
|---|
| 218 | | - return p2a(paddr, to_pci_dev(dev)); |
|---|
| 219 | | -} |
|---|
| 220 | | - |
|---|
| 221 | | -/** |
|---|
| 222 | | - * dma_to_phys - Return the physical address used for this STA2x11 DMA address |
|---|
| 223 | | - * @dev: device for a PCI device |
|---|
| 224 | | - * @daddr: STA2x11 AMBA DMA address |
|---|
| 225 | | - */ |
|---|
| 226 | | -phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) |
|---|
| 227 | | -{ |
|---|
| 228 | | - if (!dev->archdata.is_sta2x11) |
|---|
| 229 | | - return daddr; |
|---|
| 230 | | - return a2p(daddr, to_pci_dev(dev)); |
|---|
| 231 | | -} |
|---|
| 232 | | - |
|---|
| 233 | 112 | |
|---|
| 234 | 113 | /* |
|---|
| 235 | 114 | * At boot we must set up the mappings for the pcie-to-amba bridge. |
|---|
| .. | .. |
|---|
| 250 | 129 | /* At probe time, enable mapping for each endpoint, using the pdev */ |
|---|
| 251 | 130 | static void sta2x11_map_ep(struct pci_dev *pdev) |
|---|
| 252 | 131 | { |
|---|
| 253 | | - struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev); |
|---|
| 254 | | - int i; |
|---|
| 132 | + struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev); |
|---|
| 133 | + struct device *dev = &pdev->dev; |
|---|
| 134 | + u32 amba_base, max_amba_addr; |
|---|
| 135 | + int i, ret; |
|---|
| 255 | 136 | |
|---|
| 256 | | - if (!map) |
|---|
| 137 | + if (!instance) |
|---|
| 257 | 138 | return; |
|---|
| 258 | | - pci_read_config_dword(pdev, AHB_BASE(0), &map->amba_base); |
|---|
| 139 | + |
|---|
| 140 | + pci_read_config_dword(pdev, AHB_BASE(0), &amba_base); |
|---|
| 141 | + max_amba_addr = amba_base + STA2X11_AMBA_SIZE - 1; |
|---|
| 142 | + |
|---|
| 143 | + ret = dma_direct_set_offset(dev, 0, amba_base, STA2X11_AMBA_SIZE); |
|---|
| 144 | + if (ret) |
|---|
| 145 | + dev_err(dev, "sta2x11: could not set DMA offset\n"); |
|---|
| 146 | + |
|---|
| 147 | + dev->bus_dma_limit = max_amba_addr; |
|---|
| 148 | + pci_set_consistent_dma_mask(pdev, max_amba_addr); |
|---|
| 149 | + pci_set_dma_mask(pdev, max_amba_addr); |
|---|
| 259 | 150 | |
|---|
| 260 | 151 | /* Configure AHB mapping */ |
|---|
| 261 | 152 | pci_write_config_dword(pdev, AHB_PEXLBASE(0), 0); |
|---|
| .. | .. |
|---|
| 269 | 160 | |
|---|
| 270 | 161 | dev_info(&pdev->dev, |
|---|
| 271 | 162 | "sta2x11: Map EP %i: AMBA address %#8x-%#8x\n", |
|---|
| 272 | | - sta2x11_pdev_to_ep(pdev), map->amba_base, |
|---|
| 273 | | - map->amba_base + STA2X11_AMBA_SIZE - 1); |
|---|
| 163 | + sta2x11_pdev_to_ep(pdev), amba_base, max_amba_addr); |
|---|
| 274 | 164 | } |
|---|
| 275 | 165 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_map_ep); |
|---|
| 276 | 166 | |
|---|
| 277 | 167 | #ifdef CONFIG_PM /* Some register values must be saved and restored */ |
|---|
| 278 | 168 | |
|---|
| 169 | +static struct sta2x11_mapping *sta2x11_pdev_to_mapping(struct pci_dev *pdev) |
|---|
| 170 | +{ |
|---|
| 171 | + struct sta2x11_instance *instance; |
|---|
| 172 | + int ep; |
|---|
| 173 | + |
|---|
| 174 | + instance = sta2x11_pdev_to_instance(pdev); |
|---|
| 175 | + if (!instance) |
|---|
| 176 | + return NULL; |
|---|
| 177 | + ep = sta2x11_pdev_to_ep(pdev); |
|---|
| 178 | + return instance->map + ep; |
|---|
| 179 | +} |
|---|
| 180 | + |
|---|
| 279 | 181 | static void suspend_mapping(struct pci_dev *pdev) |
|---|
| 280 | 182 | { |
|---|
| 281 | 183 | struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev); |
|---|