Revision d82310f7

b/hw/omap.h
668 668
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
669 669
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
670 670

  
671
/* omap1 gpio module interface */
671 672
struct omap_gpio_s;
672 673
struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
673 674
                qemu_irq irq, omap_clk clk);
......
675 676
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s);
676 677
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler);
677 678

  
679
/* omap2 gpio interface */
678 680
struct omap_gpif_s;
679 681
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
680 682
                qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules);
683
void omap_gpif_reset(struct omap_gpif_s *s);
681 684
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start);
682 685
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler);
683 686

  
b/hw/omap2.c
559 559
                      omap_synctimer_readfn, omap_synctimer_writefn, s));
560 560
}
561 561

  
562
/* General-Purpose Interface of OMAP2 */
563
struct omap2_gpio_s {
564
    qemu_irq irq[2];
565
    qemu_irq wkup;
566
    qemu_irq *in;
567
    qemu_irq handler[32];
568

  
569
    uint8_t config[2];
570
    uint32_t inputs;
571
    uint32_t outputs;
572
    uint32_t dir;
573
    uint32_t level[2];
574
    uint32_t edge[2];
575
    uint32_t mask[2];
576
    uint32_t wumask;
577
    uint32_t ints[2];
578
    uint32_t debounce;
579
    uint8_t delay;
580
};
581

  
582
static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s,
583
                int line)
584
{
585
    qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
586
}
587

  
588
static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line)
589
{
590
    if (!(s->config[0] & (1 << 2)))			/* ENAWAKEUP */
591
        return;
592
    if (!(s->config[0] & (3 << 3)))			/* Force Idle */
593
        return;
594
    if (!(s->wumask & (1 << line)))
595
        return;
596

  
597
    qemu_irq_raise(s->wkup);
598
}
599

  
600
static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s,
601
                uint32_t diff)
602
{
603
    int ln;
604

  
605
    s->outputs ^= diff;
606
    diff &= ~s->dir;
607
    while ((ln = ffs(diff))) {
608
        ln --;
609
        qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
610
        diff &= ~(1 << ln);
611
    }
612
}
613

  
614
static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line)
615
{
616
    s->ints[line] |= s->dir &
617
            ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
618
    omap_gpio_module_int_update(s, line);
619
}
620

  
621
static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line)
622
{
623
    s->ints[0] |= 1 << line;
624
    omap_gpio_module_int_update(s, 0);
625
    s->ints[1] |= 1 << line;
626
    omap_gpio_module_int_update(s, 1);
627
    omap_gpio_module_wake(s, line);
628
}
629

  
630
static void omap_gpio_module_set(void *opaque, int line, int level)
631
{
632
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
633

  
634
    if (level) {
635
        if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
636
            omap_gpio_module_int(s, line);
637
        s->inputs |= 1 << line;
638
    } else {
639
        if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
640
            omap_gpio_module_int(s, line);
641
        s->inputs &= ~(1 << line);
642
    }
643
}
644

  
645
static void omap_gpio_module_reset(struct omap2_gpio_s *s)
646
{
647
    s->config[0] = 0;
648
    s->config[1] = 2;
649
    s->ints[0] = 0;
650
    s->ints[1] = 0;
651
    s->mask[0] = 0;
652
    s->mask[1] = 0;
653
    s->wumask = 0;
654
    s->dir = ~0;
655
    s->level[0] = 0;
656
    s->level[1] = 0;
657
    s->edge[0] = 0;
658
    s->edge[1] = 0;
659
    s->debounce = 0;
660
    s->delay = 0;
661
}
662

  
663
static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr)
664
{
665
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
666

  
667
    switch (addr) {
668
    case 0x00:	/* GPIO_REVISION */
669
        return 0x18;
670

  
671
    case 0x10:	/* GPIO_SYSCONFIG */
672
        return s->config[0];
673

  
674
    case 0x14:	/* GPIO_SYSSTATUS */
675
        return 0x01;
676

  
677
    case 0x18:	/* GPIO_IRQSTATUS1 */
678
        return s->ints[0];
679

  
680
    case 0x1c:	/* GPIO_IRQENABLE1 */
681
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
682
    case 0x64:	/* GPIO_SETIRQENABLE1 */
683
        return s->mask[0];
684

  
685
    case 0x20:	/* GPIO_WAKEUPENABLE */
686
    case 0x80:	/* GPIO_CLEARWKUENA */
687
    case 0x84:	/* GPIO_SETWKUENA */
688
        return s->wumask;
689

  
690
    case 0x28:	/* GPIO_IRQSTATUS2 */
691
        return s->ints[1];
692

  
693
    case 0x2c:	/* GPIO_IRQENABLE2 */
694
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
695
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
696
        return s->mask[1];
697

  
698
    case 0x30:	/* GPIO_CTRL */
699
        return s->config[1];
700

  
701
    case 0x34:	/* GPIO_OE */
702
        return s->dir;
703

  
704
    case 0x38:	/* GPIO_DATAIN */
705
        return s->inputs;
706

  
707
    case 0x3c:	/* GPIO_DATAOUT */
708
    case 0x90:	/* GPIO_CLEARDATAOUT */
709
    case 0x94:	/* GPIO_SETDATAOUT */
710
        return s->outputs;
711

  
712
    case 0x40:	/* GPIO_LEVELDETECT0 */
713
        return s->level[0];
714

  
715
    case 0x44:	/* GPIO_LEVELDETECT1 */
716
        return s->level[1];
717

  
718
    case 0x48:	/* GPIO_RISINGDETECT */
719
        return s->edge[0];
720

  
721
    case 0x4c:	/* GPIO_FALLINGDETECT */
722
        return s->edge[1];
723

  
724
    case 0x50:	/* GPIO_DEBOUNCENABLE */
725
        return s->debounce;
726

  
727
    case 0x54:	/* GPIO_DEBOUNCINGTIME */
728
        return s->delay;
729
    }
730

  
731
    OMAP_BAD_REG(addr);
732
    return 0;
733
}
734

  
735
static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr,
736
                uint32_t value)
737
{
738
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
739
    uint32_t diff;
740
    int ln;
741

  
742
    switch (addr) {
743
    case 0x00:	/* GPIO_REVISION */
744
    case 0x14:	/* GPIO_SYSSTATUS */
745
    case 0x38:	/* GPIO_DATAIN */
746
        OMAP_RO_REG(addr);
747
        break;
748

  
749
    case 0x10:	/* GPIO_SYSCONFIG */
750
        if (((value >> 3) & 3) == 3)
751
            fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
752
        if (value & 2)
753
            omap_gpio_module_reset(s);
754
        s->config[0] = value & 0x1d;
755
        break;
756

  
757
    case 0x18:	/* GPIO_IRQSTATUS1 */
758
        if (s->ints[0] & value) {
759
            s->ints[0] &= ~value;
760
            omap_gpio_module_level_update(s, 0);
761
        }
762
        break;
763

  
764
    case 0x1c:	/* GPIO_IRQENABLE1 */
765
        s->mask[0] = value;
766
        omap_gpio_module_int_update(s, 0);
767
        break;
768

  
769
    case 0x20:	/* GPIO_WAKEUPENABLE */
770
        s->wumask = value;
771
        break;
772

  
773
    case 0x28:	/* GPIO_IRQSTATUS2 */
774
        if (s->ints[1] & value) {
775
            s->ints[1] &= ~value;
776
            omap_gpio_module_level_update(s, 1);
777
        }
778
        break;
779

  
780
    case 0x2c:	/* GPIO_IRQENABLE2 */
781
        s->mask[1] = value;
782
        omap_gpio_module_int_update(s, 1);
783
        break;
784

  
785
    case 0x30:	/* GPIO_CTRL */
786
        s->config[1] = value & 7;
787
        break;
788

  
789
    case 0x34:	/* GPIO_OE */
790
        diff = s->outputs & (s->dir ^ value);
791
        s->dir = value;
792

  
793
        value = s->outputs & ~s->dir;
794
        while ((ln = ffs(diff))) {
795
            diff &= ~(1 <<-- ln);
796
            qemu_set_irq(s->handler[ln], (value >> ln) & 1);
797
        }
798

  
799
        omap_gpio_module_level_update(s, 0);
800
        omap_gpio_module_level_update(s, 1);
801
        break;
802

  
803
    case 0x3c:	/* GPIO_DATAOUT */
804
        omap_gpio_module_out_update(s, s->outputs ^ value);
805
        break;
806

  
807
    case 0x40:	/* GPIO_LEVELDETECT0 */
808
        s->level[0] = value;
809
        omap_gpio_module_level_update(s, 0);
810
        omap_gpio_module_level_update(s, 1);
811
        break;
812

  
813
    case 0x44:	/* GPIO_LEVELDETECT1 */
814
        s->level[1] = value;
815
        omap_gpio_module_level_update(s, 0);
816
        omap_gpio_module_level_update(s, 1);
817
        break;
818

  
819
    case 0x48:	/* GPIO_RISINGDETECT */
820
        s->edge[0] = value;
821
        break;
822

  
823
    case 0x4c:	/* GPIO_FALLINGDETECT */
824
        s->edge[1] = value;
825
        break;
826

  
827
    case 0x50:	/* GPIO_DEBOUNCENABLE */
828
        s->debounce = value;
829
        break;
830

  
831
    case 0x54:	/* GPIO_DEBOUNCINGTIME */
832
        s->delay = value;
833
        break;
834

  
835
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
836
        s->mask[0] &= ~value;
837
        omap_gpio_module_int_update(s, 0);
838
        break;
839

  
840
    case 0x64:	/* GPIO_SETIRQENABLE1 */
841
        s->mask[0] |= value;
842
        omap_gpio_module_int_update(s, 0);
843
        break;
844

  
845
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
846
        s->mask[1] &= ~value;
847
        omap_gpio_module_int_update(s, 1);
848
        break;
849

  
850
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
851
        s->mask[1] |= value;
852
        omap_gpio_module_int_update(s, 1);
853
        break;
854

  
855
    case 0x80:	/* GPIO_CLEARWKUENA */
856
        s->wumask &= ~value;
857
        break;
858

  
859
    case 0x84:	/* GPIO_SETWKUENA */
860
        s->wumask |= value;
861
        break;
862

  
863
    case 0x90:	/* GPIO_CLEARDATAOUT */
864
        omap_gpio_module_out_update(s, s->outputs & value);
865
        break;
866

  
867
    case 0x94:	/* GPIO_SETDATAOUT */
868
        omap_gpio_module_out_update(s, ~s->outputs & value);
869
        break;
870

  
871
    default:
872
        OMAP_BAD_REG(addr);
873
        return;
874
    }
875
}
876

  
877
static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr)
878
{
879
    return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
880
}
881

  
882
static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr,
883
                uint32_t value)
