Revision 4a2c8ac2 hw/omap.c

b/hw/omap.c
3603 3603
    cpu_register_physical_memory(s->pwt.base, 0x800, iomemtype);
3604 3604
}
3605 3605

  
3606
/* Inter-Integrated Circuit Controller (only the "New I2C") */
3607
struct omap_i2c_s {
3608
    target_phys_addr_t base;
3609
    qemu_irq irq;
3610
    qemu_irq drq[2];
3611
    i2c_slave slave;
3612
    i2c_bus *bus;
3613

  
3614
    uint8_t mask;
3615
    uint16_t stat;
3616
    uint16_t dma;
3617
    uint16_t count;
3618
    int count_cur;
3619
    uint32_t fifo;
3620
    int rxlen;
3621
    int txlen;
3622
    uint16_t control;
3623
    uint16_t addr[2];
3624
    uint8_t divider;
3625
    uint8_t times[2];
3626
    uint16_t test;
3627
};
3628

  
3629
static void omap_i2c_interrupts_update(struct omap_i2c_s *s)
3630
{
3631
    qemu_set_irq(s->irq, s->stat & s->mask);
3632
    if ((s->dma >> 15) & 1)				/* RDMA_EN */
3633
        qemu_set_irq(s->drq[0], (s->stat >> 3) & 1);	/* RRDY */
3634
    if ((s->dma >> 7) & 1)				/* XDMA_EN */
3635
        qemu_set_irq(s->drq[1], (s->stat >> 4) & 1);	/* XRDY */
3636
}
3637

  
3638
/* These are only stubs now.  */
3639
static void omap_i2c_event(i2c_slave *i2c, enum i2c_event event)
3640
{
3641
    struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
3642

  
3643
    if ((~s->control >> 15) & 1)				/* I2C_EN */
3644
        return;
3645

  
3646
    switch (event) {
3647
    case I2C_START_SEND:
3648
    case I2C_START_RECV:
3649
        s->stat |= 1 << 9;					/* AAS */
3650
        break;
3651
    case I2C_FINISH:
3652
        s->stat |= 1 << 2;					/* ARDY */
3653
        break;
3654
    case I2C_NACK:
3655
        s->stat |= 1 << 1;					/* NACK */
3656
        break;
3657
    }
3658

  
3659
    omap_i2c_interrupts_update(s);
3660
}
3661

  
3662
static int omap_i2c_rx(i2c_slave *i2c)
3663
{
3664
    struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
3665
    uint8_t ret = 0;
3666

  
3667
    if ((~s->control >> 15) & 1)				/* I2C_EN */
3668
        return -1;
3669

  
3670
    if (s->txlen)
3671
        ret = s->fifo >> ((-- s->txlen) << 3) & 0xff;
3672
    else
3673
        s->stat |= 1 << 10;					/* XUDF */
3674
    s->stat |= 1 << 4;						/* XRDY */
3675

  
3676
    omap_i2c_interrupts_update(s);
3677
    return ret;
3678
}
3679

  
3680
static int omap_i2c_tx(i2c_slave *i2c, uint8_t data)
3681
{
3682
    struct omap_i2c_s *s = (struct omap_i2c_s *) i2c;
3683

  
3684
    if ((~s->control >> 15) & 1)				/* I2C_EN */
3685
        return 1;
3686

  
3687
    if (s->rxlen < 4)
3688
        s->fifo |= data << ((s->rxlen ++) << 3);
3689
    else
3690
        s->stat |= 1 << 11;					/* ROVR */
3691
    s->stat |= 1 << 3;						/* RRDY */
3692

  
3693
    omap_i2c_interrupts_update(s);
3694
    return 1;
3695
}
3696

  
3697
static void omap_i2c_fifo_run(struct omap_i2c_s *s)
3698
{
3699
    int ack = 1;
3700

  
3701
    if (!i2c_bus_busy(s->bus))
3702
        return;
3703

  
3704
    if ((s->control >> 2) & 1) {				/* RM */
3705
        if ((s->control >> 1) & 1) {				/* STP */
3706
            i2c_end_transfer(s->bus);
3707
            s->control &= ~(1 << 1);				/* STP */
3708
            s->count_cur = s->count;
3709
        } else if ((s->control >> 9) & 1) {			/* TRX */
3710
            while (ack && s->txlen)
3711
                ack = (i2c_send(s->bus,
3712
                                        (s->fifo >> ((-- s->txlen) << 3)) &
3713
                                        0xff) >= 0);
3714
            s->stat |= 1 << 4;					/* XRDY */
3715
        } else {
3716
            while (s->rxlen < 4)
3717
                s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
3718
            s->stat |= 1 << 3;					/* RRDY */
3719
        }
3720
    } else {
3721
        if ((s->control >> 9) & 1) {				/* TRX */
3722
            while (ack && s->count_cur && s->txlen) {
3723
                ack = (i2c_send(s->bus,
3724
                                        (s->fifo >> ((-- s->txlen) << 3)) &
3725
                                        0xff) >= 0);
3726
                s->count_cur --;
3727
            }
3728
            if (ack && s->count_cur)
3729
                s->stat |= 1 << 4;				/* XRDY */
3730
            if (!s->count_cur) {
3731
                s->stat |= 1 << 2;				/* ARDY */
3732
                s->control &= ~(1 << 10);			/* MST */
3733
            }
3734
        } else {
3735
            while (s->count_cur && s->rxlen < 4) {
3736
                s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3);
3737
                s->count_cur --;
3738
            }
3739
            if (s->rxlen)
3740
                s->stat |= 1 << 3;				/* RRDY */
3741
        }
3742
        if (!s->count_cur) {
3743
            if ((s->control >> 1) & 1) {			/* STP */
3744
                i2c_end_transfer(s->bus);
3745
                s->control &= ~(1 << 1);			/* STP */
3746
                s->count_cur = s->count;
3747
            } else {
3748
                s->stat |= 1 << 2;				/* ARDY */
3749
                s->control &= ~(1 << 10);			/* MST */
3750
            }
3751
        }
3752
    }
