~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to hw/pxa2xx_lcd.c

  • Committer: Bazaar Package Importer
  • Author(s): Riku Voipio, Josh Triplett, Riku Voipio
  • Date: 2009-07-29 13:28:05 UTC
  • mfrom: (1.4.1 upstream)
  • mto: (12.1.1 sid) (10.1.13 sid)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20090729132805-cau7rfexh7dawyb8
Tags: 0.10.50+git20090729-1
[ Josh Triplett ]
* Remove myself from Uploaders.

[ Riku Voipio ]
* new upstream RC version
* nuke all linux-user patches (applied upstream)
  06_exit_segfault
  12_signal_powerpc_support
  21_net_soopts
  30_syscall_ipc
  32_syscall_sysctl
  35_syscall_sockaddr
  48_signal_terminate
  55_unmux_socketcall
* nuke all other applied-upstream patches
  01_nostrip (better version upstream)
  07_i386_exec_name (can be reintroduced in debian/rules)
  50_linuxbios_isa_bios_ram (shouldn't be needed anymore)
  51_linuxbios_piix_ram_size (applied)
  56_dhcp (crap)
  60_ppc_ld (reintroduce if needed)
  64_ppc_asm_constraints (ditto)
  66_tls_ld.patch (ditto)
  81_compile_dtb.patch (applied upstream)
  82_qemu-img_decimal (ditto)
* move to git
* simplify build rules
* Correct my email address

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#include "pixel_ops.h"
14
14
/* FIXME: For graphic_rotate. Should probably be done in common code.  */
15
15
#include "sysemu.h"
16
 
 
17
 
typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int, int);
18
 
 
19
 
struct pxa2xx_lcdc_s {
 
16
#include "framebuffer.h"
 
17
 
 
18
struct PXA2xxLCDState {
20
19
    qemu_irq irq;
21
20
    int irqlevel;
22
21
 
56
55
        int up;
57
56
        uint8_t palette[1024];
58
57
        uint8_t pbuffer[1024];
59
 
