![]() |
|
|||
0001 /* 0002 * Copyright (c) 2012 Intel Corporation. All rights reserved. 0003 * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. 0004 * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. 0005 * 0006 * This software is available to you under a choice of one of two 0007 * licenses. You may choose to be licensed under the terms of the GNU 0008 * General Public License (GPL) Version 2, available from the file 0009 * COPYING in the main directory of this source tree, or the 0010 * OpenIB.org BSD license below: 0011 * 0012 * Redistribution and use in source and binary forms, with or 0013 * without modification, are permitted provided that the following 0014 * conditions are met: 0015 * 0016 * - Redistributions of source code must retain the above 0017 * copyright notice, this list of conditions and the following 0018 * disclaimer. 0019 * 0020 * - Redistributions in binary form must reproduce the above 0021 * copyright notice, this list of conditions and the following 0022 * disclaimer in the documentation and/or other materials 0023 * provided with the distribution. 0024 * 0025 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 0026 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 0027 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 0028 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 0029 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 0030 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 0031 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 0032 * SOFTWARE. 0033 */ 0034 0035 /* 0036 * This file is conditionally built on x86_64 only. Otherwise weak symbol 0037 * versions of the functions exported from here are used. 0038 */ 0039 0040 #include <linux/pci.h> 0041 #include <asm/mtrr.h> 0042 #include <asm/processor.h> 0043 0044 #include "qib.h" 0045 0046 /** 0047 * qib_enable_wc - enable write combining for MMIO writes to the device 0048 * @dd: qlogic_ib device 0049 * 0050 * This routine is x86_64-specific; it twiddles the CPU's MTRRs to enable 0051 * write combining. 0052 */ 0053 int qib_enable_wc(struct qib_devdata *dd) 0054 { 0055 int ret = 0; 0056 u64 pioaddr, piolen; 0057 unsigned bits; 0058 const unsigned long addr = pci_resource_start(dd->pcidev, 0); 0059 const size_t len = pci_resource_len(dd->pcidev, 0); 0060 0061 /* 0062 * Set the PIO buffers to be WCCOMB, so we get HT bursts to the 0063 * chip. Linux (possibly the hardware) requires it to be on a power 0064 * of 2 address matching the length (which has to be a power of 2). 0065 * For rev1, that means the base address, for rev2, it will be just 0066 * the PIO buffers themselves. 0067 * For chips with two sets of buffers, the calculations are 0068 * somewhat more complicated; we need to sum, and the piobufbase 0069 * register has both offsets, 2K in low 32 bits, 4K in high 32 bits. 0070 * The buffers are still packed, so a single range covers both. 0071 */ 0072 if (dd->piobcnt2k && dd->piobcnt4k) { 0073 /* 2 sizes for chip */ 0074 unsigned long pio2kbase, pio4kbase; 0075 0076 pio2kbase = dd->piobufbase & 0xffffffffUL; 0077 pio4kbase = (dd->piobufbase >> 32) & 0xffffffffUL; 0078 if (pio2kbase < pio4kbase) { 0079 /* all current chips */ 0080 pioaddr = addr + pio2kbase; 0081 piolen = pio4kbase - pio2kbase + 0082 dd->piobcnt4k * dd->align4k; 0083 } else { 0084 pioaddr = addr + pio4kbase; 0085 piolen = pio2kbase - pio4kbase + 0086 dd->piobcnt2k * dd->palign; 0087 } 0088 } else { /* single buffer size (2K, currently) */ 0089 pioaddr = addr + dd->piobufbase; 0090 piolen = dd->piobcnt2k * dd->palign + 0091 dd->piobcnt4k * dd->align4k; 0092 } 0093 0094 for (bits = 0; !(piolen & (1ULL << bits)); bits++) 0095 ; /* do nothing */ 0096 0097 if (piolen != (1ULL << bits)) { 0098 piolen >>= bits; 0099 while (piolen >>= 1) 0100 bits++; 0101 piolen = 1ULL << (bits + 1); 0102 } 0103 if (pioaddr & (piolen - 1)) { 0104 u64 atmp = pioaddr & ~(piolen - 1); 0105 0106 if (atmp < addr || (atmp + piolen) > (addr + len)) { 0107 qib_dev_err(dd, 0108 "No way to align address/size (%llx/%llx), no WC mtrr\n", 0109 (unsigned long long) atmp, 0110 (unsigned long long) piolen << 1); 0111 ret = -ENODEV; 0112 } else { 0113 pioaddr = atmp; 0114 piolen <<= 1; 0115 } 0116 } 0117 0118 if (!ret) { 0119 dd->wc_cookie = arch_phys_wc_add(pioaddr, piolen); 0120 if (dd->wc_cookie < 0) 0121 /* use error from routine */ 0122 ret = dd->wc_cookie; 0123 } 0124 0125 return ret; 0126 } 0127 0128 /** 0129 * qib_disable_wc - disable write combining for MMIO writes to the device 0130 * @dd: qlogic_ib device 0131 */ 0132 void qib_disable_wc(struct qib_devdata *dd) 0133 { 0134 arch_phys_wc_del(dd->wc_cookie); 0135 } 0136 0137 /** 0138 * qib_unordered_wc - indicate whether write combining is ordered 0139 * 0140 * Because our performance depends on our ability to do write combining mmio 0141 * writes in the most efficient way, we need to know if we are on an Intel 0142 * or AMD x86_64 processor. AMD x86_64 processors flush WC buffers out in 0143 * the order completed, and so no special flushing is required to get 0144 * correct ordering. Intel processors, however, will flush write buffers 0145 * out in "random" orders, and so explicit ordering is needed at times. 0146 */ 0147 int qib_unordered_wc(void) 0148 { 0149 return boot_cpu_data.x86_vendor != X86_VENDOR_AMD; 0150 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |