Revision f9d43072 hw/omap.c

b/hw/omap.c
4626 4626
    slave->tx_start = qemu_allocate_irqs(omap_mcbsp_i2s_start, s, 1)[0];
4627 4627
}
4628 4628

  
4629
/* LED Pulse Generators */
4630
struct omap_lpg_s {
4631
    target_phys_addr_t base;
4632
    QEMUTimer *tm;
4633

  
4634
    uint8_t control;
4635
    uint8_t power;
4636
    int64_t on;
4637
    int64_t period;
4638
    int clk;
4639
    int cycle;
4640
};
4641

  
4642
static void omap_lpg_tick(void *opaque)
4643
{
4644
    struct omap_lpg_s *s = opaque;
4645

  
4646
    if (s->cycle)
4647
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->period - s->on);
4648
    else
4649
        qemu_mod_timer(s->tm, qemu_get_clock(rt_clock) + s->on);
4650

  
4651
    s->cycle = !s->cycle;
4652
    printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
4653
}
4654

  
4655
static void omap_lpg_update(struct omap_lpg_s *s)
4656
{
4657
    int64_t on, period = 1, ticks = 1000;
4658
    static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
4659

  
4660
    if (~s->control & (1 << 6))					/* LPGRES */
4661
        on = 0;
4662
    else if (s->control & (1 << 7))				/* PERM_ON */
4663
        on = period;
4664
    else {
4665
        period = muldiv64(ticks, per[s->control & 7],		/* PERCTRL */
4666
                        256 / 32);
4667
        on = (s->clk && s->power) ? muldiv64(ticks,
4668
                        per[(s->control >> 3) & 7], 256) : 0;	/* ONCTRL */
4669
    }
4670

  
4671
    qemu_del_timer(s->tm);
4672
    if (on == period && s->on < s->period)
4673
        printf("%s: LED is on\n", __FUNCTION__);
4674
    else if (on == 0 && s->on)
4675
        printf("%s: LED is off\n", __FUNCTION__);
4676
    else if (on && (on != s->on || period != s->period)) {
4677
        s->cycle = 0;
4678
        s->on = on;
4679
        s->period = period;
4680
        omap_lpg_tick(s);
4681
        return;
4682
    }
4683

  
4684
    s->on = on;
4685
    s->period = period;
4686
}
4687

  
4688
static void omap_lpg_reset(struct omap_lpg_s *s)
4689
{
4690
    s->control = 0x00;
4691
    s->power = 0x00;
4692
    s->clk = 1;
4693
    omap_lpg_update(s);
4694
}
4695

  
4696
static uint32_t omap_lpg_read(void *opaque, target_phys_addr_t addr)
4697
{
4698
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4699
    int offset = addr & OMAP_MPUI_REG_MASK;
4700

  
4701
    switch (offset) {
4702
    case 0x00:	/* LCR */
4703
        return s->control;
4704

  
4705
    case 0x04:	/* PMR */
4706
        return s->power;
4707
    }
4708

  
4709
    OMAP_BAD_REG(addr);
4710
    return 0;
4711
}
4712

  
4713
static void omap_lpg_write(void *opaque, target_phys_addr_t addr,
4714
                uint32_t value)
4715
{
4716
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4717
    int offset = addr & OMAP_MPUI_REG_MASK;
4718

  
4719
    switch (offset) {
4720
    case 0x00:	/* LCR */
4721
        if (~value & (1 << 6))					/* LPGRES */
4722
            omap_lpg_reset(s);
4723
        s->control = value & 0xff;
4724
        omap_lpg_update(s);
4725
        return;
4726

  
4727
    case 0x04:	/* PMR */
4728
        s->power = value & 0x01;
4729
        omap_lpg_update(s);
4730
        return;
4731

  
4732
    default:
4733
        OMAP_BAD_REG(addr);
4734
        return;
4735
    }
4736
}
4737

  
4738
static CPUReadMemoryFunc *omap_lpg_readfn[] = {
4739
    omap_lpg_read,
4740
    omap_badwidth_read8,
4741
    omap_badwidth_read8,
4742
};
4743

  
4744
static CPUWriteMemoryFunc *omap_lpg_writefn[] = {
4745
    omap_lpg_write,
4746
    omap_badwidth_write8,
4747
    omap_badwidth_write8,
4748
};
4749

  
4750
static void omap_lpg_clk_update(void *opaque, int line, int on)
4751
{
4752
    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
4753

  
4754
    s->clk = on;
4755
    omap_lpg_update(s);
4756
}
4757

  
4758
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
4759
{
4760
    int iomemtype;
4761
    struct omap_lpg_s *s = (struct omap_lpg_s *)
4762
            qemu_mallocz(sizeof(struct omap_lpg_s));
4763

  
4764
    s->base = base;
4765
    s->tm = qemu_new_timer(rt_clock, omap_lpg_tick, s);
4766

  
4767
    omap_lpg_reset(s);
4768

  
4769
    iomemtype = cpu_register_io_memory(0, omap_lpg_readfn,
4770
                    omap_lpg_writefn, s);
4771
    cpu_register_physical_memory(s->base, 0x800, iomemtype);
4772

  
4773
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_lpg_clk_update, s, 1)[0]);
4774

  
4775
    return s;