884
{
885
    uint32_t cur = 0;
886
    uint32_t mask = 0xffff;
887

  
888
    switch (addr & ~3) {
889
    case 0x00:	/* GPIO_REVISION */
890
    case 0x14:	/* GPIO_SYSSTATUS */
891
    case 0x38:	/* GPIO_DATAIN */
892
        OMAP_RO_REG(addr);
893
        break;
894

  
895
    case 0x10:	/* GPIO_SYSCONFIG */
896
    case 0x1c:	/* GPIO_IRQENABLE1 */
897
    case 0x20:	/* GPIO_WAKEUPENABLE */
898
    case 0x2c:	/* GPIO_IRQENABLE2 */
899
    case 0x30:	/* GPIO_CTRL */
900
    case 0x34:	/* GPIO_OE */
901
    case 0x3c:	/* GPIO_DATAOUT */
902
    case 0x40:	/* GPIO_LEVELDETECT0 */
903
    case 0x44:	/* GPIO_LEVELDETECT1 */
904
    case 0x48:	/* GPIO_RISINGDETECT */
905
    case 0x4c:	/* GPIO_FALLINGDETECT */
906
    case 0x50:	/* GPIO_DEBOUNCENABLE */
907
    case 0x54:	/* GPIO_DEBOUNCINGTIME */
908
        cur = omap_gpio_module_read(opaque, addr & ~3) &
909
                ~(mask << ((addr & 3) << 3));
910

  
911
        /* Fall through.  */
912
    case 0x18:	/* GPIO_IRQSTATUS1 */
913
    case 0x28:	/* GPIO_IRQSTATUS2 */
914
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
915
    case 0x64:	/* GPIO_SETIRQENABLE1 */
916
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
917
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
918
    case 0x80:	/* GPIO_CLEARWKUENA */
919
    case 0x84:	/* GPIO_SETWKUENA */
920
    case 0x90:	/* GPIO_CLEARDATAOUT */
921
    case 0x94:	/* GPIO_SETDATAOUT */
922
        value <<= (addr & 3) << 3;
923
        omap_gpio_module_write(opaque, addr, cur | value);
924
        break;
925

  
926
    default:
927
        OMAP_BAD_REG(addr);
928
        return;
929
    }
930
}
931

  
932
static CPUReadMemoryFunc * const omap_gpio_module_readfn[] = {
933
    omap_gpio_module_readp,
934
    omap_gpio_module_readp,
935
    omap_gpio_module_read,
936
};
937

  
938
static CPUWriteMemoryFunc * const omap_gpio_module_writefn[] = {
939
    omap_gpio_module_writep,
940
    omap_gpio_module_writep,
941
    omap_gpio_module_write,
942
};
943

  
944
static void omap_gpio_module_init(struct omap2_gpio_s *s,
945
                struct omap_target_agent_s *ta, int region,
946
                qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
947
                omap_clk fclk, omap_clk iclk)
948
{
949
    int iomemtype;
950

  
951
    s->irq[0] = mpu;
952
    s->irq[1] = dsp;
953
    s->wkup = wkup;
954
    s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32);
955

  
956
    iomemtype = l4_register_io_memory(omap_gpio_module_readfn,
957
                    omap_gpio_module_writefn, s);
958
    omap_l4_attach(ta, region, iomemtype);
959
}
960

  
961
struct omap_gpif_s {
962
    struct omap2_gpio_s module[5];
963
    int modules;
964

  
965
    int autoidle;
966
    int gpo;
967
};
968

  
969
static void omap_gpif_reset(struct omap_gpif_s *s)
970
{
971
    int i;
972

  
973
    for (i = 0; i < s->modules; i ++)
974
        omap_gpio_module_reset(s->module + i);
975

  
976
    s->autoidle = 0;
977
    s->gpo = 0;
978
}
979

  
980
static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
981
{
982
    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
983

  
984
    switch (addr) {
985
    case 0x00:	/* IPGENERICOCPSPL_REVISION */
986
        return 0x18;
987

  
988
    case 0x10:	/* IPGENERICOCPSPL_SYSCONFIG */
989
        return s->autoidle;
990

  
991
    case 0x14:	/* IPGENERICOCPSPL_SYSSTATUS */
992
        return 0x01;
993

  
994
    case 0x18:	/* IPGENERICOCPSPL_IRQSTATUS */
995
        return 0x00;
996

  
997
    case 0x40:	/* IPGENERICOCPSPL_GPO */
998
        return s->gpo;
999

  
1000
    case 0x50:	/* IPGENERICOCPSPL_GPI */
1001
        return 0x00;
1002
    }
1003

  
1004
    OMAP_BAD_REG(addr);
1005
    return 0;
1006
}
1007

  
1008
static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
1009
                uint32_t value)
1010
{
1011
    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
1012

  
1013
    switch (addr) {
1014
    case 0x00:	/* IPGENERICOCPSPL_REVISION */
1015
    case 0x14:	/* IPGENERICOCPSPL_SYSSTATUS */
1016
    case 0x18:	/* IPGENERICOCPSPL_IRQSTATUS */
1017
    case 0x50:	/* IPGENERICOCPSPL_GPI */
1018
        OMAP_RO_REG(addr);
1019
        break;
1020

  
1021
    case 0x10:	/* IPGENERICOCPSPL_SYSCONFIG */
1022
        if (value & (1 << 1))					/* SOFTRESET */
1023
            omap_gpif_reset(s);
1024
        s->autoidle = value & 1;
1025
        break;
1026

  
1027
    case 0x40:	/* IPGENERICOCPSPL_GPO */
1028
        s->gpo = value & 1;
1029
        break;
1030

  
1031
    default:
1032
        OMAP_BAD_REG(addr);
1033
        return;
1034
    }
1035
}
1036

  
1037
static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = {
1038
    omap_gpif_top_read,
1039
    omap_gpif_top_read,
1040
    omap_gpif_top_read,
1041
};
1042

  
1043
static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = {
1044
    omap_gpif_top_write,
1045
    omap_gpif_top_write,
1046
    omap_gpif_top_write,
1047
};
1048

  
1049
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
1050
                qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
1051
{
1052
    int iomemtype, i;
1053
    struct omap_gpif_s *s = (struct omap_gpif_s *)
1054
            qemu_mallocz(sizeof(struct omap_gpif_s));
1055
    int region[4] = { 0, 2, 4, 5 };
1056

  
1057
    s->modules = modules;
1058
    for (i = 0; i < modules; i ++)
1059
        omap_gpio_module_init(s->module + i, ta, region[i],
1060
                              irq[i], NULL, NULL, fclk[i], iclk);
1061

  
1062
    omap_gpif_reset(s);
1063

  
1064
    iomemtype = l4_register_io_memory(omap_gpif_top_readfn,
1065
                    omap_gpif_top_writefn, s);
1066
    omap_l4_attach(ta, 1, iomemtype);
1067

  
1068
    return s;
1069
}
1070

  
1071
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
1072
{
1073
    if (start >= s->modules * 32 || start < 0)
1074
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, start);
1075
    return s->module[start >> 5].in + (start & 31);