        void (*redraw)(struct pxa2xx_lcdc_s *s, uint8_t *fb,
 
58
        void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
60
59
                        int *miny, int *maxy);
61
60
 
62
61
        target_phys_addr_t descriptor;
69
68
    int orientation;
70
69
};
71
70
 
72
 
struct __attribute__ ((__packed__)) pxa_frame_descriptor_s {
 
71
typedef struct __attribute__ ((__packed__)) {
73
72
    uint32_t fdaddr;
74
73
    uint32_t fsaddr;
75
74
    uint32_t fidr;
76
75
    uint32_t ldcmd;
77
 
};
 
76
} PXAFrameDescriptor;
78
77
 
79
78
#define LCCR0   0x000   /* LCD Controller Control register 0 */
80
79
#define LCCR1   0x004   /* LCD Controller Control register 1 */
178
177
#define LDCMD_PAL       (1 << 26)
179
178
 
180
179
/* Route internal interrupt lines to the global IC */
181
 
static void pxa2xx_lcdc_int_update(struct pxa2xx_lcdc_s *s)
 
180
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
182
181
{
183
182
    int level = 0;
184
183
    level |= (s->status[0] & LCSR0_LDD)    && !(s->control[0] & LCCR0_LDM);
198
197
}
199
198
 
200
199
/* Set Branch Status interrupt high and poke associated registers */
201
 
static inline void pxa2xx_dma_bs_set(struct pxa2xx_lcdc_s *s, int ch)
 
200
static inline void pxa2xx_dma_bs_set(PXA2xxLCDState *s, int ch)
202
201
{
203
202
    int unmasked;
204
203
    if (ch == 0) {
218
217
}
219
218
 
220
219
/* Set Start Of Frame Status interrupt high and poke associated registers */
221
 
static inline void pxa2xx_dma_sof_set(struct pxa2xx_lcdc_s *s, int ch)
 
220
static inline void pxa2xx_dma_sof_set(PXA2xxLCDState *s, int ch)
222
221
{
223
222
    int unmasked;
224
223
    if (!(s->dma_ch[ch].command & LDCMD_SOFINT))
241
240
}
242
241
 
243
242
/* Set End Of Frame Status interrupt high and poke associated registers */
244
 
static inline void pxa2xx_dma_eof_set(struct pxa2xx_lcdc_s *s, int ch)
 
243
static inline void pxa2xx_dma_eof_set(PXA2xxLCDState *s, int ch)
245
244
{
246
245
    int unmasked;
247
246
    if (!(s->dma_ch[ch].command & LDCMD_EOFINT))
264
263
}
265
264
 
266
265
/* Set Bus Error Status interrupt high and poke associated registers */
267
 
static inline void pxa2xx_dma_ber_set(struct pxa2xx_lcdc_s *s, int ch)
 
266
static inline void pxa2xx_dma_ber_set(PXA2xxLCDState *s, int ch)
268
267
{
269
268
    s->status[0] |= LCSR0_BERCH(ch) | LCSR0_BER;
270
269
    if (s->irqlevel)
274
273
}
275
274
 
276
275
/* Set Read Status interrupt high and poke associated registers */
277
 
static inline void pxa2xx_dma_rdst_set(struct pxa2xx_lcdc_s *s)
 
276
static inline void pxa2xx_dma_rdst_set(PXA2xxLCDState *s)
278
277
{
279
278
    s->status[0] |= LCSR0_RDST;
280
279
    if (s->irqlevel && !(s->control[0] & LCCR0_RDSTM))
282
281
}
283
282
 
284
283
/* Load new Frame Descriptors from DMA */
285
 
static void pxa2xx_descriptor_load(struct pxa2xx_lcdc_s *s)
 
284
static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
286
285
{
287
 
    struct pxa_frame_descriptor_s *desc[PXA_LCDDMA_CHANS];
 
286
    PXAFrameDescriptor desc;
288
287
    target_phys_addr_t descptr;
289
288
    int i;
290
289
 
291
290
    for (i = 0; i < PXA_LCDDMA_CHANS; i ++) {
292
 
        desc[i] = 0;
293
291
        s->dma_ch[i].source = 0;
294
292
 
295
293
        if (!s->dma_ch[i].up)
304
302
            descptr = s->dma_ch[i].descriptor;
305
303
 
306
304
        if (!(descptr >= PXA2XX_SDRAM_BASE && descptr +
307
 
                    sizeof(*desc[i]) <= PXA2XX_SDRAM_BASE + phys_ram_size))
 
305
                    sizeof(desc) <= PXA2XX_SDRAM_BASE + ram_size))
308
306
            continue;
309
307
 
310
 
        descptr -= PXA2XX_SDRAM_BASE;
311
 
        desc[i] = (struct pxa_frame_descriptor_s *) (phys_ram_base + descptr);
312
 
        s->dma_ch[i].descriptor = desc[i]->fdaddr;
313
 
        s->dma_ch[i].source = desc[i]->fsaddr;
314
 
        s->dma_ch[i].id = desc[i]->fidr;
315
 
        s->dma_ch[i].command = desc[i]->ldcmd;
 
308
        cpu_physical_memory_read(descptr, (void *)&desc, sizeof(desc));
 
309
        s->dma_ch[i].descriptor = tswap32(desc.fdaddr);
 
310
        s->dma_ch[i].source = tswap32(desc.fsaddr);
 
311
        s->dma_ch[i].id = tswap32(desc.fidr);
 
312
        s->dma_ch[i].command = tswap32(desc.ldcmd);
316
313
    }
317
314
}
318
315
 
319
316
static uint32_t pxa2xx_lcdc_read(void *opaque, target_phys_addr_t offset)
320
317
{
321
 
    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
 
318
    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
322
319
    int ch;
323
320
 
324
321
    switch (offset) {
403
400
 
404
401
    default:
405
402
    fail:
406
 
        cpu_abort(cpu_single_env,
407
 
                "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
 
403
        hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
408
404
    }
409
405
 
410
406
    return 0;
413
409
static void pxa2xx_lcdc_write(void *opaque,
414
410
                target_phys_addr_t offset, uint32_t value)
415
411
{
416
 
    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
 
412
    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
417
413
    int ch;
418
414
 
419
415
    switch (offset) {
559
555
 
560
556
    default:
561
557
    fail:
562
 
        cpu_abort(cpu_single_env,
563
 
                "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
 
558
        hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
564
559
    }
565
560
}
566
561
 
577
572
};
578
573
 
579
574
/* Load new palette for a given DMA channel, convert to internal format */
580
 
static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp)
 
575
static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
581
576
{
582
577
    int i, n, format, r, g, b, alpha;
583
578
    uint32_t *dest, *src;
668
663
    }
669
664
}
670
665
 
671
 
static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
672
 
                uint8_t *fb, int *miny, int *maxy)
 
666
static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s,
 
667
                target_phys_addr_t addr, int *miny, int *maxy)
