Commit d951f6ff3fff1121e8b20e7655cb88b2601b61e6

Authored by balrog
1 parent 1b6fd0bc

Implement OMAP MicroWire controller.

Fix GPIO interrupt number.
Reorder a couple of variables.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3477 c046a42c-6fe2-441c-8c8c-71466251a162
hw/omap.c
... ... @@ -3101,7 +3101,6 @@ static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
3101 3101 {
3102 3102 struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
3103 3103 int offset = addr - s->base;
3104   - uint16_t ret;
3105 3104  
3106 3105 switch (offset) {
3107 3106 case 0x00: /* DATA_INPUT */
... ... @@ -3238,6 +3237,175 @@ void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
3238 3237 s->handler[line] = handler;
3239 3238 }
3240 3239  
  3240 +/* MicroWire Interface */
  3241 +struct omap_uwire_s {
  3242 + target_phys_addr_t base;
  3243 + qemu_irq txirq;
  3244 + qemu_irq rxirq;
  3245 + qemu_irq txdrq;
  3246 +
  3247 + uint16_t txbuf;
  3248 + uint16_t rxbuf;
  3249 + uint16_t control;
  3250 + uint16_t setup[5];
  3251 +
  3252 + struct uwire_slave_s *chip[4];
  3253 +};
  3254 +
  3255 +static void omap_uwire_transfer_start(struct omap_uwire_s *s)
  3256 +{
  3257 + int chipselect = (s->control >> 10) & 3; /* INDEX */
  3258 + struct uwire_slave_s *slave = s->chip[chipselect];
  3259 +
  3260 + if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */
  3261 + if (s->control & (1 << 12)) /* CS_CMD */
  3262 + if (slave && slave->send)
  3263 + slave->send(slave->opaque,
  3264 + s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
  3265 + s->control &= ~(1 << 14); /* CSRB */
  3266 + /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
  3267 + * a DRQ. When is the level IRQ supposed to be reset? */
  3268 + }
  3269 +
  3270 + if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */
  3271 + if (s->control & (1 << 12)) /* CS_CMD */
  3272 + if (slave && slave->receive)
  3273 + s->rxbuf = slave->receive(slave->opaque);
  3274 + s->control |= 1 << 15; /* RDRB */
  3275 + /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
  3276 + * a DRQ. When is the level IRQ supposed to be reset? */
  3277 + }
  3278 +}
  3279 +
  3280 +static uint32_t omap_uwire_read(void *opaque, target_phys_addr_t addr)
  3281 +{
  3282 + struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
  3283 + int offset = addr - s->base;
  3284 +
  3285 + switch (offset) {
  3286 + case 0x00: /* RDR */
  3287 + s->control &= ~(1 << 15); /* RDRB */
  3288 + return s->rxbuf;
  3289 +
  3290 + case 0x04: /* CSR */
  3291 + return s->control;
  3292 +
  3293 + case 0x08: /* SR1 */
  3294 + return s->setup[0];
  3295 + case 0x0c: /* SR2 */
  3296 + return s->setup[1];
  3297 + case 0x10: /* SR3 */
  3298 + return s->setup[2];
  3299 + case 0x14: /* SR4 */
  3300 + return s->setup[3];
  3301 + case 0x18: /* SR5 */
  3302 + return s->setup[4];
  3303 + }
  3304 +
  3305 + OMAP_BAD_REG(addr);
  3306 + return 0;
  3307 +}
  3308 +
  3309 +static void omap_uwire_write(void *opaque, target_phys_addr_t addr,
  3310 + uint32_t value)
  3311 +{
  3312 + struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
  3313 + int offset = addr - s->base;
  3314 +
  3315 + switch (offset) {
  3316 + case 0x00: /* TDR */
  3317 + s->txbuf = value; /* TD */
  3318 + s->control |= 1 << 14; /* CSRB */
  3319 + if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */
  3320 + ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */
  3321 + (s->control & (1 << 12)))) /* CS_CMD */
  3322 + omap_uwire_transfer_start(s);
  3323 + break;
  3324 +
  3325 + case 0x04: /* CSR */
  3326 + s->control = value & 0x1fff;
  3327 + if (value & (1 << 13)) /* START */
  3328 + omap_uwire_transfer_start(s);
  3329 + break;
  3330 +
  3331 + case 0x08: /* SR1 */
  3332 + s->setup[0] = value & 0x003f;
  3333 + break;
  3334 +
  3335 + case 0x0c: /* SR2 */
  3336 + s->setup[1] = value & 0x0fc0;
  3337 + break;
  3338 +
  3339 + case 0x10: /* SR3 */
  3340 + s->setup[2] = value & 0x0003;
  3341 + break;
  3342 +
  3343 + case 0x14: /* SR4 */
  3344 + s->setup[3] = value & 0x0001;
  3345 + break;
  3346 +
  3347 + case 0x18: /* SR5 */
  3348 + s->setup[4] = value & 0x000f;
  3349 + break;
  3350 +
  3351 + default:
  3352 + OMAP_BAD_REG(addr);
  3353 + return;
  3354 + }
  3355 +}
  3356 +
  3357 +static CPUReadMemoryFunc *omap_uwire_readfn[] = {
  3358 + omap_badwidth_read16,
  3359 + omap_uwire_read,
  3360 + omap_badwidth_read16,
  3361 +};
  3362 +
  3363 +static CPUWriteMemoryFunc *omap_uwire_writefn[] = {
  3364 + omap_badwidth_write16,
  3365 + omap_uwire_write,
  3366 + omap_badwidth_write16,
  3367 +};
  3368 +
  3369 +void omap_uwire_reset(struct omap_uwire_s *s)
  3370 +{
  3371 + s->control= 0;
  3372 + s->setup[0] = 0;
  3373 + s->setup[1] = 0;
  3374 + s->setup[2] = 0;
  3375 + s->setup[3] = 0;
  3376 + s->setup[4] = 0;
  3377 +}
  3378 +
  3379 +struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
  3380 + qemu_irq *irq, qemu_irq dma, omap_clk clk)
  3381 +{
  3382 + int iomemtype;
  3383 + struct omap_uwire_s *s = (struct omap_uwire_s *)
  3384 + qemu_mallocz(sizeof(struct omap_uwire_s));
  3385 +
  3386 + s->base = base;
  3387 + s->txirq = irq[0];
  3388 + s->rxirq = irq[1];
  3389 + s->txdrq = dma;
  3390 + omap_uwire_reset(s);
  3391 +
  3392 + iomemtype = cpu_register_io_memory(0, omap_uwire_readfn,
  3393 + omap_uwire_writefn, s);
  3394 + cpu_register_physical_memory(s->base, 0x800, iomemtype);
  3395 +
  3396 + return s;
  3397 +}
  3398 +
  3399 +void omap_uwire_attach(struct omap_uwire_s *s,
  3400 + struct uwire_slave_s *slave, int chipselect)
  3401 +{
  3402 + if (chipselect < 0 || chipselect > 3)
  3403 + cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
  3404 + chipselect);
  3405 +
  3406 + s->chip[chipselect] = slave;
  3407 +}
  3408 +