1076
}
1077

  
1078
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
1079
{
1080
    if (line >= s->modules * 32 || line < 0)
1081
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
1082
    s->module[line >> 5].handler[line & 31] = handler;
1083
}
1084

  
1085 562
/* Multichannel SPI */
1086 563
struct omap_mcspi_s {
1087 564
    qemu_irq irq;
b/hw/omap_gpio.c
200 200
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
201 201
    s->handler[line] = handler;
202 202
}
203

  
204
/* General-Purpose Interface of OMAP2 */
205
struct omap2_gpio_s {
206
    qemu_irq irq[2];
207
    qemu_irq wkup;
208
    qemu_irq *in;
209
    qemu_irq handler[32];
210

  
211
    uint8_t config[2];
212
    uint32_t inputs;
213
    uint32_t outputs;
214
    uint32_t dir;
215
    uint32_t level[2];
216
    uint32_t edge[2];
217
    uint32_t mask[2];
218
    uint32_t wumask;
219
    uint32_t ints[2];
220
    uint32_t debounce;
221
    uint8_t delay;
222
};
223

  
224
static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
225
                int line)
226
{
227
    qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
228
}
229

  
230
static void omap2_gpio_module_wake(struct omap2_gpio_s *s, int line)
231
{
232
    if (!(s->config[0] & (1 << 2)))			/* ENAWAKEUP */
233
        return;
234
    if (!(s->config[0] & (3 << 3)))			/* Force Idle */
235
        return;
236
    if (!(s->wumask & (1 << line)))
237
        return;
238

  
239
    qemu_irq_raise(s->wkup);
240
}
241

  
242
static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
243
                uint32_t diff)
244
{
245
    int ln;
246

  
247
    s->outputs ^= diff;
248
    diff &= ~s->dir;
249
    while ((ln = ffs(diff))) {
250
        ln --;
251
        qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
252
        diff &= ~(1 << ln);
253
    }
254
}
255

  
256
static void omap2_gpio_module_level_update(struct omap2_gpio_s *s, int line)
257
{
258
    s->ints[line] |= s->dir &
259
            ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
260
    omap2_gpio_module_int_update(s, line);
261
}
262

  
263
static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
264
{
265
    s->ints[0] |= 1 << line;
266
    omap2_gpio_module_int_update(s, 0);
267
    s->ints[1] |= 1 << line;
268
    omap2_gpio_module_int_update(s, 1);
269
    omap2_gpio_module_wake(s, line);
270
}
271

  
272
static void omap2_gpio_module_set(void *opaque, int line, int level)
273
{
274
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
275

  
276
    if (level) {
277
        if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
278
            omap2_gpio_module_int(s, line);
279
        s->inputs |= 1 << line;
280
    } else {
281
        if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
282
            omap2_gpio_module_int(s, line);
283
        s->inputs &= ~(1 << line);
284
    }
285
}
286

  
287
static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
288
{
289
    s->config[0] = 0;
290
    s->config[1] = 2;
291
    s->ints[0] = 0;
292
    s->ints[1] = 0;
293
    s->mask[0] = 0;
294
    s->mask[1] = 0;
295
    s->wumask = 0;
296
    s->dir = ~0;
297
    s->level[0] = 0;
298
    s->level[1] = 0;
299
    s->edge[0] = 0;
300
    s->edge[1] = 0;
301
    s->debounce = 0;
302
    s->delay = 0;
303
}
304

  
305
static uint32_t omap2_gpio_module_read(void *opaque, target_phys_addr_t addr)
306
{
307
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
308

  
309
    switch (addr) {
310
    case 0x00:	/* GPIO_REVISION */
311
        return 0x18;
312

  
313
    case 0x10:	/* GPIO_SYSCONFIG */
314
        return s->config[0];
315

  
316
    case 0x14:	/* GPIO_SYSSTATUS */
317
        return 0x01;
318

  
319
    case 0x18:	/* GPIO_IRQSTATUS1 */
320
        return s->ints[0];
321

  
322
    case 0x1c:	/* GPIO_IRQENABLE1 */
323
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
324
    case 0x64:	/* GPIO_SETIRQENABLE1 */
325
        return s->mask[0];
326

  
327
    case 0x20:	/* GPIO_WAKEUPENABLE */
328
    case 0x80:	/* GPIO_CLEARWKUENA */
329
    case 0x84:	/* GPIO_SETWKUENA */
330
        return s->wumask;
331

  
332
    case 0x28:	/* GPIO_IRQSTATUS2 */
333
        return s->ints[1];
334

  
335
    case 0x2c:	/* GPIO_IRQENABLE2 */
336
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
337
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
338
        return s->mask[1];
339

  
340
    case 0x30:	/* GPIO_CTRL */
341
        return s->config[1];
342

  
343
    case 0x34:	/* GPIO_OE */
344
        return s->dir;
345

  
346
    case 0x38:	/* GPIO_DATAIN */
347
        return s->inputs;
348

  
349
    case 0x3c:	/* GPIO_DATAOUT */
350
    case 0x90:	/* GPIO_CLEARDATAOUT */
351
    case 0x94:	/* GPIO_SETDATAOUT */
352
        return s->outputs;
353

  
354
    case 0x40:	/* GPIO_LEVELDETECT0 */
355
        return s->level[0];
356

  
357
    case 0x44:	/* GPIO_LEVELDETECT1 */
358
        return s->level[1];
359

  
360
    case 0x48:	/* GPIO_RISINGDETECT */
361
        return s->edge[0];
362

  
363
    case 0x4c:	/* GPIO_FALLINGDETECT */
364
        return s->edge[1];
365

  
366
    case 0x50:	/* GPIO_DEBOUNCENABLE */
367
        return s->debounce;
368

  
369
    case 0x54:	/* GPIO_DEBOUNCINGTIME */
370
        return s->delay;
371
    }
372

  
373
    OMAP_BAD_REG(addr);
374
    return 0;
375
}
376

  
377
static void omap2_gpio_module_write(void *opaque, target_phys_addr_t addr,
378
                uint32_t value)