3753

  
3754
    s->stat |= (!ack) << 1;					/* NACK */
3755
    if (!ack)
3756
        s->control &= ~(1 << 1);				/* STP */
3757
}
3758

  
3759
static void omap_i2c_reset(struct omap_i2c_s *s)
3760
{
3761
    s->mask = 0;
3762
    s->stat = 0;
3763
    s->dma = 0;
3764
    s->count = 0;
3765
    s->count_cur = 0;
3766
    s->fifo = 0;
3767
    s->rxlen = 0;
3768
    s->txlen = 0;
3769
    s->control = 0;
3770
    s->addr[0] = 0;
3771
    s->addr[1] = 0;
3772
    s->divider = 0;
3773
    s->times[0] = 0;
3774
    s->times[1] = 0;
3775
    s->test = 0;
3776
}
3777

  
3778
static uint32_t omap_i2c_read(void *opaque, target_phys_addr_t addr)
3779
{
3780
    struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
3781
    int offset = addr - s->base;
3782
    uint16_t ret;
3783

  
3784
    switch (offset) {
3785
    case 0x00:	/* I2C_REV */
3786
        /* TODO: set a value greater or equal to real hardware */
3787
        return 0x11;						/* REV */
3788

  
3789
    case 0x04:	/* I2C_IE */
3790
        return s->mask;
3791

  
3792
    case 0x08:	/* I2C_STAT */
3793
        return s->stat | (i2c_bus_busy(s->bus) << 12);
3794

  
3795
    case 0x0c:	/* I2C_IV */
3796
        ret = ffs(s->stat & s->mask);
3797
        if (ret)
3798
            s->stat ^= 1 << (ret - 1);
3799
        omap_i2c_interrupts_update(s);
3800
        return ret;
3801

  
3802
    case 0x14:	/* I2C_BUF */
3803
        return s->dma;
3804

  
3805
    case 0x18:	/* I2C_CNT */
3806
        return s->count_cur;					/* DCOUNT */
3807

  
3808
    case 0x1c:	/* I2C_DATA */
3809
        ret = 0;
3810
        if (s->control & (1 << 14)) {				/* BE */
3811
            ret |= ((s->fifo >> 0) & 0xff) << 8;
3812
            ret |= ((s->fifo >> 8) & 0xff) << 0;
3813
        } else {
3814
            ret |= ((s->fifo >> 8) & 0xff) << 8;
3815
            ret |= ((s->fifo >> 0) & 0xff) << 0;
3816
        }
3817
        if (s->rxlen == 1) {
3818
            s->stat |= 1 << 15;					/* SBD */
3819
            s->rxlen = 0;
3820
        } else if (s->rxlen > 1) {
3821
            if (s->rxlen > 2)
3822
                s->fifo >>= 16;
3823
            s->rxlen -= 2;
3824
        } else
3825
            /* XXX: remote access (qualifier) error - what's that?  */;
3826
        if (!s->rxlen) {
3827
            s->stat |= ~(1 << 3);				/* RRDY */
3828
            if (((s->control >> 10) & 1) &&			/* MST */
3829
                            ((~s->control >> 9) & 1)) {		/* TRX */
3830
                s->stat |= 1 << 2;				/* ARDY */
3831
                s->control &= ~(1 << 10);			/* MST */
3832
            }
3833
        }
3834
        s->stat &= ~(1 << 11);					/* ROVR */
3835
        omap_i2c_fifo_run(s);
3836
        omap_i2c_interrupts_update(s);
3837
        return ret;
3838

  
3839
    case 0x24:	/* I2C_CON */
3840
        return s->control;
3841

  
3842
    case 0x28:	/* I2C_OA */
3843
        return s->addr[0];
3844

  
3845
    case 0x2c:	/* I2C_SA */
3846
        return s->addr[1];
3847

  
3848
    case 0x30:	/* I2C_PSC */
3849
        return s->divider;
3850

  
3851
    case 0x34:	/* I2C_SCLL */
3852
        return s->times[0];
3853

  
3854
    case 0x38:	/* I2C_SCLH */
3855
        return s->times[1];
3856

  
3857
    case 0x3c:	/* I2C_SYSTEST */
3858
        if (s->test & (1 << 15)) {				/* ST_EN */
3859
            s->test ^= 0xa;
3860
            return s->test;
3861
        } else
3862
            return s->test & ~0x300f;
3863
    }
3864

  
3865
    OMAP_BAD_REG(addr);
3866
    return 0;
3867
}
3868

  
3869
static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
3870
                uint32_t value)
