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 |
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 |
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 |
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 |
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;
|