379
{
380
    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
381
    uint32_t diff;
382
    int ln;
383

  
384
    switch (addr) {
385
    case 0x00:	/* GPIO_REVISION */
386
    case 0x14:	/* GPIO_SYSSTATUS */
387
    case 0x38:	/* GPIO_DATAIN */
388
        OMAP_RO_REG(addr);
389
        break;
390

  
391
    case 0x10:	/* GPIO_SYSCONFIG */
392
        if (((value >> 3) & 3) == 3)
393
            fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
394
        if (value & 2)
395
            omap2_gpio_module_reset(s);
396
        s->config[0] = value & 0x1d;
397
        break;
398

  
399
    case 0x18:	/* GPIO_IRQSTATUS1 */
400
        if (s->ints[0] & value) {
401
            s->ints[0] &= ~value;
402
            omap2_gpio_module_level_update(s, 0);
403
        }
404
        break;
405

  
406
    case 0x1c:	/* GPIO_IRQENABLE1 */
407
        s->mask[0] = value;
408
        omap2_gpio_module_int_update(s, 0);
409
        break;
410

  
411
    case 0x20:	/* GPIO_WAKEUPENABLE */
412
        s->wumask = value;
413
        break;
414

  
415
    case 0x28:	/* GPIO_IRQSTATUS2 */
416
        if (s->ints[1] & value) {
417
            s->ints[1] &= ~value;
418
            omap2_gpio_module_level_update(s, 1);
419
        }
420
        break;
421

  
422
    case 0x2c:	/* GPIO_IRQENABLE2 */
423
        s->mask[1] = value;
424
        omap2_gpio_module_int_update(s, 1);
425
        break;
426

  
427
    case 0x30:	/* GPIO_CTRL */
428
        s->config[1] = value & 7;
429
        break;
430

  
431
    case 0x34:	/* GPIO_OE */
432
        diff = s->outputs & (s->dir ^ value);
433
        s->dir = value;
434

  
435
        value = s->outputs & ~s->dir;
436
        while ((ln = ffs(diff))) {
437
            diff &= ~(1 <<-- ln);
438
            qemu_set_irq(s->handler[ln], (value >> ln) & 1);
439
        }
440

  
441
        omap2_gpio_module_level_update(s, 0);
442
        omap2_gpio_module_level_update(s, 1);
443
        break;
444

  
445
    case 0x3c:	/* GPIO_DATAOUT */
446
        omap2_gpio_module_out_update(s, s->outputs ^ value);
447
        break;
448

  
449
    case 0x40:	/* GPIO_LEVELDETECT0 */
450
        s->level[0] = value;
451
        omap2_gpio_module_level_update(s, 0);
452
        omap2_gpio_module_level_update(s, 1);
453
        break;
454

  
455
    case 0x44:	/* GPIO_LEVELDETECT1 */
456
        s->level[1] = value;
457
        omap2_gpio_module_level_update(s, 0);
458
        omap2_gpio_module_level_update(s, 1);
459
        break;
460

  
461
    case 0x48:	/* GPIO_RISINGDETECT */
462
        s->edge[0] = value;
463
        break;
464

  
465
    case 0x4c:	/* GPIO_FALLINGDETECT */
466
        s->edge[1] = value;
467
        break;
468

  
469
    case 0x50:	/* GPIO_DEBOUNCENABLE */
470
        s->debounce = value;
471
        break;
472

  
473
    case 0x54:	/* GPIO_DEBOUNCINGTIME */
474
        s->delay = value;
475
        break;
476

  
477
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
478
        s->mask[0] &= ~value;
479
        omap2_gpio_module_int_update(s, 0);
480
        break;
481

  
482
    case 0x64:	/* GPIO_SETIRQENABLE1 */
483
        s->mask[0] |= value;
484
        omap2_gpio_module_int_update(s, 0);
485
        break;
486

  
487
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
488
        s->mask[1] &= ~value;
489
        omap2_gpio_module_int_update(s, 1);
490
        break;
491

  
492
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
493
        s->mask[1] |= value;
494
        omap2_gpio_module_int_update(s, 1);
495
        break;
496

  
497
    case 0x80:	/* GPIO_CLEARWKUENA */
498
        s->wumask &= ~value;
499
        break;
500

  
501
    case 0x84:	/* GPIO_SETWKUENA */
502
        s->wumask |= value;
503
        break;
504

  
505
    case 0x90:	/* GPIO_CLEARDATAOUT */
506
        omap2_gpio_module_out_update(s, s->outputs & value);
507
        break;
508

  
509
    case 0x94:	/* GPIO_SETDATAOUT */
510
        omap2_gpio_module_out_update(s, ~s->outputs & value);
511
        break;
512

  
513
    default:
514
        OMAP_BAD_REG(addr);
515
        return;
516
    }
517
}
518

  
519
static uint32_t omap2_gpio_module_readp(void *opaque, target_phys_addr_t addr)
520
{
521
    return omap2_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
522
}
523

  
524
static void omap2_gpio_module_writep(void *opaque, target_phys_addr_t addr,
525
                uint32_t value)
