/*
 * (C) Copyright 2001
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 * 
 * (C) Copyright 2001 
 * James Dougherty (jfd@cs.stanford.edu)
 *
 * 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 __MPC824X_PCI
#define __MPC824X_PCI

/*
 * PCI Configuration space Library and constants for MPC824x based
 * systems.
 */

typedef unsigned char  uint8;
typedef unsigned int   uint32;
typedef unsigned short uint16;
typedef int INT32;
#define LOCAL static
#define IMPORT extern

#ifndef NULL
#define NULL 0
#endif

#define OK     1
#define NONE 0
#define ERROR -1
#define TRUE   1
#define FALSE (!TRUE)
    

#define PCI_MAX_BUS	255
#define PCI_MAX_DEV	32
#define PCI_MAX_FUNC	8


/* PCI Configuration I/O Addresses */
#define	PCI_CONFIG_ADDR		0x0cf8	/* write 32 bits to set address */
#define	PCI_CONFIG_DATA		0x0cfc	/* 8, 16, or 32 bit accesses */
#define	PCI_CONFIG_CSE		0x0cf8	/* CSE register */
#define	PCI_CONFIG_FORWARD	0x0cfa	/* forward register */
#define	PCI_CONFIG_BASE		0xc000	/* base register */

/* PCI command bits */
#define PCI_CMD_IO_ENABLE	0x0001	/* IO access enable */
#define PCI_CMD_MEM_ENABLE	0x0002	/* memory access enable */
#define PCI_CMD_MASTER_ENABLE	0x0004	/* bus master enable */
#define PCI_CMD_MON_ENABLE	0x0008	/* monitor special cycles enable */
#define PCI_CMD_WI_ENABLE	0x0010	/* write and invalidate enable */
#define PCI_CMD_SNOOP_ENABLE	0x0020	/* palette snoop enable */
#define PCI_CMD_PERR_ENABLE	0x0040	/* parity error enable */
#define PCI_CMD_WC_ENABLE	0x0080	/* wait cycle enable */
#define PCI_CMD_SERR_ENABLE	0x0100	/* system error enable */
#define PCI_CMD_FBTB_ENABLE	0x0200	/* fast back to back enable */

/* PCI base address mask bits */

#define PCI_MEMBASE_MASK	~0xf	/* mask for memory base address */
#define PCI_IOBASE_MASK		~0x3	/* mask for IO base address */
#define PCI_BASE_IO		0x1	/* IO space indicator */
#define PCI_BASE_BELOW_1M	0x2	/* memory locate below 1MB */
#define PCI_BASE_IN_64BITS	0x4	/* memory locate anywhere in 64 bits */
#define PCI_BASE_PREFETCH	0x8	/* memory prefetchable */

/* Base Address Register Memory/IO Attribute bits */

#define PCI_BAR_SPACE_MASK	(0x01)
#define PCI_BAR_SPACE_IO	(0x01)
#define PCI_BAR_SPACE_MEM	(0x00)

#define PCI_BAR_MEM_TYPE_MASK   (0x06)
#define PCI_BAR_MEM_ADDR32      (0x00)
#define PCI_BAR_MEM_BELOW_1MB	(0x02)
#define PCI_BAR_MEM_ADDR64      (0x04)
#define PCI_BAR_MEM_RESERVED    (0x06)

#define PCI_BAR_MEM_PREF_MASK   (0x08)
#define PCI_BAR_MEM_PREFETCH    (0x08)
#define PCI_BAR_MEM_NON_PREF    (0x00)

#define PCI_BAR_ALL_MASK        (PCI_BAR_SPACE_MASK | \
                                 PCI_BAR_MEM_TYPE_MASK | \
                                 PCI_BAR_MEM_PREF_MASK)

/* PCI header type bits */

#define PCI_HEADER_TYPE_MASK	0x7f	/* mask for header type */
#define PCI_HEADER_PCI_PCI	0x01	/* PCI to PCI bridge */
#define PCI_HEADER_TYPE0        0x00    /* normal device header */
#define PCI_HEADER_MULTI_FUNC	0x80	/* multi function device */

/* PCI configuration device and driver */
 
#define SNOOZE_MODE             0x40    /* snooze mode */
#define SLEEP_MODE_DIS          0x00    /* sleep mode disable */

/* 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

/* PCI Class definitions for find by class function */

#define PCI_CLASS_PRE_PCI20	0x00
#define PCI_CLASS_MASS_STORAGE	0x01
#define PCI_CLASS_NETWORK_CTLR	0x02
#define PCI_CLASS_DISPLAY_CTLR	0x03
#define PCI_CLASS_MMEDIA_DEVICE	0x04
#define PCI_CLASS_MEM_CTLR	0x05
#define PCI_CLASS_BRIDGE_CTLR	0x06
#define PCI_CLASS_COMM_CTLR	0x07
#define PCI_CLASS_BASE_PERIPH	0x08
#define PCI_CLASS_INPUT_DEVICE	0x09
#define PCI_CLASS_DOCK_DEVICE	0x0A
#define PCI_CLASS_PROCESSOR	0x0B
#define PCI_CLASS_SERIAL_BUS	0x0C
#define PCI_CLASS_UNDEFINED	0xFF

/* PCI Subclass definitions */

#define PCI_SUBCLASS_00         0x00
#define PCI_SUBCLASS_01         0x01
#define PCI_SUBCLASS_02         0x02
#define PCI_SUBCLASS_03         0x03
#define PCI_SUBCLASS_04         0x04
#define PCI_SUBCLASS_05         0x05
#define PCI_SUBCLASS_06         0x06
#define PCI_SUBCLASS_07         0x07
#define PCI_SUBCLASS_10         0x10
#define PCI_SUBCLASS_20         0x20
#define PCI_SUBCLASS_80         0x80

