/*
 * (C) Copyright 2001
 * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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
 */



#ifndef _PCI_H
#define _PCI_H



#define TRUE 1
#define FALSE 0		
#define MAX_PCI_BASE_REG	6 /* max six mem description per PCI dev */
#define DESC_IS_IO				1 /* IO Attribute */
#define DESC_IS_MEM				2 /* Memory attribute     */
#define DESC_IS_PREFETCH	4 /* Memory is Prefetchable */
#define DESC_IS_LOWMEM		8 /* locate below 1M */
#define DESC_IS_64BIT			0x10 /* dual address cycles */
#define DESC_IS_NOT_VALID	0 /* Memory description is nat valid    */

/*----------------------------------------------------------------------------+
| 405GP PCI core memory map defines.
+----------------------------------------------------------------------------*/
#define MIN_PCI_MEMADDR1    0x80000000
#define MIN_PCI_MEMADDR2    0x00000000
#define MIN_PLB_PCI_IOADDR  0xE8000000  /* PLB side of PCI I/O address space */
#define MIN_PCI_PCI_IOADDR1 0x00000000  /* PCI side of PCI I/O address space */
#define MAX_PCI_PCI_IOADDR1 0x00010000  /* PCI side of PCI I/O address space */
#define MIN_PCI_PCI_IOADDR2 0x00800000  /* PCI side of PCI I/O address space */
#define MAX_PCI_DEVICES     32
#define MAX_PCI_FUNCTIONS		7
/*----------------------------------------------------------------------------+
| Defines for the 405GP PCI Config address and data registers followed by
| defines for the standard PCI device configuration header.
+----------------------------------------------------------------------------*/
#define PCICFGADR       0xEEC00000
#define PCICFGDATA      0xEEC00004

#define PCIVENDORID     0x00
#define PCIDEVICEID     0x02
#define PCICMD          0x04
  #define SERR_EN       0x0100
  #define BM_EN         0x0004
  #define MEM_EN        0x0002
  #define IO_EN         0x0001
#define PCISTATUS       0x06
  #define CAPABLE_66MHZ 0x0020
#define PCIREVID        0x08
#define PCICLASSPI      0x09
#define PCICLASSCODE    0x0A
#define PCICACHELINE    0x0C
#define PCILATENCYTIM   0x0D
#define PCIHEADERTYPE   0x0E
#define PCIBIST         0x0F
#define PCIBASEADDR0    0x10
#define PCIBASEADDR1    0x14
#define PCIBASEADDR2    0x18
#define PCISSVENDORID   0x2C
#define PCISSDEVICEID   0x2E
#define PCIINTLINE      0x3C
#define PCIINTPIN       0x3D
#define PCIMINGRANT     0x3E
#define PCIMAXLATENCY   0x3F

#define PCIBUSNUM       0x40        /* 405GP specific parameters */
#define PCISUBBUSNUM    0x41
#define PCIDISCOUNT     0x42
#define PCIBRDGOPT1     0x4A
#define PCIBRDGOPT2     0x60

/*----------------------------------------------------------------------------+
| Defines for 405GP PCI Master local configuration regs.
+----------------------------------------------------------------------------*/
#define PMM0LA          0xEF400000
#define PMM0MA          0xEF400004
#define PMM0PCILA       0xEF400008
#define PMM0PCIHA       0xEF40000C
#define PMM1LA          0xEF400010
#define PMM1MA          0xEF400014
#define PMM1PCILA       0xEF400018
#define PMM1PCIHA       0xEF40001C
#define PMM2LA          0xEF400020
#define PMM2MA          0xEF400024
#define PMM2PCILA       0xEF400028
#define PMM2PCIHA       0xEF40002C

/*----------------------------------------------------------------------------+
| Defines for 405GP PCI Target local configuration regs.
+----------------------------------------------------------------------------*/
#define PTM1MS          0xEF400030
#define PTM1LA          0xEF400034
#define PTM2MS          0xEF400038
#define PTM2LA          0xEF40003C

/*-----------------------------------------------------------------------------+
|       PCI-PCI bridge header
+-----------------------------------------------------------------------------*/
#define PCIPCI_PRIMARYBUS       0x18
#define PCIPCI_SECONDARYBUS     0x19
#define PCIPCI_SUBORDINATEBUS   0x1A
#define PCIPCI_SECONDARYLATENCY 0x1B
#define PCIPCI_IOBASE           0x1C
#define PCIPCI_IOLIMIT          0x1D
#define PCIPCI_SECONDARYSTATUS  0x1E
#define PCIPCI_MEMBASE          0x20
#define PCIPCI_MEMLIMIT         0x22
#define PCIPCI_PREFETCHMEMBASE  0x24
#define PCIPCI_PREFETCHMEMLIMIT 0x26
#define PCIPCI_IOBASEUPPER16    0x30
#define PCIPCI_IOLIMITUPPER16   0x32