526
{
527
    uint32_t cur = 0;
528
    uint32_t mask = 0xffff;
529

  
530
    switch (addr & ~3) {
531
    case 0x00:	/* GPIO_REVISION */
532
    case 0x14:	/* GPIO_SYSSTATUS */
533
    case 0x38:	/* GPIO_DATAIN */
534
        OMAP_RO_REG(addr);
535
        break;
536

  
537
    case 0x10:	/* GPIO_SYSCONFIG */
538
    case 0x1c:	/* GPIO_IRQENABLE1 */
539
    case 0x20:	/* GPIO_WAKEUPENABLE */
540
    case 0x2c:	/* GPIO_IRQENABLE2 */
541
    case 0x30:	/* GPIO_CTRL */
542
    case 0x34:	/* GPIO_OE */
543
    case 0x3c:	/* GPIO_DATAOUT */
544
    case 0x40:	/* GPIO_LEVELDETECT0 */
545
    case 0x44:	/* GPIO_LEVELDETECT1 */
546
    case 0x48:	/* GPIO_RISINGDETECT */
547
    case 0x4c:	/* GPIO_FALLINGDETECT */
548
    case 0x50:	/* GPIO_DEBOUNCENABLE */
549
    case 0x54:	/* GPIO_DEBOUNCINGTIME */
550
        cur = omap2_gpio_module_read(opaque, addr & ~3) &
551
                ~(mask << ((addr & 3) << 3));
552

  
553
        /* Fall through.  */
554
    case 0x18:	/* GPIO_IRQSTATUS1 */
555
    case 0x28:	/* GPIO_IRQSTATUS2 */
556
    case 0x60:	/* GPIO_CLEARIRQENABLE1 */
557
    case 0x64:	/* GPIO_SETIRQENABLE1 */
558
    case 0x70:	/* GPIO_CLEARIRQENABLE2 */
559
    case 0x74:	/* GPIO_SETIREQNEABLE2 */
560
    case 0x80:	/* GPIO_CLEARWKUENA */
561
    case 0x84:	/* GPIO_SETWKUENA */
562
    case 0x90:	/* GPIO_CLEARDATAOUT */
563
    case 0x94:	/* GPIO_SETDATAOUT */
564
        value <<= (addr & 3) << 3;
565
        omap2_gpio_module_write(opaque, addr, cur | value);
566
        break;
567

  
568
    default:
569
        OMAP_BAD_REG(addr);
570
        return;
571
    }
572
}
573

  
574
static CPUReadMemoryFunc * const omap2_gpio_module_readfn[] = {
575
    omap2_gpio_module_readp,
576
    omap2_gpio_module_readp,
577
    omap2_gpio_module_read,
578
};
579

  
580
static CPUWriteMemoryFunc * const omap2_gpio_module_writefn[] = {
581
    omap2_gpio_module_writep,
582
    omap2_gpio_module_writep,
583
    omap2_gpio_module_write,
584
};
585

  
586
static void omap2_gpio_module_init(struct omap2_gpio_s *s,
587
                struct omap_target_agent_s *ta, int region,
588
                qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
589
                omap_clk fclk, omap_clk iclk)