/* Bridge Device subclasses */

#define PCI_SUBCLASS_HOST_PCI_BRIDGE	(PCI_SUBCLASS_00)
#define PCI_SUBCLASS_ISA_BRIDGE		(PCI_SUBCLASS_01)
#define PCI_SUBCLASS_P2P_BRIDGE		(PCI_SUBCLASS_04)
#define PCI_SUBCLASS_PCMCIA_BRIDGE	(PCI_SUBCLASS_05)
#define PCI_SUBCLASS_CARDBUS_BRIDGE	(PCI_SUBCLASS_07)

/* Processor subclasses */

#define PCI_SUBCLASS_PROCESSOR_386	(PCI_SUBCLASS_00)
#define PCI_SUBCLASS_PROCESSOR_486	(PCI_SUBCLASS_01)
#define PCI_SUBCLASS_PROCESSOR_PENTIUM	(PCI_SUBCLASS_02)
#define PCI_SUBCLASS_PROCESSOR_ALPHA	(PCI_SUBCLASS_10)
#define PCI_SUBCLASS_PROCESSOR_POWERPC	(PCI_SUBCLASS_20)

/* Serial bus subclasses */

#define PCI_SUBCLASS_SERBUS_FIREWIRE	(PCI_SUBCLASS_00)
#define PCI_SUBCLASS_SERBUS_USB		(PCI_SUBCLASS_03)

/* Network subclasses */

#define PCI_SUBCLASS_NET_ETHERNET	(PCI_SUBCLASS_00)
#define PCI_SUBCLASS_NET_TOKEN_RING	(PCI_SUBCLASS_01)
#define PCI_SUBCLASS_NET_FDDI		(PCI_SUBCLASS_02)
#define PCI_SUBCLASS_NET_ATM		(PCI_SUBCLASS_03)

/* Conditional defines for new configuration definitions */

#define PCI_CMD_MASK	0xffff0000	
#define PCI_BASE_ADDRESS_MEM_MASK	(~0x0fUL)
#define PCI_BASE_ADDRESS_IO_MASK	(~0x03UL)

/* Vendor and Device ID's */

/* Promise ATA */
#define PCI_VENDOR_ID_PROMISE		0x105a
#define PCI_DEVICE_ID_PROMISE_20265	0x0d30
#define PCI_DEVICE_ID_PROMISE_20267	0x4d30
#define PCI_DEVICE_ID_PROMISE_20246	0x4d33
#define PCI_DEVICE_ID_PROMISE_20262	0x4d38
#define PCI_DEVICE_ID_PROMISE_5300	0x5300

/* DEC Ethernet */
#define PCI_VENDOR_ID_DEC		0x1011
#define PCI_DEVICE_ID_DEC_BRD		0x0001
#define PCI_DEVICE_ID_DEC_TULIP		0x0002
#define PCI_DEVICE_ID_DEC_TGA		0x0004
#define PCI_DEVICE_ID_DEC_TULIP_FAST	0x0009
#define PCI_DEVICE_ID_DEC_TGA2		0x000D
#define PCI_DEVICE_ID_DEC_FDDI		0x000F
#define PCI_DEVICE_ID_DEC_TULIP_PLUS	0x0014
#define PCI_DEVICE_ID_DEC_21142		0x0019
#define PCI_DEVICE_ID_DEC_21052		0x0021
#define PCI_DEVICE_ID_DEC_21150		0x0022
#define PCI_DEVICE_ID_DEC_21152		0x0024
#define PCI_DEVICE_ID_DEC_21153		0x0025
#define PCI_DEVICE_ID_DEC_21154		0x0026
#define PCI_DEVICE_ID_DEC_21285		0x1065
#define PCI_DEVICE_ID_COMPAQ_42XX	0x0046



/* Cache Line Size - 32 32-bit value = 128 bytes */
#ifndef PCI_CACHE_LINE_SIZE
#define PCI_CACHE_LINE_SIZE            0x20
#endif /* PCI_CACHE_LINE_SIZE */

/* Latency Timer value - 255 PCI clocks */
#ifndef PCI_LATENCY_TIMER
#define PCI_LATENCY_TIMER           0xff
#endif /* PCI_LATENCY_TIMER */

#ifndef _ASMLANGUAGE
int pci_dev_init(int b);
int pci_dev_find(int vid, int devId, int idx,int *bus, int* dev, int* func);
int pci_class_find(int class, int idx, int* bus, int* dev, int *func);
int pci_config_inb(int b, int d, int f, int address, uint8 * pData);
int pci_config_inw(int b, int d, int f, int address, uint16 * pData);
int pci_config_inl(int b, int d, int f, int address, uint32 * pData);
int pci_config_outb(int b, int d, int f, int address, uint8 data);
int pci_config_outw(int b, int d, int f, int address, uint16 data);
int pci_config_outl(int b, int d, int f, int address, uint32 data);
int pci_special_cycle(int b, uint32 message);
int pci_config_bdf_pack(int b, int d, int f);
int pci_dev_config(int b, int d, int f, uint32 iobar, uint32 mbar, uint32 cm );
int pci_config_modl(int b, int d, int f, int offset,
		    uint32 bitMask, uint32 data );
int pci_config_modw(int b, int d, int f, int off,   
		    uint16 bitMask, uint16 data );
int pci_config_modb(int b, int d, int f, int offset,   
		    uint8 bitMask, uint8 data );
unsigned int pci_size_bar(unsigned int, unsigned long mask);
#endif	/* _ASMLANGUAGE */

#endif /* __MPC824X_PCI */