3241 3409 /* General chip reset */
3242 3410 static void omap_mpu_reset(void *opaque)
3243 3411 {
... ... @@ -3261,12 +3429,13 @@ static void omap_mpu_reset(void *opaque)
3261 3429 omap_dpll_reset(&mpu->dpll[0]);
3262 3430 omap_dpll_reset(&mpu->dpll[1]);
3263 3431 omap_dpll_reset(&mpu->dpll[2]);
3264   - omap_uart_reset(mpu->uart1);
3265   - omap_uart_reset(mpu->uart2);
3266   - omap_uart_reset(mpu->uart3);
  3432 + omap_uart_reset(mpu->uart[0]);
  3433 + omap_uart_reset(mpu->uart[1]);
  3434 + omap_uart_reset(mpu->uart[2]);
3267 3435 omap_mmc_reset(mpu->mmc);
3268 3436 omap_mpuio_reset(mpu->mpuio);
3269 3437 omap_gpio_reset(mpu->gpio);
  3438 + omap_uwire_reset(mpu->microwire);
3270 3439 cpu_reset(mpu->env);
3271 3440 }
3272 3441  
... ... @@ -3361,13 +3530,13 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
3361 3530  
3362 3531 omap_tcmi_init(0xfffecc00, s);
3363 3532  
3364   - s->uart1 = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
  3533 + s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
