/**
* linux/arch/arm/common/pci_wmt.c
*
* Copyright (c) 2008 WonderMedia Technologies, Inc.
*
* 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, see .
*
* WonderMedia Technologies, Inc.
* 10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
*/
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PATA
/*#define SATA*/
#define USB_HOST
#define MAC
/*#define EXT_PCI*/
#ifdef USB_HOST
char enable_ehci_wake = 0;
char enable_uhci0_wake = 0;
char enable_uhci1_wake = 0;
#endif
/* #define CONFIG_PCI_DEBUG */
ulong
PCI_GetConfigRegisterDWORD(
int bus,
int device,
int fctn,
int target
);
void
PCI_SetConfigRegisterDWORD(
int bus,
int device,
int fctn,
int target,
ulong data
);
#ifdef PATA
void init_int_pata(void);
#endif
#ifdef SATA
void init_int_sata(void);
#endif
#ifdef USB_HOST
void init_int_usb(void);
#endif
#ifdef MAC
void init_int_mac(void);
#endif
#ifdef EXT_PCI
void init_ext_pci(void);
#endif
#define CONFIG_CMD(bus, devfn, where) (0x80000000 | ((devfn) << 8) | ((where) & ~3))
static u32 pci_config_ba;
static u32 pci_config_addr;
static u32 pci_config_data;
#define MAX_PCI_DEV 0xC
#define INT_SATA 0
#define INT_PATA 1
#define INT_MAC0 2
#define INT_MAC1 3
#define INT_USB_EHCI 4
#define INT_USB_UHCI 5
#define INT_USB_UHCI2 6
#define EXT_PCI7 7
#define EXT_PCI8 8
#define EXT_PCI9 9
#define EXT_PCIA 0xA
#define EXT_PCIB 0xB
u32 pci_config_mask[MAX_PCI_DEV][8][0x10];
u32 pci_config_shadow[MAX_PCI_DEV][8][0x10];
u32 pci_config_ro[MAX_PCI_DEV][8][0x10];
#ifdef SATA
#define SATA_PCI_CONFIG (BA_SATA+0x100) //0xFE00d100
#endif
static int
wmt_read_config(
struct pci_bus *bus,
unsigned int devfn,
int where,
int size,
u32 *value
)
{
u32 bar, mask, devno, func;
devno = devfn >> 3;
func = devfn & 7;
*value = 0xFFFFFFFF;
#ifndef EXT_PCI
if (devno > 6)
return 0;
#endif
switch (devno) { /* Check the dev number */
/* external PCI devices */
case EXT_PCI7:
case EXT_PCI8:
case EXT_PCI9:
case EXT_PCIA:
case EXT_PCIB:
{
if ((where >= 0x10) && (where < 0x28)) {
switch (size) {
case 1:
bar = (where & ~3)/4;
mask = 0xFF << 8*(where & 3);
*value = pci_config_shadow[devno][func][bar] & mask;
*value = (*value) >> 8*(where & 3);
break;
case 2:
bar = (where & ~3)/4;
mask = 0xFFFF << 8*(where & 2);
*value = pci_config_shadow[devno][func][bar] & mask;
*value = (*value) >> 8*(where & 2);
break;
case 4:
bar = (where & ~3)/4;
mask = 0xFFFFFFFF;
*value = pci_config_shadow[devno][func][bar] & mask;
}
} else {
writel(CONFIG_CMD(bus, devfn, where), pci_config_addr);
switch (size) {
case 1:
*value = readb(pci_config_data + (where&3));
break;
case 2:
*value = readw(pci_config_data + (where&2));
break;
case 4:
*value = readl(pci_config_data);
break;
}
}
}
break;
/* internal PCI devices */
#ifdef SATA
case INT_SATA:
if ((where >= 0xA0) && (where <= 0xAF)) {
switch (size) {
case 1:
*value = inb((SATA_PCI_CONFIG + where));
break;
case 2:
*value = inw((SATA_PCI_CONFIG + (where & ~1)));
break;
case 4:
*value = inl((SATA_PCI_CONFIG + (where & ~3)));
break;
}
break;
}
#endif
case INT_PATA:
case INT_MAC0:
case INT_MAC1:
if (devfn & 7)
break;
switch (size) {
case 1:
if ((where < 0x40)) {
bar = (where & ~3)/4;
mask = 0xFF << 8*(where & 3);
*value = pci_config_shadow[devno][0][bar] & mask;
*value = (*value) >> 8*(where & 3);
} else
*value = 0;
break;
case 2:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFFFF << 8*(where & 2);
*value = pci_config_shadow[devno][0][bar] & mask;
*value = (*value) >> 8*(where & 2);
} else
*value = 0;
break;
case 4:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFFFFFFFF;
*value = pci_config_shadow[devno][0][bar] & mask;
} else
*value = 0;
}
break;
case INT_USB_UHCI:
case INT_USB_UHCI2:
case INT_USB_EHCI:
if (devfn & 7)
break;
switch (size) {
case 1:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFF << 8*(where & 3);
*value = pci_config_shadow[devno][0][bar] & mask;
*value = (*value) >> 8*(where & 3);
} else {
// *value = 0;
#if 1
if (enable_ehci_wake) {
if (devno == INT_USB_EHCI)
*value = * (volatile unsigned char *)(0xfe007800 + where);
else if (devno == INT_USB_UHCI)
*value = * (volatile unsigned char *)(0xfe007a00 + where);
else if (devno == INT_USB_UHCI2)
*value = * (volatile unsigned char *)(0xfe008c00 + where);
else
*value = 0;
}
else
*value = 0;
#endif
}
break;
case 2:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFFFF << 8*(where & 2);
*value = pci_config_shadow[devno][0][bar] & mask;
*value = (*value) >> 8*(where & 2);
} else if (where == 0x84) {
if ((devno == INT_USB_UHCI)||(devno == INT_USB_UHCI2)) {
bar = pci_config_shadow[devno][0][8];
bar &= ~0x1;
} else
bar = pci_config_shadow[devno][0][4];
bar = bar - 0x100;
/*CharlesTu,2011.02.16,modify ehci pci base address to vertual address 0xfe007800*/
if (devno == INT_USB_EHCI)
bar = bar + WMT_MMAP_OFFSET;
*value = * (volatile unsigned short *)(bar + where);
}else {
// *value = 0;
#if 1
if (enable_ehci_wake) {
if (devno == INT_USB_EHCI)
*value = * (volatile unsigned short *)(0xfe007800 + where);
else if (devno == INT_USB_UHCI)
*value = * (volatile unsigned short *)(0xfe007a00 + where);
else if (devno == INT_USB_UHCI2)
*value = * (volatile unsigned short *)(0xfe008c00 + where);
else
*value = 0;
}
else
*value = 0;
#endif
}
break;
case 4:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFFFFFFFF;
*value = pci_config_shadow[devno][0][bar] & mask;
} else {
// *value = 0;
#if 1
if (enable_ehci_wake) {
if (devno == INT_USB_EHCI)
*value = * (volatile unsigned int *)(0xfe007800 + where);
else if (devno == INT_USB_UHCI)
*value = * (volatile unsigned int *)(0xfe007a00 + where);
else if (devno == INT_USB_UHCI2)
*value = * (volatile unsigned int *)(0xfe008c00 + where);
else
*value = 0;
}
else
*value = 0;
#endif
}
}
default:
break;
}
#ifdef CONFIG_PCI_DEBUG
if (size == 1)
printk("pci config read(B):dev:0x%02X fn:0x%02X where:0x%02X-> 0x%08X\n",
devfn>>3,
devfn&7,
where,
*value
);
else if (size == 2)
printk("pci config read(W):dev:0x%02X fn:0x%02X where:0x%02X-> 0x%08X\n",
devfn>>3,
devfn&7,
where,
*value
);
else
printk("pci config read(L):dev:0x%02X fn:0x%02X where:0x%02X-> 0x%08X\n",
devfn>>3,
devfn&7,
where,
*value
);
#endif /* CONFIG_PCI_DEBUG */
return PCIBIOS_SUCCESSFUL;
}
static int
wmt_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 value)
{
u32 bar, mask, devno, func;
devno = devfn >> 3;
func = devfn & 7;
switch (devno) { /* Check the dev number */
/* external PCI devices */
case EXT_PCI7:
case EXT_PCI8:
case EXT_PCI9:
case EXT_PCIA:
case EXT_PCIB:
{
if ((where >= 0x10) && (where < 0x28)) {
switch (size) {
case 1:
if (where < 0x40) {
bar = (where & ~3)/4;
value = value << 8*(where & 3);
mask = 0xFF << 8*(where & 3);
/* clear the written byte content */
pci_config_shadow[devno][func][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][func][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][func][bar] &= pci_config_mask[devno][func][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][func][bar] |= pci_config_ro[devno][func][bar];
}
break;
case 2:
if (where < 0x40) {
bar = (where & ~3)/4;
value = value << 8*(where & 2);
mask = 0xFFFF << 8*(where & 2);
/* clear the written byte content */
pci_config_shadow[devno][func][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][func][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][func][bar] &= pci_config_mask[devno][func][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][func][bar] |= pci_config_ro[devno][func][bar];
}
break;
case 4:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFFFFFFFF;
/* clear the written byte content */
pci_config_shadow[devno][func][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][func][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][func][bar] &= pci_config_mask[devno][func][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][func][bar] |= pci_config_ro[devno][func][bar];
}
break;
}
} else {
writel(CONFIG_CMD(bus, devfn, where), pci_config_addr);
switch (size) {
case 1:
outb(value, pci_config_data + (where&3));
break;
case 2:
outw(value, pci_config_data + (where&2));
break;
case 4:
outl(value, pci_config_data);
break;
}
}
break;
}
break;
/* internal PCI devices */
#ifdef SATA
case INT_SATA:
if ((where >= 0xA0) && (where <= 0xAF)) {
switch (size) {
case 1:
outb(value, SATA_PCI_CONFIG + where);
break;
case 2:
outw(value, SATA_PCI_CONFIG + (where & ~1));
break;
case 4:
outl(value, SATA_PCI_CONFIG + (where & ~3));
break;
}
break;
}
#endif
case INT_PATA:
case INT_MAC0:
case INT_MAC1:
if (devfn & 7)
break;
switch (size) {
case 1:
if (where < 0x40) {
bar = (where & ~3)/4;
value = value << 8*(where & 3);
mask = 0xFF << 8*(where & 3);
/* clear the written byte content */
pci_config_shadow[devno][0][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][0][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][0][bar] &= pci_config_mask[devno][0][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][0][bar] |= pci_config_ro[devno][0][bar];
}
break;
case 2:
if (where < 0x40) {
bar = (where & ~3)/4;
value = value << 8*(where & 2);
mask = 0xFFFF << 8*(where & 2);
/* clear the written byte content */
pci_config_shadow[devno][0][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][0][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][0][bar] &= pci_config_mask[devno][0][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][0][bar] |= pci_config_ro[devno][0][bar];
}
break;
case 4:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFFFFFFFF;
/* clear the written byte content */
pci_config_shadow[devno][0][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][0][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][0][bar] &= pci_config_mask[devno][0][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][0][bar] |= pci_config_ro[devno][0][bar];
}
break;
}
break;
case INT_USB_UHCI:
case INT_USB_UHCI2:
case INT_USB_EHCI:
if (devfn & 7)
break;
switch (size) {
case 1:
if (where < 0x40) {
bar = (where & ~3)/4;
value = value << 8*(where & 3);
mask = 0xFF << 8*(where & 3);
/* clear the written byte content */
pci_config_shadow[devno][0][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][0][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][0][bar] &= pci_config_mask[devno][0][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][0][bar] |= pci_config_ro[devno][0][bar];
}
break;
case 2:
if (where < 0x40) {
bar = (where & ~3)/4;
value = value << 8*(where & 2);
mask = 0xFFFF << 8*(where & 2);
/* clear the written byte content */
pci_config_shadow[devno][0][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][0][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][0][bar] &= pci_config_mask[devno][0][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][0][bar] |= pci_config_ro[devno][0][bar];
} else if (where == 0x84) {
if ((devno == INT_USB_UHCI)||(devno == INT_USB_UHCI2)) {
bar = pci_config_shadow[devno][0][8];
bar &= ~0x1;
} else
bar = pci_config_shadow[devno][0][4];
bar = bar - 0x100;
/*CharlesTu,2011.02.16,modify ehci pci base address to vertual address 0xfe007800*/
if (devno == INT_USB_EHCI)
bar = bar + WMT_MMAP_OFFSET;
* (volatile unsigned short *)(bar + where) = value;
}
else if (where < 0xC0) {
if (devno == INT_USB_UHCI){
* (volatile unsigned short *)(0xfe007a00 + where) = value;
printk("****gri INT_USB_UHCI1 pci w =%x %x %x\n",size,where,value);
}
else if (devno == INT_USB_UHCI2){
* (volatile unsigned short *)(0xfe008c00 + where) = value;
printk("****gri INT_USB_UHCI2 pci w =%x %x %x\n",size,where,value);
}
else{
* (volatile unsigned short *)(0xfe007800 + where) = value;
printk("****gri INT_USB_EHCI pci w =%x %x %x\n",size,where,value);
}
}
break;
case 4:
if (where < 0x40) {
bar = (where & ~3)/4;
mask = 0xFFFFFFFF;
/* clear the written byte content */
pci_config_shadow[devno][0][bar] &= ~mask;
/* set the written byte content */
pci_config_shadow[devno][0][bar] |= (value & mask);
/* only writing the bits which are writable and which is checked
by the pci_config_mask[][] */
pci_config_shadow[devno][0][bar] &= pci_config_mask[devno][0][bar];
/* set the read only bits which may be clear when written. */
pci_config_shadow[devno][0][bar] |= pci_config_ro[devno][0][bar];
}
else if (where < 0xC0) {
if (devno == INT_USB_UHCI){
* (volatile unsigned int *)(0xfe007a00 + where) = value;
printk("****gri INT_USB_UHCI1 pci w =%x %x %x\n",size,where,value);
}
else if (devno == INT_USB_UHCI2){
* (volatile unsigned int *)(0xfe008c00 + where) = value;
printk("****gri INT_USB_UHCI2 pci w =%x %x %x\n",size,where,value);
}
else{
* (volatile unsigned int *)(0xfe007800 + where) = value;
printk("****gri INT_USB_EHCI pci w =%x %x %x\n",size,where,value);
}
}
break;
}
break;
default:
break;
}
#ifdef CONFIG_PCI_DEBUG
if (size == 1)
printk("pci config write(B):dev:0x%02X fn:0x%02X where:0x%02X-> 0x%08X\n",
devfn>>3,
devfn&7,
where,
value
);
else if (size == 2)
printk("pci config write(W):dev:0x%02X fn:0x%02X where:0x%02X-> 0x%08X\n",
devfn>>3,
devfn&7,
where,
value
);
else
printk("pci config write(L):dev:0x%02X fn:0x%02X where:0x%02X-> 0x%08X\n",
devfn>>3,
devfn&7,
where,
value
);
#endif /* CONFIG_PCI_DEBUG */
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops wmt_pci_ops = {
.read = wmt_read_config,
.write = wmt_write_config,
};
#ifdef PATA
void init_int_pata(void)
{
if (0) {
/* if (ARCH_VT8430) */
pci_config_shadow[INT_PATA][0][0] = 0x13571106;
pci_config_shadow[INT_PATA][0][1] = 0x02100005;
/* {JHTseng 2007/03/02 Change the Byte1 from 8A into 8F,
Otherwise, the resource will be clear by the kernel */
pci_config_shadow[INT_PATA][0][2] = 0x01018F00;
pci_config_shadow[INT_PATA][0][3] = 0x00002000;
/* Mark 2007/03/12 Modify PCI BAR address, PATA's SG register
base address from Secondary to Primary */
//pci_config_shadow[INT_PATA][0][4] = 0xD8008271;
pci_config_shadow[INT_PATA][0][4] = 0xFE008271;
//pci_config_shadow[INT_PATA][0][5] = 0xD8008375;
pci_config_shadow[INT_PATA][0][5] = 0xFE008375;
pci_config_shadow[INT_PATA][0][6] = 0x0;
pci_config_shadow[INT_PATA][0][7] = 0x0;
//pci_config_shadow[INT_PATA][0][8] = 0xD8008509;
pci_config_shadow[INT_PATA][0][8] = 0xFE008509;
pci_config_shadow[INT_PATA][0][9] = 0x0;
pci_config_shadow[INT_PATA][0][0xA] = 0x0;
pci_config_shadow[INT_PATA][0][0xB] = 0x05811106;
pci_config_shadow[INT_PATA][0][0xC] = 0x0;
pci_config_shadow[INT_PATA][0][0xD] = 0x0;
pci_config_shadow[INT_PATA][0][0xE] = 0x0;
pci_config_shadow[INT_PATA][0][0xF] = 0x0103;
pci_config_mask[INT_PATA][0][0] = 0x0;
pci_config_mask[INT_PATA][0][1] = 0x0;
pci_config_mask[INT_PATA][0][2] = 0x0;
pci_config_mask[INT_PATA][0][3] = 0x0;
pci_config_mask[INT_PATA][0][4] = 0xFFFFFFF8;
pci_config_mask[INT_PATA][0][5] = 0xFFFFFFFC;
pci_config_mask[INT_PATA][0][6] = 0x0;
pci_config_mask[INT_PATA][0][7] = 0x0;
pci_config_mask[INT_PATA][0][8] = 0xFFFFFFF0;
pci_config_mask[INT_PATA][0][9] = 0x0;
pci_config_mask[INT_PATA][0][0xA] = 0x0;
pci_config_mask[INT_PATA][0][0xB] = 0x0;
pci_config_mask[INT_PATA][0][0xC] = 0x0;
pci_config_mask[INT_PATA][0][0xD] = 0x0;
pci_config_mask[INT_PATA][0][0xE] = 0x0;
pci_config_mask[INT_PATA][0][0xF] = 0x0;
pci_config_ro[INT_PATA][0][0] = 0x13591106;
pci_config_ro[INT_PATA][0][1] = 0x02100005;
pci_config_ro[INT_PATA][0][2] = 0x01018A00;
pci_config_ro[INT_PATA][0][3] = 0x00002000;
pci_config_ro[INT_PATA][0][4] = 0x1;
pci_config_ro[INT_PATA][0][5] = 0x1;
pci_config_ro[INT_PATA][0][6] = 0x0;
pci_config_ro[INT_PATA][0][7] = 0x0;
pci_config_ro[INT_PATA][0][8] = 0x1;
pci_config_ro[INT_PATA][0][9] = 0x0;
pci_config_ro[INT_PATA][0][0xA] = 0x0;
pci_config_ro[INT_PATA][0][0xB] = 0x05811106;
pci_config_ro[INT_PATA][0][0xC] = 0x0;
pci_config_ro[INT_PATA][0][0xD] = 0x0;
pci_config_ro[INT_PATA][0][0xE] = 0x0;
pci_config_ro[INT_PATA][0][0xF] = 0x0103;
} else {
pci_config_shadow[INT_PATA][0][0] = 0x13591106;
pci_config_shadow[INT_PATA][0][1] = 0x02000005;
/* {JHTseng 2007/03/02 Change the Byte1 from 8A into 8F,
Otherwise, the resource will be clear by the kernel */
pci_config_shadow[INT_PATA][0][2] = 0x01018F00;
pci_config_shadow[INT_PATA][0][3] = 0x00000000;/* 0x00002000; */
/* Mark 2007/03/12 Modify PCI BAR address, PATA's SG register
base address from Secondary to Primary */
//pci_config_shadow[INT_PATA][0][4] = 0xD8008101;/* 0xD8008271; */
pci_config_shadow[INT_PATA][0][4] = 0xFE008101;/* 0xD8008271; */
//pci_config_shadow[INT_PATA][0][5] = 0xD8008145;/* 0xD8008375; */
pci_config_shadow[INT_PATA][0][5] = 0xFE008145;/* 0xD8008375; */
pci_config_shadow[INT_PATA][0][6] = 0x0;
pci_config_shadow[INT_PATA][0][7] = 0x0;
//pci_config_shadow[INT_PATA][0][8] = 0xD8008181;
pci_config_shadow[INT_PATA][0][8] = 0xFE008181;
pci_config_shadow[INT_PATA][0][9] = 0x0;
pci_config_shadow[INT_PATA][0][0xA] = 0x0;
pci_config_shadow[INT_PATA][0][0xB] = 0x13581106;/* 0x05811106; */
pci_config_shadow[INT_PATA][0][0xC] = 0x0;
pci_config_shadow[INT_PATA][0][0xD] = 0x0;
pci_config_shadow[INT_PATA][0][0xE] = 0x0;
pci_config_shadow[INT_PATA][0][0xF] = 0x0103;
pci_config_mask[INT_PATA][0][0] = 0x0;
pci_config_mask[INT_PATA][0][1] = 0x0;
pci_config_mask[INT_PATA][0][2] = 0x0;
pci_config_mask[INT_PATA][0][3] = 0x0;
pci_config_mask[INT_PATA][0][4] = 0xFFFFFFF8;
pci_config_mask[INT_PATA][0][5] = 0xFFFFFFFC;
pci_config_mask[INT_PATA][0][6] = 0x0;
pci_config_mask[INT_PATA][0][7] = 0x0;
pci_config_mask[INT_PATA][0][8] = 0xFFFFFFF0;
pci_config_mask[INT_PATA][0][9] = 0x0;
pci_config_mask[INT_PATA][0][0xA] = 0x0;
pci_config_mask[INT_PATA][0][0xB] = 0x0;
pci_config_mask[INT_PATA][0][0xC] = 0x0;
pci_config_mask[INT_PATA][0][0xD] = 0x0;
pci_config_mask[INT_PATA][0][0xE] = 0x0;
pci_config_mask[INT_PATA][0][0xF] = 0x0;
pci_config_ro[INT_PATA][0][0] = 0x13591106;
pci_config_ro[INT_PATA][0][1] = 0x02000005;
pci_config_ro[INT_PATA][0][2] = 0x01018A00;
pci_config_ro[INT_PATA][0][3] = 0x00002000;
pci_config_ro[INT_PATA][0][4] = 0x1;
pci_config_ro[INT_PATA][0][5] = 0x1;
pci_config_ro[INT_PATA][0][6] = 0x0;
pci_config_ro[INT_PATA][0][7] = 0x0;
pci_config_ro[INT_PATA][0][8] = 0x1;
pci_config_ro[INT_PATA][0][9] = 0x0;
pci_config_ro[INT_PATA][0][0xA] = 0x0;
pci_config_ro[INT_PATA][0][0xB] = 0x13581106;/* 0x05811106; */
pci_config_ro[INT_PATA][0][0xC] = 0x0;
pci_config_ro[INT_PATA][0][0xD] = 0x0;
pci_config_ro[INT_PATA][0][0xE] = 0x0;
pci_config_ro[INT_PATA][0][0xF] = 0x0103;
}
}
#endif
#ifdef SATA
void init_int_sata(void)
{
pci_config_shadow[INT_SATA][0][0] = 0x23591106;
pci_config_shadow[INT_SATA][0][1] = 0x02900007;
pci_config_shadow[INT_SATA][0][2] = 0x01018f00;
pci_config_shadow[INT_SATA][0][3] = 0x00001000;
//pci_config_shadow[INT_SATA][0][4] = 0xd800d2f1;
pci_config_shadow[INT_SATA][0][4] = 0xFE00d2f1;
//pci_config_shadow[INT_SATA][0][5] = 0xd800d3f5;
pci_config_shadow[INT_SATA][0][5] = 0xFE00d3f5;
pci_config_shadow[INT_SATA][0][6] = 0x0;
pci_config_shadow[INT_SATA][0][7] = 0x0;
//pci_config_shadow[INT_SATA][0][8] = 0xd800d401;
pci_config_shadow[INT_SATA][0][8] = 0xFE00d401;
pci_config_shadow[INT_SATA][0][9] = 0x0;
pci_config_shadow[INT_SATA][0][0xA] = 0x0;
pci_config_shadow[INT_SATA][0][0xB] = 0x23591106;
pci_config_shadow[INT_SATA][0][0xC] = 0x0;
pci_config_shadow[INT_SATA][0][0xD] = 0x0;
pci_config_shadow[INT_SATA][0][0xE] = 0x0;
pci_config_shadow[INT_SATA][0][0xF] = 0x0104;
pci_config_mask[INT_SATA][0][0] = 0x0;
pci_config_mask[INT_SATA][0][1] = 0x00000477;
pci_config_mask[INT_SATA][0][2] = 0x500;
pci_config_mask[INT_SATA][0][3] = 0x0000F000;
pci_config_mask[INT_SATA][0][4] = 0xFFFFFFF8;
pci_config_mask[INT_SATA][0][5] = 0xFFFFFFFC;
pci_config_mask[INT_SATA][0][6] = 0x0;
pci_config_mask[INT_SATA][0][7] = 0x0;
pci_config_mask[INT_SATA][0][8] = 0xFFFFFFF0;
pci_config_mask[INT_SATA][0][9] = 0x0;
pci_config_mask[INT_SATA][0][0xA] = 0x0;
pci_config_mask[INT_SATA][0][0xB] = 0x0;
pci_config_mask[INT_SATA][0][0xC] = 0x0;
pci_config_mask[INT_SATA][0][0xD] = 0x0;
pci_config_mask[INT_SATA][0][0xE] = 0x0;
pci_config_mask[INT_SATA][0][0xF] = 0x0;
pci_config_ro[INT_SATA][0][0] = 0x23591106;
pci_config_ro[INT_SATA][0][1] = 0x02900000;
pci_config_ro[INT_SATA][0][2] = 0x01018A00;
pci_config_ro[INT_SATA][0][3] = 0x0;
pci_config_ro[INT_SATA][0][4] = 0x1;
pci_config_ro[INT_SATA][0][5] = 0x1;
pci_config_ro[INT_SATA][0][6] = 0x0;
pci_config_ro[INT_SATA][0][7] = 0x0;
pci_config_ro[INT_SATA][0][8] = 0x1;
pci_config_ro[INT_SATA][0][9] = 0x0;
pci_config_ro[INT_SATA][0][0xA] = 0x0;
pci_config_ro[INT_SATA][0][0xB] = 0x23591106;
pci_config_ro[INT_SATA][0][0xC] = 0x0;
pci_config_ro[INT_SATA][0][0xD] = 0x0;
pci_config_ro[INT_SATA][0][0xE] = 0x0;
pci_config_ro[INT_SATA][0][0xF] = 0x0104;
}
#endif
#ifdef USB_HOST
void init_int_usb(void)
{
/* EHCI */
pci_config_shadow[INT_USB_EHCI][0][0] = 0x31041106;
pci_config_shadow[INT_USB_EHCI][0][1] = 0x02100000;
pci_config_shadow[INT_USB_EHCI][0][2] = 0x0C032090;
pci_config_shadow[INT_USB_EHCI][0][3] = 0x00801600;
pci_config_shadow[INT_USB_EHCI][0][4] = 0xD8007900; /* phy 0xD8007900; */
pci_config_shadow[INT_USB_EHCI][0][5] = 0x00000000;
pci_config_shadow[INT_USB_EHCI][0][6] = 0x0;
pci_config_shadow[INT_USB_EHCI][0][7] = 0x0;
pci_config_shadow[INT_USB_EHCI][0][8] = 0x00000000;
pci_config_shadow[INT_USB_EHCI][0][9] = 0x0;
pci_config_shadow[INT_USB_EHCI][0][0xA] = 0x0;
pci_config_shadow[INT_USB_EHCI][0][0xB] = 0x31041106;
pci_config_shadow[INT_USB_EHCI][0][0xC] = 0x0;
pci_config_shadow[INT_USB_EHCI][0][0xD] = 0x0;
pci_config_shadow[INT_USB_EHCI][0][0xE] = 0x0;
// pci_config_shadow[INT_USB_EHCI][0][0xF] = 0x041A; /* 0x041A; for WM3445 */
pci_config_shadow[INT_USB_EHCI][0][0xF] = 0x043A; /* 0x041A; for WM3445 */
pci_config_mask[INT_USB_EHCI][0][0] = 0x0;
pci_config_mask[INT_USB_EHCI][0][1] = 0x00000477;
pci_config_mask[INT_USB_EHCI][0][2] = 0x00000000;
pci_config_mask[INT_USB_EHCI][0][3] = 0x0000FFFF;
pci_config_mask[INT_USB_EHCI][0][4] = 0xFFFFFF00;
pci_config_mask[INT_USB_EHCI][0][5] = 0x0;
pci_config_mask[INT_USB_EHCI][0][6] = 0x0;
pci_config_mask[INT_USB_EHCI][0][7] = 0x0;
pci_config_mask[INT_USB_EHCI][0][8] = 0x0;
pci_config_mask[INT_USB_EHCI][0][9] = 0x0;
pci_config_mask[INT_USB_EHCI][0][0xA] = 0x0;
pci_config_mask[INT_USB_EHCI][0][0xB] = 0x0;
pci_config_mask[INT_USB_EHCI][0][0xC] = 0x0;
pci_config_mask[INT_USB_EHCI][0][0xD] = 0x0;
pci_config_mask[INT_USB_EHCI][0][0xE] = 0x0;
pci_config_mask[INT_USB_EHCI][0][0xF] = 0xFF;
pci_config_ro[INT_USB_EHCI][0][0] = 0x31041106;
pci_config_ro[INT_USB_EHCI][0][1] = 0x02100000;
pci_config_ro[INT_USB_EHCI][0][2] = 0x0C032090;
pci_config_ro[INT_USB_EHCI][0][3] = 0x00800000;
pci_config_ro[INT_USB_EHCI][0][4] = 0x0;
pci_config_ro[INT_USB_EHCI][0][5] = 0x0;
pci_config_ro[INT_USB_EHCI][0][6] = 0x0;
pci_config_ro[INT_USB_EHCI][0][7] = 0x0;
pci_config_ro[INT_USB_EHCI][0][8] = 0x0;
pci_config_ro[INT_USB_EHCI][0][9] = 0x0;
pci_config_ro[INT_USB_EHCI][0][0xA] = 0x0;
pci_config_ro[INT_USB_EHCI][0][0xB] = 0x31041106;
pci_config_ro[INT_USB_EHCI][0][0xC] = 0x0;
pci_config_ro[INT_USB_EHCI][0][0xD] = 0x0;
pci_config_ro[INT_USB_EHCI][0][0xE] = 0x0;
pci_config_ro[INT_USB_EHCI][0][0xF] = 0x100;
/* UHCI */
pci_config_shadow[INT_USB_UHCI][0][0] = 0x30381106;
pci_config_shadow[INT_USB_UHCI][0][1] = 0x02100000;
pci_config_shadow[INT_USB_UHCI][0][2] = 0x0C030090;
pci_config_shadow[INT_USB_UHCI][0][3] = 0x00801600;
pci_config_shadow[INT_USB_UHCI][0][4] = 0x00000000;
pci_config_shadow[INT_USB_UHCI][0][5] = 0x00000000;
pci_config_shadow[INT_USB_UHCI][0][6] = 0x0;
pci_config_shadow[INT_USB_UHCI][0][7] = 0x0;
//pci_config_shadow[INT_USB_UHCI][0][8] = 0xD8007B01; /* 0xD8007B01; */
pci_config_shadow[INT_USB_UHCI][0][8] = 0xFE007B01; /* 0xFE007B01; */
pci_config_shadow[INT_USB_UHCI][0][9] = 0x0;
pci_config_shadow[INT_USB_UHCI][0][0xA] = 0x0;
pci_config_shadow[INT_USB_UHCI][0][0xB] = 0x30381106;
pci_config_shadow[INT_USB_UHCI][0][0xC] = 0x0;
pci_config_shadow[INT_USB_UHCI][0][0xD] = 0x0;
pci_config_shadow[INT_USB_UHCI][0][0xE] = 0x0;
// pci_config_shadow[INT_USB_UHCI][0][0xF] = 0x011A; /* 0x01A; for WM3445 uhci */
pci_config_shadow[INT_USB_UHCI][0][0xF] = 0x013A; /* 0x01A; for WM3445 uhci */
pci_config_mask[INT_USB_UHCI][0][0] = 0x0;
pci_config_mask[INT_USB_UHCI][0][1] = 0x00000417;
pci_config_mask[INT_USB_UHCI][0][2] = 0x00000000;
pci_config_mask[INT_USB_UHCI][0][3] = 0x0000FFFF;
pci_config_mask[INT_USB_UHCI][0][4] = 0x00000000;
pci_config_mask[INT_USB_UHCI][0][5] = 0x00000000;
pci_config_mask[INT_USB_UHCI][0][6] = 0x0;
pci_config_mask[INT_USB_UHCI][0][7] = 0x0;
pci_config_mask[INT_USB_UHCI][0][8] = 0xFFFFFFE0;
pci_config_mask[INT_USB_UHCI][0][9] = 0x0;
pci_config_mask[INT_USB_UHCI][0][0xA] = 0x0;
pci_config_mask[INT_USB_UHCI][0][0xB] = 0x0;
pci_config_mask[INT_USB_UHCI][0][0xC] = 0x0;
pci_config_mask[INT_USB_UHCI][0][0xD] = 0x0;
pci_config_mask[INT_USB_UHCI][0][0xE] = 0x0;
pci_config_mask[INT_USB_UHCI][0][0xF] = 0x000000FF;
pci_config_ro[INT_USB_UHCI][0][0] = 0x30381106;
pci_config_ro[INT_USB_UHCI][0][1] = 0x02100000;
pci_config_ro[INT_USB_UHCI][0][2] = 0x0C030090;
pci_config_ro[INT_USB_UHCI][0][3] = 0x00800000;
pci_config_ro[INT_USB_UHCI][0][4] = 0x00000000;
pci_config_ro[INT_USB_UHCI][0][5] = 0x00000000;
pci_config_ro[INT_USB_UHCI][0][6] = 0x0;
pci_config_ro[INT_USB_UHCI][0][7] = 0x0;
pci_config_ro[INT_USB_UHCI][0][8] = 0x1;
pci_config_ro[INT_USB_UHCI][0][9] = 0x0;
pci_config_ro[INT_USB_UHCI][0][0xA] = 0x0;
pci_config_ro[INT_USB_UHCI][0][0xB] = 0x30381106;
pci_config_ro[INT_USB_UHCI][0][0xC] = 0x0;
pci_config_ro[INT_USB_UHCI][0][0xD] = 0x0;
pci_config_ro[INT_USB_UHCI][0][0xE] = 0x0;
pci_config_ro[INT_USB_UHCI][0][0xF] = 0x0100;
/* UHCI2 */
pci_config_shadow[INT_USB_UHCI2][0][0] = 0x30381106;
pci_config_shadow[INT_USB_UHCI2][0][1] = 0x02100000;
pci_config_shadow[INT_USB_UHCI2][0][2] = 0x0C030090;
pci_config_shadow[INT_USB_UHCI2][0][3] = 0x00801600;
pci_config_shadow[INT_USB_UHCI2][0][4] = 0x00000000;
pci_config_shadow[INT_USB_UHCI2][0][5] = 0x00000000;
pci_config_shadow[INT_USB_UHCI2][0][6] = 0x0;
pci_config_shadow[INT_USB_UHCI2][0][7] = 0x0;
//pci_config_shadow[INT_USB_UHCI2][0][8] = 0xD8008D01; /* phy 0xD8008D01; */
pci_config_shadow[INT_USB_UHCI2][0][8] = 0xFE008D01; /* vertual 0xFE008D01; */
pci_config_shadow[INT_USB_UHCI2][0][9] = 0x0;
pci_config_shadow[INT_USB_UHCI2][0][0xA] = 0x0;
pci_config_shadow[INT_USB_UHCI2][0][0xB] = 0x30381106;
pci_config_shadow[INT_USB_UHCI2][0][0xC] = 0x0;
pci_config_shadow[INT_USB_UHCI2][0][0xD] = 0x0;
pci_config_shadow[INT_USB_UHCI2][0][0xE] = 0x0;
// pci_config_shadow[INT_USB_UHCI2][0][0xF] = 0x011A; /* 0x011A; for WM3445 uhci */
pci_config_shadow[INT_USB_UHCI2][0][0xF] = 0x013A; /* 0x011A; for WM3445 uhci */
pci_config_mask[INT_USB_UHCI2][0][0] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][1] = 0x00000417;
pci_config_mask[INT_USB_UHCI2][0][2] = 0x00000000;
pci_config_mask[INT_USB_UHCI2][0][3] = 0x0000FFFF;
pci_config_mask[INT_USB_UHCI2][0][4] = 0x00000000;
pci_config_mask[INT_USB_UHCI2][0][5] = 0x00000000;
pci_config_mask[INT_USB_UHCI2][0][6] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][7] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][8] = 0xFFFFFFE0;
pci_config_mask[INT_USB_UHCI2][0][9] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][0xA] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][0xB] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][0xC] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][0xD] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][0xE] = 0x0;
pci_config_mask[INT_USB_UHCI2][0][0xF] = 0x000000FF;
pci_config_ro[INT_USB_UHCI2][0][0] = 0x30381106;
pci_config_ro[INT_USB_UHCI2][0][1] = 0x02100000;
pci_config_ro[INT_USB_UHCI2][0][2] = 0x0C030090;
pci_config_ro[INT_USB_UHCI2][0][3] = 0x00800000;
pci_config_ro[INT_USB_UHCI2][0][4] = 0x00000000;
pci_config_ro[INT_USB_UHCI2][0][5] = 0x00000000;
pci_config_ro[INT_USB_UHCI2][0][6] = 0x0;
pci_config_ro[INT_USB_UHCI2][0][7] = 0x0;
pci_config_ro[INT_USB_UHCI2][0][8] = 0x1;
pci_config_ro[INT_USB_UHCI2][0][9] = 0x0;
pci_config_ro[INT_USB_UHCI2][0][0xA] = 0x0;
pci_config_ro[INT_USB_UHCI2][0][0xB] = 0x30381106;
pci_config_ro[INT_USB_UHCI2][0][0xC] = 0x0;
pci_config_ro[INT_USB_UHCI2][0][0xD] = 0x0;
pci_config_ro[INT_USB_UHCI2][0][0xE] = 0x0;
pci_config_ro[INT_USB_UHCI2][0][0xF] = 0x0100;
}
#endif
#ifdef MAC
void init_int_mac(void)
{
pci_config_shadow[INT_MAC0][0][0] = 0x31061106;
pci_config_shadow[INT_MAC0][0][1] = 0x02100017;
pci_config_shadow[INT_MAC0][0][2] = 0x02000084;
pci_config_shadow[INT_MAC0][0][3] = 0x00004004;
//pci_config_shadow[INT_MAC0][0][4] = 0xD8004001;
pci_config_shadow[INT_MAC0][0][4] = 0xFE004001;
pci_config_shadow[INT_MAC0][0][5] = 0xD8004000;
pci_config_shadow[INT_MAC0][0][6] = 0x0;
pci_config_shadow[INT_MAC0][0][7] = 0x0;
pci_config_shadow[INT_MAC0][0][8] = 0x0;
pci_config_shadow[INT_MAC0][0][9] = 0x0;
pci_config_shadow[INT_MAC0][0][0xA] = 0x0;
pci_config_shadow[INT_MAC0][0][0xB] = 0x01061106;
pci_config_shadow[INT_MAC0][0][0xC] = 0x0;
pci_config_shadow[INT_MAC0][0][0xD] = 0x0;
pci_config_shadow[INT_MAC0][0][0xE] = 0x0;
pci_config_shadow[INT_MAC0][0][0xF] = 0x010A;
pci_config_mask[INT_MAC0][0][0] = 0x0;
pci_config_mask[INT_MAC0][0][1] = 0x000003D7;
pci_config_mask[INT_MAC0][0][2] = 0x0;
pci_config_mask[INT_MAC0][0][3] = 0x0000F8FF;
pci_config_mask[INT_MAC0][0][4] = 0xFFFFFF00;
pci_config_mask[INT_MAC0][0][5] = 0xFFFFFF00;
pci_config_mask[INT_MAC0][0][6] = 0x0;
pci_config_mask[INT_MAC0][0][7] = 0x0;
pci_config_mask[INT_MAC0][0][8] = 0x0;
pci_config_mask[INT_MAC0][0][9] = 0x0;
pci_config_mask[INT_MAC0][0][0xA] = 0x0;
pci_config_mask[INT_MAC0][0][0xB] = 0x0;
pci_config_mask[INT_MAC0][0][0xC] = 0x0;
pci_config_mask[INT_MAC0][0][0xD] = 0x0;
pci_config_mask[INT_MAC0][0][0xE] = 0x0;
pci_config_mask[INT_MAC0][0][0xF] = 0xFF;
pci_config_ro[INT_MAC0][0][0] = 0x31061106;
pci_config_ro[INT_MAC0][0][1] = 0x02100000;
pci_config_ro[INT_MAC0][0][2] = 0x0;
pci_config_ro[INT_MAC0][0][3] = 0x0;
pci_config_ro[INT_MAC0][0][4] = 0x1;
pci_config_ro[INT_MAC0][0][5] = 0x0;
pci_config_ro[INT_MAC0][0][6] = 0x0;
pci_config_ro[INT_MAC0][0][7] = 0x0;
pci_config_ro[INT_MAC0][0][8] = 0x0;
pci_config_ro[INT_MAC0][0][9] = 0x0;
pci_config_ro[INT_MAC0][0][0xA] = 0x0;
pci_config_ro[INT_MAC0][0][0xB] = 0x01061106;
pci_config_ro[INT_MAC0][0][0xC] = 0x0;
pci_config_ro[INT_MAC0][0][0xD] = 0x0;
pci_config_ro[INT_MAC0][0][0xE] = 0x0;
pci_config_ro[INT_MAC0][0][0xF] = 0x10;
if (0) {/* !ARCH_VT8430) */
/* MAC1 */
pci_config_shadow[INT_MAC1][0][0] = 0x31061106;
pci_config_shadow[INT_MAC1][0][1] = 0x02100017;
pci_config_shadow[INT_MAC1][0][2] = 0x02000084;
pci_config_shadow[INT_MAC1][0][3] = 0x00004004;
//pci_config_shadow[INT_MAC1][0][4] = 0xD8005001;
pci_config_shadow[INT_MAC1][0][4] = 0xFE005001;
pci_config_shadow[INT_MAC1][0][5] = 0xD8005000;
pci_config_shadow[INT_MAC1][0][6] = 0x0;
pci_config_shadow[INT_MAC1][0][7] = 0x0;
pci_config_shadow[INT_MAC1][0][8] = 0x0;
pci_config_shadow[INT_MAC1][0][9] = 0x0;
pci_config_shadow[INT_MAC1][0][0xA] = 0x0;
pci_config_shadow[INT_MAC1][0][0xB] = 0x01061106;
pci_config_shadow[INT_MAC1][0][0xC] = 0x0;
pci_config_shadow[INT_MAC1][0][0xD] = 0x0;
pci_config_shadow[INT_MAC1][0][0xE] = 0x0;
pci_config_shadow[INT_MAC1][0][0xF] = 0x01011;
pci_config_mask[INT_MAC1][0][0] = 0x0;
pci_config_mask[INT_MAC1][0][1] = 0x000003D7;
pci_config_mask[INT_MAC1][0][2] = 0x0;
pci_config_mask[INT_MAC1][0][3] = 0x0000F8FF;
pci_config_mask[INT_MAC1][0][4] = 0xFFFFFF00;
pci_config_mask[INT_MAC1][0][5] = 0xFFFFFF00;
pci_config_mask[INT_MAC1][0][6] = 0x0;
pci_config_mask[INT_MAC1][0][7] = 0x0;
pci_config_mask[INT_MAC1][0][8] = 0x0;
pci_config_mask[INT_MAC1][0][9] = 0x0;
pci_config_mask[INT_MAC1][0][0xA] = 0x0;
pci_config_mask[INT_MAC1][0][0xB] = 0x0;
pci_config_mask[INT_MAC1][0][0xC] = 0x0;
pci_config_mask[INT_MAC1][0][0xD] = 0x0;
pci_config_mask[INT_MAC1][0][0xE] = 0x0;
pci_config_mask[INT_MAC1][0][0xF] = 0xFF;
pci_config_ro[INT_MAC1][0][0] = 0x31061106;
pci_config_ro[INT_MAC1][0][1] = 0x02100000;
pci_config_ro[INT_MAC1][0][2] = 0x0;
pci_config_ro[INT_MAC1][0][3] = 0x0;
pci_config_ro[INT_MAC1][0][4] = 0x1;
pci_config_ro[INT_MAC1][0][5] = 0x0;
pci_config_ro[INT_MAC1][0][6] = 0x0;
pci_config_ro[INT_MAC1][0][7] = 0x0;
pci_config_ro[INT_MAC1][0][8] = 0x0;
pci_config_ro[INT_MAC1][0][9] = 0x0;
pci_config_ro[INT_MAC1][0][0xA] = 0x0;
pci_config_ro[INT_MAC1][0][0xB] = 0x01061106;
pci_config_ro[INT_MAC1][0][0xC] = 0x0;
pci_config_ro[INT_MAC1][0][0xD] = 0x0;
pci_config_ro[INT_MAC1][0][0xE] = 0x0;
pci_config_ro[INT_MAC1][0][0xF] = 0x10;
}
}
#endif
#ifdef EXT_PCI
void init_ext_pci(void)
{
int i, func, bar, size;
u32 val, ori_val, new_val;
/* windows size is 64KB */
u32 io_base = 0x10000;
/* windows size is 16MB, but according to the architecture spec,
the windows is 64MB. */
u32 mem_base = 0xC2000000;
/* assign resource for I/O, Memory and IRQ */
for (i = EXT_PCI7; i <= EXT_PCIB; i++) {
for (func = 0; func < 8; func++) {
val = PCI_GetConfigRegisterDWORD(0, i, func, 0);
if ((val != 0xFFFFFFFF) && (val != 0x0)) {
/* PCI_INTA connect to IRQ44 */
/* PCI_INTB connect to IRQ45 */
/* PCI_INTC connect to IRQ46 */
/* PCI_INTD connect to IRQ47 */
u8 pci_int[4] = {44, 45, 46, 47};
/* Dev8 PCI_INTA->PCI_INTA,
PCI_INTB->PCI_INTB,
PCI_INTC->PCI_INTC,
PCI_INTD->PCI_INTD */
/* Dev9 PCI_INTA->PCI_INTB, ... */
/* DevA PCI_INTA->PCI_INTC, ... */
/* DevB PCI_INTA->PCI_INTD, ... */
u8 pci_int_rout_table[4][4] =
{ {0, 1, 2, 3}, {1, 2, 3, 0}, {2, 3, 0, 1}, {3, 0, 1, 2} };
/* IRQ routing */
/* Dev8 Dev9 DevA DevB */
/* A B C D */
/* B C D A */
/* C D A B */
/* D A B C */
u8 irq_pin, irq_line;
printk("pci vid&pid = 0x%08X\n", val);
val = PCI_GetConfigRegisterDWORD(0, i, func, 0x3C);
irq_pin = (val & 0xFF00)>>8;
if (irq_pin) {
/* irq_pin = 1->PCI_INTA according to the PCI spec */
irq_pin--;
#ifdef CONFIG_PCI_DEBUG
printk("irq_pin:0x%02X\n", irq_pin);
#endif /* CONFIG_PCI_DEBUG */
irq_line = pci_int[pci_int_rout_table[(i-8)&3][irq_pin]];
#ifdef CONFIG_PCI_DEBUG
printk("irq_line:0x%02X\n", irq_line);
#endif /* CONFIG_PCI_DEBUG */
val = (val & 0xFFFFFF00) | irq_line;
PCI_SetConfigRegisterDWORD(0, i, func, 0x3C, val);
val = PCI_GetConfigRegisterDWORD(0, i, func, 0x3C);
#ifdef CONFIG_PCI_DEBUG
printk("[0x3C = 0x%08X]\n", val);
#endif /* CONFIG_PCI_DEBUG */
}
for (bar = 0; bar < 6; bar++) {
PCI_SetConfigRegisterDWORD(0, i, func, 0x10+bar*4, 0xFFFFFFFF);
new_val = PCI_GetConfigRegisterDWORD(0, i, func, 0x10+bar*4);
#ifdef CONFIG_PCI_DEBUG
printk("[bar:%d] new val:0x%08X\n", bar, new_val);
#endif /* CONFIG_PCI_DEBUG */
if (new_val == 0)
continue;
if (new_val & 1) { /* IO Space */
size = new_val & ~0x1;
size = ~size + 1;
io_base -= size;
io_base = io_base & ~(size-1);
PCI_SetConfigRegisterDWORD(0, i, func, 0x10+bar*4, io_base);
#ifdef CONFIG_PCI_DEBUG
printk("io_base:0x%08X\n", io_base);
#endif /* CONFIG_PCI_DEBUG */
continue;
} else { /* Memory Space */
size = new_val & ~0xF;
size = ~size + 1;
mem_base -= size;
mem_base = mem_base & ~(size-1);
PCI_SetConfigRegisterDWORD(0, i, func, 0x10+bar*4, mem_base);
#ifdef CONFIG_PCI_DEBUG
printk("mem_base:0x%08X\n", mem_base);
#endif /* CONFIG_PCI_DEBUG */
continue;
}
}
}
}
}
for (i = EXT_PCI7; i <= EXT_PCIB; i++) {
for (func = 0; func < 8; func++) {
val = PCI_GetConfigRegisterDWORD(0, i, func, 0);
if (val != 0xFFFFFFFF) {
for (bar = 0; bar < 6; bar++) {
ori_val = PCI_GetConfigRegisterDWORD(0, i, func, 0x10+bar*4);
PCI_SetConfigRegisterDWORD(0, i, func, 0x10+bar*4, 0xFFFFFFFF);
new_val = PCI_GetConfigRegisterDWORD(0, i, func, 0x10+bar*4);
if (new_val == 0)
continue;
pci_config_mask[i][func][bar+4] = new_val;
if (new_val & 1) { /* IO Space */
pci_config_shadow[i][func][bar+4] =
(0xC0000000 + ori_val) & ~1;
size = new_val & ~1;
size = ~size + 1;
#ifdef CONFIG_PCI_DEBUG
printk("(P)pci_config_shadow[i][func][bar]:0x%08X\n",
pci_config_shadow[i][func][bar+4]);
#endif /* CONFIG_PCI_DEBUG */
pci_config_shadow[i][func][bar+4] = (ulong)ioremap_nocache(
pci_config_shadow[i][func][bar+4], size);
/* #ifdef CONFIG_PCI_DEBUG */
/* PCI_SetConfigRegisterDWORD(0, i, 0, 4, 0x17); */
/* printk("io:addr:0x%08X=0x%08X\n",
pci_config_shadow[i][bar+4],
*((ulong *)(pci_config_shadow[i][bar+4]))); */
/* #endif //CONFIG_PCI_DEBUG */
pci_config_ro[i][func][bar+4] = 1;
pci_config_shadow[i][func][bar+4] |=
pci_config_ro[i][func][bar+4];
} else { /* Memory Space */
pci_config_shadow[i][func][bar+4] = ori_val & ~0xF;
size = new_val & ~0xF;
size = ~size + 1;
/* #ifdef CONFIG_PCI_DEBUG */
/* printk("(p)pci_config_shadow[i][bar]:0x%08X\n",
pci_config_shadow[i][bar+4]); */
/* printk("(v)pci_config_shadow[i][bar]:0x%08X\n",
ioremap_nocache(pci_config_shadow[i][bar+4], size)); */
/* PCI_SetConfigRegisterDWORD(0, i, 0, 4, 0x17); */
/* #endif //CONFIG_PCI_DEBUG */
/* pci_config_shadow[i][bar+4] = (ulong)ioremap_nocache(
pci_config_shadow[i][bar+4], size); */
pci_config_ro[i][func][bar+4] = new_val & 0xF;
pci_config_shadow[i][func][bar+4] |=
pci_config_ro[i][func][bar+4];
}
PCI_SetConfigRegisterDWORD(0, i, func, 0x10+bar*4, ori_val);
#ifdef CONFIG_PCI_DEBUG
printk("JHT [Dev:0x%0X] [Func:0x%0X] [Bar:0x%02X]:", i, func,bar);
printk("(ori}0x%08X (new)0x%08X (shadow)0x%08X size 0x%04X\n"
, ori_val, new_val, pci_config_shadow[i][bar+4], size);
#endif /* CONFIG_PCI_DEBUG */
}
}
}
}
/*
* PCI Bridge Memory Map is between 0xC0000:0000 - 0xC3FF:FFFF(64MB)
* The first 64KB is allocated for the PCI I/O Space, except for the
* 0xCF8 - 0xCFF(8Bytes) for the PCI Configuration
* Others are reserved for the MemorySpace.
*/
if (!request_region(0xC0000CF8, 8, "pci config")) {
printk("WonderMidia Technology PCI: Unable to request region 0xCF8\n");
return;
}
}
#endif
/* void __init wmt_pci_preinit(void *sysdata) */
void __init wmt_pci_preinit(void)
{
int i, j, bar;
printk("PCI: WonderMidia Technology PCI Bridge\n");
if (!pci_config_ba) {
pci_config_ba = (ulong)ioremap_nocache(0xC0000CF8, 8);
pci_config_addr = pci_config_ba;
pci_config_data = pci_config_ba+4;
}
for (i = 0; i < MAX_PCI_DEV; i++) {
for (j = 0; j < 8; j++) {
for (bar = 0; bar < 0x10; bar++) {
pci_config_shadow[i][j][bar] = 0xFFFFFFFF;
pci_config_mask[i][j][bar] = 0;
pci_config_ro[i][j][bar] = 0;
}
}
}
#ifdef PATA
init_int_pata();
#endif
#ifdef SATA
init_int_sata();
#endif
#ifdef USB_HOST
init_int_usb();
#endif
#ifdef MAC
init_int_mac();
#endif
#ifdef EXT_PCI
init_ext_pci();
#endif
}
int __init wmt_pci_setup(int nr, struct pci_sys_data *sys)
{
return (nr == 0);
}
struct pci_bus * __init wmt_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
if (nr == 0)
return pci_scan_bus(0, &wmt_pci_ops, sysdata);
return NULL;
}
/*
* [Description]
* Get the PCI Config Register for the specific PCI bus number,
* device number and function number in DWORD.
*
* [Arguments]
* bus : The target device's bus number.
* device : The target device's device number.
* funcn : The target device's function number.
* target : The target device's PCI config register Offset.
*
* [Return]
* The target device pci config register value will be returned.
*/
ulong
PCI_GetConfigRegisterDWORD(
int bus,
int device,
int fctn,
int target
)
{
outl(CONFIG_CMD(0, (device << 3) | fctn, target), pci_config_addr);
return inl(pci_config_data);
}
/*
* [Description]
* Set the PCI Config Register for the specific PCI bus number,
* device number and function number in DWORD.
*
* [Arguments]
* bus : The target device's bus number.
* device : The target device's device number.
* funcn : The target device's function number.
* target : The target device's PCI config register Offset.
* data : The written data to the target PCI device.
*
* [Return]
* Return value: 1 if found, 0 not found
*/
void
PCI_SetConfigRegisterDWORD(
int bus,
int device,
int fctn,
int target,
ulong data
)
{
outl(CONFIG_CMD(0, (device << 3) | fctn, target), pci_config_addr);
outl(data, pci_config_data);
}