#define PCIDEVID_405GP 	0x0

/* Standard device configuration register offsets */
/* Note that only modulo-4 addresses are written to the address register */

#define	PCI_CFG_VENDOR_ID	0x00
#define	PCI_CFG_DEVICE_ID	0x02
#define	PCI_CFG_COMMAND		0x04
#define	PCI_CFG_STATUS		0x06
#define	PCI_CFG_REVISION	0x08
#define	PCI_CFG_PROGRAMMING_IF	0x09
#define	PCI_CFG_SUBCLASS	0x0a
#define	PCI_CFG_CLASS		0x0b
#define	PCI_CFG_CACHE_LINE_SIZE	0x0c
#define	PCI_CFG_LATENCY_TIMER	0x0d
#define	PCI_CFG_HEADER_TYPE	0x0e
#define	PCI_CFG_BIST		0x0f
#define	PCI_CFG_BASE_ADDRESS_0	0x10
#define	PCI_CFG_BASE_ADDRESS_1	0x14
#define	PCI_CFG_BASE_ADDRESS_2	0x18
#define	PCI_CFG_BASE_ADDRESS_3	0x1c
#define	PCI_CFG_BASE_ADDRESS_4	0x20
#define	PCI_CFG_BASE_ADDRESS_5	0x24
#define	PCI_CFG_CIS		0x28
#define	PCI_CFG_SUB_VENDER_ID	0x2c
#define	PCI_CFG_SUB_SYSTEM_ID	0x2e
#define	PCI_CFG_EXPANSION_ROM	0x30
#define	PCI_CFG_RESERVED_0	0x34
#define	PCI_CFG_RESERVED_1	0x38
#define	PCI_CFG_DEV_INT_LINE	0x3c
#define	PCI_CFG_DEV_INT_PIN	0x3d
#define	PCI_CFG_MIN_GRANT	0x3e
#define	PCI_CFG_MAX_LATENCY	0x3f
#define PCI_CFG_SPECIAL_USE     0x41
#define PCI_CFG_MODE            0x43


/* PCI-to-PCI bridge configuration register offsets */
/* Note that only modulo-4 addresses are written to the address register */

#define	PCI_CFG_PRIMARY_BUS	0x18
#define	PCI_CFG_SECONDARY_BUS	0x19
#define	PCI_CFG_SUBORDINATE_BUS	0x1a
#define	PCI_CFG_SEC_LATENCY	0x1b
#define	PCI_CFG_IO_BASE		0x1c
#define	PCI_CFG_IO_LIMIT	0x1d
#define	PCI_CFG_SEC_STATUS	0x1e
#define	PCI_CFG_MEM_BASE	0x20
#define	PCI_CFG_MEM_LIMIT	0x22
#define	PCI_CFG_PRE_MEM_BASE	0x24
#define	PCI_CFG_PRE_MEM_LIMIT	0x26
#define	PCI_CFG_PRE_MEM_BASE_U	0x28
#define	PCI_CFG_PRE_MEM_LIMIT_U	0x2c
#define	PCI_CFG_IO_BASE_U	0x30
#define	PCI_CFG_IO_LIMIT_U	0x32
#define	PCI_CFG_ROM_BASE	0x38
#define	PCI_CFG_BRG_INT_LINE	0x3c
#define	PCI_CFG_BRG_INT_PIN	0x3d
#define	PCI_CFG_BRIDGE_CONTROL	0x3e


/***********************************************************************
 * 405GP PCI Master configuration.
 * Map one 512 MB range of PLB/processor addresses to PCI memory space.
 *   PLB address 0x80000000-0x9FFFFFFF ==> PCI address 0x80000000-0x9FFFFFFF
 *   Use byte reversed out routines to handle endianess.
 ***********************************************************************/
#define PCI_M0_LOCAL_ADDR	0x80000000
#define PCI_M0_PCI_LOW_ADDR	0x80000000
#define PCI_M0_PCI_HIGH_ADDR	0x00000000
#define PCI_M0_MASK_ATTRIB	0xE0000001  /* no prefetching, and enable region */
/**************************************************************************
 * Map one 512 MB range of PLB/processor addresses to PCI memory space.
 * PLB address 0xA0000000-0xBFFFFFFF ==> PCI address 0x00000000-0x1FFFFFFF
 * This space is for the VGA card.
 **************************************************************************/
