changeset 745:524cd8104dfd

Add PCI interrupts (extended support)
author gthomas
date Mon, 24 Feb 2003 18:10:07 +0000
parents 42861b9d6e75
children 96630430dc17
files packages/hal/arm/xscale/uE250/current/ChangeLog packages/hal/arm/xscale/uE250/current/include/hal_plf_ints.h packages/hal/arm/xscale/uE250/current/include/plf_io.h packages/hal/arm/xscale/uE250/current/include/plx.h packages/hal/arm/xscale/uE250/current/src/uE250_misc.c packages/hal/arm/xscale/uE250/current/src/uE250_pci.c
diffstat 6 files changed, 144 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/xscale/uE250/current/ChangeLog
+++ b/packages/hal/arm/xscale/uE250/current/ChangeLog
@@ -1,3 +1,12 @@
+2003-02-24  Gary Thomas  <gary@mind.be>
+
+	* include/plx.h: Clean up unused code.
+
+	* src/uE250_pci.c: 
+	* src/uE250_misc.c: 
+	* include/plf_io.h: 
+	* include/hal_plf_ints.h: Support interrupts via PCI bus.
+
 2003-02-04  Gary Thomas  <gary@mind.be>
 
 	* src/xilinx-load.c: 
--- a/packages/hal/arm/xscale/uE250/current/include/hal_plf_ints.h
+++ b/packages/hal/arm/xscale/uE250/current/include/hal_plf_ints.h
@@ -61,6 +61,62 @@
 #include <cyg/hal/plf_io.h>
 
 //----------------------------------------------------------------------------
+// Additional interrupts from PCI & Motherboard
+#define _uPCI_BASE_INTERRUPT   (96+17)
+
+#define CYGNUM_HAL_INTERRUPT_PCI_INTA    (_uPCI_BASE_INTERRUPT+0)   
+#define CYGNUM_HAL_INTERRUPT_PCI_INTB    (_uPCI_BASE_INTERRUPT+1)   
+#define CYGNUM_HAL_INTERRUPT_PCI_INTC    (_uPCI_BASE_INTERRUPT+2)   
+#define CYGNUM_HAL_INTERRUPT_PCI_INTD    (_uPCI_BASE_INTERRUPT+3)   
+#define CYGNUM_HAL_INTERRUPT_PXA         (_uPCI_BASE_INTERRUPT+4)   
+
+#undef  CYGNUM_HAL_ISR_MIN
+#undef  CYGNUM_HAL_ISR_MAX
+#define CYGNUM_HAL_ISR_MIN               0
+#define CYGNUM_HAL_ISR_MAX               (_uPCI_BASE_INTERRUPT+4)   
+
+//----------------------------------------------------------------------------
+// Platform specific interrupt handling
+externC int  _uE250_extended_irq(void);
+externC void _uE250_extended_int_mask(int vector);
+externC void _uE250_extended_int_unmask(int vector);
+externC void _uE250_extended_int_acknowledge(int vector);
+externC void _uE250_extended_int_configure(int vector, int level, int up);
+externC void _uE250_extended_int_set_level(int vector, int level);
+
+#define HAL_EXTENDED_IRQ_HANDLER(sources)                       \
+    if ((sources & (1 << CYGNUM_HAL_INTERRUPT_GPIO1)) != 0) {   \
+        int res = _uE250_extended_irq();                        \
+        if (res) return res;                                    \
+    };
+#define HAL_EXTENDED_INTERRUPT_MASK(vector)     \
+    if (vector >= _uPCI_BASE_INTERRUPT) {       \
+        _uE250_extended_int_mask(vector);       \
+        return;                                 \
+    }
+#define HAL_EXTENDED_INTERRUPT_UNMASK(vector)   \
+    if (vector >= _uPCI_BASE_INTERRUPT) {       \
+        _uE250_extended_int_unmask(vector);     \
+        return;                                 \
+    }
+#define HAL_EXTENDED_INTERRUPT_ACKNOWLEDGE(vector)      \
+    if (vector >= _uPCI_BASE_INTERRUPT) {               \
+        _uE250_extended_int_acknowledge(vector);        \
+        return;                                         \
+    }
+#define HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up)     \
+    if (vector >= _uPCI_BASE_INTERRUPT) {                       \
+        _uE250_extended_int_configure(vector, level, up);       \
+        return;                                                 \
+    }
+#define HAL_EXTENDED_INTERRUPT_SET_LEVEL(vector, level) \
+    if (vector >= _uPCI_BASE_INTERRUPT) {               \
+        _uE250_extended_int_set_level(vector, level);   \
+        return;                                         \
+    }
+
+
+//----------------------------------------------------------------------------
 // Reset.
 #undef  HAL_PLATFORM_RESET
 #define HAL_PLATFORM_RESET()                                               \