3871
{
3872
    struct omap_i2c_s *s = (struct omap_i2c_s *) opaque;
3873
    int offset = addr - s->base;
3874
    int nack;
3875

  
3876
    switch (offset) {
3877
    case 0x00:	/* I2C_REV */
3878
    case 0x08:	/* I2C_STAT */
3879
    case 0x0c:	/* I2C_IV */
3880
        OMAP_BAD_REG(addr);
3881
        return;
3882

  
3883
    case 0x04:	/* I2C_IE */
3884
        s->mask = value & 0x1f;
3885
        break;
3886

  
3887
    case 0x14:	/* I2C_BUF */
3888
        s->dma = value & 0x8080;
3889
        if (value & (1 << 15))					/* RDMA_EN */
3890
            s->mask &= ~(1 << 3);				/* RRDY_IE */
3891
        if (value & (1 << 7))					/* XDMA_EN */
3892
            s->mask &= ~(1 << 4);				/* XRDY_IE */
3893
        break;
3894

  
3895
    case 0x18:	/* I2C_CNT */
3896
        s->count = value;					/* DCOUNT */
3897
        break;
3898

  
3899
    case 0x1c:	/* I2C_DATA */
3900
        if (s->txlen > 2) {
3901
            /* XXX: remote access (qualifier) error - what's that?  */
3902
            break;
3903
        }
3904
        s->fifo <<= 16;
3905
        s->txlen += 2;
3906
        if (s->control & (1 << 14)) {				/* BE */
3907
            s->fifo |= ((value >> 8) & 0xff) << 8;
3908
            s->fifo |= ((value >> 0) & 0xff) << 0;
3909
        } else {
3910
            s->fifo |= ((value >> 0) & 0xff) << 8;
3911
            s->fifo |= ((value >> 8) & 0xff) << 0;
3912
        }
3913
        s->stat &= ~(1 << 10);					/* XUDF */
3914
        if (s->txlen > 2)
3915
            s->stat &= ~(1 << 4);				/* XRDY */
3916
        omap_i2c_fifo_run(s);
3917
        omap_i2c_interrupts_update(s);
3918
        break;
3919

  
3920
    case 0x24:	/* I2C_CON */
3921
        s->control = value & 0xcf07;
3922
        if (~value & (1 << 15)) {				/* I2C_EN */
3923
            omap_i2c_reset(s);
3924
            break;
3925
        }
3926
        if (~value & (1 << 10)) {				/* MST */
3927
            printf("%s: I^2C slave mode not supported\n", __FUNCTION__);
3928
            break;
3929
        }
3930
        if (value & (1 << 9)) {					/* XA */
3931
            printf("%s: 10-bit addressing mode not supported\n", __FUNCTION__);
3932
            break;
3933
        }
3934
        if (value & (1 << 0)) {					/* STT */
3935
            nack = !!i2c_start_transfer(s->bus, s->addr[1],	/* SA */
3936
                            (~value >> 9) & 1);			/* TRX */
3937
            s->stat |= nack << 1;				/* NACK */
3938
            s->control &= ~(1 << 0);				/* STT */
3939
            if (nack)
3940
                s->control &= ~(1 << 1);			/* STP */
3941
            else
3942
                omap_i2c_fifo_run(s);
3943
            omap_i2c_interrupts_update(s);
3944
        }
3945
        break;
3946

  
3947
    case 0x28:	/* I2C_OA */
3948
        s->addr[0] = value & 0x3ff;
3949
        i2c_set_slave_address(&s->slave, value & 0x7f);
3950
        break;
3951

  
3952
    case 0x2c:	/* I2C_SA */
3953
        s->addr[1] = value & 0x3ff;
3954
        break;
3955

  
3956
    case 0x30:	/* I2C_PSC */
3957
        s->divider = value;
3958
        break;
3959

  
3960
    case 0x34:	/* I2C_SCLL */
3961
        s->times[0] = value;
3962
        break;
3963

  
3964
    case 0x38:	/* I2C_SCLH */
3965
        s->times[1] = value;
3966
        break;
3967

  
3968
    case 0x3c:	/* I2C_SYSTEST */
3969
        s->test = value & 0xf00f;
3970
        if (value & (1 << 15))					/* ST_EN */
3971
            printf("%s: System Test not supported\n", __FUNCTION__);
3972
        break;
3973

  
3974
    default:
3975
        OMAP_BAD_REG(addr);
3976
        return;
3977
    }
3978
}
3979

  
3980
static CPUReadMemoryFunc *omap_i2c_readfn[] = {
3981
    omap_badwidth_read16,
3982
    omap_i2c_read,
3983
    omap_badwidth_read16,
3984
};
3985

  
3986
static CPUWriteMemoryFunc *omap_i2c_writefn[] = {
3987
    omap_badwidth_write16,
3988
    omap_i2c_write,
3989
    omap_i2c_write,	/* TODO: Only the last fifo write can be 8 bit.  */
3990
};
3991

  
3992
struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
3993
                qemu_irq irq, qemu_irq *dma, omap_clk clk)
