Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 77b2555b52a894a2e39a42e43d993df875c46a6a 391 lines 10 kB view raw
1/* 2 * Copyright 2001 MontaVista Software Inc. 3 * Author: MontaVista Software, Inc. 4 * ahennessy@mvista.com 5 * 6 * Copyright (C) 2000-2001 Toshiba Corporation 7 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) 8 * 9 * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c 10 * 11 * Define the pci_ops for JMR3927. 12 * 13 * Much of the code is derived from the original DDB5074 port by 14 * Geert Uytterhoeven <geert@sonycom.com> 15 * 16 * This program is free software; you can redistribute it and/or modify it 17 * under the terms of the GNU General Public License as published by the 18 * Free Software Foundation; either version 2 of the License, or (at your 19 * option) any later version. 20 * 21 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 24 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * You should have received a copy of the GNU General Public License along 33 * with this program; if not, write to the Free Software Foundation, Inc., 34 * 675 Mass Ave, Cambridge, MA 02139, USA. 35 */ 36#include <linux/types.h> 37#include <linux/pci.h> 38#include <linux/kernel.h> 39#include <linux/init.h> 40 41#include <asm/addrspace.h> 42#include <asm/jmr3927/jmr3927.h> 43#include <asm/debug.h> 44 45static inline int mkaddr(unsigned char bus, unsigned char dev_fn, 46 unsigned char where) 47{ 48 if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0)) 49 return PCIBIOS_DEVICE_NOT_FOUND; 50 51 tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) | 52 ((dev_fn & 0xff) << 0x08) | 53 (where & 0xfc); 54 55 /* clear M_ABORT and Disable M_ABORT Int. */ 56 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; 57 tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT; 58 59 return PCIBIOS_SUCCESSFUL; 60} 61 62static inline int check_abort(void) 63{ 64 if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) 65 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; 66 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; 67 return PCIBIOS_DEVICE_NOT_FOUND; 68 69 return PCIBIOS_SUCCESSFUL; 70} 71 72static int jmr3927_pci_read_config(struct pci_bus *bus, unsigned int devfn, 73 int where, int size, u32 * val) 74{ 75 int ret, busno; 76 77 /* check if the bus is top-level */ 78 if (bus->parent != NULL) 79 busno = bus->number; 80 81 ret = mkaddr(busno, devfn, where); 82 if (ret) 83 return ret; 84 85 switch (size) { 86 case 1: 87 *val = *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)); 88 break; 89 90 case 2: 91 *val = le16_to_cpu(*(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3))); 92 break; 93 94 case 4: 95 *val = le32_to_cpu(tx3927_pcicptr->icd); 96 break; 97 } 98 99 return check_abort(); 100} 101 102static int jmr3927_pci_write_config(struct pci_bus *bus, unsigned int devfn, 103 int where, int size, u32 val) 104{ 105 int ret, busno; 106 107 /* check if the bus is top-level */ 108 if (bus->parent != NULL) 109 bus = bus->number; 110 else 111 bus = 0; 112 113 ret = mkaddr(busno, devfn, where); 114 if (ret) 115 return ret; 116 117 switch (size) { 118 case 1: 119 *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)) = val; 120 break; 121 122 case 2: 123 *(volatile u16 *) (unsigned longulong) & tx3927_pcicptr->icd | (where & 2)) = 124 cpu_to_le16(val); 125 break; 126 127 case 4: 128 tx3927_pcicptr->icd = cpu_to_le32(val); 129 } 130 131 if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) 132 tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; 133 tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; 134 return PCIBIOS_DEVICE_NOT_FOUND; 135 136 return check_abort(); 137} 138 139struct pci_ops jmr3927_pci_ops = { 140 jmr3927_pcibios_read_config, 141 jmr3927_pcibios_write_config, 142}; 143 144 145#ifndef JMR3927_INIT_INDIRECT_PCI 146 147inline unsigned long tc_readl(volatile __u32 * addr) 148{ 149 return readl(addr); 150} 151 152inline void tc_writel(unsigned long data, volatile __u32 * addr) 153{ 154 writel(data, addr); 155} 156#else 157 158unsigned long tc_readl(volatile __u32 * addr) 159{ 160 unsigned long val; 161 162 addr = PHYSADDR(addr); 163 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 164 (unsigned long) addr; 165 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 166 (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | 167 PCI_IPCIBE_IBE_LONG; 168 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 169 val = 170 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> 171 ipcidata); 172 /* clear by setting */ 173 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 174 return val; 175} 176 177void tc_writel(unsigned long data, volatile __u32 * addr) 178{ 179 addr = PHYSADDR(addr); 180 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = 181 cpu_to_le32(data); 182 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 183 (unsigned long) addr; 184 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 185 (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) | 186 PCI_IPCIBE_IBE_LONG; 187 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 188 /* clear by setting */ 189 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 190} 191 192unsigned char tx_ioinb(unsigned char *addr) 193{ 194 unsigned long val; 195 __u32 ioaddr; 196 int offset; 197 int byte; 198 199 ioaddr = (unsigned long) addr; 200 offset = ioaddr & 0x3; 201 if (offset == 0) 202 byte = 0x7; 203 else if (offset == 1) 204 byte = 0xb; 205 else if (offset == 2) 206 byte = 0xd; 207 else if (offset == 3) 208 byte = 0xe; 209 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 210 (unsigned long) ioaddr; 211 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 212 (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; 213 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 214 val = 215 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> 216 ipcidata); 217 val = val & 0xff; 218 /* clear by setting */ 219 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 220 return val; 221} 222 223void tx_iooutb(unsigned long data, unsigned char *addr) 224{ 225 __u32 ioaddr; 226 int offset; 227 int byte; 228 229 data = data | (data << 8) | (data << 16) | (data << 24); 230 ioaddr = (unsigned long) addr; 231 offset = ioaddr & 0x3; 232 if (offset == 0) 233 byte = 0x7; 234 else if (offset == 1) 235 byte = 0xb; 236 else if (offset == 2) 237 byte = 0xd; 238 else if (offset == 3) 239 byte = 0xe; 240 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data; 241 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 242 (unsigned long) ioaddr; 243 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 244 (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; 245 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 246 /* clear by setting */ 247 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 248} 249 250unsigned short tx_ioinw(unsigned short *addr) 251{ 252 unsigned long val; 253 __u32 ioaddr; 254 int offset; 255 int byte; 256 257 ioaddr = (unsigned long) addr; 258 offset = ioaddr & 0x3; 259 if (offset == 0) 260 byte = 0x3; 261 else if (offset == 2) 262 byte = 0xc; 263 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 264 (unsigned long) ioaddr; 265 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 266 (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; 267 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 268 val = 269 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> 270 ipcidata); 271 val = val & 0xffff; 272 /* clear by setting */ 273 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 274 return val; 275 276} 277 278void tx_iooutw(unsigned long data, unsigned short *addr) 279{ 280 __u32 ioaddr; 281 int offset; 282 int byte; 283 284 data = data | (data << 16); 285 ioaddr = (unsigned long) addr; 286 offset = ioaddr & 0x3; 287 if (offset == 0) 288 byte = 0x3; 289 else if (offset == 2) 290 byte = 0xc; 291 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data; 292 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 293 (unsigned long) ioaddr; 294 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 295 (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; 296 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 297 /* clear by setting */ 298 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 299} 300 301unsigned long tx_ioinl(unsigned int *addr) 302{ 303 unsigned long val; 304 __u32 ioaddr; 305 306 ioaddr = (unsigned long) addr; 307 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 308 (unsigned long) ioaddr; 309 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 310 (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | 311 PCI_IPCIBE_IBE_LONG; 312 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 313 val = 314 le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> 315 ipcidata); 316 /* clear by setting */ 317 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 318 return val; 319} 320 321void tx_iooutl(unsigned long data, unsigned int *addr) 322{ 323 __u32 ioaddr; 324 325 ioaddr = (unsigned long) addr; 326 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = 327 cpu_to_le32(data); 328 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = 329 (unsigned long) ioaddr; 330 *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = 331 (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | 332 PCI_IPCIBE_IBE_LONG; 333 while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); 334 /* clear by setting */ 335 tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; 336} 337 338void tx_insbyte(unsigned char *addr, void *buffer, unsigned int count) 339{ 340 unsigned char *ptr = (unsigned char *) buffer; 341 342 while (count--) { 343 *ptr++ = tx_ioinb(addr); 344 } 345} 346 347void tx_insword(unsigned short *addr, void *buffer, unsigned int count) 348{ 349 unsigned short *ptr = (unsigned short *) buffer; 350 351 while (count--) { 352 *ptr++ = tx_ioinw(addr); 353 } 354} 355 356void tx_inslong(unsigned int *addr, void *buffer, unsigned int count) 357{ 358 unsigned long *ptr = (unsigned long *) buffer; 359 360 while (count--) { 361 *ptr++ = tx_ioinl(addr); 362 } 363} 364 365void tx_outsbyte(unsigned char *addr, void *buffer, unsigned int count) 366{ 367 unsigned char *ptr = (unsigned char *) buffer; 368 369 while (count--) { 370 tx_iooutb(*ptr++, addr); 371 } 372} 373 374void tx_outsword(unsigned short *addr, void *buffer, unsigned int count) 375{ 376 unsigned short *ptr = (unsigned short *) buffer; 377 378 while (count--) { 379 tx_iooutw(*ptr++, addr); 380 } 381} 382 383void tx_outslong(unsigned int *addr, void *buffer, unsigned int count) 384{ 385 unsigned long *ptr = (unsigned long *) buffer; 386 387 while (count--) { 388 tx_iooutl(*ptr++, addr); 389 } 390} 391#endif