Path: blob/master/arch/ia64/sn/pci/pcibr/pcibr_dma.c
15133 views
/*1* This file is subject to the terms and conditions of the GNU General Public2* License. See the file "COPYING" in the main directory of this archive3* for more details.4*5* Copyright (C) 2001-2005 Silicon Graphics, Inc. All rights reserved.6*/78#include <linux/types.h>9#include <linux/pci.h>10#include <asm/sn/addrs.h>11#include <asm/sn/geo.h>12#include <asm/sn/pcibr_provider.h>13#include <asm/sn/pcibus_provider_defs.h>14#include <asm/sn/pcidev.h>15#include <asm/sn/pic.h>16#include <asm/sn/sn_sal.h>17#include <asm/sn/tiocp.h>18#include "tio.h"19#include "xtalk/xwidgetdev.h"20#include "xtalk/hubdev.h"2122extern int sn_ioif_inited;2324/* =====================================================================25* DMA MANAGEMENT26*27* The Bridge ASIC provides three methods of doing DMA: via a "direct map"28* register available in 32-bit PCI space (which selects a contiguous 2G29* address space on some other widget), via "direct" addressing via 64-bit30* PCI space (all destination information comes from the PCI address,31* including transfer attributes), and via a "mapped" region that allows32* a bunch of different small mappings to be established with the PMU.33*34* For efficiency, we most prefer to use the 32bit direct mapping facility,35* since it requires no resource allocations. The advantage of using the36* PMU over the 64-bit direct is that single-cycle PCI addressing can be37* used; the advantage of using 64-bit direct over PMU addressing is that38* we do not have to allocate entries in the PMU.39*/4041static dma_addr_t42pcibr_dmamap_ate32(struct pcidev_info *info,43u64 paddr, size_t req_size, u64 flags, int dma_flags)44{4546struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;47struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->48pdi_pcibus_info;49u8 internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info->50pdi_linux_pcidev->devfn)) - 1;51int ate_count;52int ate_index;53u64 ate_flags = flags | PCI32_ATE_V;54u64 ate;55u64 pci_addr;56u64 xio_addr;57u64 offset;5859/* PIC in PCI-X mode does not supports 32bit PageMap mode */60if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) {61return 0;62}6364/* Calculate the number of ATEs needed. */65if (!(MINIMAL_ATE_FLAG(paddr, req_size))) {66ate_count = IOPG((IOPGSIZE - 1) /* worst case start offset */67+req_size /* max mapping bytes */68- 1) + 1; /* round UP */69} else { /* assume requested target is page aligned */70ate_count = IOPG(req_size /* max mapping bytes */71- 1) + 1; /* round UP */72}7374/* Get the number of ATEs required. */75ate_index = pcibr_ate_alloc(pcibus_info, ate_count);76if (ate_index < 0)77return 0;7879/* In PCI-X mode, Prefetch not supported */80if (IS_PCIX(pcibus_info))81ate_flags &= ~(PCI32_ATE_PREF);8283if (SN_DMA_ADDRTYPE(dma_flags == SN_DMA_ADDR_PHYS))84xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) :85PHYS_TO_TIODMA(paddr);86else87xio_addr = paddr;8889offset = IOPGOFF(xio_addr);90ate = ate_flags | (xio_addr - offset);9192/* If PIC, put the targetid in the ATE */93if (IS_PIC_SOFT(pcibus_info)) {94ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT);95}9697/*98* If we're mapping for MSI, set the MSI bit in the ATE. If it's a99* TIOCP based pci bus, we also need to set the PIO bit in the ATE.100*/101if (dma_flags & SN_DMA_MSI) {102ate |= PCI32_ATE_MSI;103if (IS_TIOCP_SOFT(pcibus_info))104ate |= PCI32_ATE_PIO;105}106107ate_write(pcibus_info, ate_index, ate_count, ate);108109/*110* Set up the DMA mapped Address.111*/112pci_addr = PCI32_MAPPED_BASE + offset + IOPGSIZE * ate_index;113114/*115* If swap was set in device in pcibr_endian_set()116* we need to turn swapping on.117*/118if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR)119ATE_SWAP_ON(pci_addr);120121122return pci_addr;123}124125static dma_addr_t126pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,127u64 dma_attributes, int dma_flags)128{129struct pcibus_info *pcibus_info = (struct pcibus_info *)130((info->pdi_host_pcidev_info)->pdi_pcibus_info);131u64 pci_addr;132133/* Translate to Crosstalk View of Physical Address */134if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)135pci_addr = IS_PIC_SOFT(pcibus_info) ?136PHYS_TO_DMA(paddr) :137PHYS_TO_TIODMA(paddr);138else139pci_addr = paddr;140pci_addr |= dma_attributes;141142/* Handle Bus mode */143if (IS_PCIX(pcibus_info))144pci_addr &= ~PCI64_ATTR_PREF;145146/* Handle Bridge Chipset differences */147if (IS_PIC_SOFT(pcibus_info)) {148pci_addr |=149((u64) pcibus_info->150pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT);151} else152pci_addr |= (dma_flags & SN_DMA_MSI) ?153TIOCP_PCI64_CMDTYPE_MSI :154TIOCP_PCI64_CMDTYPE_MEM;155156/* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */157if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn))158pci_addr |= PCI64_ATTR_VIRTUAL;159160return pci_addr;161}162163static dma_addr_t164pcibr_dmatrans_direct32(struct pcidev_info * info,165u64 paddr, size_t req_size, u64 flags, int dma_flags)166{167struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;168struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->169pdi_pcibus_info;170u64 xio_addr;171172u64 xio_base;173u64 offset;174u64 endoff;175176if (IS_PCIX(pcibus_info)) {177return 0;178}179180if (dma_flags & SN_DMA_MSI)181return 0;182183if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)184xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) :185PHYS_TO_TIODMA(paddr);186else187xio_addr = paddr;188189xio_base = pcibus_info->pbi_dir_xbase;190offset = xio_addr - xio_base;191endoff = req_size + offset;192if ((req_size > (1ULL << 31)) || /* Too Big */193(xio_addr < xio_base) || /* Out of range for mappings */194(endoff > (1ULL << 31))) { /* Too Big */195return 0;196}197198return PCI32_DIRECT_BASE | offset;199}200201/*202* Wrapper routine for freeing DMA maps203* DMA mappings for Direct 64 and 32 do not have any DMA maps.204*/205void206pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction)207{208struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);209struct pcibus_info *pcibus_info =210(struct pcibus_info *)pcidev_info->pdi_pcibus_info;211212if (IS_PCI32_MAPPED(dma_handle)) {213int ate_index;214215ate_index =216IOPG((ATE_SWAP_OFF(dma_handle) - PCI32_MAPPED_BASE));217pcibr_ate_free(pcibus_info, ate_index);218}219}220221/*222* On SN systems there is a race condition between a PIO read response and223* DMA's. In rare cases, the read response may beat the DMA, causing the224* driver to think that data in memory is complete and meaningful. This code225* eliminates that race. This routine is called by the PIO read routines226* after doing the read. For PIC this routine then forces a fake interrupt227* on another line, which is logically associated with the slot that the PIO228* is addressed to. It then spins while watching the memory location that229* the interrupt is targeted to. When the interrupt response arrives, we230* are sure that the DMA has landed in memory and it is safe for the driver231* to proceed. For TIOCP use the Device(x) Write Request Buffer Flush232* Bridge register since it ensures the data has entered the coherence domain,233* unlike the PIC Device(x) Write Request Buffer Flush register.234*/235236void sn_dma_flush(u64 addr)237{238nasid_t nasid;239int is_tio;240int wid_num;241int i, j;242unsigned long flags;243u64 itte;244struct hubdev_info *hubinfo;245struct sn_flush_device_kernel *p;246struct sn_flush_device_common *common;247struct sn_flush_nasid_entry *flush_nasid_list;248249if (!sn_ioif_inited)250return;251252nasid = NASID_GET(addr);253if (-1 == nasid_to_cnodeid(nasid))254return;255256hubinfo = (NODEPDA(nasid_to_cnodeid(nasid)))->pdinfo;257258BUG_ON(!hubinfo);259260flush_nasid_list = &hubinfo->hdi_flush_nasid_list;261if (flush_nasid_list->widget_p == NULL)262return;263264is_tio = (nasid & 1);265if (is_tio) {266int itte_index;267268if (TIO_HWIN(addr))269itte_index = 0;270else if (TIO_BWIN_WINDOWNUM(addr))271itte_index = TIO_BWIN_WINDOWNUM(addr);272else273itte_index = -1;274275if (itte_index >= 0) {276itte = flush_nasid_list->iio_itte[itte_index];277if (! TIO_ITTE_VALID(itte))278return;279wid_num = TIO_ITTE_WIDGET(itte);280} else281wid_num = TIO_SWIN_WIDGETNUM(addr);282} else {283if (BWIN_WINDOWNUM(addr)) {284itte = flush_nasid_list->iio_itte[BWIN_WINDOWNUM(addr)];285wid_num = IIO_ITTE_WIDGET(itte);286} else287wid_num = SWIN_WIDGETNUM(addr);288}289if (flush_nasid_list->widget_p[wid_num] == NULL)290return;291p = &flush_nasid_list->widget_p[wid_num][0];292293/* find a matching BAR */294for (i = 0; i < DEV_PER_WIDGET; i++,p++) {295common = p->common;296for (j = 0; j < PCI_ROM_RESOURCE; j++) {297if (common->sfdl_bar_list[j].start == 0)298break;299if (addr >= common->sfdl_bar_list[j].start300&& addr <= common->sfdl_bar_list[j].end)301break;302}303if (j < PCI_ROM_RESOURCE && common->sfdl_bar_list[j].start != 0)304break;305}306307/* if no matching BAR, return without doing anything. */308if (i == DEV_PER_WIDGET)309return;310311/*312* For TIOCP use the Device(x) Write Request Buffer Flush Bridge313* register since it ensures the data has entered the coherence314* domain, unlike PIC.315*/316if (is_tio) {317/*318* Note: devices behind TIOCE should never be matched in the319* above code, and so the following code is PIC/CP centric.320* If CE ever needs the sn_dma_flush mechanism, we will have321* to account for that here and in tioce_bus_fixup().322*/323u32 tio_id = HUB_L(TIO_IOSPACE_ADDR(nasid, TIO_NODE_ID));324u32 revnum = XWIDGET_PART_REV_NUM(tio_id);325326/* TIOCP BRINGUP WAR (PV907516): Don't write buffer flush reg */327if ((1 << XWIDGET_PART_REV_NUM_REV(revnum)) & PV907516) {328return;329} else {330pcireg_wrb_flush_get(common->sfdl_pcibus_info,331(common->sfdl_slot - 1));332}333} else {334spin_lock_irqsave(&p->sfdl_flush_lock, flags);335*common->sfdl_flush_addr = 0;336337/* force an interrupt. */338*(volatile u32 *)(common->sfdl_force_int_addr) = 1;339340/* wait for the interrupt to come back. */341while (*(common->sfdl_flush_addr) != 0x10f)342cpu_relax();343344/* okay, everything is synched up. */345spin_unlock_irqrestore(&p->sfdl_flush_lock, flags);346}347return;348}349350/*351* DMA interfaces. Called from pci_dma.c routines.352*/353354dma_addr_t355pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int dma_flags)356{357dma_addr_t dma_handle;358struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);359360/* SN cannot support DMA addresses smaller than 32 bits. */361if (hwdev->dma_mask < 0x7fffffff) {362return 0;363}364365if (hwdev->dma_mask == ~0UL) {366/*367* Handle the most common case: 64 bit cards. This368* call should always succeed.369*/370371dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr,372PCI64_ATTR_PREF, dma_flags);373} else {374/* Handle 32-63 bit cards via direct mapping */375dma_handle = pcibr_dmatrans_direct32(pcidev_info, phys_addr,376size, 0, dma_flags);377if (!dma_handle) {378/*379* It is a 32 bit card and we cannot do direct mapping,380* so we use an ATE.381*/382383dma_handle = pcibr_dmamap_ate32(pcidev_info, phys_addr,384size, PCI32_ATE_PREF,385dma_flags);386}387}388389return dma_handle;390}391392dma_addr_t393pcibr_dma_map_consistent(struct pci_dev * hwdev, unsigned long phys_addr,394size_t size, int dma_flags)395{396dma_addr_t dma_handle;397struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);398399if (hwdev->dev.coherent_dma_mask == ~0UL) {400dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr,401PCI64_ATTR_BAR, dma_flags);402} else {403dma_handle = (dma_addr_t) pcibr_dmamap_ate32(pcidev_info,404phys_addr, size,405PCI32_ATE_BAR, dma_flags);406}407408return dma_handle;409}410411EXPORT_SYMBOL(sn_dma_flush);412413414