/* * arch/arm/mach-ks8695/pci.c * * Copyright (C) 2003, Micrel Semiconductors * Copyright (C) 2006, Greg Ungerer * Copyright (C) 2006, Ben Dooks * Copyright (C) 2007, Andrew Victor * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include static int pci_dbg; static int pci_cfg_dbg; static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where) { unsigned long pbca; pbca = PBCA_ENABLE | (where & ~3); pbca |= PCI_SLOT(devfn) << 11 ; pbca |= PCI_FUNC(devfn) << 8; pbca |= bus_nr << 16; if (bus_nr == 0) { /* use Type-0 transaction */ __raw_writel(pbca, KS8695_PCI_VA + KS8695_PBCA); } else { /* use Type-1 transaction */ __raw_writel(pbca | PBCA_TYPE1, KS8695_PCI_VA + KS8695_PBCA); } } /* * The KS8695 datasheet prohibits anything other than 32bit accesses * to the IO registers, so all our configuration must be done with * 32bit operations, and the correct bit masking and shifting. */ static int ks8695_pci_readconfig(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { ks8695_pci_setupconfig(bus->number, devfn, where); *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD); switch (size) { case 4: break; case 2: *value = *value >> ((where & 2) * 8); *value &= 0xffff; break; case 1: *value = *value >> ((where & 3) * 8); *value &= 0xff; break; } if (pci_cfg_dbg) { printk("read: %d,%08x,%02x,%d: %08x (%08x)\n", bus->number, devfn, where, size, *value, __raw_readl(KS8695_PCI_VA + KS8695_PBCD)); } return PCIBIOS_SUCCESSFUL; } static int ks8695_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { unsigned long tmp; if (pci_cfg_dbg) { printk("write: %d,%08x,%02x,%d: %08x\n", bus->number, devfn, where, size, value); } ks8695_pci_setupconfig(bus->number, devfn, where); switch (size) { case 4: __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD); break;