/*
* iop13xx PCI support
* Copyright (c) 2005-2006, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 <linux/pci.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/export.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <asm/sizes.h>
#include <asm/signal.h>
#include <asm/mach/pci.h>
#include <mach/pci.h>
#define IOP13XX_PCI_DEBUG 0
#define PRINTK(x...) ((void)(IOP13XX_PCI_DEBUG && printk(x)))
u32 iop13xx_atux_pmmr_offset; /* This offset can change based on strapping */
u32 iop13xx_atue_pmmr_offset; /* This offset can change based on strapping */
static struct pci_bus *pci_bus_atux = 0;
static struct pci_bus *pci_bus_atue = 0;
u32 iop13xx_atue_mem_base;
u32 iop13xx_atux_mem_base;
size_t iop13xx_atue_mem_size;
size_t iop13xx_atux_mem_size;
EXPORT_SYMBOL(iop13xx_atue_mem_base);
EXPORT_SYMBOL(iop13xx_atux_mem_base);
EXPORT_SYMBOL(iop13xx_atue_mem_size);
EXPORT_SYMBOL(iop13xx_atux_mem_size);
int init_atu = 0; /* Flag to select which ATU(s) to initialize / disable */
static unsigned long atux_trhfa_timeout = 0; /* Trhfa = RST# high to first
access */
/* Scan the initialized busses and ioremap the requested memory range
*/
void iop13xx_map_pci_memory(void)
{
int atu;
struct pci_bus *bus;
struct pci_dev *dev;
resource_size_t end = 0;
for (atu = 0; atu < 2; atu++) {
bus = atu ? pci_bus_atue : pci_bus_atux;
if (bus) {
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
int max = 7;
if (dev->subordinate)
max = DEVICE_COUNT_RESOURCE;
for (i = 0; i < max; i++) {
struct resource *res = &dev->resource[i];
if (res->flags & IORESOURCE_MEM)
end = max(res->end, end);
}
}
switch(atu) {
case 0:
iop13xx_atux_mem_size =
(end - IOP13XX_PCIX_LOWER_MEM_RA) + 1;
/* 16MB align the request */
if (iop13xx_atux_mem_size & (SZ_16M - 1)) {
iop13xx_atux_mem_size &= ~(SZ_16M - 1);
iop13xx_atux_mem_size += SZ_16M;
}
if (end) {
iop13xx_atux_mem_base =
(u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA)
, 0, iop13xx_atux_mem_size, MT_DEVICE);
if (!iop13xx_atux_mem_base) {
printk("%s: atux allocation "
"failed\n", __func__);
BUG();
}
} else
iop13xx_atux_mem_size = 0;
PRINTK("%s: atu: %d bus_size: %d mem_base: %x\n",
__func__, atu, iop13xx_atux_mem_size,
iop13xx_atux_mem_base);
break;
case 1:
iop13xx_atue_mem_size =
(end - IOP13XX_PCIE_LOWER_MEM_RA) + 1;
/* 16MB align the request */
if (iop13xx_atue_mem_size & (SZ_16M - 1)) {
iop13xx_atue_mem_size &= ~(SZ_16M - 1);
iop13xx_atue_mem_size += SZ_16M;
}
if (end) {
iop13xx_atue_mem_base =
(u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA)
, 0, iop13xx_atue_mem_size, MT_DEVICE);
if (!iop13xx_atue_mem_base) {
printk("%s: atue allocation &