#define PCI_M1_LOCAL_ADDR	0xA0000000
#define PCI_M1_PCI_LOW_ADDR	0x00000000
#define PCI_M1_PCI_HIGH_ADDR	0x00000000
#define PCI_M1_MASK_ATTRIB	0xE0000001  /* no prefetching, and enable region */
/***************************************************************************
 * PMM2 is not used.  Initialize them to zero.
 *****************************************************************************/
#define PCI_M2_LOCAL_ADDR	0x00000000
#define PCI_M2_PCI_LOW_ADDR	0x00000000
#define PCI_M2_PCI_HIGH_ADDR	0x00000000
#define PCI_M2_MASK_ATTRIB	0x00000000  /* not enabled */

typedef struct pciHeaderDevice
{
	short	vendorId;	/* vendor ID */
	short	deviceId;	/* device ID */
	short	command;	/* command register */
	short	status;		/* status register */
	char	revisionId;	/* revision ID */
	char	classCode;	/* class code */
	char	subClass;	/* sub class code */
	char	progIf;		/* programming interface */
	char	cacheLine;	/* cache line */
	char	latency;	/* latency time */
	char	headerType;	/* header type */
	char	bist;		/* BIST */
	int	base0;		/* base address 0 */
	int	base1;		/* base address 1 */
	int	base2;		/* base address 2 */
	int	base3;		/* base address 3 */
	int	base4;		/* base address 4 */
	int	base5;		/* base address 5 */
	int	cis;		/* cardBus CIS pointer */
	short	subVendorId;	/* sub system vendor ID */
	short	subSystemId;	/* sub system ID */
	int	romBase;	/* expansion ROM base address */
	int	reserved0;	/* reserved */
	int	reserved1;	/* reserved */
	char	intLine;	/* interrupt line */
	char	intPin;		/* interrupt pin */
	char	minGrant;	/* min Grant */
	char	maxLatency;	/* max Latency */
} PCI_HEADER_DEVICE;

typedef struct pciHeaderBridge
{
    short	vendorId;	/* vendor ID */
    short	deviceId;	/* device ID */
    short	command;	/* command register */
    short	status;		/* status register */
    char	revisionId;	/* revision ID */
    char	classCode;	/* class code */
    char	subClass;	/* sub class code */
    char	progIf;		/* programming interface */
    char	cacheLine;	/* cache line */
    char	latency;	/* latency time */
    char	headerType;	/* header type */
    char	bist;		/* BIST */
    int		base0;		/* base address 0 */
    int		base1;		/* base address 1 */
    char	priBus;		/* primary bus number */
    char	secBus;		/* secondary bus number */
    char	subBus;		/* subordinate bus number */
    char	secLatency;	/* secondary latency timer */
    char	ioBase;		/* IO base */
    char	ioLimit;	/* IO limit */
    short	secStatus;	/* secondary status */
    short	memBase;	/* memory base */
    short	memLimit;	/* memory limit */
    short	preBase;	/* prefetchable memory base */
    short	preLimit;	/* prefetchable memory limit */
    int		preBaseUpper;	/* prefetchable memory base upper 32 bits */
    int		preLimitUpper;	/* prefetchable memory base upper 32 bits */
    short	ioBaseUpper;	/* IO base upper 16 bits */
    short	ioLimitUpper;	/* IO limit upper 16 bits */
    int		reserved;	/* reserved */
    int		romBase;	/* expansion ROM base address */
    char	intLine;	/* interrupt line */
    char	intPin;		/* interrupt pin */
    short	control;	/* bridge control */
    } PCI_HEADER_BRIDGE;


typedef struct pciRecourceDesc
{
	unsigned long	BusDevFunc; /* location of the device */
	short	vendorId;		/* vendor ID */
	short	deviceId;		/* device ID */
	char	revisionId;	/* revision ID */
	char	classCode;	/* class code */
	char	subClass;		/* sub class code */
	char	progIf;		/* programming interface */
	char	headerType;	/* header type */
	unsigned long		size[MAX_PCI_BASE_REG];		/* memory sizes */
	char	attr[MAX_PCI_BASE_REG];		/* memory attributes */
	char	intLine;	/* interrupt line */
	char	intPin;		/* interrupt pin */
	char	pciInt; 	/* Pci Interrupt Line ( 0 = no, 1 = A...)*/
} PCI_RESOURCE_DESC;


/* table for PCI Initialization */

typedef struct {
	const int index;
	const unsigned long val;
	const int with;
} PCI_CFG_TABLE;


typedef struct {
	int 		index; 	/* address */
	unsigned long 	val;	/* value */
	int 		width;	/* data size */
}PCI_FCN_CFG_TABLE;