3365 3534 omap_findclk(s, "uart1_ck"),
3366 3535 serial_hds[0]);
3367   - s->uart2 = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
  3536 + s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
3368 3537 omap_findclk(s, "uart2_ck"),
3369 3538 serial_hds[0] ? serial_hds[1] : 0);
3370   - s->uart3 = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
  3539 + s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
3371 3540 omap_findclk(s, "uart3_ck"),
3372 3541 serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
3373 3542  
... ... @@ -3382,9 +3551,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
3382 3551 s->irq[1][OMAP_INT_KEYBOARD], s->irq[1][OMAP_INT_MPUIO],
3383 3552 s->wakeup, omap_findclk(s, "clk32-kHz"));
3384 3553  
3385   - s->gpio = omap_gpio_init(0xfffcf000, s->irq[1][OMAP_INT_KEYBOARD],
  3554 + s->gpio = omap_gpio_init(0xfffcf000, s->irq[0][OMAP_INT_GPIO_BANK1],
3386 3555 omap_findclk(s, "mpuper_ck"));
3387 3556  
  3557 + s->microwire = omap_uwire_init(0xfffb3000, &s->irq[1][OMAP_INT_uWireTX],
  3558 + s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
  3559 +
3388 3560 qemu_register_reset(omap_mpu_reset, s);
3389 3561  
3390 3562 return s;
... ...
hw/omap.h
... ... @@ -464,6 +464,17 @@ struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
464 464 qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s);
465 465 void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler);
466 466  
  467 +struct uwire_slave_s {
  468 + uint16_t (*receive)(void *opaque);
  469 + void (*send)(void *opaque, uint16_t data);
  470 + void *opaque;
  471 +};
  472 +struct omap_uwire_s;
  473 +struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
  474 + qemu_irq *irq, qemu_irq dma, omap_clk clk);
  475 +void omap_uwire_attach(struct omap_uwire_s *s,
  476 + struct uwire_slave_s *slave, int chipselect);
  477 +
467 478 /* omap_lcdc.c */
468 479 struct omap_lcd_panel_s;
469 480 void omap_lcdc_reset(struct omap_lcd_panel_s *s);
... ... @@ -510,16 +521,19 @@ struct omap_mpu_state_s {
510 521 unsigned long sram_size;
511 522  
512 523 /* MPUI-TIPB peripherals */
513   - struct omap_uart_s *uart3;
  524 + struct omap_uart_s *uart[3];
  525 +
  526 + struct omap_gpio_s *gpio;
514 527  
515 528 /* MPU public TIPB peripherals */
516 529 struct omap_32khz_timer_s *os_timer;
517 530  
518   - struct omap_uart_s *uart1;
519   - struct omap_uart_s *uart2;
520   -
521 531 struct omap_mmc_s *mmc;
522 532  
  533 + struct omap_mpuio_s *mpuio;
  534 +
  535 + struct omap_uwire_s *microwire;
  536 +
523 537 /* MPU private TIPB peripherals */
524 538 struct omap_intr_handler_s *ih[2];
525 539  
... ... @@ -578,9 +592,6 @@ struct omap_mpu_state_s {
578 592 uint16_t dsp_idlect2;
579 593 uint16_t dsp_rstct2;
580 594 } clkm;
581   -
582   - struct omap_mpuio_s *mpuio;
583   - struct omap_gpio_s *gpio;
584 595 } *omap310_mpu_init(unsigned long sdram_size,
585 596 DisplayState *ds, const char *core);
586 597  
... ...
hw/palm.c
... ... @@ -37,7 +37,8 @@ static uint32_t static_readw(void *opaque, target_phys_addr_t offset) {
37 37 }
38 38  
39 39 static void static_write(void *opaque, target_phys_addr_t offset,
40   - uint32_t value) {
  40 + uint32_t value)
  41 +{
41 42 #ifdef SPY
42 43 printf("%s: value %08lx written at " PA_FMT "\n",
43 44 __FUNCTION__, value, offset);
... ...