673
668
{
674
 
    int y, src_width, dest_width, dirty[2];
675
 
    uint8_t *src, *dest;
676
 
    ram_addr_t x, addr, new_addr, start, end;
 
669
    int src_width, dest_width;
677
670
    drawfn fn = 0;
678
671
    if (s->dest_width)
679
672
        fn = s->line_fn[s->transp][s->bpp];
680
673
    if (!fn)
681
674
        return;
682
675
 
683
 
    src = fb;
684
676
    src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
685
677
    if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
686
678
        src_width *= 3;
689
681
    else if (s->bpp > pxa_lcdc_8bpp)
690
682
        src_width *= 2;
691
683
 
692
 
    dest = ds_get_data(s->ds);
693
684
    dest_width = s->xres * s->dest_width;
694
 
 
695
 
    addr = (ram_addr_t) (fb - phys_ram_base);
696
 
    start = addr + s->yres * src_width;
697
 
    end = addr;
698
 
    dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
699
 
    for (y = 0; y < s->yres; y ++) {
700
 
        new_addr = addr + src_width;
701
 
        for (x = addr + TARGET_PAGE_SIZE; x < new_addr;
702
 
                        x += TARGET_PAGE_SIZE) {
703
 
            dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
704
 
            dirty[0] |= dirty[1];
705
 
        }
706
 
        if (dirty[0] || s->invalidated) {
707
 
            fn((uint32_t *) s->dma_ch[0].palette,
708
 
                            dest, src, s->xres, s->dest_width);
709
 
            if (addr < start)
710
 
                start = addr;
711
 
            end = new_addr;
712
 
            if (y < *miny)
713
 
                *miny = y;
714
 
            if (y >= *maxy)
715
 
                *maxy = y + 1;
716
 
        }
717
 
        addr = new_addr;
718
 
        dirty[0] = dirty[1];
719
 
        src += src_width;
720
 
        dest += dest_width;
721
 
    }
722
 
 
723
 
    if (end > start)
724
 
        cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
 
685
    *miny = 0;
 
686
    framebuffer_update_display(s->ds,
 
687
                               addr, s->xres, s->yres,
 
688
                               src_width, dest_width, s->dest_width,
 
689
                               s->invalidated,
 
690
                               fn, s->dma_ch[0].palette, miny, maxy);
725
691
}
726
692
 
727
 
static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
728
 
                uint8_t *fb, int *miny, int *maxy)
 
693
static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s,
 
694
               target_phys_addr_t addr, int *miny, int *maxy)
729
695
{
730
 
    int y, src_width, dest_width, dirty[2];
731
 
    uint8_t *src, *dest;
732
 
    ram_addr_t x, addr, new_addr, start, end;
 
696
    int src_width, dest_width;
733
697
    drawfn fn = 0;
734
698
    if (s->dest_width)
735
699
        fn = s->line_fn[s->transp][s->bpp];
736
700
    if (!fn)
737
701
        return;
738
702
 
739
 
    src = fb;
740
703
    src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
741
704
    if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
742
705
        src_width *= 3;
746
709
        src_width *= 2;
747
710
 
748
711
    dest_width = s->yres * s->dest_width;
749
 
    dest = ds_get_data(s->ds) + dest_width * (s->xres - 1);
750
 
 
751
 
    addr = (ram_addr_t) (fb - phys_ram_base);
752
 
    start = addr + s->yres * src_width;
753
 
    end = addr;
754
 
    x = addr + TARGET_PAGE_SIZE;
755
 
    dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG);
756
 
    for (y = 0; y < s->yres; y ++) {
757
 
        new_addr = addr + src_width;
758
 
        for (; x < new_addr; x += TARGET_PAGE_SIZE) {
759
 
            dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
760
 
            dirty[0] |= dirty[1];
761
 
        }
762
 
        if (dirty[0] || s->invalidated) {
763
 
            fn((uint32_t *) s->dma_ch[0].palette,
764
 
                            dest, src, s->xres, -dest_width);
765
 
            if (addr < start)
766
 
                start = addr;
767
 
            end = new_addr;
768
 
            if (y < *miny)
769
 
                *miny = y;
770
 
            if (y >= *maxy)
771
 
                *maxy = y + 1;
772
 
        }
773
 
        addr = new_addr;
774
 
        dirty[0] = dirty[1];
775
 
        src += src_width;
776
 
        dest += s->dest_width;
777
 
    }
778
 
 
779
 
    if (end > start)
780
 
        cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
 
712
    *miny = 0;
 
713
    framebuffer_update_display(s->ds,
 
714
                               addr, s->xres, s->yres,
 
715
                               src_width, s->dest_width, -dest_width,
 
716
                               s->invalidated,
 
717
                               fn, s->dma_ch[0].palette,
 
718
                               miny, maxy);
781
719
}
782
720
 
783
 
static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s)
 