typedef struct {
	unsigned short	vendorID;	/* Vendor ID */
	unsigned short	deviceID;	/* Device ID */
	unsigned char	revision;	/* Device ID */
	unsigned char	func;		/* Function number */
	PCI_FCN_CFG_TABLE fcntable[10];
}PCI_DEV_CFG_TABLE;


unsigned long    PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width);
int  	PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned long Value, int Width);
void  PCI_Scan(int BusNum);
void  PCI_Config_Device(int BusDevFunc, int NumBaseAddr);
void  PCI_Config_VGA_Device(int BusDevFunc, int NumBaseAddr);
void  PCI_Config_Bridge(int BusDevFunc);
void  PCI_Dump_Device(int BusDevFunc);
int   PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID);
void  pciHeaderShow(int BusDevFunc);
void  pciDheaderPrint(PCI_HEADER_DEVICE * pD);
void  pciBheaderPrint(PCI_HEADER_BRIDGE * pB);
void  PCI_Config_ISABridge(int BusDevFunc);
void  PCI_Config_VGA_contrl(int BusDevFunc);

void pciScanForDevices(int BusNum);
void pciShowRes(PCI_RESOURCE_DESC *pd);
int pciGetResource(PCI_RESOURCE_DESC * pR);
int pciGetHeader0(PCI_HEADER_DEVICE * pD,int BusDevFunc);

/***************************************************************************
* Defines PIIX4 Config Registers
****************************************************************************/

/* Function 0 ISA Bridge */
#define	PCI_CFG_PIIX4_IORT		0x4C	/* 8 bit ISA Recovery Timer Reg (default 0x4D) */
#define	PCI_CFG_PIIX4_XBCS		0x4E	/* 16 bit XBus Chip select reg (default 0x0003) */
#define	PCI_CFG_PIIX4_PIRQC		0x60  /* PCI IRQ Route Register 4 x 8bit (default )*/
#define	PCI_CFG_PIIX4_SERIRQ	0x64
#define	PCI_CFG_PIIX4_TOM			0x69
#define	PCI_CFG_PIIX4_MSTAT		0x6A
#define	PCI_CFG_PIIX4_MBDMA		0x76
#define	PCI_CFG_PIIX4_APICBS	0x80
#define	PCI_CFG_PIIX4_DLC			0x82
#define	PCI_CFG_PIIX4_PDMACFG	0x90
#define	PCI_CFG_PIIX4_DDMABS	0x92
#define	PCI_CFG_PIIX4_GENCFG	0xB0
#define	PCI_CFG_PIIX4_RTCCFG	0xCB

/* IO Addresses */
#define PIIX4_ISA_DMA1_CH0BA	0x00
#define PIIX4_ISA_DMA1_CH0CA	0x01
#define PIIX4_ISA_DMA1_CH1BA	0x02
#define PIIX4_ISA_DMA1_CH1CA	0x03
#define PIIX4_ISA_DMA1_CH2BA	0x04
#define PIIX4_ISA_DMA1_CH2CA	0x05
#define PIIX4_ISA_DMA1_CH3BA	0x06
#define PIIX4_ISA_DMA1_CH3CA	0x07
#define PIIX4_ISA_DMA1_CMDST	0x08
#define PIIX4_ISA_DMA1_REQ		0x09
#define PIIX4_ISA_DMA1_WSBM		0x0A
#define PIIX4_ISA_DMA1_CH_MOD	0x0B
#define PIIX4_ISA_DMA1_CLR_PT	0x0C
#define PIIX4_ISA_DMA1_M_CLR	0x0D
#define PIIX4_ISA_DMA1_CLR_M	0x0E
#define PIIX4_ISA_DMA1_RWAMB	0x0F

#define PIIX4_ISA_DMA2_CH0BA	0xC0
#define PIIX4_ISA_DMA2_CH0CA	0xC1
#define PIIX4_ISA_DMA2_CH1BA	0xC2
#define PIIX4_ISA_DMA2_CH1CA	0xC3
#define PIIX4_ISA_DMA2_CH2BA	0xC4
#define PIIX4_ISA_DMA2_CH2CA	0xC5
#define PIIX4_ISA_DMA2_CH3BA	0xC6
#define PIIX4_ISA_DMA2_CH3CA	0xC7
#define PIIX4_ISA_DMA2_CMDST	0xD0
#define PIIX4_ISA_DMA2_REQ		0xD2
#define PIIX4_ISA_DMA2_WSBM		0xD4
#define PIIX4_ISA_DMA2_CH_MOD	0xD6
#define PIIX4_ISA_DMA2_CLR_PT	0xD8
#define PIIX4_ISA_DMA2_M_CLR	0xDA
#define PIIX4_ISA_DMA2_CLR_M	0xDC
#define PIIX4_ISA_DMA2_RWAMB	0xDE