590
{
591
    int iomemtype;
592

  
593
    s->irq[0] = mpu;
594
    s->irq[1] = dsp;
595
    s->wkup = wkup;
596
    s->in = qemu_allocate_irqs(omap2_gpio_module_set, s, 32);
597

  
598
    iomemtype = l4_register_io_memory(omap2_gpio_module_readfn,
599
                    omap2_gpio_module_writefn, s);
600
    omap_l4_attach(ta, region, iomemtype);
601
}
602

  
603
struct omap_gpif_s {
604
    struct omap2_gpio_s module[5];
605
    int modules;
606

  
607
    int autoidle;
608
    int gpo;
609
};
610

  
611
void omap_gpif_reset(struct omap_gpif_s *s)
612
{
613
    int i;
614

  
615
    for (i = 0; i < s->modules; i ++)
616
        omap2_gpio_module_reset(s->module + i);
617

  
618
    s->autoidle = 0;
619
    s->gpo = 0;
620
}
621

  
622
static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
623
{
624
    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
625

  
626
    switch (addr) {
627
    case 0x00:	/* IPGENERICOCPSPL_REVISION */
628
        return 0x18;
629

  
630
    case 0x10:	/* IPGENERICOCPSPL_SYSCONFIG */
631
        return s->autoidle;
632

  
633
    case 0x14:	/* IPGENERICOCPSPL_SYSSTATUS */
634
        return 0x01;
635

  
636
    case 0x18:	/* IPGENERICOCPSPL_IRQSTATUS */
637
        return 0x00;
638

  
639
    case 0x40:	/* IPGENERICOCPSPL_GPO */
640
        return s->gpo;
641

  
642
    case 0x50:	/* IPGENERICOCPSPL_GPI */
643
        return 0x00;
644
    }
645

  
646
    OMAP_BAD_REG(addr);
647
    return 0;
648
}
649

  
650
static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
651
                uint32_t value)
652
{
653
    struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
654

  
655
    switch (addr) {
656
    case 0x00:	/* IPGENERICOCPSPL_REVISION */
657
    case 0x14:	/* IPGENERICOCPSPL_SYSSTATUS */
658
    case 0x18:	/* IPGENERICOCPSPL_IRQSTATUS */
659
    case 0x50:	/* IPGENERICOCPSPL_GPI */
660
        OMAP_RO_REG(addr);
661
        break;
662

  
663
    case 0x10:	/* IPGENERICOCPSPL_SYSCONFIG */
664
        if (value & (1 << 1))					/* SOFTRESET */
665
            omap_gpif_reset(s);
666
        s->autoidle = value & 1;
667
        break;
668

  
669
    case 0x40:	/* IPGENERICOCPSPL_GPO */
670
        s->gpo = value & 1;
671
        break;
672

  
673
    default:
674
        OMAP_BAD_REG(addr);
675
        return;
676
    }
677
}
678

  
679
static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = {
680
    omap_gpif_top_read,
681
    omap_gpif_top_read,
682
    omap_gpif_top_read,
683
};
684

  
685
static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = {
686
    omap_gpif_top_write,
687
    omap_gpif_top_write,
688
    omap_gpif_top_write,
689
};
690

  
691
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
692
                qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
693
{
694
    int iomemtype, i;
695
    struct omap_gpif_s *s = (struct omap_gpif_s *)
696
            qemu_mallocz(sizeof(struct omap_gpif_s));
697
    int region[4] = { 0, 2, 4, 5 };
698

  
699
    s->modules = modules;
700
    for (i = 0; i < modules; i ++)
701
        omap2_gpio_module_init(s->module + i, ta, region[i],
702
                              irq[i], NULL, NULL, fclk[i], iclk);
703

  
704
    omap_gpif_reset(s);
705

  
706
    iomemtype = l4_register_io_memory(omap_gpif_top_readfn,
707
                    omap_gpif_top_writefn, s);
708
    omap_l4_attach(ta, 1, iomemtype);
709

  
710
    return s;
711
}
712

  
713
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
714
{
715
    if (start >= s->modules * 32 || start < 0)
716
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, start);
717
    return s->module[start >> 5].in + (start & 31);
718
}
719

  
720
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
721
{
722
    if (line >= s->modules * 32 || line < 0)
723
        hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
724
    s->module[line >> 5].handler[line & 31] = handler;
725
}

Also available in: Unified diff