721
static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
784
722
{
785
723
    int width, height;
786
724
    if (!(s->control[0] & LCCR0_ENB))
802
740
 
803
741
static void pxa2xx_update_display(void *opaque)
804
742
{
805
 
    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
806
 
    uint8_t *fb;
 
743
    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
807
744
    target_phys_addr_t fbptr;
808
745
    int miny, maxy;
809
746
    int ch;
825
762
            }
826
763
            fbptr = s->dma_ch[ch].source;
827
764
            if (!(fbptr >= PXA2XX_SDRAM_BASE &&
828
 
                    fbptr <= PXA2XX_SDRAM_BASE + phys_ram_size)) {
 
765
                    fbptr <= PXA2XX_SDRAM_BASE + ram_size)) {
829
766
                pxa2xx_dma_ber_set(s, ch);
830
767
                continue;
831
768
            }
832
 
            fbptr -= PXA2XX_SDRAM_BASE;
833
 
            fb = phys_ram_base + fbptr;
834
769
 
835
770
            if (s->dma_ch[ch].command & LDCMD_PAL) {
836
 
                memcpy(s->dma_ch[ch].pbuffer, fb,
837
 
                                MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
838
 
                                sizeof(s->dma_ch[ch].pbuffer)));
 
771
                cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
 
772
                    MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
 
773
                        sizeof(s->dma_ch[ch].pbuffer)));
839
774
                pxa2xx_palette_parse(s, ch, s->bpp);
840
775
            } else {
841
776
                /* Do we need to reparse palette */
845
780
                /* ACK frame start */
846
781
                pxa2xx_dma_sof_set(s, ch);
847
782
 
848
 
                s->dma_ch[ch].redraw(s, fb, &miny, &maxy);
 
783
                s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
849
784
                s->invalidated = 0;
850
785
 
851
786
                /* ACK frame completed */
859
794
        s->status[0] |= LCSR0_LDD;
860
795
    }
861
796
 
862
 
    if (s->orientation)
863
 
        dpy_update(s->ds, miny, 0, maxy, s->xres);
864
 
    else
865
 
        dpy_update(s->ds, 0, miny, s->xres, maxy);
 
797
    if (miny >= 0) {
 
798
        if (s->orientation)
 
799
            dpy_update(s->ds, miny, 0, maxy, s->xres);
 
800
        else
 
801
            dpy_update(s->ds, 0, miny, s->xres, maxy);
 
802
    }
866
803
    pxa2xx_lcdc_int_update(s);
867
804
 
868
805
    qemu_irq_raise(s->vsync_cb);
870
807
 
871
808
static void pxa2xx_invalidate_display(void *opaque)
872
809
{
873
 
    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
 
810
    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
874
811
    s->invalidated = 1;
875
812
}
876
813
 
881
818
 
882
819
static void pxa2xx_lcdc_orientation(void *opaque, int angle)
883
820
{
884
 
    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
 
821
    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
885
822
 
886
823
    if (angle) {
887
824
        s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_vert;
896
833
 
897
834
static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque)
898
835
{
899
 
    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
 
836
    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
900
837
    int i;
901
838
 
902
839
    qemu_put_be32(f, s->irqlevel);
931
868
 
932
869
static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
933
870
{
934
 
    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
 
871
    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
935
872
    int i;
936
873
 
937
874
    s->irqlevel = qemu_get_be32(f);
980
917
#define BITS 32
981
918
#include "pxa2xx_template.h"
982
919
 
983
 
struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
 
920
PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
984
921
{
985
922
    int iomemtype;
986
 
    struct pxa2xx_lcdc_s *s;
 
923
    PXA2xxLCDState *s;
987
924
 
988
 
    s = (struct pxa2xx_lcdc_s *) qemu_mallocz(sizeof(struct pxa2xx_lcdc_s));
 
925
    s = (PXA2xxLCDState *) qemu_mallocz(sizeof(PXA2xxLCDState));
989
926
    s->invalidated = 1;
990
927
    s->irq = irq;
991
928
 
992
929
    pxa2xx_lcdc_orientation(s, graphic_rotate);
993
930
 
994
 
    iomemtype = cpu_register_io_memory(0, pxa2xx_lcdc_readfn,
 
931
    iomemtype = cpu_register_io_memory(pxa2xx_lcdc_readfn,
995
932
                    pxa2xx_lcdc_writefn, s);
996
933
    cpu_register_physical_memory(base, 0x00100000, iomemtype);
997
934
 
1039
976
    return s;
1040
977
}
1041
978
 
1042
 
void pxa2xx_lcd_vsync_notifier(struct pxa2xx_lcdc_s *s, qemu_irq handler)
 
979
void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler)
1043
980
{
1044
981
    s->vsync_cb = handler;
1045
982
}