Initial revision
diff --git a/cpu/mpc824x/drivers/i2o.h b/cpu/mpc824x/drivers/i2o.h
new file mode 100644
index 0000000..87225ab
--- /dev/null
+++ b/cpu/mpc824x/drivers/i2o.h
@@ -0,0 +1,344 @@
+#ifndef I2O_H
+#define I2O_H
+/*********************************************************
+ *
+ * copyright @ Motorola, 1999
+ *********************************************************/
+
+#define I2O_REG_OFFSET 0x0004
+
+#define PCI_CFG_CLA 0x0B
+#define PCI_CFG_SCL 0x0A
+#define PCI_CFG_PIC 0x09
+
+#define I2O_IMR0 0x0050
+#define I2O_IMR1 0x0054
+#define I2O_OMR0 0x0058
+#define I2O_OMR1 0x005C
+
+#define I2O_ODBR 0x0060
+#define I2O_IDBR 0x0068
+
+#define I2O_OMISR 0x0030
+#define I2O_OMIMR 0x0034
+#define I2O_IMISR 0x0100
+#define I2O_IMIMR 0x0104
+
+/* accessable to PCI master but local processor */
+#define I2O_IFQPR 0x0040
+#define I2O_OFQPR 0x0044
+
+/* accessable to local processor */
+#define I2O_IFHPR 0x0120
+#define I2O_IFTPR 0x0128
+#define I2O_IPHPR 0x0130
+#define I2O_IPTPR 0x0138
+#define I2O_OFHPR 0x0140
+#define I2O_OFTPR 0x0148
+#define I2O_OPHPR 0x0150
+#define I2O_OPTPR 0x0158
+#define I2O_MUCR 0x0164
+#define I2O_QBAR 0x0170
+
+#define I2O_NUM_MSG 2
+
+typedef enum _i2o_status
+{
+ I2OSUCCESS = 0,
+ I2OINVALID,
+ I2OMSGINVALID,
+ I2ODBINVALID,
+ I2OQUEINVALID,
+ I2OQUEEMPTY,
+ I2OQUEFULL,
+ I2ONOEVENT,
+} I2OSTATUS;
+
+typedef enum _queue_size
+{
+ QSIZE_4K = 0x02,
+ QSIZE_8K = 0x04,
+ QSIZE_16K = 0x08,
+ QSIZE_32K = 0x10,
+ QSIZe_64K = 0x20,
+} QUEUE_SIZE;
+
+typedef enum _location
+{
+ LOCAL = 0, /* used by local processor to access its own on board device,
+ local processor's eumbbar is required */
+ REMOTE, /* used by PCI master to access the devices on its PCI device,
+ device's pcsrbar is required */
+} LOCATION;
+
+/* door bell */
+typedef enum _i2o_in_db
+{
+ IN_DB = 1,
+ MC, /* machine check */
+} I2O_IN_DB;
+
+/* I2O PCI configuration identification */
+typedef struct _i2o_iop
+{
+ unsigned int base_class : 8;
+ unsigned int sub_class : 8;
+ unsigned int prg_code : 8;
+} I2OIOP;
+
+/* I2O Outbound Message Interrupt Status Register */
+typedef struct _i2o_om_stat
+{
+ unsigned int rsvd0 : 26;
+ unsigned int opqi : 1;
+ unsigned int rsvd1 : 1;
+ unsigned int odi : 1;
+ unsigned int rsvd2 : 1;
+ unsigned int om1i : 1;
+ unsigned int om0i : 1;
+} I2OOMSTAT;
+
+/* I2O inbound Message Interrupt Status Register */
+typedef struct _i2o_im_stat
+{
+ unsigned int rsvd0 : 23;
+ unsigned int ofoi : 1;
+ unsigned int ipoi : 1;
+ unsigned int rsvd1 : 1;
+ unsigned int ipqi : 1;
+ unsigned int mci : 1;
+ unsigned int idi : 1;
+ unsigned int rsvd2 : 1;
+ unsigned int im1i : 1;
+ unsigned int im0i : 1;
+} I2OIMSTAT;
+
+/**
+ Enable the interrupt associated with in/out bound msg
+
+ Inbound message interrupt generated by PCI master and serviced by local processor
+ local processor needs to enable its inbound interrupts it wants to handle (LOCAL)
+
+ Outbound message interrupt generated by local processor and serviced by PCI master
+ PCI master needs to enable the devices' outbound interrupts it wants to handle (REMOTE)
+ **/
+extern I2OSTATUS I2OMsgEnable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ); /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+
+/**
+ Disable the interrupt associated with in/out bound msg
+
+ local processor needs to disable its inbound interrupts it is not interested (LOCAL)
+
+ PCI master needs to disable outbound interrupts of devices it is not interested (REMOTE)
+ **/
+extern I2OSTATUS I2OMsgDisable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned char n ); /* b'1' - msg 0
+ * b'10'- msg 1
+ * b'11'- both
+ */
+
+/**
+ Read the msg register either from local inbound msg 0/1,
+ or an outbound msg 0/1 of devices.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, outbound msg of the device is read.
+ Otherwise local inbound msg is read.
+ **/
+extern I2OSTATUS I2OMsgGet ( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int *msg );
+
+/**
+ Write to nth Msg register either on local outbound msg 0/1,
+ or aninbound msg 0/1 of devices
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, inbound msg on the device is written.
+ Otherwise local outbound msg is written.
+ **/
+extern I2OSTATUS I2OMsgPost( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /*pcsrbar/eumbbar */
+ unsigned int n, /* 0 or 1 */
+ unsigned int msg );
+
+/**
+ Enable the In/Out DoorBell Interrupt
+
+ InDoorBell interrupt is generated by PCI master and serviced by local processor
+ local processor needs to enable its inbound doorbell interrupts it wants to handle
+
+ OutDoorbell interrupt is generated by local processor and serviced by PCI master
+ PCI master needs to enable outbound doorbell interrupts of the devices it wants to handle
+ **/
+extern I2OSTATUS I2ODBEnable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db );/* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+
+/**
+ Disable the In/Out DoorBell Interrupt
+
+ local processor needs to disable its inbound doorbell interrupts it is not interested
+
+ PCI master needs to disable outbound doorbell interrupts of devices it is not interested
+
+ **/
+extern I2OSTATUS I2ODBDisable( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int in_db ); /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
+
+/**
+ Read a local indoorbell register, or an outdoorbell of devices.
+ Reading a doorbell register, the register will be cleared.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, outdoorbell register on the device is read.
+ Otherwise local in doorbell is read
+ **/
+extern unsigned int I2ODBGet( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base); /* pcsrbar/eumbbar */
+
+/**
+ Write to a local outdoorbell register, or an indoorbell register of devices.
+
+ If it is not local, pcsrbar must be passed to the function.
+ Otherwise eumbbar is passed.
+
+ If it is remote, in doorbell register on the device is written.
+ Otherwise local out doorbell is written
+ **/
+extern void I2ODBPost( LOCATION, /* REMOTE/LOCAL */
+ unsigned int base, /* pcsrbar/eumbbar */
+ unsigned int msg ); /* in / out */
+
+/**
+ Read the outbound msg unit interrupt status of devices. Reading an interrupt status register,
+ the register will be cleared.
+
+ The outbound interrupt status is AND with the outbound
+ interrupt mask. The result is returned.
+
+ PCI master must pass the pcsrbar to the function.
+ **/
+extern I2OSTATUS I2OOutMsgStatGet( unsigned int pcsrbar, I2OOMSTAT * );
+
+/**
+ Read the inbound msg unit interrupt status. Reading an interrupt status register,
+ the register will be cleared.
+
+ The inbound interrupt status is AND with the inbound
+ interrupt mask. The result is returned.
+
+ Local process must pass its eumbbar to the function.
+**/
+extern I2OSTATUS I2OInMsgStatGet( unsigned int eumbbar, I2OIMSTAT * );
+
+/**
+ Configure the I2O FIFO, including QBAR, IFHPR/IFTPR,IPHPR/IPTPR,OFHPR/OFTPR, OPHPR/OPTPR,
+ MUCR.
+ **/
+extern I2OSTATUS I2OFIFOInit( unsigned int eumbbar,
+ QUEUE_SIZE,
+ unsigned int qba);/* queue base address that must be aligned at 1M */
+/**
+ Enable the circular queue
+ **/
+extern I2OSTATUS I2OFIFOEnable( unsigned int eumbbar );
+
+/**
+ Disable the circular queue
+ **/
+extern void I2OFIFODisable( unsigned int eumbbar );
+
+/**
+ Enable the circular queue interrupt
+ PCI master enables outbound FIFO interrupt of device
+ Device enables its inbound FIFO interrupt
+ **/
+extern void I2OFIFOIntEnable( LOCATION, unsigned int base );
+
+/**
+ Disable the circular queue interrupt
+ PCI master disables outbound FIFO interrupt of device
+ Device disables its inbound FIFO interrupt
+ **/
+extern void I2OFIFOIntDisable( LOCATION, unsigned int base );
+
+/**
+ Enable the circular queue overflow interrupt
+ **/
+extern void I2OFIFOOverflowIntEnable( unsigned int eumbbar );
+
+/**
+ Disable the circular queue overflow interrupt
+ **/
+extern void I2OFIFOOverflowIntDisable( unsigned int eumbbar );
+
+/**
+ Allocate a free msg frame from free FIFO.
+
+ PCI Master allocates a free msg frame through inbound queue port of device(IFQPR)
+ while local processor allocates a free msg frame from outbound free queue(OFTPR)
+
+ Unless both free queues are initialized, allocating a free MF will return 0xffffffff
+ **/
+extern I2OSTATUS I2OFIFOAlloc( LOCATION,
+ unsigned int base,
+ void **pMsg);
+/**
+ Free a used msg frame back to free queue
+ PCI Master frees a MFA through outbound queue port of device(OFQPR)
+ while local processor frees a MFA into its inbound free queue(IFHPR)
+
+ Used msg frame does not need to be recycled in the order they
+ read
+
+ This function has to be called by PCI master to initialize Inbound free queue
+ and by device to initialize Outbound free queue before I2OFIFOAlloc can be used.
+ **/
+extern I2OSTATUS I2OFIFOFree( LOCATION,
+ unsigned int base,
+ void *pMsg );
+
+/**
+ Post a msg into FIFO
+ PCI Master posts a msg through inbound queue port of device(IFQPR)
+ while local processor post a msg into its outbound post queue(OPHPR)
+
+ The total number of msg must be less than the max size of the queue
+ Otherwise queue overflow interrupt will assert.
+ **/
+extern I2OSTATUS I2OFIFOPost( LOCATION,
+ unsigned int base,
+ void *pMsg );
+
+/**
+ Read a msg from FIFO
+ PCI Master reads a msg through outbound queue port of device(OFQPR)
+ while local processor reads a msg from its inbound post queue(IPTPR)
+ **/
+extern I2OSTATUS I2OFIFOGet( LOCATION,
+ unsigned int base,
+ void **pMsg );
+
+/**
+ Get the I2O PCI configuration identification register
+ **/
+extern I2OSTATUS I2OPCIConfigGet( LOCATION,
+ unsigned int base,
+ I2OIOP *);
+
+#endif