Changeset 41ce4d9 in mainline
- Timestamp:
- 2010-07-15T10:24:39Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 074c9bd
- Parents:
- 0e796cc
- Location:
- kernel
- Files:
-
- 2 added
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/src/mach/gta02/gta02.c
r0e796cc r41ce4d9 41 41 #include <genarch/fb/visuals.h> 42 42 #include <genarch/drivers/s3c24xx_uart/s3c24xx_uart.h> 43 #include <genarch/drivers/s3c24xx_irqc/s3c24xx_irqc.h> 44 #include <genarch/drivers/s3c24xx_timer/s3c24xx_timer.h> 45 #include <interrupt.h> 43 46 #include <ddi/ddi.h> 47 #include <ddi/device.h> 44 48 45 49 #define GTA02_MEMORY_START 0x30000000 /* physical */ … … 52 56 /** GTA02 framebuffer base address */ 53 57 #define GTA02_FB_BASE 0x08800000 58 59 /** IRQ number used for clock */ 60 #define GTA02_TIMER_IRQ S3C24XX_INT_TIMER0 54 61 55 62 static void gta02_init(void); … … 62 69 static void gta02_input_init(void); 63 70 71 static void gta02_timer_irq_init(void); 72 static void gta02_timer_start(void); 73 static irq_ownership_t gta02_timer_irq_claim(irq_t *irq); 74 static void gta02_timer_irq_handler(irq_t *irq); 75 64 76 static void *gta02_scons_out; 77 static s3c24xx_irqc_t *gta02_irqc; 78 static s3c24xx_timer_t *gta02_timer; 79 80 static irq_t gta02_timer_irq; 65 81 66 82 struct arm_machine_ops gta02_machine_ops = { … … 78 94 { 79 95 gta02_scons_out = (void *) hw_map(GTA02_SCONS_BASE, PAGE_SIZE); 96 gta02_irqc = (void *) hw_map(S3C24XX_IRQC_ADDRESS, PAGE_SIZE); 97 gta02_timer = (void *) hw_map(S3C24XX_TIMER_ADDRESS, PAGE_SIZE); 98 99 /* Make all interrupt sources use IRQ mode (not FIQ). */ 100 pio_write_32(>a02_irqc->intmod, 0x00000000); 101 102 /* Disable all interrupt sources. */ 103 pio_write_32(>a02_irqc->intmsk, 0xffffffff); 104 105 /* Disable interrupts from all sub-sources. */ 106 pio_write_32(>a02_irqc->intsubmsk, 0xffffffff); 80 107 } 81 108 82 109 static void gta02_timer_irq_start(void) 83 110 { 111 gta02_timer_irq_init(); 112 gta02_timer_start(); 84 113 } 85 114 … … 101 130 static void gta02_irq_exception(unsigned int exc_no, istate_t *istate) 102 131 { 132 uint32_t inum; 133 134 inum = pio_read_32(>a02_irqc->intoffset); 135 136 irq_t *irq = irq_dispatch_and_lock(inum); 137 if (irq) { 138 /* The IRQ handler was found. */ 139 irq->handler(irq); 140 spinlock_unlock(&irq->lock); 141 } else { 142 /* Spurious interrupt.*/ 143 printf("cpu%d: spurious interrupt (inum=%d)\n", 144 CPU->id, inum); 145 } 146 147 /* Clear interrupt condition in the interrupt controller. */ 148 pio_write_32(>a02_irqc->srcpnd, S3C24XX_INT_BIT(inum)); 149 pio_write_32(>a02_irqc->intpnd, S3C24XX_INT_BIT(inum)); 103 150 } 104 151 … … 140 187 } 141 188 189 static void gta02_timer_irq_init(void) 190 { 191 irq_initialize(>a02_timer_irq); 192 gta02_timer_irq.devno = device_assign_devno(); 193 gta02_timer_irq.inr = GTA02_TIMER_IRQ; 194 gta02_timer_irq.claim = gta02_timer_irq_claim; 195 gta02_timer_irq.handler = gta02_timer_irq_handler; 196 197 irq_register(>a02_timer_irq); 198 } 199 200 static irq_ownership_t gta02_timer_irq_claim(irq_t *irq) 201 { 202 return IRQ_ACCEPT; 203 } 204 205 static void gta02_timer_irq_handler(irq_t *irq) 206 { 207 /* 208 * We are holding a lock which prevents preemption. 209 * Release the lock, call clock() and reacquire the lock again. 210 */ 211 spinlock_unlock(&irq->lock); 212 clock(); 213 spinlock_lock(&irq->lock); 214 } 215 216 static void gta02_timer_start(void) 217 { 218 s3c24xx_timer_t *timer = gta02_timer; 219 220 /* 221 * See S3C2442B user manual chapter 10 (PWM Timer) for description 222 * of timer operation. Starting a timer is described in the 223 * section 'Timer initialization using manual update bit and 224 * inverter bit'. 225 */ 226 227 /* Set prescaler values to zero. (no pre-divison), no dead zone. */ 228 pio_write_32(&timer->tcfg0, 0); 229 230 /* No DMA request, divider value = 2 for all timers. */ 231 pio_write_32(&timer->tcfg1, 0); 232 233 /* Stop all timers. */ 234 pio_write_32(&timer->tcon, 0); 235 236 /* Start counting from 64k-1. Compare value is irrelevant. */ 237 pio_write_32(&timer->timer[0].cntb, 0xffff); 238 pio_write_32(&timer->timer[0].cmpb, 0); 239 240 /* Enable interrupts from timer0 */ 241 pio_write_32(>a02_irqc->intmsk, pio_read_32(>a02_irqc->intmsk) & 242 ~S3C24XX_INT_BIT(S3C24XX_INT_TIMER0)); 243 244 /* Load data from tcntb0/tcmpb0 into tcnt0/tcmp0. */ 245 pio_write_32(&timer->tcon, TCON_T0_AUTO_RLD | TCON_T0_MUPDATE); 246 247 /* Start timer 0. Inverter is off. */ 248 pio_write_32(&timer->tcon, TCON_T0_AUTO_RLD | TCON_T0_START); 249 } 250 142 251 /** @} 143 252 */
Note:
See TracChangeset
for help on using the changeset viewer.