4776
}
4777

  
4778
/* MPUI Peripheral Bridge configuration */
4779
static uint32_t omap_mpui_io_read(void *opaque, target_phys_addr_t addr)
4780
{
4781
    if (addr == OMAP_MPUI_BASE)	/* CMR */
4782
        return 0xfe4d;
4783

  
4784
    OMAP_BAD_REG(addr);
4785
    return 0;
4786
}
4787

  
4788
static CPUReadMemoryFunc *omap_mpui_io_readfn[] = {
4789
    omap_badwidth_read16,
4790
    omap_mpui_io_read,
4791
    omap_badwidth_read16,
4792
};
4793

  
4794
static CPUWriteMemoryFunc *omap_mpui_io_writefn[] = {
4795
    omap_badwidth_write16,
4796
    omap_badwidth_write16,
4797
    omap_badwidth_write16,
4798
};
4799

  
4800
static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4801
{
4802
    int iomemtype = cpu_register_io_memory(0, omap_mpui_io_readfn,
4803
                    omap_mpui_io_writefn, mpu);
4804
    cpu_register_physical_memory(OMAP_MPUI_BASE, 0x7fff, iomemtype);
4805
}
4806

  
4629 4807
/* General chip reset */
4630 4808
static void omap_mpu_reset(void *opaque)
4631 4809
{
......
4663 4841
    omap_mcbsp_reset(mpu->mcbsp1);
4664 4842
    omap_mcbsp_reset(mpu->mcbsp2);
4665 4843
    omap_mcbsp_reset(mpu->mcbsp3);
4844
    omap_lpg_reset(mpu->led[0]);
4845
    omap_lpg_reset(mpu->led[1]);
4666 4846
    cpu_reset(mpu->env);
4667 4847
}
4668 4848

  
......
4846 5026
    s->mcbsp3 = omap_mcbsp_init(0xfffb7000, &s->irq[1][OMAP_INT_McBSP3TX],
4847 5027
                    &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
4848 5028

  
5029
    s->led[0] = omap_lpg_init(0xfffbd000, omap_findclk(s, "clk32-kHz"));
5030
    s->led[1] = omap_lpg_init(0xfffbd800, omap_findclk(s, "clk32-kHz"));
5031

  
4849 5032
    /* Register mappings not currenlty implemented:
4850 5033
     * MCSI2 Comm	fffb2000 - fffb27ff (not mapped on OMAP310)
4851 5034
     * MCSI1 Bluetooth	fffb2800 - fffb2fff (not mapped on OMAP310)
......
4855 5038
     * FAC		fffba800 - fffbafff
4856 5039
     * HDQ/1-Wire	fffbc000 - fffbc7ff
4857 5040
     * TIPB switches	fffbc800 - fffbcfff
4858
     * LED1		fffbd000 - fffbd7ff
4859
     * LED2		fffbd800 - fffbdfff
4860 5041
     * Mailbox		fffcf000 - fffcf7ff
4861 5042
     * Local bus IF	fffec100 - fffec1ff
4862 5043
     * Local bus MMU	fffec200 - fffec2ff
......
4864 5045
     */
4865 5046

  
4866 5047
    omap_setup_dsp_mapping(omap15xx_dsp_mm);
5048
    omap_setup_mpui_io(s);
4867 5049

  
4868 5050
    qemu_register_reset(omap_mpu_reset, s);
4869 5051

  

Also available in: Unified diff