Revision 29885477

b/hw/omap.h
60 60
                unsigned long size, unsigned char nbanks,
61 61
                qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk);
62 62

  
63
struct omap_target_agent_s;
64
static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
65
                int region, int iotype) { return 0; }
66

  
63 67
/*
64 68
 * Common IRQ numbers for level 1 interrupt handler
65 69
 * See /usr/include/asm-arm/arch-omap/irqs.h in Linux.
......
573 577
struct omap_i2c_s;
574 578
struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
575 579
                qemu_irq irq, qemu_irq *dma, omap_clk clk);
580
struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
581
                qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk);
576 582
void omap_i2c_reset(struct omap_i2c_s *s);
577 583
i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
578 584

  
b/hw/omap_i2c.c
29 29
    i2c_slave slave;
30 30
    i2c_bus *bus;
31 31

  
32
    uint8_t revision;
32 33
    uint8_t mask;
33 34
    uint16_t stat;
34 35
    uint16_t dma;
......
44 45
    uint16_t test;
45 46
};
46 47

  
48
#define OMAP2_INTR_REV	0x34
49
#define OMAP2_GC_REV	0x34
50

  
47 51
static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
48 52
{
49 53
    qemu_set_irq(s->irq, s->stat & s->mask);
......
124 128
            i2c_end_transfer(s->bus);
125 129
            s->control &= ~(1 << 1);				/* STP */
126 130
            s->count_cur = s->count;
131
            s->txlen = 0;