--- a/packages/hal/arm/xscale/uE250/current/include/plf_io.h
+++ b/packages/hal/arm/xscale/uE250/current/include/plf_io.h
@@ -69,7 +69,7 @@
 #define PCICTL_CONFIG_REMAP        PCI_CTL_IO(0x0008)
 #define PCICTL_INT_RESET           PCI_CTL_IO(0x0010)
 #define PCICTL_STATUS_REG          PCI_CTL_IO_BYTE(0x0010)
-#define PCICTL_INT_EDGE            PCI_CTL_IO(0x0011)
+#define PCICTL_INT_EDGE            PCI_CTL_IO_BYTE(0x0011)
 #define PCICTL_IRQ_MASK            PCI_CTL_IO(0x0014)
 #define PCICTL_MISC                PCI_CTL_IO(0x001C)
 
@@ -171,7 +171,9 @@ extern void cyg_hal_plf_pci_cfg_write_by
 externC void cyg_hal_plf_pci_init(void);
 #define HAL_PCI_INIT() cyg_hal_plf_pci_init()
 
-#define HAL_PCI_TRANSLATE_INTERRUPT(__bus, __devfn, __vector, __valid)
+externC void _uE250_pci_translate_interrupt(int bus, int devfn, int *vector, int *valid);
+#define HAL_PCI_TRANSLATE_INTERRUPT(__bus, __devfn, __vector, __valid) \
+  _uE250_pci_translate_interrupt(__bus, __devfn, &__vector, &__valid)
 
 // Special I/O access functions
 externC cyg_uint8 pci_io_read_8(cyg_uint32 address);
--- a/packages/hal/arm/xscale/uE250/current/include/plx.h
+++ b/packages/hal/arm/xscale/uE250/current/include/plx.h
@@ -41,16 +41,8 @@
 //####ECOSGPLCOPYRIGHTEND####
 //=============================================================================
 
-#if 0
-#define PCI_MEM_BASE            0x0C000000
-#define LOCALBUS_MEM_BASE       0x00100000
-#define PCI_MEM_BASE2           0x10000000
-#define DISPLAY_MEM_BASE        0x04000000
-#define PLX_PCI_SLOT            0x5
-#else
 #define LOCALBUS_CONFIG_OFFSET  0x0
 #define LOCALBUS_OFFSET         0x100
-#endif
 
 #ifndef _DEFINE_VARS
 #define __global externC
@@ -61,17 +53,6 @@
 __global cyg_uint32 _plx_localbus_addr;
 #undef __global
 
-#if 0
-#define plx_config_readl(a) (*(volatile cyg_uint32 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_CONFIG_OFFSET + (a)))
-#define plx_config_writel(v,a)  (*(volatile cyg_uint32 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_CONFIG_OFFSET + (a)))=(v)
-
-#define localbus_readb(a) (*(volatile cyg_uint8 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_OFFSET + (a)))
-#define localbus_readw(a) (*(volatile cyg_uint16 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_OFFSET + (a)))
-#define localbus_readl(a) (*(volatile cyg_uint32 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_OFFSET + (a)))
-#define localbus_writeb(v,a) (*(volatile cyg_uint8 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_OFFSET + (a)))=(v)
-#define localbus_writew(v,a) (*(volatile cyg_uint16 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_OFFSET + (a)))=(v)
-#define localbus_writel(v,a) (*(volatile cyg_uint32 *)(PCI_MEM_BASE + LOCALBUS_MEM_BASE + LOCALBUS_OFFSET + (a)))=(v)
-#else
 #define plx_config_readl(a) (*(volatile cyg_uint32 *)(_plx_config_addr + (a)))
 #define plx_config_writel(v,a)  (*(volatile cyg_uint32 *)(_plx_config_addr + (a)))=(v)
 