#define PIIX4_ISA_INT1_ICW1		0x20
#define PIIX4_ISA_INT1_OCW2		0x20
#define PIIX4_ISA_INT1_OCW3		0x20
#define PIIX4_ISA_INT1_ICW2		0x21
#define PIIX4_ISA_INT1_ICW3		0x21
#define PIIX4_ISA_INT1_ICW4		0x21
#define PIIX4_ISA_INT1_OCW1		0x21

#define PIIX4_ISA_INT1_ELCR		0x4D0

#define PIIX4_ISA_INT2_ICW1		0xA0
#define PIIX4_ISA_INT2_OCW2		0xA0
#define PIIX4_ISA_INT2_OCW3		0xA0
#define PIIX4_ISA_INT2_ICW2		0xA1
#define PIIX4_ISA_INT2_ICW3		0xA1
#define PIIX4_ISA_INT2_ICW4		0xA1
#define PIIX4_ISA_INT2_OCW1		0xA1
#define PIIX4_ISA_INT2_IMR		0xA1 /* read only */

#define PIIX4_ISA_INT2_ELCR		0x4D1

#define PIIX4_ISA_TMR0_CNT_ST	0x40
#define PIIX4_ISA_TMR1_CNT_ST	0x41
#define PIIX4_ISA_TMR2_CNT_ST	0x42
#define PIIX4_ISA_TMR_TCW			0x43

#define PIIX4_ISA_RST_XBUS		0x60

#define PIIX4_ISA_NMI_CNT_ST	0x61
#define PIIX4_ISA_NMI_ENABLE	0x70

#define PIIX4_ISA_RTC_INDEX		0x70
#define PIIX4_ISA_RTC_DATA		0x71
#define PIIX4_ISA_RTCEXT_IND	0x70
#define PIIX4_ISA_RTCEXT_DATA	0x71

#define PIIX4_ISA_DMA1_CH2LPG	0x81
#define PIIX4_ISA_DMA1_CH3LPG	0x82
#define PIIX4_ISA_DMA1_CH1LPG	0x83
#define PIIX4_ISA_DMA1_CH0LPG	0x87
#define PIIX4_ISA_DMA2_CH2LPG	0x89
#define PIIX4_ISA_DMA2_CH3LPG	0x8A
#define PIIX4_ISA_DMA2_CH1LPG	0x8B
#define PIIX4_ISA_DMA2_LPGRFR	0x8F

#define PIIX4_ISA_PORT_92			0x92

#define PIIX4_ISA_APM_CONTRL	0xB2
#define PIIX4_ISA_APM_STATUS	0xB3

#define PIIX4_ISA_COCPU_ERROR	0xF0

/* Function 1 IDE Controller */
#define	PCI_CFG_PIIX4_BMIBA		0x20
#define	PCI_CFG_PIIX4_IDETIM	0x40
#define	PCI_CFG_PIIX4_SIDETIM	0x44
#define	PCI_CFG_PIIX4_UDMACTL	0x48
#define	PCI_CFG_PIIX4_UDMATIM 0x4A

/* Function 2 USB Controller */
#define	PCI_CFG_PIIX4_SBRNUM	0x60
#define	PCI_CFG_PIIX4_LEGSUP	0xC0

/* Function 3 Power Management */
#define	PCI_CFG_PIIX4_PMAB		0x40
#define	PCI_CFG_PIIX4_CNTA		0x44
#define	PCI_CFG_PIIX4_CNTB		0x48
#define	PCI_CFG_PIIX4_GPICTL	0x4C
#define	PCI_CFG_PIIX4_DEVRESD	0x50
#define	PCI_CFG_PIIX4_DEVACTA	0x54
#define	PCI_CFG_PIIX4_DEVACTB	0x58
#define	PCI_CFG_PIIX4_DEVRESA	0x5C
#define	PCI_CFG_PIIX4_DEVRESB	0x60
#define	PCI_CFG_PIIX4_DEVRESC	0x64
#define	PCI_CFG_PIIX4_DEVRESE	0x68
#define	PCI_CFG_PIIX4_DEVRESF	0x6C
#define	PCI_CFG_PIIX4_DEVRESG	0x70
#define	PCI_CFG_PIIX4_DEVRESH	0x74
#define	PCI_CFG_PIIX4_DEVRESI	0x78


#endif
