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 PXAInterruptController::PXAInterruptController(fdt_module_info *fdt, fdt_device_node node) 44 : InterruptController(fdt, node) { 45 fRegArea = fFDT->map_reg_range(node, 0, (void**)&fRegBase); 46 if (fRegArea < 0) 47 panic("PXAInterruptController: cannot map registers!"); 48 49 fRegBase[PXA_ICMR] = 0; 50 fRegBase[PXA_ICMR2] = 0; 51 } 52 53 #define PXA_TIMERS_INTERRUPT 7 /* OST_4_11 */ 54 55 #define PXA_OSSR 0x05 56 #define PXA_OIER 0x07 57 #define PXA_OSCR4 0x10 58 #define PXA_OSCR5 0x11 59 #define PXA_OSMR4 0x20 60 #define PXA_OSMR5 0x21 61 #define PXA_OMCR4 0x30 62 #define PXA_OMCR5 0x31 63 64 #define PXA_RES_S (3 << 0) 65 #define PXA_RES_MS (1 << 1) 66 #define PXA_RES_US (1 << 2) 67 68 #define US2S(bt) ((bt) / 1000000ULL) 69 #define US2MS(bt) ((bt) / 1000ULL) 70 71 void 72 PXATimer::SetTimeout(bigtime_t timeout) 73 { 74 uint32 val = timeout & UINT_MAX; 75 uint32 res = PXA_RES_US; 76 77 if (timeout & ~UINT_MAX) { 78 // Does not fit, so scale resolution down to milliseconds 79 if (US2MS(timeout) & ~UINT_MAX) { 80 // Still does not fit, scale down to seconds as last ditch attempt 81 val = US2S(timeout) & UINT_MAX; 82 res = PXA_RES_S; 83 } else { 84 // Fits in millisecond resolution 85 val = US2MS(timeout) & UINT_MAX; 86 res = PXA_RES_MS; 87 } 88 } 89 90 dprintf("arch_timer_set_hardware_timer(val=%lu, res=%lu)\n", val, res); 91 fRegBase[PXA_OIER] |= (1 << 4); 92 fRegBase[PXA_OMCR4] = res; 93 fRegBase[PXA_OSMR4] = val; 94 fRegBase[PXA_OSCR4] = 0; // start counting from 0 again 95 } 96 97 void 98 PXATimer::Clear() 99 { 100 fRegBase[PXA_OMCR4] = 0; // disable our timer 101 fRegBase[PXA_OIER] &= ~(1 << 4); 102 } 103 104 105 bigtime_t 106 PXATimer::Time() 107 { 108 if (fRegArea < 0) 109 return 0; 110 111 return (fRegBase != NULL) ? 112 fSystemTime + fRegBase[PXA_OSCR5] : 113 0ULL; 114 } 115 116 117 int32 118 PXATimer::_InterruptWrapper(void *data) 119 { 120 return ((PXATimer*)data)->HandleInterrupt(); 121 } 122 123 124 int32 125 PXATimer::HandleInterrupt() 126 { 127 if (fRegBase[PXA_OSSR] & (1 << 4)) { 128 fRegBase[PXA_OSSR] |= (1 << 4); 129 return timer_interrupt(); 130 } 131 132 if (fRegBase[PXA_OSSR] & (1 << 5)) { 133 fRegBase[PXA_OSSR] |= (1 << 5); 134 fSystemTime += UINT_MAX + 1ULL; 135 } 136 137 return B_HANDLED_INTERRUPT; 138 } 139 140 141 PXATimer::PXATimer(fdt_module_info *fdt, fdt_device_node node) 142 : HardwareTimer(fdt, node) 143 { 144 fRegArea = fFDT->map_reg_range(node, 0, (void**)&fRegBase); 145 if (fRegArea < 0) 146 panic("Cannot map PXATimer registers!"); 147 148 fRegBase[PXA_OIER] |= (1 << 5); // enable timekeeping timer 149 fRegBase[PXA_OMCR5] = PXA_RES_US | (1 << 7); 150 fRegBase[PXA_OSMR5] = UINT_MAX; 151 fRegBase[PXA_OSCR5] = 0; 152 153 install_io_interrupt_handler(PXA_TIMERS_INTERRUPT, &PXATimer::_InterruptWrapper, NULL, 0); 154 } 155