127 132
        } else if ((s->control >> 9) & 1) {			/* TRX */
128 133
            while (ack && s->txlen)
129 134
                ack = (i2c_send(s->bus,
......
162 167
                i2c_end_transfer(s->bus);
163 168
                s->control &= ~(1 << 1);			/* STP */
164 169
                s->count_cur = s->count;
170
                s->txlen = 0;
165 171
            } else {
166 172
                s->stat |= 1 << 2;				/* ARDY */
167 173
                s->control &= ~(1 << 10);			/* MST */
......
201 207

  
202 208
    switch (offset) {
203 209
    case 0x00:	/* I2C_REV */
204
        /* TODO: set a value greater or equal to real hardware */
205
        return 0x11;						/* REV */
210
        return s->revision;					/* REV */
206 211

  
207 212
    case 0x04:	/* I2C_IE */
208 213
        return s->mask;
......
211 216
        return s->stat | (i2c_bus_busy(s->bus) << 12);
212 217

  
213 218
    case 0x0c:	/* I2C_IV */
219
        if (s->revision >= OMAP2_INTR_REV)
220
            break;
214 221
        ret = ffs(s->stat & s->mask);
215 222
        if (ret)
216 223
            s->stat ^= 1 << (ret - 1);
217 224
        omap_i2c_interrupts_update(s);
218 225
        return ret;
219 226

  
227
    case 0x10:	/* I2C_SYSS */
228
        return (s->control >> 15) & 1;				/* I2C_EN */
229

  
220 230
    case 0x14:	/* I2C_BUF */
221 231
        return s->dma;
222 232

  
......
242 252
        } else
243 253
            /* XXX: remote access (qualifier) error - what's that?  */;
244 254
        if (!s->rxlen) {
245
            s->stat |= ~(1 << 3);				/* RRDY */
255
            s->stat &= ~(1 << 3);				/* RRDY */
246 256
            if (((s->control >> 10) & 1) &&			/* MST */
247 257
                            ((~s->control >> 9) & 1)) {		/* TRX */
248 258
                s->stat |= 1 << 2;				/* ARDY */
......
254 264
        omap_i2c_interrupts_update(s);
255 265
        return ret;
256 266

  
267
    case 0x20:	/* I2C_SYSC */
268
        return 0;
269

  
257 270
    case 0x24:	/* I2C_CON */
258 271
        return s->control;
259 272

  
......
293 306

  
294 307
    switch (offset) {
295 308
    case 0x00:	/* I2C_REV */
296
    case 0x08:	/* I2C_STAT */
297 309
    case 0x0c:	/* I2C_IV */
298
        OMAP_BAD_REG(addr);
310
    case 0x10:	/* I2C_SYSS */
311
        OMAP_RO_REG(addr);
299 312
        return;
300 313

  
301 314
    case 0x04:	/* I2C_IE */
302
        s->mask = value & 0x1f;
315
        s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f);
316
        break;
317

  
318
    case 0x08:	/* I2C_STAT */
319
        if (s->revision < OMAP2_INTR_REV) {
320
            OMAP_RO_REG(addr);
321
            return;
322
        }
323

  
324
        s->stat &= ~(value & 0x3f);
325
        omap_i2c_interrupts_update(s);
303 326
        break;
304 327

  
305 328
    case 0x14:	/* I2C_BUF */
......
335 358
        omap_i2c_interrupts_update(s);
336 359
        break;
337 360

  
361
    case 0x20:	/* I2C_SYSC */
362
        if (s->revision < OMAP2_INTR_REV) {
363
            OMAP_BAD_REG(addr);
364
            return;
365
        }
366

  
367
        if (value & 2)
368
            omap_i2c_reset(s);
369
        break;
370

  
338 371
    case 0x24:	/* I2C_CON */
339
        s->control = value & 0xcf07;
372
        s->control = value & 0xcf87;
340 373
        if (~value & (1 << 15)) {				/* I2C_EN */
341
            omap_i2c_reset(s);
374
            if (s->revision < OMAP2_INTR_REV)
375
                omap_i2c_reset(s);
342 376
            break;
343 377
        }
344
        if (~value & (1 << 10)) {				/* MST */
378
        if ((value & (1 << 15)) && !(value & (1 << 10))) {	/* MST */
345 379
            printf("%s: I^2C slave mode not supported\n", __FUNCTION__);
346 380
            break;
347 381
        }
348
        if (value & (1 << 9)) {					/* XA */
382
        if ((value & (1 << 15)) && value & (1 << 8)) {		/* XA */
349 383
            printf("%s: 10-bit addressing mode not supported\n", __FUNCTION__);
350 384
            break;
351 385
        }
352
        if (value & (1 << 0)) {					/* STT */
386
        if ((value & (1 << 15)) && value & (1 << 0)) {		/* STT */
353 387
            nack = !!i2c_start_transfer(s->bus, s->addr[1],	/* SA */
354 388
                            (~value >> 9) & 1);			/* TRX */
355 389
            s->stat |= nack << 1;				/* NACK */
356 390
            s->control &= ~(1 << 0);				/* STT */
357 391
            if (nack)
358 392
                s->control &= ~(1 << 1);			/* STP */
359
            else
393
            else {
394
                s->count_cur = s->count;
360 395
                omap_i2c_fifo_run(s);
396
            }
361 397
            omap_i2c_interrupts_update(s);
362 398
        }
363 399
        break;
......
384 420
        break;
385 421

  
386 422
    case 0x3c:	/* I2C_SYSTEST */
387
        s->test = value & 0xf00f;
423
        s->test = value & 0xf80f;
424
        if (value & (1 << 11))					/* SBB */
425
            if (s->revision >= OMAP2_INTR_REV) {
426
                s->stat |= 0x3f;
427
                omap_i2c_interrupts_update(s);
428
            }
388 429
        if (value & (1 << 15))					/* ST_EN */
389 430
            printf("%s: System Test not supported\n", __FUNCTION__);
390 431
        break;
......
395 436
    }
396 437
}
397 438

  
439
static void omap_i2c_writeb(void *opaque, target_phys_addr_t addr,
440
                uint32_t value)
441
{
442
    struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
443
    int offset = addr & OMAP_MPUI_REG_MASK;
444

  
445
    switch (offset) {
446
    case 0x1c:	/* I2C_DATA */
447
        if (s->txlen > 2) {
448
            /* XXX: remote access (qualifier) error - what's that?  */
449
            break;
450
        }
451
        s->fifo <<= 8;
452
        s->txlen += 1;
453
        s->fifo |= value & 0xff;
454
        s->stat &= ~(1 << 10);					/* XUDF */
455
        if (s->txlen > 2)
456
            s->stat &= ~(1 << 4);				/* XRDY */
457
        omap_i2c_fifo_run(s);
458
        omap_i2c_interrupts_update(s);
459
        break;
460

  
461
    default:
462
        OMAP_BAD_REG(addr);
463
        return;
464
    }
465
}
466

  
398 467
static CPUReadMemoryFunc *omap_i2c_readfn[] = {
399 468
    omap_badwidth_read16,
400 469
    omap_i2c_read,
......
402 471
};
403 472

  
404 473
static CPUWriteMemoryFunc *omap_i2c_writefn[] = {
405
    omap_badwidth_write16,
474
    omap_i2c_writeb,	/* Only the last fifo write can be 8 bit.  */
406 475
    omap_i2c_write,
407
    omap_i2c_write,	/* TODO: Only the last fifo write can be 8 bit.  */
476
    omap_badwidth_write16,
408 477
};
409 478

  
410 479
struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
......
414 483
    struct omap_i2c_s *s = (struct omap_i2c_s *)
415 484
            qemu_mallocz(sizeof(struct omap_i2c_s));
416 485

  
486
    /* TODO: set a value greater or equal to real hardware */
487
    s->revision = 0x11;
417 488
    s->base = base;
418 489
    s->irq = irq;
419 490
    s->drq[0] = dma[0];
......
431 502
    return s;
432 503
}
433 504

  
505
struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
506
                qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk)
507
{
508
    int iomemtype;
509
    struct omap_i2c_s *s = (struct omap_i2c_s *)
510
            qemu_mallocz(sizeof(struct omap_i2c_s));
511

  
512
    s->revision = 0x34;
513
    s->irq = irq;
514
    s->drq[0] = dma[0];
515
    s->drq[1] = dma[1];
516
    s->slave.event = omap_i2c_event;
517
    s->slave.recv = omap_i2c_rx;
518
    s->slave.send = omap_i2c_tx;
519
    s->bus = i2c_init_bus();
520
    omap_i2c_reset(s);
521

  
522
    iomemtype = cpu_register_io_memory(0, omap_i2c_readfn,
523
                    omap_i2c_writefn, s);
524
    s->base = omap_l4_attach(ta, 0, iomemtype);
525

  
526
    return s;
527
}
528

  
434 529
i2c_bus *omap_i2c_bus(struct omap_i2c_s *s)
435 530
{
436 531
    return s->bus;

Also available in: Unified diff