@@ -81,7 +62,6 @@
 #define localbus_writeb(v,a) (*(volatile cyg_uint8 *)(_plx_localbus_addr + (a)))=(v)
 #define localbus_writew(v,a) (*(volatile cyg_uint16 *)(_plx_localbus_addr + (a)))=(v)
 #define localbus_writel(v,a) (*(volatile cyg_uint32 *)(_plx_localbus_addr + (a)))=(v)
-#endif
 
 #define display_readb(a) (*(volatile cyg_uint8 *)(PCI_MEM_BASE2 + DISPLAY_MEM_BASE + (a)))
 #define display_readw(a) (*(volatile cyg_uint16 *)(PCI_MEM_BASE2 + DISPLAY_MEM_BASE + (a)))
--- a/packages/hal/arm/xscale/uE250/current/src/uE250_misc.c
+++ b/packages/hal/arm/xscale/uE250/current/src/uE250_misc.c
@@ -133,6 +133,12 @@ plf_hardware_init(void)
     hal_if_init();
 
     cyg_hal_plf_pci_init();
+    // Set up to handle PCI interrupts
+    HAL_INTERRUPT_CONFIGURE(CYGNUM_HAL_INTERRUPT_GPIO1, 0, 0);  // Falling edge
+    HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_GPIO1);
+    PCICTL_INT_RESET = 0xFF;  // Clear all pending interrupts
+    PCICTL_INT_EDGE = 0xFF;   // Generate interrupts
+    PCICTL_IRQ_MASK = 0x00;   // All masked
 
     initialize_plx_bridge();
 }
@@ -168,4 +174,64 @@ hal_arm_mem_real_region_top( cyg_uint8 *
 }
 
 // ------------------------------------------------------------------------
+// Extended, platform-specific, interrupt handling
+
+// FIXME - still needs work to support interrupts from PXA bridge
+
+int  
+_uE250_extended_irq(void)
+{
+    cyg_uint32 stat = PCICTL_STATUS_REG;
+    int irq = 0;
+
+    if (stat & 0x1F0) {
+        PCICTL_INT_RESET = 0xFF;  // Clear all pending interrupts
+    }
+    if (stat & 0x00F) {
+        // PCI interrupt
+        for (irq = 0;  irq < 4; irq++) {
+            if ((stat & (1 << irq)) != 0) {
+                break;
+            }
+        }
+        irq += _uPCI_BASE_INTERRUPT;
+    }
+    HAL_INTERRUPT_ACKNOWLEDGE(CYGNUM_HAL_INTERRUPT_GPIO1);
+    PCICTL_INT_EDGE = 0xFF;   // Generate interrupts
+    return irq;
+}
+
+void 
+_uE250_extended_int_mask(int vector)
+{
+    if (vector <= CYGNUM_HAL_INTERRUPT_PCI_INTD) {
+        PCICTL_IRQ_MASK &= ~(1<<(vector-CYGNUM_HAL_INTERRUPT_PCI_INTA));
+    }
+}
+
+void 
+_uE250_extended_int_unmask(int vector)
+{
+    if (vector <= CYGNUM_HAL_INTERRUPT_PCI_INTD) {
+        PCICTL_IRQ_MASK |= (1<<(vector-CYGNUM_HAL_INTERRUPT_PCI_INTA));
+    }
+}
+
+void 
+_uE250_extended_int_acknowledge(int vector)
+{
+}
+
+void 
+_uE250_extended_int_configure(int vector, int level, int up)
+{
+}
+
+void 
+_uE250_extended_int_set_level(int vector, int level)
+{
+}
+
+
+// ------------------------------------------------------------------------
 // EOF uE250_misc.c
--- a/packages/hal/arm/xscale/uE250/current/src/uE250_pci.c
+++ b/packages/hal/arm/xscale/uE250/current/src/uE250_pci.c
@@ -151,7 +151,16 @@ cyg_hal_plf_pci_init(void)
             }
         }
     }
+}
 
+void 
+_uE250_pci_translate_interrupt(int bus, int devfn, int *vector, int *valid)
+{
+    int dev = CYG_PCI_DEV_GET_DEV(devfn);
+
+    *vector = _uPCI_BASE_INTERRUPT+(dev-1);
+    diag_printf("%s.%d - dev: %d = %d\n", __FUNCTION__, __LINE__, dev, *vector);
+    valid = true;;
 }
 
 static void