1 #include "soc_pxa.h" 2 3 /* PXA Interrupt Controller Registers */ 4 #define PXA_ICIP 0x00 5 #define PXA_ICMR 0x01 6 #define PXA_ICFP 0x03 7 #define PXA_ICMR2 0x28 8 9 void 10 PXAInterruptController::EnableInterrupt(int irq) 11 { 12 if (irq <= 31) { 13 fRegBase[PXA_ICMR] |= 1 << irq; 14 return; 15 } 16 17 fRegBase[PXA_ICMR2] |= 1 << (irq - 32); 18 } 19 20 21 void 22 PXAInterruptController::DisableInterrupt(int irq) 23 { 24 if (irq <= 31) { 25 fRegBase[PXA_ICMR] &= ~(1 << irq); 26 return; 27 } 28 29 fRegBase[PXA_ICMR2] &= ~(1 << (irq - 32)); 30 } 31 32 33 void 34 PXAInterruptController::HandleInterrupt() 35 { 36 for (int i=0; i < 32; i++) { 37 if (fRegBase[PXA_ICIP] & (1 << i)) 38 int_io_interrupt_handler(i, true); 39 } 40 } 41 42 43 #if 0 44 PXAInterruptController::PXAInterruptController(fdt_module_info *fdt, fdt_device_node node) 45 : InterruptController(fdt, node) { 46 fRegArea = fFDT->map_reg_range(node, 0, (void**)&fRegBase); 47 if (fRegArea < 0) 48 panic("PXAInterruptController: cannot map registers!"); 49 50 fRegBase[PXA_ICMR] = 0; 51 fRegBase[PXA_ICMR2] = 0; 52 } 53 #endif 54 55 #define PXA_TIMERS_INTERRUPT 7 /* OST_4_11 */ 56 57 #define PXA_OSSR 0x05 58 #define PXA_OIER 0x07 59 #define PXA_OSCR4 0x10 60 #define PXA_OSCR5 0x11 61 #define PXA_OSMR4 0x20 62 #define PXA_OSMR5 0x21 63 #define PXA_OMCR4 0x30 64 #define PXA_OMCR5 0x31 65 66 #define PXA_RES_S (3 << 0) 67 #define PXA_RES_MS (1 << 1) 68 #define PXA_RES_US (1 << 2) 69 70 #define US2S(bt) ((bt) / 1000000ULL) 71 #define US2MS(bt) ((bt) / 1000ULL) 72 73 void 74 PXATimer::SetTimeout(bigtime_t timeout) 75 { 76 uint32 val = timeout & UINT_MAX; 77 uint32 res = PXA_RES_US; 78 79 if (timeout & ~UINT_MAX) { 80 // Does not fit, so scale resolution down to milliseconds 81 if (US2MS(timeout) & ~UINT_MAX) { 82 // Still does not fit, scale down to seconds as last ditch attempt 83 val = US2S(timeout) & UINT_MAX; 84 res = PXA_RES_S; 85 } else { 86 // Fits in millisecond resolution 87 val = US2MS(timeout) & UINT_MAX; 88 res = PXA_RES_MS; 89 } 90 } 91 92 dprintf("arch_timer_set_hardware_timer(val=%lu, res=%lu)\n", val, res); 93 fRegBase[PXA_OIER] |= (1 << 4); 94 fRegBase[PXA_OMCR4] = res; 95 fRegBase[PXA_OSMR4] = val; 96 fRegBase[PXA_OSCR4] = 0; // start counting from 0 again 97 } 98 99 void 100 PXATimer::Clear() 101 { 102 fRegBase[PXA_OMCR4] = 0; // disable our timer 103 fRegBase[PXA_OIER] &= ~(1 << 4); 104 } 105 106 107 bigtime_t 108 PXATimer::Time() 109 { 110 if (fRegArea < 0) 111 return 0; 112 113 return (fRegBase != NULL) ? 114 fSystemTime + fRegBase[PXA_OSCR5] : 115 0ULL; 116 } 117 118 119 int32 120 PXATimer::_InterruptWrapper(void *data) 121 { 122 return ((PXATimer*)data)->HandleInterrupt(); 123 } 124 125 126 int32 127 PXATimer::HandleInterrupt() 128 { 129 if (fRegBase[PXA_OSSR] & (1 << 4)) { 130 fRegBase[PXA_OSSR] |= (1 << 4); 131 return timer_interrupt(); 132 } 133 134 if (fRegBase[PXA_OSSR] & (1 << 5)) { 135 fRegBase[PXA_OSSR] |= (1 << 5); 136 fSystemTime += UINT_MAX + 1ULL; 137 } 138 139 return B_HANDLED_INTERRUPT; 140 } 141 142 143 #if 0 144 PXATimer::PXATimer(fdt_module_info *fdt, fdt_device_node node) 145 : HardwareTimer(fdt, node) 146 { 147 fRegArea = fFDT->map_reg_range(node, 0, (void**)&fRegBase); 148 if (fRegArea < 0) 149 panic("Cannot map PXATimer registers!"); 150 151 fRegBase[PXA_OIER] |= (1 << 5); // enable timekeeping timer 152 fRegBase[PXA_OMCR5] = PXA_RES_US | (1 << 7); 153 fRegBase[PXA_OSMR5] = UINT_MAX; 154 fRegBase[PXA_OSCR5] = 0; 155 156 install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, &PXATimer::_InterruptWrapper, NULL, 0); 157 } 158 #endif 159