3994
{
3995
    int iomemtype;
3996
    struct omap_i2c_s *s = (struct omap_i2c_s *)
3997
            qemu_mallocz(sizeof(struct omap_i2c_s));
3998

  
3999
    s->base = base;
4000
    s->irq = irq;
4001
    s->drq[0] = dma[0];
4002
    s->drq[1] = dma[1];
4003
    s->slave.event = omap_i2c_event;
4004
    s->slave.recv = omap_i2c_rx;
4005
    s->slave.send = omap_i2c_tx;
4006
    s->bus = i2c_init_bus();
4007
    omap_i2c_reset(s);
4008

  
4009
    iomemtype = cpu_register_io_memory(0, omap_i2c_readfn,
4010
                    omap_i2c_writefn, s);
4011
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4012

  
4013
    return s;
4014
}
4015

  
4016
i2c_bus *omap_i2c_bus(struct omap_i2c_s *s)
4017
{
4018
    return s->bus;
4019
}
4020

  
3606 4021
/* General chip reset */
3607 4022
static void omap_mpu_reset(void *opaque)
3608 4023
{
......
3634 4049
    omap_gpio_reset(mpu->gpio);
3635 4050
    omap_uwire_reset(mpu->microwire);
3636 4051
    omap_pwl_reset(mpu);
4052
    omap_pwt_reset(mpu);
4053
    omap_i2c_reset(mpu->i2c);
3637 4054
    cpu_reset(mpu->env);
3638 4055
}
3639 4056

  
......
3758 4175
    omap_pwl_init(0xfffb5800, s, omap_findclk(s, "clk32-kHz"));
3759 4176
    omap_pwt_init(0xfffb6000, s, omap_findclk(s, "xtal_osc_12m"));
3760 4177

  
4178
    s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4179
                    &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4180

  
3761 4181
    qemu_register_reset(omap_mpu_reset, s);
3762 4182

  
3763 4183
    return s;

Also available in: Unified diff