~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/linaro-patches-1.5.0/0047-dsi-generate-complexio-ulps0-irq-when-asserting-lane.patch/hw/display/omap_dss.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * OMAP2/3 Display Subsystem.
3
 
 *
4
 
 * Copyright (C) 2008,2009 Nokia Corporation
5
 
 * Original OMAP2 support written by Andrzej Zaborowski <andrew@openedhand.com>
6
 
 * Enhancements and OMAP3 support written by Juha Riihimäki
7
 
 *
8
 
 * This program is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU General Public License as
10
 
 * published by the Free Software Foundation; either version 2 or
11
 
 * (at your option) any later version of the License.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 * GNU General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU General Public License along
19
 
 * with this program; if not, see <http://www.gnu.org/licenses/>.
20
 
 */
21
 
 
22
 
#include "hw/arm/omap.h"
23
 
#include "hw/sysbus.h"
24
 
#include "ui/console.h"
25
 
#include "hw/dsi.h"
26
 
 
27
 
//#define OMAP_DSS_DEBUG
28
 
#define OMAP_DSS_DEBUG_DISPC
29
 
#define OMAP_DSS_DEBUG_DISS
30
 
#define OMAP_DSS_DEBUG_DSI
31
 
#define OMAP_DSS_DEBUG_RFBI
32
 
//#define OMAP_DSS_DEBUG_VENC
33
 
 
34
 
#ifdef OMAP_DSS_DEBUG
35
 
#define TRACE(fmt,...) fprintf(stderr, "%s@%d: " fmt "\n", __FUNCTION__, \
36
 
                               __LINE__, ##__VA_ARGS__)
37
 
#define LAYERNAME(n) ((!(n)) ? "GFX" : ((n)==1) ? "VID1" : "VID2")
38
 
#ifdef OMAP_DSS_DEBUG_DISPC
39
 
#define TRACEDISPC(fmt,...) TRACE(fmt, ##__VA_ARGS__)
40
 
#else
41
 
#define TRACEDISPC(...)
42
 
#endif
43
 
#ifdef OMAP_DSS_DEBUG_DISS
44
 
#define TRACEDISS(fmt,...) TRACE(fmt, ##__VA_ARGS__)
45
 
#else
46
 
#define TRACEDISS(...)
47
 
#endif
48
 
#ifdef OMAP_DSS_DEBUG_DSI
49
 
#define TRACEDSI(fmt,...) TRACE(fmt, ##__VA_ARGS__)
50
 
#else
51
 
#define TRACEDSI(...)
52
 
#endif
53
 
#ifdef OMAP_DSS_DEBUG_RFBI
54
 
#define TRACERFBI(fmt,...) TRACE(fmt, ##__VA_ARGS__)
55
 
#else
56
 
#define TRACERFBI(...)
57
 
#endif
58
 
#ifdef OMAP_DSS_DEBUG_VENC
59
 
#define TRACEVENC(fmt,...) TRACE(fmt, ##__VA_ARGS__)
60
 
#else
61
 
#define TRACEVENC(...)
62
 
#endif
63
 
#else
64
 
#define TRACE(...)
65
 
#define TRACEDISPC(...)
66
 
#define TRACEDISS(...)
67
 
#define TRACEDSI(...)
68
 
#define TRACERFBI(...)
69
 
#define TRACEVENC(...)
70
 
#undef OMAP_RO_REG
71
 
#undef OMAP_RO_REGV
72
 
#undef OMAP_BAD_REG
73
 
#undef OMAP_BAD_REGV
74
 
#define OMAP_RO_REG(...)
75
 
#define OMAP_RO_REGV(...)
76
 
#define OMAP_BAD_REG(...)
77
 
#define OMAP_BAD_REGV(...)
78
 
#endif
79
 
 
80
 
#define OMAP_DSI_RX_FIFO_SIZE 32
81
 
 
82
 
struct omap_dss_plane_s {
83
 
    int enable;
84
 
    int bpp;
85
 
    int posx;
86
 
    int posy;
87
 
    int nx;
88
 
    int ny;
89
 
    
90
 
    int rotation_flag;
91
 
    int gfx_format;
92
 
    int gfx_channel;
93
 
    
94
 
    hwaddr addr[3]; /* BA0, BA1, TABLE_BA */
95
 
    
96
 
    uint32_t attr;
97
 
    uint32_t tresh;
98
 
    int rowinc;
99
 
    int colinc;
100
 
    int wininc;
101
 
    
102
 
    uint32_t preload;
103
 
    
104
 
    /* following used for planes 1 and 2 only (VID1 and VID2) */
105
 
    uint32_t fir;
106
 
    uint32_t fir_coef_h[8];
107
 
    uint32_t fir_coef_hv[8];
108
 
    uint32_t fir_coef_v[8];
109
 
    uint32_t conv_coef[5];
110
 
    uint32_t picture_size;
111
 
    uint32_t accu[2];
112
 
};
113
 
 
114
 
struct omap_dss_panel_s {
115
 
    int attached;
116
 
    int invalidate;
117
 
    QemuConsole *con;
118
 
    struct {
119
 
        uint32_t control;
120
 
        uint32_t width;
121
 
        uint32_t height;
122
 
        struct omap_dss_plane_s gfx;
123
 
        struct omap_dss_plane_s vid1;
124
 
        struct omap_dss_plane_s vid2;
125
 
        uint32_t *gfx_palette;
126
 
        uint32_t gfx_palette_size;
127
 
    } shadow;
128
 
};
129
 
 
130
 
struct omap_dss_s {
131
 
    SysBusDevice busdev;
132
 
    MemoryRegion iomem_diss1, iomem_disc1, iomem_rfbi1, iomem_venc1, iomem_im3;
133
 
    MemoryRegion iomem_dsi;
134
 
    int32_t mpu_model;
135
 
    qemu_irq irq;
136
 
    qemu_irq drq;
137
 
    
138
 
    uint32_t autoidle;
139
 
    uint32_t control;
140
 
    uint32_t sdi_control;
141
 
    uint32_t pll_control;
142
 
    uint32_t dss_status;
143
 
    
144
 
    struct omap_dss_panel_s dig, lcd;
145
 
 
146
 
    struct {
147
 
        QEMUTimer *lcdframer;
148
 
        
149
 
        uint8_t rev;
150
 
        uint32_t idlemode;
151
 
        uint32_t irqst;
152
 
        uint32_t irqen;
153
 
        uint32_t control;
154
 
        uint32_t config;
155
 
        uint32_t capable;
156
 
        uint32_t timing[4];
157
 
        uint32_t line;
158
 
        uint32_t bg[2];
159
 
        uint32_t trans[2];
160
 
        uint32_t size_dig;
161
 
        uint32_t size_lcd;
162
 
        uint32_t global_alpha;
163
 
        uint32_t cpr_coef_r;
164
 
        uint32_t cpr_coef_g;
165
 
        uint32_t cpr_coef_b;
166
 
        
167
 
        struct omap_dss_plane_s plane[3]; /* GFX, VID1, VID2 */
168
 
    } dispc;
169
 
    
170
 
    struct {
171
 
        int idlemode;
172
 
        uint32_t control;
173
 
        int enable;
174
 
        int pixels;
175
 
        int busy;
176
 
        int skiplines;
177
 
        uint16_t rxbuf;
178
 
        uint32_t config[2];
179
 
        uint32_t time[4];
180
 
        uint32_t data[6];
181
 
        uint16_t vsync;
182
 
        uint16_t hsync;
183
 
        const struct rfbi_chip_s *chip[2];
184
 
    } rfbi;
185
 
    
186
 
    struct {
187
 
        DSIHost *host;
188
 
        QEMUTimer *xfer_timer;
189
 
        qemu_irq drq[4];
190
 
        /* protocol engine registers */
191
 
        uint32_t sysconfig;
192
 
        uint32_t irqst;
193
 
        uint32_t irqen;
194
 
        uint32_t ctrl;
195
 
        uint32_t complexio_cfg1;
196
 
        uint32_t complexio_cfg2;
197
 
        uint32_t complexio_irqst;
198
 
        uint32_t complexio_irqen;
199
 
        uint32_t clk_ctrl;
200
 
        uint32_t timing1;
201
 
        uint32_t timing2;
202
 
        uint32_t vm_timing1;
203
 
        uint32_t vm_timing2;
204
 
        uint32_t vm_timing3;
205
 
        uint32_t vm_timing4;
206
 
        uint32_t vm_timing5;
207
 
        uint32_t vm_timing6;
208
 
        uint32_t vm_timing7;
209
 
        uint32_t clk_timing;
210
 
        uint32_t stopclk_timing;
211
 
        uint32_t tx_fifo_vc_size;
212
 
        uint32_t rx_fifo_vc_size;
213
 
        struct {
214
 
            uint32_t ctrl;
215
 
            uint32_t te;
216
 
            uint32_t lp_header;
217
 
            uint32_t lp_payload;
218
 
            int lp_counter;
219
 
            uint32_t sp_header;
220
 
            uint32_t irqst;
221
 
            uint32_t irqen;
222
 
            uint32_t rx_fifo[OMAP_DSI_RX_FIFO_SIZE];
223
 
            int rx_fifo_pos;
224
 
            int rx_fifo_len;
225
 
        } vc[4];
226
 
        /* phy registers */
227
 
        uint32_t phy_cfg0;
228
 
        uint32_t phy_cfg1;
229
 
        uint32_t phy_cfg2;
230
 
        /* pll controller registers */
231
 
        uint32_t pll_control;
232
 
        uint32_t pll_go;
233
 
        uint32_t pll_config1;
234
 
        uint32_t pll_config2;
235
 
    } dsi;
236
 
};
237
 
 
238
 
#include "ui/pixel_ops.h"
239
 
#include "framebuffer.h"
240
 
#define DEPTH 8
241
 
#include "omap_dss_drawfn.h"
242
 
#define DEPTH 15
243
 
#include "omap_dss_drawfn.h"
244
 
#define DEPTH 16
245
 
#include "omap_dss_drawfn.h"
246
 
#define DEPTH 24
247
 
#include "omap_dss_drawfn.h"
248
 
#define DEPTH 32
249
 
#include "omap_dss_drawfn.h"
250
 
#undef DEPTH
251
 
 
252
 
static drawfn omap_dss_linefn(const DeviceState *dev, int format, int bpp)
253
 
{
254
 
    switch (bpp) {
255
 
        case 8:  return omap_dss_drawfn_8[format];
256
 
        case 15: return omap_dss_drawfn_15[format];
257
 
        case 16: return omap_dss_drawfn_16[format];
258
 
        case 24: return omap_dss_drawfn_24[format];
259
 
        case 32: return omap_dss_drawfn_32[format];
260
 
        default:
261
 
            hw_error("%s: unsupported host display color depth: %d\n",
262
 
                     __FUNCTION__, bpp);
263
 
            break;
264
 
    }
265
 
    return NULL;
266
 
}
267
 
 
268
 
/* Bytes(!) per pixel */
269
 
static const int omap_lcd_Bpp[0x10] = {
270
 
    0,  /* 0x0: BITMAP1 (CLUT) */
271
 
    0,  /* 0x1: BITMAP2 (CLUT) */
272
 
    0,  /* 0x2: BITMAP4 (CLUT) */
273
 
    1,  /* 0x3: BITMAP8 (CLUT) */
274
 
    2,  /* 0x4: RGB12 (unpacked 16-bit container)*/
275
 
    2,  /* 0x5: ARGB16 */
276
 
    2,  /* 0x6: RGB16 */
277
 
    0,  /* 0x7: reserved */
278
 
    4,  /* 0x8: RGB24 (unpacked in 32-bit container) */
279
 
    3,  /* 0x9: RGB24 (packed in 24-bit container) */
280
 
    2,  /* 0xa: YUV2 422 */
281
 
    2,  /* 0xb: UYVY 422 */
282
 
    4,  /* 0xc: ARGB32 */
283
 
    4,  /* 0xd: RGBA32 */
284
 
    4,  /* 0xe: RGBx32 (24-bit RGB aligned on MSB of the 32-bit container) */
285
 
    0,  /* 0xf: reserved */
286
 
};
287
 
 
288
 
static void omap_dss_interrupt_update(struct omap_dss_s *s)
289
 
{
290
 
    qemu_set_irq(s->irq, 
291
 
                 (s->dsi.irqst & s->dsi.irqen)
292
 
                 | (s->dsi.complexio_irqst & s->dsi.complexio_irqen)
293
 
                 | (s->dsi.vc[0].irqst & s->dsi.vc[0].irqen)
294
 
                 | (s->dsi.vc[1].irqst & s->dsi.vc[1].irqen)
295
 
                 | (s->dsi.vc[2].irqst & s->dsi.vc[2].irqen)
296
 
                 | (s->dsi.vc[3].irqst & s->dsi.vc[3].irqen)
297
 
                 | (s->dispc.irqst & s->dispc.irqen));
298
 
}
299
 
 
300
 
static void omap_dss_framedone(void *opaque)
301
 
{
302
 
    struct omap_dss_s *s = (struct omap_dss_s *)opaque;
303
 
    if (s->dispc.control & 3) { /* DIGITALENABLE | LCDENABLE */
304
 
        if ((s->dispc.control & (1 << 11))) { /* STALLMODE */
305
 
            s->dispc.control &= ~1; /* LCDENABLE */
306
 
            if ((s->rfbi.control & 1)) { /* ENABLE */
307
 
                s->rfbi.pixels = 0;
308
 
                s->rfbi.busy = 0;
309
 
            }
310
 
            if (s->dispc.lcdframer) {
311
 
                qemu_del_timer(s->dispc.lcdframer);
312
 
            }
313
 
        } else {
314
 
            if (s->dispc.lcdframer) {
315
 
                qemu_mod_timer(s->dispc.lcdframer,
316
 
                               qemu_get_clock_ns(vm_clock)
317
 
                               + get_ticks_per_sec() / 10);
318
 
            }
319
 
        }
320
 
        s->dispc.irqst |= 1 | 2;    /* FRAMEDONE | VSYNC */
321
 
        omap_dss_interrupt_update(s);
322
 
    }
323
 
}
324
 
 
325
 
static void omap_dsi_te_trigger(DeviceState *dev, int vc)
326
 
{
327
 
    struct omap_dss_s *s = FROM_SYSBUS(struct omap_dss_s,
328
 
                                       SYS_BUS_DEVICE(dev));
329
 
    if ((s->dsi.ctrl & 1) &&        /* IF_EN */
330
 
        (s->dsi.vc[vc].ctrl & 1)) { /* VC_EN */
331
 
        s->dsi.irqst |= 1 << 16;    /* TE_TRIGGER_IRQ */
332
 
        omap_dss_interrupt_update(s);
333
 
    }
334
 
}
335
 
 
336
 
static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
337
 
{
338
 
    if (!s->rfbi.busy)
339
 
        return;
340
 
 
341
 
    /* TODO: in non-Bypass mode we probably need to just deassert the DRQ.  */
342
 
 
343
 
    s->rfbi.busy = 0;
344
 
    s->rfbi.control &= ~0x10; /* ITE */
345
 
}
346
 
 
347
 
static void omap_rfbi_transfer_start(struct omap_dss_s *s)
348
 
{
349
 
    void *data;
350
 
    hwaddr len;
351
 
    hwaddr data_addr;
352
 
    int pitch;
353
 
    static void *bounce_buffer;
354
 
    static hwaddr bounce_len;
355
 
 
356
 
    if (!s->rfbi.enable || s->rfbi.busy)
357
 
        return;
358
 
 
359
 
    if (s->rfbi.control & (1 << 1)) {                           /* BYPASS */
360
 
        /* TODO: in non-Bypass mode we probably need to just assert the
361
 
         * DRQ and wait for DMA to write the pixels.  */
362
 
        hw_error("%s: Bypass mode unimplemented", __FUNCTION__);
363
 
    }
364
 
 
365
 
    if (!(s->dispc.control & (1 << 11))) /* STALLMODE */
366
 
        return;
367
 
 
368
 
    s->rfbi.busy = 1;
369
 
 
370
 
    len = s->rfbi.pixels * 2;
371
 
 
372
 
    data_addr = s->dispc.plane[0].addr[0];
373
 
    data = cpu_physical_memory_map(data_addr, &len, 0);
374
 
    if (data && len != s->rfbi.pixels * 2) {
375
 
        cpu_physical_memory_unmap(data, len, 0, 0);
376
 
        data = NULL;
377
 
        len = s->rfbi.pixels * 2;
378
 
    }
379
 
    if (!data) {
380
 
        if (len > bounce_len) {
381
 
            bounce_buffer = g_realloc(bounce_buffer, len);
382
 
        }
383
 
        data = bounce_buffer;
384
 
        cpu_physical_memory_read(data_addr, data, len);
385
 
    }
386
 
 
387
 
    /* TODO: negative values */
388
 
    pitch = s->dispc.plane[0].nx + (s->dispc.plane[0].rowinc - 1) / 2;
389
 
 
390
 
    if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
391
 
        s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);
392
 
    if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
393
 
        s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
394
 
 
395
 
    if (data != bounce_buffer) {
396
 
        cpu_physical_memory_unmap(data, len, 0, len);
397
 
    }
398
 
 
399
 
    omap_rfbi_transfer_stop(s);
400
 
 
401
 
    omap_dss_framedone(s);
402
 
}
403
 
 
404
 
static void omap_dsi_transfer_stop(void *opaque)
405
 
{
406
 
    struct omap_dss_s *s = opaque;
407
 
    int i;
408
 
    qemu_del_timer(s->dsi.xfer_timer);
409
 
    for (i = 0; i < 4; i++) {
410
 
        if ((s->dsi.vc[i].ctrl & 1) &&       /* VC_EN */
411
 
            ((s->dsi.vc[i].te >> 30) & 3)) { /* TE_START | TE_EN */
412
 
            TRACEDSI("TE data transfer ready, signaling framedone");
413
 
            s->dsi.vc[i].te = 0; /* transfer complete */
414
 
            omap_dss_framedone(s);
415
 
            dsi_bltdone(s->dsi.host, i);
416
 
        }
417
 
    }
418
 
}
419
 
 
420
 
static void omap_dsi_transfer_start(struct omap_dss_s *s, int ch)
421
 
{
422
 
    if (((s->dispc.control >> 11) & 1) && /* STALLMODE */
423
 
        (s->dsi.ctrl & 1) &&              /* IF_EN */
424
 
        (s->dsi.vc[ch].ctrl & 1) &&       /* VC_EN */
425
 
        ((s->dsi.vc[ch].te >> 30) & 3)) { /* TE_START | TE_EN */
426
 
        TRACEDSI("start TE data transfer on channel %d for %d bytes",
427
 
                 ch, s->dsi.vc[ch].te & 0xffffff);
428
 
        TRACEDSI("vc%d   irqenable=0x%08x", ch, s->dsi.vc[ch].irqen);
429
 
        TRACEDSI("dsi   irqenable=0x%08x", s->dsi.irqen);
430
 
        TRACEDSI("dispc irqenable=0x%08x", s->dispc.irqen);
431
 
        int tx_dma = (s->dsi.vc[ch].ctrl >> 21) & 7; /* DMA_TX_REQ_NB */
432
 
        if (tx_dma < 4) {
433
 
            qemu_irq_raise(s->dsi.drq[tx_dma]);
434
 
        } else {
435
 
            const int format = (s->dispc.plane[0].attr >> 1) & 0xf;
436
 
            const int col_pitch = omap_lcd_Bpp[format] +
437
 
                                  (s->dispc.plane[0].colinc - 1);
438
 
            const int row_pitch = (s->dispc.plane[0].nx * col_pitch) +
439
 
                                  (s->dispc.plane[0].rowinc - 1);
440
 
            hwaddr len = row_pitch * s->dispc.plane[0].ny;
441
 
            void *data = cpu_physical_memory_map(s->dispc.plane[0].addr[0],
442
 
                                                 &len, 0);
443
 
            if (!data || len != row_pitch * s->dispc.plane[0].ny) {
444
 
                fprintf(stderr, "%s: unable to map contiguous frame buffer\n",
445
 
                        __FUNCTION__);
446
 
            } else {
447
 
                dsi_blt(s->dsi.host, ch, data, s->dispc.plane[0].nx,
448
 
                        s->dispc.plane[0].ny, col_pitch, row_pitch, format);
449
 
            }
450
 
            if (data) {
451
 
                cpu_physical_memory_unmap(data, len, 0, 0);
452
 
            }
453
 
            /* We cannot signal transfer complete immediately since some
454
 
             * display drivers assume transfer takes some time. Instead,
455
 
             * setup a small delay and report transfer complete a bit
456
 
             * later. */
457
 
            s->dsi.vc[ch].ctrl &= ~(0x11 << 16); /* TX/RX fifo not full */
458
 
            qemu_mod_timer(s->dsi.xfer_timer,
459
 
                           qemu_get_clock_ns(vm_clock)
460
 
                           + get_ticks_per_sec() / 1000);
461
 
        }
462
 
    }
463
 
}
464
 
 
465
 
static void omap_dss_panel_layer_update(DisplaySurface *surface,
466
 
                                        MemoryRegion *mr,
467
 
                                        uint32_t panel_width,
468
 
                                        uint32_t panel_height,
469
 
                                        uint32_t posx,
470
 
                                        int *posy, int *endy,
471
 
                                        uint32_t width, uint32_t height,
472
 
                                        uint32_t attrib,
473
 
                                        hwaddr addr,
474
 
                                        uint32_t *palette,
475
 
                                        int full_update)
476
 
{
477
 
    if (!(attrib & 1)) { /* layer disabled? */
478
 
        return;
479
 
    }
480
 
    uint32_t format = (attrib >> 1) & 0xf;
481
 
    if ((attrib & 0x600)) { /* GFXENDIANNESS | GFXNIBBLEMODE */
482
 
        hw_error("%s: unsupported layer attributes (0x%08x)\n",
483
 
                 __FUNCTION__, attrib);
484
 
    }
485
 
    drawfn line_fn = omap_dss_linefn(NULL, format,
486
 
                                     surface_bits_per_pixel(surface));
487
 
    if (!line_fn) {
488
 
        hw_error("%s: unsupported omap dss color format: %d\n",
489
 
                 __FUNCTION__, format);
490
 
    }
491
 
    if (posx) {
492
 
        fprintf(stderr, "%s@%d: non-zero layer x-coordinate (%d), "
493
 
                "not currently supported -> using zero\n", __FUNCTION__,
494
 
                __LINE__, posx);
495
 
        posx = 0;
496
 
    }
497
 
 
498
 
    uint32_t copy_width = (posx + width) > panel_width
499
 
                          ? (panel_width - posx) : width;
500
 
    uint32_t copy_height = ((*posy) + height) > panel_height
501
 
                           ? (panel_height - (*posy)) : height;
502
 
    uint32_t linesize = surface_stride(surface);
503
 
    framebuffer_update_display(surface, mr, addr, copy_width, copy_height,
504
 
                               (format < 3)
505
 
                               ? (width >> (3 - format))
506
 
                               : (width * omap_lcd_Bpp[format]),
507
 
                               linesize, linesize / surface_width(surface),
508
 
                               full_update, line_fn, palette,
509
 
                               posy, endy);
510
 
}
511
 
 
512
 
static void omap_dss_panel_update_display(struct omap_dss_panel_s *s,
513
 
                                          MemoryRegion *mr, int lcd)
514
 
{
515
 
    DisplaySurface *surface = qemu_console_surface(s->con);
516
 
    if (s->invalidate) {
517
 
        if (s->shadow.width != surface_width(surface)
518
 
            || s->shadow.height != surface_height(surface)) {
519
 
            qemu_console_resize(s->con, s->shadow.width, s->shadow.height);
520
 
            surface = qemu_console_surface(s->con);
521
 
        }
522
 
        if ((s->shadow.gfx.attr >> 12) & 0x3) { /* GFXROTATION */
523
 
            hw_error("%s: GFX rotation is not supported", __FUNCTION__);
524
 
        }
525
 
    }
526
 
 
527
 
    /* TODO: draw background color */
528
 
    int first_row = -1;
529
 
    int last_row = 0;
530
 
    if ((lcd && !(s->shadow.gfx.attr & 0x100)) ||
531
 
        (!lcd && (s->shadow.gfx.attr & 0x100))) {
532
 
        if (s->shadow.gfx_palette && s->shadow.gfx_palette_size) {
533
 
            cpu_physical_memory_read(s->shadow.gfx.addr[2],
534
 
                                     (uint8_t *)s->shadow.gfx_palette,
535
 
                                     s->shadow.gfx_palette_size
536
 
                                     * sizeof(uint32_t));
537
 
        }
538
 
        first_row = s->shadow.gfx.posy;
539
 
        omap_dss_panel_layer_update(surface, mr,
540
 
                                    s->shadow.width, s->shadow.height,
541
 
                                    s->shadow.gfx.posx, &first_row, &last_row,
542
 
                                    s->shadow.gfx.nx, s->shadow.gfx.ny,
543
 
                                    s->shadow.gfx.attr, s->shadow.gfx.addr[0],
544
 
                                    s->shadow.gfx_palette, s->invalidate);
545
 
    }
546
 
    /* TODO: draw VID1 & VID2 layers */
547
 
    s->invalidate = 0;
548
 
 
549
 
    if (first_row >= 0) {
550
 
        dpy_gfx_update(s->con, 0, first_row, s->shadow.width,
551
 
                       last_row - first_row + 1);
552
 
    }
553
 
}
554
 
 
555
 
static void omap_lcd_panel_update_display(void *opaque)
556
 
{
557
 
    struct omap_dss_s *s = opaque;
558
 
    if (!s->lcd.con
559
 
        || !(s->lcd.shadow.control & 1)           /* LCDENABLE */
560
 
        || (s->lcd.shadow.control & (1 << 11))) { /* STALLMODE */
561
 
        return;
562
 
    }
563
 
    omap_dss_panel_update_display(&s->lcd, sysbus_address_space(&s->busdev), 1);
564
 
    omap_dss_framedone(s);
565
 
}
566
 
 
567
 
static void omap_lcd_panel_invalidate_display(void *opaque)
568
 
{
569
 
    struct omap_dss_s *s = opaque;
570
 
    s->lcd.invalidate = 1;
571
 
}
572
 
 
573
 
static void omap_dig_panel_update_display(void *opaque)
574
 
{
575
 
    struct omap_dss_s *s = opaque;
576
 
    if (!s->dig.con || !(s->dig.shadow.control & 2)) { /* DIGITALENABLE */
577
 
        return;
578
 
    }
579
 
    omap_dss_panel_update_display(&s->dig, sysbus_address_space(&s->busdev), 0);
580
 
    omap_dss_framedone(s);
581
 
}
582
 
 
583
 
static void omap_dig_panel_invalidate_display(void *opaque)
584
 
{
585
 
    struct omap_dss_s *s = opaque;
586
 
    s->dig.invalidate = 1;
587
 
}
588
 
 
589
 
static void omap_dss_panel_go(struct omap_dss_s *s,
590
 
                              struct omap_dss_panel_s *p,
591
 
                              uint32_t size)
592
 
{
593
 
    if (p->attached) {
594
 
        p->invalidate = 1;
595
 
        p->shadow.control = s->dispc.control;
596
 
        p->shadow.width = (size & 0x7ff) + 1;
597
 
        p->shadow.height = ((size >> 16) & 0x7ff) + 1;
598
 
        p->shadow.gfx = s->dispc.plane[0];
599
 
        p->shadow.vid1 = s->dispc.plane[1];
600
 
        p->shadow.vid2 = s->dispc.plane[2];
601
 
        int new_size = 0;
602
 
        switch ((p->shadow.gfx.attr >> 1) & 0x0f) {
603
 
            case 0: new_size = 2; break;
604
 
            case 1: new_size = 4; break;
605
 
            case 2: new_size = 16; break;
606
 
            case 3: new_size = 256; break;
607
 
            default: break;
608
 
        }
609
 
        if (new_size != p->shadow.gfx_palette_size) {
610
 
            if (p->shadow.gfx_palette) {
611
 
                g_free(p->shadow.gfx_palette);
612
 
                p->shadow.gfx_palette = NULL;
613
 
            }
614
 
            if (new_size) {
615
 
                p->shadow.gfx_palette = g_malloc(new_size * sizeof(uint32_t));
616
 
            }
617
 
            p->shadow.gfx_palette_size = new_size;
618
 
        }
619
 
    }
620
 
}
621
 
 
622
 
static void omap_dss_panel_reset(void *opaque)
623
 
{
624
 
    struct omap_dss_panel_s *s = opaque;
625
 
    if (s->attached) {
626
 
        s->shadow.control = 0;
627
 
        memset(&s->shadow.gfx, 0, sizeof(s->shadow.gfx));
628
 
        memset(&s->shadow.vid1, 0, sizeof(s->shadow.vid1));
629
 
        memset(&s->shadow.vid2, 0, sizeof(s->shadow.vid2));
630
 
        if (s->shadow.gfx_palette) {
631
 
            g_free(s->shadow.gfx_palette);
632
 
            s->shadow.gfx_palette = NULL;
633
 
            s->shadow.gfx_palette_size = 0;
634
 
        }
635
 
    }
636
 
}
637
 
 
638
 
static void omap_dsi_reset(struct omap_dss_s *s)
639
 
{
640
 
    int i;
641
 
 
642
 
    s->dsi.sysconfig = 0x11;
643
 
    s->dsi.irqst = 0;
644
 
    s->dsi.irqen = 0;
645
 
    s->dsi.ctrl = 0x100;
646
 
    s->dsi.complexio_cfg1 = 0x20000000;
647
 
    s->dsi.complexio_cfg2 = 0;
648
 
    s->dsi.complexio_irqst = 0;
649
 
    s->dsi.complexio_irqen = 0;
650
 
    s->dsi.clk_ctrl = 1;
651
 
    s->dsi.timing1 = 0x7fff7fff;
652
 
    s->dsi.timing2 = 0x7fff7fff;
653
 
    s->dsi.vm_timing1 = 0;
654
 
    s->dsi.vm_timing2 = 0;
655
 
    s->dsi.vm_timing3 = 0;
656
 
    s->dsi.vm_timing4 = 0;
657
 
    s->dsi.vm_timing5 = 0;
658
 
    s->dsi.vm_timing6 = 0;
659
 
    s->dsi.vm_timing7 = 0;
660
 
    s->dsi.clk_timing = 0x0101;
661
 
    s->dsi.stopclk_timing = 0x80;
662
 
    s->dsi.tx_fifo_vc_size = 0;
663
 
    s->dsi.rx_fifo_vc_size = 0;
664
 
    for (i = 0; i < 4; i++) {
665
 
        s->dsi.vc[i].ctrl = 0;
666
 
        s->dsi.vc[i].te = 0;
667
 
        s->dsi.vc[i].lp_header = 0;
668
 
        s->dsi.vc[i].lp_payload = 0;
669
 
        s->dsi.vc[i].lp_counter = 0;
670
 
        s->dsi.vc[i].sp_header = 0;
671
 
        s->dsi.vc[i].irqst = 0;
672
 
        s->dsi.vc[i].irqen = 0;
673
 
        s->dsi.vc[i].rx_fifo_pos = 0;
674
 
        s->dsi.vc[i].rx_fifo_len = 0;
675
 
    }
676
 
    if (s->mpu_model < omap3630) {
677
 
        s->dsi.phy_cfg0 = 0x1a3c1a28;
678
 
        s->dsi.phy_cfg1 = 0x420a1875;
679
 
        s->dsi.phy_cfg2 = 0xb800001b;
680
 
    } else {
681
 
        s->dsi.phy_cfg0 = 0x1e481d3a;
682
 
        s->dsi.phy_cfg1 = 0x420a1a6a;
683
 
        s->dsi.phy_cfg2 = 0xb800001a;
684
 
    }
685
 
    s->dsi.pll_control = 0;
686
 
    s->dsi.pll_go = 0;
687
 
    s->dsi.pll_config1 = 0;
688
 
    s->dsi.pll_config2 = 0;
689
 
    omap_dss_interrupt_update(s);
690
 
}
691
 
 
692
 
static void omap_rfbi_reset(struct omap_dss_s *s)
693
 
{
694
 
    s->rfbi.idlemode = 0;
695
 
    s->rfbi.control = 2;
696
 
    s->rfbi.enable = 0;
697
 
    s->rfbi.pixels = 0;
698
 
    s->rfbi.skiplines = 0;
699
 
    s->rfbi.busy = 0;
700
 
    s->rfbi.config[0] = 0x00310000;
701
 
    s->rfbi.config[1] = 0x00310000;
702
 
    s->rfbi.time[0] = 0;
703
 
    s->rfbi.time[1] = 0;
704
 
    s->rfbi.time[2] = 0;
705
 
    s->rfbi.time[3] = 0;
706
 
    s->rfbi.data[0] = 0;
707
 
    s->rfbi.data[1] = 0;
708
 
    s->rfbi.data[2] = 0;
709
 
    s->rfbi.data[3] = 0;
710
 
    s->rfbi.data[4] = 0;
711
 
    s->rfbi.data[5] = 0;
712
 
    s->rfbi.vsync = 0;
713
 
    s->rfbi.hsync = 0;
714
 
}
715
 
 
716
 
static void omap_dss_reset(DeviceState *dev)
717
 
{
718
 
    int i, j;
719
 
 
720
 
    struct omap_dss_s *s = FROM_SYSBUS(struct omap_dss_s,
721
 
                                       SYS_BUS_DEVICE(dev));
722
 
    s->autoidle = 0x10; /* was 0 for OMAP2 but bit4 must be set for OMAP3 */
723
 
    s->control = 0;
724
 
    if (s->mpu_model == omap3430) {
725
 
        s->sdi_control = 0;
726
 
        s->pll_control = 0;
727
 
        s->dss_status = 0x81; /* bit 7 is not present prior to OMAP3 */
728
 
    } else { /* omap2, omap3630 */
729
 
        s->dss_status = 0x01;
730
 
    }
731
 
 
732
 
    s->dispc.idlemode = 0;
733
 
    s->dispc.irqst = 0;
734
 
    s->dispc.irqen = 0;
735
 
    s->dispc.control = 0;
736
 
    s->dispc.config = 0;
737
 
    s->dispc.capable = 0x161;
738
 
    s->dispc.timing[0] = 0;
739
 
    s->dispc.timing[1] = 0;
740
 
    s->dispc.timing[2] = 0;
741
 
    s->dispc.timing[3] = 0x00010002;
742
 
    s->dispc.line = 0;
743
 
    s->dispc.bg[0] = 0;
744
 
    s->dispc.bg[1] = 0;
745
 
    s->dispc.trans[0] = 0;
746
 
    s->dispc.trans[1] = 0;
747
 
    s->dispc.size_dig = 0;
748
 
    s->dispc.size_lcd = 0;
749
 
    s->dispc.global_alpha = 0;
750
 
    s->dispc.cpr_coef_r = 0;
751
 
    s->dispc.cpr_coef_g = 0;
752
 
    s->dispc.cpr_coef_b = 0;
753
 
 
754
 
    for (i = 0; i < 3; i++) {
755
 
        s->dispc.plane[i].enable = 0;
756
 
        s->dispc.plane[i].bpp = 0;
757
 
        s->dispc.plane[i].addr[0] = 0;
758
 
        s->dispc.plane[i].addr[1] = 0;
759
 
        s->dispc.plane[i].addr[2] = 0;
760
 
        s->dispc.plane[i].posx = 0;
761
 
        s->dispc.plane[i].posy = 0;
762
 
        s->dispc.plane[i].nx = 1;
763
 
        s->dispc.plane[i].ny = 1;
764
 
        s->dispc.plane[i].attr = 0;
765
 
        s->dispc.plane[i].tresh = (s->dispc.rev < 0x30) ? 0 : 0x03ff03c0;
766
 
        s->dispc.plane[i].rowinc = 1;
767
 
        s->dispc.plane[i].colinc = 1;
768
 
        s->dispc.plane[i].wininc = 0;
769
 
        s->dispc.plane[i].preload = 0x100;
770
 
        s->dispc.plane[i].fir = 0;
771
 
        s->dispc.plane[i].picture_size = 0;
772
 
        s->dispc.plane[i].accu[0] = 0;
773
 
        s->dispc.plane[i].accu[1] = 0;
774
 
        for (j = 0; j < 5; j++)
775
 
            s->dispc.plane[i].conv_coef[j] = 0;
776
 
        for (j = 0; j < 8; j++) {
777
 
            s->dispc.plane[i].fir_coef_h[j] = 0;
778
 
            s->dispc.plane[i].fir_coef_hv[j] = 0;
779
 
            s->dispc.plane[i].fir_coef_v[j] = 0;
780
 
        }
781
 
    }
782
 
 
783
 
    omap_dsi_reset(s);
784
 
    omap_rfbi_reset(s);
785
 
    omap_dss_panel_reset(&s->lcd);
786
 
    omap_dss_panel_reset(&s->dig);
787
 
    omap_dss_interrupt_update(s);
788
 
}
789
 
 
790
 
static uint64_t omap_diss_read(void *opaque, hwaddr addr,
791
 
                               unsigned size)
792
 
{
793
 
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
794
 
    uint32_t x;
795
 
 
796
 
    if (size != 4) {
797
 
        return omap_badwidth_read32(opaque, addr);
798
 
    }
799
 
 
800
 
    switch (addr) {
801
 
    case 0x00:  /* DSS_REVISIONNUMBER */
802
 
        TRACEDISS("DSS_REVISIONNUMBER: 0x20");
803
 
        return 0x20;
804
 
 
805
 
    case 0x10:  /* DSS_SYSCONFIG */
806
 
        TRACEDISS("DSS_SYSCONFIG: 0x%08x", s->autoidle);
807
 
        return s->autoidle;
808
 
 
809
 
    case 0x14:  /* DSS_SYSSTATUS */
810
 
        TRACEDISS("DSS_SYSSTATUS: 0x1");
811
 
        return 1; /* RESETDONE */
812
 
 
813
 
    case 0x18:  /* DSS_IRQSTATUS */
814
 
        x = (s->dispc.irqst & s->dispc.irqen) ? 1 : 0;
815
 
        if ((s->dsi.irqst & s->dsi.irqen)
816
 
            | (s->dsi.complexio_irqst & s->dsi.complexio_irqen)
817
 
            | (s->dsi.vc[0].irqst & s->dsi.vc[0].irqen)
818
 
            | (s->dsi.vc[1].irqst & s->dsi.vc[1].irqen)
819
 
            | (s->dsi.vc[2].irqst & s->dsi.vc[2].irqen)
820
 
            | (s->dsi.vc[3].irqst & s->dsi.vc[3].irqen))
821
 
            x |= 2;
822
 
        TRACEDISS("DSS_IRQSTATUS: 0x%08x", x);
823
 
        return x;
824
 
 
825
 
    case 0x40:  /* DSS_CONTROL */
826
 
        TRACEDISS("DSS_CONTROL: 0x%08x", s->control);
827
 
        return s->control;
828
 
 
829
 
    case 0x44:  /* DSS_SDI_CONTROL */
830
 
        if (s->mpu_model == omap3430) {
831
 
            TRACEDISS("DSS_SDI_CONTROL: 0x%08x", s->sdi_control);
832
 
            return s->sdi_control;
833
 
        }
834
 
        break;
835
 
 
836
 
    case 0x48: /* DSS_PLL_CONTROL */
837
 
        if (s->mpu_model == omap3430) {
838
 
            TRACEDISS("DSS_PLL_CONTROL: 0x%08x", s->pll_control);
839
 
            return s->pll_control;
840
 
        }
841
 
        break;
842
 
 
843
 
    case 0x50:  /* DSS_PSA_LCD_REG_1 */
844
 
    case 0x54:  /* DSS_PSA_LCD_REG_2 */
845
 
    case 0x58:  /* DSS_PSA_VIDEO_REG */
846
 
        if (s->mpu_model < omap3430) {
847
 
            TRACEDISS("DSS_PSA_xxx: 0");
848
 
            /* TODO: fake some values according to s->control bits */
849
 
            return 0;
850
 
        }
851
 
        break;
852
 
 
853
 
    case 0x5c:
854
 
        x = s->dss_status;
855
 
        if (s->mpu_model < omap3430) {
856
 
            TRACEDISS("DSS_STATUS: 0x%08x", x);
857
 
        } else {
858
 
            if (s->mpu_model == omap3430) {
859
 
                s->dss_status &= ~(1 << 6); /* SDI_PLL_BUSYFLAG */
860
 
                TRACEDISS("DSS_SDI_STATUS: 0x%08x", x);
861
 
            } else { /* omap3630 */
862
 
                TRACEDISS("DSS_CLK_STATUS: 0x%08x", x);
863
 
            }
864
 
        }
865
 
        return x;
866
 
    default:
867
 
        break;
868
 
    }
869
 
    OMAP_BAD_REG(addr);
870
 
    return 0;
871
 
}
872
 
 
873
 
static void omap_diss_write(void *opaque, hwaddr addr,
874
 
                            uint64_t value, unsigned size)
875
 
{
876
 
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
877
 
 
878
 
    if (size != 4) {
879
 
        return omap_badwidth_write32(opaque, addr, value);
880
 
    }
881
 
 
882
 
    switch (addr) {
883
 
    case 0x00:  /* DSS_REVISIONNUMBER */
884
 
    case 0x14:  /* DSS_SYSSTATUS */
885
 
    case 0x18:  /* DSS_IRQSTATUS */
886
 
    case 0x50:  /* DSS_PSA_LCD_REG_1 */
887
 
    case 0x54:  /* DSS_PSA_LCD_REG_2 */
888
 
    case 0x58:  /* DSS_PSA_VIDEO_REG */
889
 
    case 0x5c:  /* DSS_STATUS */
890
 
        /* quietly ignore */
891
 
        /*OMAP_RO_REGV(addr, value);*/
892
 
        break;
893
 
 
894
 
    case 0x10:  /* DSS_SYSCONFIG */
895
 
        TRACEDISS("DSS_SYSCONFIG = 0x%08x", value);
896
 
        if (value & 2) { /* SOFTRESET */
897
 
            omap_dss_reset(&s->busdev.qdev);
898
 
        }
899
 
        if (s->mpu_model < omap3430) {
900
 
            value &= 0x01;
901
 
        } else {
902
 
            value &= 0x19;
903
 
        }
904
 
        s->autoidle = value;
905
 
        break;
906
 
 
907
 
    case 0x40:  /* DSS_CONTROL */
908
 
        TRACEDISS("DSS_CONTROL = 0x%08x", value);
909
 
        if (s->mpu_model < omap3430) {
910
 
            value &= 0x3dd;
911
 
        } else {
912
 
            value &= 0x3ff;
913
 
        }
914
 
        s->control = value;
915
 
        s->dss_status &= ~0x3;
916
 
        s->dss_status |= 1 + (s->control & 1);
917
 
        break;
918
 
 
919
 
    case 0x44: /* DSS_SDI_CONTROL */
920
 
        if (s->mpu_model == omap3430) {
921
 
            TRACEDISS("DSS_SDI_CONTROL = 0x%08x", value);
922
 
            s->sdi_control = value & 0x000ff80f;
923
 
        } else {
924
 
            OMAP_BAD_REGV(addr, value);
925
 
        }
926
 
        break;
927
 
 
928
 
    case 0x48: /* DSS_PLL_CONTROL */
929
 
        if (s->mpu_model == omap3430) {
930
 
            TRACEDISS("DSS_PLL_CONTROL = 0x%08x", value);
931
 
            if (value & (1 << 18)) { /* SDI_PLL_SYSRESET */
932
 
                s->dss_status |= 1 << 2;    /* SDI_PLL_RESETDONE */
933
 
            } else {
934
 
                s->dss_status &= ~(1 << 2); /* SDI_PLL_RESETDONE */
935
 
            }
936
 
            if (value & (1 << 28)) { /* SDI_PLL_GOBIT */
937
 
                s->dss_status |= 1 << 6;    /* SDI_PLL_BUSYFLAG */
938
 
                s->dss_status &= ~(1 << 5); /* SDI_PLL_LOCK */
939
 
            } else {
940
 
                if (s->pll_control & (1 << 28)) { /* SDI_PLL_GOBIT */
941
 
                    s->dss_status &= ~(1 << 6); /* SDI_PLL_BUSYFLAG */
942
 
                    s->dss_status |= 1 << 5;    /* SDI_PLL_LOCK */
943
 
                }
944
 
            }
945
 
            s->pll_control = value;
946
 
        } else {
947
 
            OMAP_BAD_REGV(addr, value);
948
 
        }
949
 
        break;
950
 
 
951
 
    default:
952
 
        OMAP_BAD_REGV(addr, value);
953
 
        break;
954
 
    }
955
 
}
956
 
 
957
 
static const MemoryRegionOps omap_diss_ops = {
958
 
    .read = omap_diss_read,
959
 
    .write = omap_diss_write,
960
 
    .endianness = DEVICE_NATIVE_ENDIAN,
961
 
};
962
 
 
963
 
static uint64_t omap_disc_read(void *opaque, hwaddr addr,
964
 
                               unsigned size)
965
 
{
966
 
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
967
 
    int n = 0;
968
 
 
969
 
    if (size != 4) {
970
 
        return omap_badwidth_read32(opaque, addr);
971
 
    }
972
 
 
973
 
    switch (addr) {
974
 
    case 0x000: /* DISPC_REVISION */
975
 
        TRACEDISPC("DISPC_REVISION: 0x%08x", s->dispc.rev);
976
 
        return s->dispc.rev;
977
 
    case 0x010: /* DISPC_SYSCONFIG */
978
 
        TRACEDISPC("DISPC_SYSCONFIG: 0x%08x", s->dispc.idlemode);
979
 
        return s->dispc.idlemode;
980
 
    case 0x014: /* DISPC_SYSSTATUS */
981
 
        TRACEDISPC("DISPC_SYSSTATUS: 1");
982
 
        return 1;                                               /* RESETDONE */
983
 
    case 0x018: /* DISPC_IRQSTATUS */
984
 
        TRACEDISPC("DISPC_IRQSTATUS: 0x%08x", s->dispc.irqst);
985
 
        return s->dispc.irqst;
986
 
    case 0x01c: /* DISPC_IRQENABLE */
987
 
        TRACEDISPC("DISPC_IRQENABLE: 0x%08x", s->dispc.irqen);
988
 
        return s->dispc.irqen;
989
 
    case 0x040: /* DISPC_CONTROL */
990
 
        TRACEDISPC("DISPC_CONTROL: 0x%08x", s->dispc.control);
991
 
        return s->dispc.control;
992
 
    case 0x044: /* DISPC_CONFIG */
993
 
        TRACEDISPC("DISPC_CONFIG: 0x%08x", s->dispc.config);
994
 
        return s->dispc.config;
995
 
    case 0x048: /* DISPC_CAPABLE */
996
 
        TRACEDISPC("DISPC_CAPABLE: 0x%08x", s->dispc.capable);
997
 
        return s->dispc.capable;
998
 
    case 0x04c: /* DISPC_DEFAULT_COLOR0 */
999
 
        TRACEDISPC("DISPC_DEFAULT_COLOR0: 0x%08x", s->dispc.bg[0]);
1000
 
        return s->dispc.bg[0];
1001
 
    case 0x050: /* DISPC_DEFAULT_COLOR1 */
1002
 
        TRACEDISPC("DISPC_DEFAULT_COLOR0: 0x%08x", s->dispc.bg[1]);
1003
 
        return s->dispc.bg[1];
1004
 
    case 0x054: /* DISPC_TRANS_COLOR0 */
1005
 
        TRACEDISPC("DISPC_TRANS_COLOR0: 0x%08x", s->dispc.trans[0]);
1006
 
        return s->dispc.trans[0];
1007
 
    case 0x058: /* DISPC_TRANS_COLOR1 */
1008
 
        TRACEDISPC("DISPC_TRANS_COLOR0: 0x%08x", s->dispc.trans[1]);
1009
 
        return s->dispc.trans[1];
1010
 
    case 0x05c: /* DISPC_LINE_STATUS */
1011
 
        TRACEDISPC("DISPC_LINE_STATUS: 0x7ff");
1012
 
        return 0x7ff;
1013
 
    case 0x060: /* DISPC_LINE_NUMBER */
1014
 
        TRACEDISPC("DISPC_LINE_NUMBER: 0x%08x", s->dispc.line);
1015
 
        return s->dispc.line;
1016
 
    case 0x064: /* DISPC_TIMING_H */
1017
 
        TRACEDISPC("DISPC_TIMING_H: 0x%08x", s->dispc.timing[0]);
1018
 
        return s->dispc.timing[0];
1019
 
    case 0x068: /* DISPC_TIMING_V */
1020
 
        TRACEDISPC("DISPC_TIMING_H: 0x%08x", s->dispc.timing[1]);
1021
 
        return s->dispc.timing[1];
1022
 
    case 0x06c: /* DISPC_POL_FREQ */
1023
 
        TRACEDISPC("DISPC_POL_FREQ: 0x%08x", s->dispc.timing[2]);
1024
 
        return s->dispc.timing[2];
1025
 
    case 0x070: /* DISPC_DIVISOR */
1026
 
        TRACEDISPC("DISPC_DIVISOR: 0x%08x", s->dispc.timing[3]);
1027
 
        return s->dispc.timing[3];
1028
 
    case 0x074: /* DISPC_GLOBAL_ALPHA */
1029
 
        TRACEDISPC("DISPC_GLOBAL_ALPHA: 0x%08x", s->dispc.global_alpha);
1030
 
        return s->dispc.global_alpha;
1031
 
    case 0x078: /* DISPC_SIZE_DIG */
1032
 
        TRACEDISPC("DISPC_SIZE_DIG: 0x%08x", s->dispc.size_dig);
1033
 
        return s->dispc.size_dig;
1034
 
    case 0x07c: /* DISPC_SIZE_LCD */
1035
 
        TRACEDISPC("DISPC_SIZE_LCD: 0x%08x", s->dispc.size_lcd);
1036
 
        return s->dispc.size_lcd;
1037
 
    case 0x14c: /* DISPC_VID2_BA0 */
1038
 
        n++;
1039
 
    case 0x0bc: /* DISPC_VID1_BA0 */
1040
 
        n++;
1041
 
    case 0x080: /* DISPC_GFX_BA0 */
1042
 
        TRACEDISPC("DISPC_%s_BA0: " OMAP_FMT_plx, LAYERNAME(n),
1043
 
                   s->dispc.plane[n].addr[0]);
1044
 
        return s->dispc.plane[n].addr[0];
1045
 
    case 0x150: /* DISPC_VID2_BA1 */
1046
 
        n++;
1047
 
    case 0x0c0: /* DISPC_VID1_BA1 */
1048
 
        n++;
1049
 
    case 0x084: /* DISPC_GFX_BA1 */
1050
 
        TRACEDISPC("DISPC_%s_BA1: " OMAP_FMT_plx, LAYERNAME(n),
1051
 
                   s->dispc.plane[n].addr[1]);
1052
 
        return s->dispc.plane[n].addr[1];
1053
 
    case 0x154: /* DISPC_VID2_POSITION */
1054
 
        n++;
1055
 
    case 0x0c4: /* DISPC_VID1_POSITION */
1056
 
        n++;
1057
 
    case 0x088: /* DISPC_GFX_POSITION */
1058
 
        TRACEDISPC("DISPC_%s_POSITION: 0x%08x", LAYERNAME(n),
1059
 
                   (s->dispc.plane[n].posy << 16) | s->dispc.plane[n].posx);
1060
 
        return (s->dispc.plane[n].posy << 16) | s->dispc.plane[n].posx;
1061
 
    case 0x158: /* DISPC_VID2_SIZE */
1062
 
        n++;
1063
 
    case 0x0c8: /* DISPC_VID1_SIZE */
1064
 
        n++;
1065
 
    case 0x08c: /* DISPC_GFX_SIZE */
1066
 
        TRACEDISPC("DISPC_%s_SIZE: 0x%08x", LAYERNAME(n),
1067
 
                   ((s->dispc.plane[n].ny - 1) << 16)
1068
 
                   | (s->dispc.plane[n].nx - 1));
1069
 
        return ((s->dispc.plane[n].ny - 1) << 16) | (s->dispc.plane[n].nx - 1);
1070
 
    case 0x15c: /* DISPC_VID2_ATTRIBUTES */
1071
 
        n++;
1072
 
    case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
1073
 
        n++;
1074
 
    case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
1075
 
        TRACEDISPC("DISPC_%s_ATTRIBUTES: 0x%08x", LAYERNAME(n),
1076
 
                   s->dispc.plane[n].attr);
1077
 
        return s->dispc.plane[n].attr;
1078
 
    case 0x160: /* DISPC_VID2_FIFO_THRESHOLD */
1079
 
        n++;
1080
 
    case 0x0d0: /* DISPC_VID1_FIFO_THRESHOLD */
1081
 
        n++;
1082
 
    case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
1083
 
        TRACEDISPC("DISPC_%s_THRESHOLD: 0x%08x", LAYERNAME(n),
1084
 
                   s->dispc.plane[n].tresh);
1085
 
        return s->dispc.plane[n].tresh;
1086
 
    case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */
1087
 
        n++;
1088
 
    case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */
1089
 
        n++;
1090
 
    case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
1091
 
        TRACEDISPC("DISPC_%s_FIFO_SIZE_STATUS: 0x%08x", LAYERNAME(n),
1092
 
                   s->dispc.rev < 0x30 ? 256 : 1024);
1093
 
        return s->dispc.rev < 0x30 ? 256 : 1024;
1094
 
    case 0x168: /* DISPC_VID2_ROW_INC */
1095
 
        n++;
1096
 
    case 0x0d8: /* DISPC_VID1_ROW_INC */
1097
 
        n++;
1098
 
    case 0x0ac: /* DISPC_GFX_ROW_INC */
1099
 
        TRACEDISPC("DISPC_%s_ROW_INC: 0x%08x", LAYERNAME(n),
1100
 
                   s->dispc.plane[n].rowinc);
1101
 
        return s->dispc.plane[n].rowinc;
1102
 
    case 0x16c: /* DISPC_VID2_PIXEL_INC */
1103
 
        n++;
1104
 
    case 0x0dc: /* DISPC_VID1_PIXEL_INC */
1105
 
        n++;
1106
 
    case 0x0b0: /* DISPC_GFX_PIXEL_INC */
1107
 
        TRACEDISPC("DISPC_%s_PIXEL_INC: 0x%08x", LAYERNAME(n),
1108
 
                   s->dispc.plane[n].colinc);
1109
 
        return s->dispc.plane[n].colinc;
1110
 
    case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
1111
 
        TRACEDISPC("DISPC_GFX_WINDOW_SKIP: 0x%08x", s->dispc.plane[0].wininc);
1112
 
        return s->dispc.plane[0].wininc;
1113
 
    case 0x0b8: /* DISPC_GFX_TABLE_BA */
1114
 
        TRACEDISPC("DISPC_GFX_TABLE_BA: " OMAP_FMT_plx,
1115
 
                   s->dispc.plane[0].addr[2]);
1116
 
        return s->dispc.plane[0].addr[2];
1117
 
    case 0x170: /* DISPC_VID2_FIR */
1118
 
        n++;
1119
 
    case 0x0e0: /* DISPC_VID1_FIR */
1120
 
        n++;
1121
 
        TRACEDISPC("DISPC_%s_FIR: 0x%08x", LAYERNAME(n),
1122
 
                   s->dispc.plane[n].fir);
1123
 
        return s->dispc.plane[n].fir;
1124
 
    case 0x174: /* DISPC_VID2_PICTURE_SIZE */
1125
 
        n++;
1126
 
    case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
1127
 
        n++;
1128
 
        TRACEDISPC("DISPC_%s_PICTURE_SIZE: 0x%08x", LAYERNAME(n),
1129
 
                   s->dispc.plane[n].picture_size);
1130
 
        return s->dispc.plane[n].picture_size;
1131
 
    case 0x178: /* DISPC_VID2_ACCU0 */
1132
 
    case 0x17c: /* DISPC_VID2_ACCU1 */
1133
 
        n++;
1134
 
    case 0x0e8: /* DISPC_VID1_ACCU0 */
1135
 
    case 0x0ec: /* DISPC_VID1_ACCU1 */
1136
 
        n++;
1137
 
        TRACEDISPC("DISPC_%s_ACCU%d: 0x%08x", LAYERNAME(n),
1138
 
                   (int)((addr >> 1) & 1),
1139
 
                   s->dispc.plane[n].accu[(addr >> 1 ) & 1]);
1140
 
        return s->dispc.plane[n].accu[(addr >> 1) & 1];
1141
 
    case 0x180 ... 0x1bc:       /* DISPC_VID2_FIR_COEF */
1142
 
        n++;
1143
 
    case 0x0f0 ... 0x12c:       /* DISPC_VID1_FIR_COEF */
1144
 
        n++;
1145
 
        if (addr & 4) {
1146
 
            TRACEDISPC("DISPC_%s_FIR_COEF_HV%d: 0x%08x", LAYERNAME(n),
1147
 
                       (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8),
1148
 
                       s->dispc.plane[n].fir_coef_hv[
1149
 
                           (addr - ((n > 1) ? 0x180 : 0xf0)) / 8]);
1150
 
            return s->dispc.plane[n].fir_coef_hv[
1151
 
                (addr - ((n > 1) ? 0x180 : 0xf0)) / 8];
1152
 
        }
1153
 
        TRACEDISPC("DISPC_%s_FIR_COEF_H%d: 0x%08x", LAYERNAME(n),
1154
 
                   (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8),
1155
 
                   s->dispc.plane[n].fir_coef_h[
1156
 
                       (addr - ((n > 1) ? 0x180 : 0xf0)) / 8]);
1157
 
        return s->dispc.plane[n].fir_coef_h[
1158
 
            (addr - ((n > 1) ? 0x180 : 0xf0)) / 8];
1159
 
    case 0x1c0 ... 0x1d0: /* DISPC_VID2_CONV_COEFi */
1160
 
        n++;
1161
 
    case 0x130 ... 0x140: /* DISPC_VID1_CONV_COEFi */
1162
 
        n++;
1163
 
        TRACEDISPC("DISPC_%s_CONV_COEF%d: 0x%08x", LAYERNAME(n),
1164
 
                   (int)((addr - ((n > 1) ? 0x1c0 : 0x130)) / 4),
1165
 
                   s->dispc.plane[n].conv_coef[
1166
 
                       (addr - ((n > 1) ? 0x1c0 : 0x130)) / 4]);
1167
 
        return s->dispc.plane[n].conv_coef[
1168
 
            (addr - ((n > 1) ? 0x1c0 : 0x130)) / 4];
1169
 
    case 0x1d4: /* DISPC_DATA_CYCLE1 */
1170
 
    case 0x1d8: /* DISPC_DATA_CYCLE2 */
1171
 
    case 0x1dc: /* DISPC_DATA_CYCLE3 */
1172
 
        TRACEDISPC("DISPC_DATA_CYCLE%d: 0", (int)((addr - 0x1d4) / 4));
1173
 
        return 0;
1174
 
    case 0x200 ... 0x21c: /* DISPC_VID2_FIR_COEF_Vi */
1175
 
        n++;
1176
 
    case 0x1e0 ... 0x1fc: /* DISPC_VID1_FIR_COEF_Vi */
1177
 
        n++;
1178
 
        TRACEDISPC("DISPC_%s_FIR_COEF_V%d: 0x%08x", LAYERNAME(n),
1179
 
                   (int)((addr & 0x01f) / 4),
1180
 
                   s->dispc.plane[n].fir_coef_v[(addr & 0x01f) / 4]);
1181
 
        return s->dispc.plane[n].fir_coef_v[(addr & 0x01f) / 4];
1182
 
    case 0x220: /* DISPC_CPR_COEF_R */
1183
 
        TRACEDISPC("DISPC_CPR_COEF_R: 0x%08x", s->dispc.cpr_coef_r);
1184
 
        return s->dispc.cpr_coef_r;
1185
 
    case 0x224: /* DISPC_CPR_COEF_G */
1186
 
        TRACEDISPC("DISPC_CPR_COEF_G: 0x%08x", s->dispc.cpr_coef_g);
1187
 
        return s->dispc.cpr_coef_g;
1188
 
    case 0x228: /* DISPC_CPR_COEF_B */
1189
 
        TRACEDISPC("DISPC_CPR_COEF_B: 0x%08x", s->dispc.cpr_coef_b);
1190
 
        return s->dispc.cpr_coef_b;
1191
 
    case 0x234: /* DISPC_VID2_PRELOAD */
1192
 
        n++;
1193
 
    case 0x230: /* DISPC_VID1_PRELOAD */
1194
 
        n++;
1195
 
    case 0x22c: /* DISPC_GFX_PRELOAD */
1196
 
        TRACEDISPC("DISPC_%s_PRELOAD: 0x%08x", LAYERNAME(n),
1197
 
                   s->dispc.plane[n].preload);
1198
 
        return s->dispc.plane[n].preload;
1199
 
    default:
1200
 
        break;
1201
 
    }
1202
 
    OMAP_BAD_REG(addr);
1203
 
    return 0;
1204
 
}
1205
 
 
1206
 
static void omap_disc_write(void *opaque, hwaddr addr,
1207
 
                            uint64_t value, unsigned size)
1208
 
{
1209
 
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
1210
 
    uint32_t n = 0;
1211
 
 
1212
 
    if (size != 4) {
1213
 
        return omap_badwidth_write32(opaque, addr, value);
1214
 
    }
1215
 
 
1216
 
    switch (addr) {
1217
 
    case 0x000: /* DISPC_REVISION */
1218
 
    case 0x014: /* DISPC_SYSSTATUS */
1219
 
    case 0x05c: /* DISPC_LINE_STATUS */
1220
 
    case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
1221
 
        /* quietly ignore */
1222
 
        /*OMAP_RO_REGV(addr, value);*/
1223
 
        break;
1224
 
    case 0x010: /* DISPC_SYSCONFIG */
1225
 
        TRACEDISPC("DISPC_SYSCONFIG = 0x%08x", value);
1226
 
        if (value & 2) { /* SOFTRESET */
1227
 
            omap_dss_reset(&s->busdev.qdev);
1228
 
        }
1229
 
        s->dispc.idlemode = value & ((s->dispc.rev < 0x30) ? 0x301b : 0x331f);
1230
 
        break;
1231
 
    case 0x018: /* DISPC_IRQSTATUS */
1232
 
        TRACEDISPC("DISPC_IRQSTATUS = 0x%08x", value);
1233
 
        s->dispc.irqst &= ~value;
1234
 
        omap_dss_interrupt_update(s);
1235
 
        break;
1236
 
    case 0x01c: /* DISPC_IRQENABLE */
1237
 
        TRACEDISPC("DISPC_IRQENABLE = 0x%08x", value);
1238
 
        s->dispc.irqen = value & ((s->dispc.rev < 0x30) ? 0xffff : 0x1ffff);
1239
 
        omap_dss_interrupt_update(s);
1240
 
        break;
1241
 
    case 0x040: /* DISPC_CONTROL */
1242
 
        TRACEDISPC("DISPC_CONTROL = 0x%08x", value);
1243
 
        n = s->dispc.control; /* cache old value */
1244
 
        /* always clear GODIGITAL and GOLCD to signal completed shadowing */
1245
 
        if (s->dispc.rev < 0x30) {
1246
 
            s->dispc.control = value & 0x07ff9f9f;
1247
 
        } else {
1248
 
            s->dispc.control = (value & 0xffff9b9f)
1249
 
                | (s->dispc.control & 0x6000);
1250
 
        }
1251
 
        if (value & (1 << 12))                  /* OVERLAY_OPTIMIZATION */
1252
 
            if (!((s->dispc.plane[1].attr | s->dispc.plane[2].attr) & 1)) {
1253
 
                 TRACEDISPC("Overlay Optimization when no overlay "
1254
 
                            "region effectively exists leads to "
1255
 
                            "unpredictable behaviour!");
1256
 
            }
1257
 
        if ((value & 0x21)) { /* GOLCD | LCDENABLE */
1258
 
            omap_dss_panel_go(s, &s->lcd, s->dispc.size_lcd);
1259
 
        }
1260
 
        if ((value & 0x42)) { /* GODIGITAL | DIGITALENABLE */
1261
 
            omap_dss_panel_go(s, &s->dig, s->dispc.size_dig);
1262
 
        }
1263
 
        if (value & 1) { /* LCDENABLE */
1264
 
            if ((value & (1 << 11))) { /* STALLMODE */
1265
 
                if ((s->rfbi.control & 0x11) && /* ITE | ENABLE */
1266
 
                    !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc)) { /* TRIGGERMODE */
1267
 
                    omap_rfbi_transfer_start(s);
1268
 
                }
1269
 
                if (s->dsi.ctrl & 1) { /* IF_EN */
1270
 
                    int ch;
1271
 
                    for (ch = 0; ch < 4; ch++) {
1272
 
                        if ((s->dsi.vc[ch].ctrl & 1) &&     /* VC_EN */
1273
 
                            (s->dsi.vc[ch].te >> 30) & 3) { /* TE_START | TE_EN */
1274
 
                            omap_dsi_transfer_start(s, ch);
1275
 
                        }
1276
 
                    }
1277
 
                }
1278
 
            } else if (s->dispc.lcdframer) {
1279
 
                qemu_mod_timer(s->dispc.lcdframer,
1280
 
                               qemu_get_clock_ns(vm_clock)
1281
 
                               + get_ticks_per_sec() / 10);
1282
 
            }
1283
 
        } else if (n & 1) { /* enable -> disable, signal wip frame done */
1284
 
            s->dispc.control |= 1;
1285
 
            omap_dss_framedone(s);
1286
 
            s->dispc.control &= ~1;
1287
 
        }
1288
 
        break;
1289
 
    case 0x044: /* DISPC_CONFIG */
1290
 
        TRACEDISPC("DISPC_CONFIG = 0x%08x", value);
1291
 
        s->dispc.config = value & 0x3fff;
1292
 
        /* XXX:
1293
 
         * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded
1294
 
         * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded
1295
 
         */
1296
 
        break;
1297
 
    case 0x048: /* DISPC_CAPABLE */
1298
 
        TRACEDISPC("DISPC_CAPABLE = 0x%08x", value);
1299
 
        s->dispc.capable = value & 0x3ff;
1300
 
        break;
1301
 
    case 0x04c: /* DISPC_DEFAULT_COLOR0 */
1302
 
        TRACEDISPC("DISPC_DEFAULT_COLOR0 = 0x%08x", value);
1303
 
        s->dispc.bg[0] = value & 0xffffff;
1304
 
        break;
1305
 
    case 0x050: /* DISPC_DEFAULT_COLOR1 */
1306
 
        TRACEDISPC("DISPC_DEFAULT_COLOR1 = 0x%08x", value);
1307
 
        s->dispc.bg[1] = value & 0xffffff;
1308
 
        break;
1309
 
    case 0x054: /* DISPC_TRANS_COLOR0 */
1310
 
        TRACEDISPC("DISPC_TRANS_COLOR0 = 0x%08x", value);
1311
 
        s->dispc.trans[0] = value & 0xffffff;
1312
 
        break;
1313
 
    case 0x058: /* DISPC_TRANS_COLOR1 */
1314
 
        TRACEDISPC("DISPC_TRANS_COLOR1 = 0x%08x", value);
1315
 
        s->dispc.trans[1] = value & 0xffffff;
1316
 
        break;
1317
 
    case 0x060: /* DISPC_LINE_NUMBER */
1318
 
        TRACEDISPC("DISPC_LINE_NUMBER = 0x%08x", value);
1319
 
        s->dispc.line = value & 0x7ff;
1320
 
        break;
1321
 
    case 0x064: /* DISPC_TIMING_H */
1322
 
        TRACEDISPC("DISPC_TIMING_H = 0x%08x", value);
1323
 
        s->dispc.timing[0] = value & 0x0ff0ff3f;
1324
 
        break;
1325
 
    case 0x068: /* DISPC_TIMING_V */
1326
 
        TRACEDISPC("DISPC_TIMING_V = 0x%08x", value);
1327
 
        s->dispc.timing[1] = value & 0x0ff0ff3f;
1328
 
        break;
1329
 
    case 0x06c: /* DISPC_POL_FREQ */
1330
 
        TRACEDISPC("DISPC_POL_FREQ = 0x%08x", value);
1331
 
        s->dispc.timing[2] = value & 0x0003ffff;
1332
 
        break;
1333
 
    case 0x070: /* DISPC_DIVISOR */
1334
 
        TRACEDISPC("DISPC_DIVISOR = 0x%08x", value);
1335
 
        s->dispc.timing[3] = value & 0x00ff00ff;
1336
 
        break;
1337
 
    case 0x074: /* DISPC_GLOBAL_ALPHA */
1338
 
        TRACEDISPC("DISPC_GLOBAL_ALPHA = 0x%08x", value);
1339
 
        s->dispc.global_alpha = value & 0x00ff00ff;
1340
 
        break;
1341
 
    case 0x078: /* DISPC_SIZE_DIG */
1342
 
        TRACEDISPC("DISPC_SIZE_DIG = 0x%08x (%dx%d)",
1343
 
                   value, (value & 0x7ff) + 1, ((value >> 16) & 0x7ff) + 1);
1344
 
        s->dispc.size_dig = value;
1345
 
        break;
1346
 
    case 0x07c: /* DISPC_SIZE_LCD */
1347
 
        TRACEDISPC("DISPC_SIZE_LCD = 0x%08x (%dx%d)",
1348
 
                   value, (value & 0x7ff) + 1, ((value >> 16) & 0x7ff) + 1);
1349
 
        s->dispc.size_lcd = value;
1350
 
        break;
1351
 
    case 0x14c: /* DISPC_VID2_BA0 */
1352
 
        n++;
1353
 
    case 0x0bc: /* DISPC_VID1_BA0 */
1354
 
        n++;
1355
 
    case 0x080: /* DISPC_GFX_BA0 */
1356
 
        TRACEDISPC("DISPC_%s_BA0 = 0x%08x", LAYERNAME(n), value);
1357
 
        s->dispc.plane[n].addr[0] = (hwaddr) value;
1358
 
        break;
1359
 
    case 0x150: /* DISPC_VID2_BA1 */
1360
 
        n++;
1361
 
    case 0x0c0: /* DISPC_VID1_BA1 */
1362
 
        n++;
1363
 
    case 0x084: /* DISPC_GFX_BA1 */
1364
 
        TRACEDISPC("DISPC_%s_BA1 = 0x%08x", LAYERNAME(n), value);
1365
 
        s->dispc.plane[n].addr[1] = (hwaddr) value;
1366
 
        break;
1367
 
    case 0x154: /* DISPC_VID2_POSITION */
1368
 
        n++;
1369
 
    case 0x0c4: /* DISPC_VID1_POSITION */
1370
 
        n++;
1371
 
    case 0x088: /* DISPC_GFX_POSITION */
1372
 
        s->dispc.plane[n].posx = ((value >>  0) & 0x7ff);               /* GFXPOSX */
1373
 
        s->dispc.plane[n].posy = ((value >> 16) & 0x7ff);               /* GFXPOSY */
1374
 
        TRACEDISPC("DISPC_%s_POSITION = 0x%08x (%d,%d)", LAYERNAME(n),
1375
 
                 value, s->dispc.plane[n].posx, s->dispc.plane[n].posy);
1376
 
        break;
1377
 
    case 0x158: /* DISPC_VID2_SIZE */
1378
 
        n++;
1379
 
    case 0x0c8: /* DISPC_VID1_SIZE */
1380
 
        n++;
1381
 
    case 0x08c: /* DISPC_GFX_SIZE */
1382
 
        s->dispc.plane[n].nx = ((value >>  0) & 0x7ff) + 1;             /* GFXSIZEX */
1383
 
        s->dispc.plane[n].ny = ((value >> 16) & 0x7ff) + 1;             /* GFXSIZEY */
1384
 
        TRACEDISPC("DISPC_%s_SIZE = 0x%08x (%dx%d)", LAYERNAME(n),
1385
 
                 value, s->dispc.plane[n].nx, s->dispc.plane[n].ny);
1386
 
        break;
1387
 
    case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
1388
 
        TRACEDISPC("DISPC_GFX_ATTRIBUTES = 0x%08x", value);
1389
 
        if (s->mpu_model < omap3630) {
1390
 
            value &= 0xffff;
1391
 
        } else {
1392
 
            value &= 0x1000ffff;
1393
 
        }
1394
 
        s->dispc.plane[0].attr = value;
1395
 
        if (value & (3 << 9)) {
1396
 
            hw_error("%s: Big-endian pixel format not supported",
1397
 
                     __FUNCTION__);
1398
 
        }
1399
 
        s->dispc.plane[0].enable = value & 1;
1400
 
        s->dispc.plane[0].bpp = (value >> 1) & 0xf;
1401
 
        s->dispc.plane[0].rotation_flag = (value >> 12) & 0x3;
1402
 
        s->dispc.plane[0].gfx_format = (value >> 1) & 0xf;
1403
 
        s->dispc.plane[0].gfx_channel = (value >> 8) & 0x1;
1404
 
        break;
1405
 
    case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
1406
 
        n++;
1407
 
    case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
1408
 
        n++;
1409
 
    case 0x0a4: /* DISPC_GFX_FIFO_THRESHOLD */
1410
 
        TRACEDISPC("DISPC_%s_FIFO_THRESHOLD = 0x%08x", LAYERNAME(n), value);
1411
 
        s->dispc.plane[n].tresh = value & ((s->dispc.rev < 0x30) 
1412
 
                                       ? 0x01ff01ff : 0x0fff0fff);
1413
 
        break;
1414
 
    case 0x168: /* DISPC_VID2_ROW_INC */
1415
 
        n++;
1416
 
    case 0x0d8: /* DISPC_VID1_ROW_INC */
1417
 
        n++;
1418
 
    case 0x0ac: /* DISPC_GFX_ROW_INC */
1419
 
        TRACEDISPC("DISPC_%s_ROW_INC = 0x%08x", LAYERNAME(n), value);
1420
 
        s->dispc.plane[n].rowinc = value;
1421
 
        break;
1422
 
    case 0x16c: /* DISPC_VID2_PIXEL_INC */
1423
 
        n++;
1424
 
    case 0x0dc: /* DISPC_VID1_PIXEL_INC */
1425
 
        n++;
1426
 
    case 0x0b0: /* DISPC_GFX_PIXEL_INC */
1427
 
        TRACEDISPC("DISPC_%s_PIXEL_INC = 0x%08x", LAYERNAME(n), value);
1428
 
        s->dispc.plane[n].colinc = value;
1429
 
        break;
1430
 
    case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
1431
 
        TRACEDISPC("DISPC_GFX_WINDOW_SKIP = 0x%08x", value);
1432
 
        s->dispc.plane[0].wininc = value;
1433
 
        break;
1434
 
    case 0x0b8: /* DISPC_GFX_TABLE_BA */
1435
 
        TRACEDISPC("DISPC_GFX_TABLE_BA = 0x%08x", value);
1436
 
        s->dispc.plane[0].addr[2] = (hwaddr) value;
1437
 
        break;
1438
 
    case 0x15c: /* DISPC_VID2_ATTRIBUTES */
1439
 
        n++;
1440
 
    case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
1441
 
        n++;
1442
 
        TRACEDISPC("DISPC_%s_ATTRIBUTES = 0x%08x", LAYERNAME(n), value);
1443
 
        if (s->mpu_model < omap3630) {
1444
 
            value &= 0x01ffffff;
1445
 
        } else {
1446
 
            value &= 0x11ffffff;
1447
 
        }
1448
 
        s->dispc.plane[n].attr = value;
1449
 
        break;
1450
 
    case 0x170: /* DISPC_VID2_FIR */
1451
 
        n++;
1452
 
    case 0x0e0: /* DISPC_VID1_FIR */
1453
 
        n++;
1454
 
        TRACEDISPC("DISPC_%s_FIR = 0x%08x", LAYERNAME(n), value);
1455
 
        s->dispc.plane[n].fir = value & 0x1fff1fff;
1456
 
        break;
1457
 
    case 0x174: /* DISPC_VID2_PICTURE_SIZE */
1458
 
        n++;
1459
 
    case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
1460
 
        n++;
1461
 
        TRACEDISPC("DISPC_%s_PICTURE_SIZE = 0x%08x", LAYERNAME(n), value);
1462
 
        s->dispc.plane[n].picture_size = value & 0x07ff07ff;
1463
 
        break;
1464
 
    case 0x178: /* DISPC_VID2_ACCU0 */
1465
 
    case 0x17c: /* DISPC_VID2_ACCU1 */
1466
 
        n++;
1467
 
    case 0x0e8: /* DISPC_VID1_ACCU0 */
1468
 
    case 0x0ec: /* DISPC_VID1_ACCU1 */
1469
 
        n++;
1470
 
        TRACEDISPC("DISPC_%s_ACCU%d = 0x%08x", LAYERNAME(n),
1471
 
                 (int)((addr >> 1) & 1), value);
1472
 
        s->dispc.plane[n].accu[(addr >> 1) & 1] = value & 0x03ff03ff;
1473
 
        break;
1474
 
    case 0x180 ... 0x1bc:       /* DISPC_VID2_FIR_COEF */
1475
 
        n++;
1476
 
    case 0x0f0 ... 0x12c:       /* DISPC_VID1_FIR_COEF */
1477
 
        n++;
1478
 
        if (addr & 4) {
1479
 
            TRACEDISPC("DISPC_%s_FIR_COEF_HV%d = 0x%08x", LAYERNAME(n),
1480
 
                     (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8), value);
1481
 
            s->dispc.plane[n].fir_coef_hv[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8] = value;
1482
 
        } else {
1483
 
            TRACEDISPC("DISPC_%s_FIR_COEF_H%d = 0x%08x", LAYERNAME(n),
1484
 
                     (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8), value);
1485
 
            s->dispc.plane[n].fir_coef_h[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8] = value;
1486
 
        }
1487
 
        break;
1488
 
    case 0x1c0 ... 0x1d0: /* DISPC_VID2_CONV_COEFi */
1489
 
        n++;
1490
 
    case 0x130 ... 0x140: /* DISPC_VID1_CONV_COEFi */
1491
 
        n++;
1492
 
        TRACEDISPC("DISPC_%s_CONV_COEF%d = 0x%08x", LAYERNAME(n),
1493
 
                 (int)((addr - ((n > 1) ? 0x1c0 : 0x130)) / 4), value);
1494
 
        s->dispc.plane[n].conv_coef[(addr - ((n > 1) ? 0x1c0 : 0x130)) / 4] = value;
1495
 
        break;
1496
 
    case 0x1d4: /* DISPC_DATA_CYCLE1 */
1497
 
    case 0x1d8: /* DISPC_DATA_CYCLE2 */
1498
 
    case 0x1dc: /* DISPC_DATA_CYCLE3 */
1499
 
        TRACEDISPC("DISPC_DATA_CYCLE%d = 0x%08x (ignored)",
1500
 
                 (int)((addr - 0x1d4) / 4), value);
1501
 
        break;
1502
 
    case 0x200 ... 0x21c: /* DISPC_VID2_FIR_COEF_Vi */
1503
 
        n++;
1504
 
    case 0x1e0 ... 0x1fc: /* DISPC_VID1_FIR_COEF_Vi */
1505
 
        n++;
1506
 
        TRACEDISPC("DISPC_%s_FIR_COEF_V%d = 0x%08x", LAYERNAME(n),
1507
 
                 (int)((addr & 0x01f) / 4), value);
1508
 
        s->dispc.plane[n].fir_coef_v[(addr & 0x01f) / 4] = value & 0x0000ffff;
1509
 
        break;
1510
 
    case 0x220: /* DISPC_CPR_COEF_R */
1511
 
        TRACEDISPC("DISPC_CPR_COEF_R = 0x%08x", value);
1512
 
        s->dispc.cpr_coef_r = value & 0xffbffbff;
1513
 
        break;
1514
 
    case 0x224: /* DISPC_CPR_COEF_G */
1515
 
        TRACEDISPC("DISPC_CPR_COEF_G = 0x%08x", value);
1516
 
        s->dispc.cpr_coef_g = value & 0xffbffbff;
1517
 
        break;
1518
 
    case 0x228: /* DISPC_CPR_COEF_B */
1519
 
        TRACEDISPC("DISPC_CPR_COEF_B = 0x%08x", value);
1520
 
        s->dispc.cpr_coef_b = value & 0xffbffbff;
1521
 
        break;
1522
 
    case 0x234: /* DISPC_VID2_PRELOAD */
1523
 
        n++;
1524
 
    case 0x230: /* DISPC_VID1_PRELOAD */
1525
 
        n++;
1526
 
    case 0x22c: /* DISPC_GFX_PRELOAD */
1527
 
        TRACEDISPC("DISPC_%s_PRELOAD = 0x%08x", LAYERNAME(n), value);
1528
 
        s->dispc.plane[n].preload = value & 0x0fff;
1529
 
        break;
1530
 
    default:
1531
 
        OMAP_BAD_REGV(addr, value);
1532
 
        break;
1533
 
    }
1534
 
}
1535
 
 
1536
 
static const MemoryRegionOps omap_disc_ops = {
1537
 
    .read = omap_disc_read,
1538
 
    .write = omap_disc_write,
1539
 
    .endianness = DEVICE_NATIVE_ENDIAN,
1540
 
};
1541
 
 
1542
 
static uint64_t omap_rfbi_read(void *opaque, hwaddr addr,
1543
 
                               unsigned size)
1544
 
{
1545
 
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
1546
 
 
1547
 
    if (size != 4) {
1548
 
        return omap_badwidth_read32(opaque, addr);
1549
 
    }
1550
 
 
1551
 
    switch (addr) {
1552
 
    case 0x00:  /* RFBI_REVISION */
1553
 
        TRACERFBI("RFBI_REVISION: 0x10");
1554
 
        return 0x10;
1555
 
 
1556
 
    case 0x10:  /* RFBI_SYSCONFIG */
1557
 
        TRACERFBI("RFBI_SYSCONFIG: 0x%08x", s->rfbi.idlemode);
1558
 
        return s->rfbi.idlemode;
1559
 
 
1560
 
    case 0x14:  /* RFBI_SYSSTATUS */
1561
 
        TRACERFBI("RFBI_SYSSTATUS: 0x%08x", 1 | (s->rfbi.busy << 8));
1562
 
        return 1 | (s->rfbi.busy << 8); /* RESETDONE */
1563
 
 
1564
 
    case 0x40:  /* RFBI_CONTROL */
1565
 
        TRACERFBI("RFBI_CONTROL: 0x%08x", s->rfbi.control);
1566
 
        return s->rfbi.control;
1567
 
 
1568
 
    case 0x44:  /* RFBI_PIXELCNT */
1569
 
        TRACERFBI("RFBI_PIXELCNT: 0x%08x", s->rfbi.pixels);
1570
 
        return s->rfbi.pixels;
1571
 
 
1572
 
    case 0x48:  /* RFBI_LINE_NUMBER */
1573
 
        TRACERFBI("RFBI_LINE_NUMBER: 0x%08x", s->rfbi.skiplines);
1574
 
        return s->rfbi.skiplines;
1575
 
 
1576
 
    case 0x58:  /* RFBI_READ */
1577
 
    case 0x5c:  /* RFBI_STATUS */
1578
 
        TRACERFBI("RFBI_READ/STATUS: 0x%08x", s->rfbi.rxbuf);
1579
 
        return s->rfbi.rxbuf;
1580
 
 
1581
 
    case 0x60:  /* RFBI_CONFIG0 */
1582
 
        TRACERFBI("RFBI_CONFIG0: 0x%08x", s->rfbi.config[0]);
1583
 
        return s->rfbi.config[0];
1584
 
    case 0x64:  /* RFBI_ONOFF_TIME0 */
1585
 
        TRACERFBI("RFBI_ONOFF_TIME0: 0x%08x", s->rfbi.time[0]);
1586
 
        return s->rfbi.time[0];
1587
 
    case 0x68:  /* RFBI_CYCLE_TIME0 */
1588
 
        TRACERFBI("RFBI_CYCLE_TIME0: 0x%08x", s->rfbi.time[1]);
1589
 
        return s->rfbi.time[1];
1590
 
    case 0x6c:  /* RFBI_DATA_CYCLE1_0 */
1591
 
        TRACERFBI("RFBI_DATA_CYCLE1_0: 0x%08x", s->rfbi.data[0]);
1592
 
        return s->rfbi.data[0];
1593
 
    case 0x70:  /* RFBI_DATA_CYCLE2_0 */
1594
 
        TRACERFBI("RFBI_DATA_CYCLE2_0: 0x%08x", s->rfbi.data[1]);
1595
 
        return s->rfbi.data[1];
1596
 
    case 0x74:  /* RFBI_DATA_CYCLE3_0 */
1597
 
        TRACERFBI("RFBI_DATA_CYCLE3_0: 0x%08x", s->rfbi.data[2]);
1598
 
        return s->rfbi.data[2];
1599
 
 
1600
 
    case 0x78:  /* RFBI_CONFIG1 */
1601
 
        TRACERFBI("RFBI_CONFIG1: 0x%08x", s->rfbi.config[1]);
1602
 
        return s->rfbi.config[1];
1603
 
    case 0x7c:  /* RFBI_ONOFF_TIME1 */
1604
 
        TRACERFBI("RFBI_ONOFF_TIME1: 0x%08x", s->rfbi.time[2]);
1605
 
        return s->rfbi.time[2];
1606
 
    case 0x80:  /* RFBI_CYCLE_TIME1 */
1607
 
        TRACERFBI("RFBI_CYCLE_TIME1: 0x%08x", s->rfbi.time[3]);
1608
 
        return s->rfbi.time[3];
1609
 
    case 0x84:  /* RFBI_DATA_CYCLE1_1 */
1610
 
        TRACERFBI("RFBI_DATA_CYCLE1_1: 0x%08x", s->rfbi.data[3]);
1611
 
        return s->rfbi.data[3];
1612
 
    case 0x88:  /* RFBI_DATA_CYCLE2_1 */
1613
 
        TRACERFBI("RFBI_DATA_CYCLE2_1: 0x%08x", s->rfbi.data[4]);
1614
 
        return s->rfbi.data[4];
1615
 
    case 0x8c:  /* RFBI_DATA_CYCLE3_1 */
1616
 
        TRACERFBI("RFBI_DATA_CYCLE3_1: 0x%08x", s->rfbi.data[5]);
1617
 
        return s->rfbi.data[5];
1618
 
 
1619
 
    case 0x90:  /* RFBI_VSYNC_WIDTH */
1620
 
        TRACERFBI("RFBI_VSYNC_WIDTH: 0x%08x", s->rfbi.vsync);
1621
 
        return s->rfbi.vsync;
1622
 
    case 0x94:  /* RFBI_HSYNC_WIDTH */
1623
 
        TRACERFBI("RFBI_HSYNC_WIDTH: 0x%08x", s->rfbi.hsync);
1624
 
        return s->rfbi.hsync;
1625
 
    }
1626
 
    OMAP_BAD_REG(addr);
1627
 
    return 0;
1628
 
}
1629
 
 
1630
 
static void omap_rfbi_write(void *opaque, hwaddr addr,
1631
 
                            uint64_t value, unsigned size)
1632
 
{
1633
 
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
1634
 
 
1635
 
    if (size != 4) {
1636
 
        return omap_badwidth_write32(opaque, addr, value);
1637
 
    }
1638
 
 
1639
 
    switch (addr) {
1640
 
    case 0x10:  /* RFBI_SYSCONFIG */
1641
 
        TRACERFBI("RFBI_SYSCONFIG = 0x%08x", value);
1642
 
        if (value & 2)                                          /* SOFTRESET */
1643
 
            omap_rfbi_reset(s);
1644
 
        s->rfbi.idlemode = value & 0x19;
1645
 
        break;
1646
 
 
1647
 
    case 0x40:  /* RFBI_CONTROL */
1648
 
        TRACERFBI("RFBI_CONTROL = 0x%08x", value);
1649
 
        if (s->dispc.rev < 0x30) 
1650
 
            s->rfbi.control = value & 0x1f;
1651
 
        else
1652
 
            s->rfbi.control = value & 0x1ff; 
1653
 
        s->rfbi.enable = value & 1;
1654
 
        if ((s->dispc.control & 1) && /* LCDENABLE */
1655
 
            (value & 0x10) &&         /* ITE */
1656
 
            !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc)) /* TRIGGERMODE */
1657
 
            omap_rfbi_transfer_start(s);
1658
 
        break;
1659
 
 
1660
 
    case 0x44:  /* RFBI_PIXELCNT */
1661
 
        TRACERFBI("RFBI_PIXELCNT = 0x%08x", value);
1662
 
        s->rfbi.pixels = value;
1663
 
        break;
1664
 
 
1665
 
    case 0x48:  /* RFBI_LINE_NUMBER */
1666
 
        TRACERFBI("RFBI_LINE_NUMBER = 0x%08x", value);
1667
 
        s->rfbi.skiplines = value & 0x7ff;
1668
 
        break;
1669
 
 
1670
 
    case 0x4c:  /* RFBI_CMD */
1671
 
        TRACERFBI("RFBI_CMD = 0x%08x", value);
1672
 
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1673
 
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff);
1674
 
        if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1675
 
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff);
1676
 
        break;
1677
 
    case 0x50:  /* RFBI_PARAM */
1678
 
        TRACERFBI("RFBI_PARAM = 0x%08x", value);
1679
 
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1680
 
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
1681
 
        if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1682
 
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
1683
 
        break;
1684
 
    case 0x54:  /* RFBI_DATA */
1685
 
        TRACERFBI("RFBI_DATA = 0x%08x", value);
1686
 
        /* TODO: take into account the format set up in s->rfbi.config[?] and
1687
 
         * s->rfbi.data[?], but special-case the most usual scenario so that
1688
 
         * speed doesn't suffer.  */
1689
 
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) {
1690
 
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
1691
 
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16);
1692
 
        }
1693
 
        if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) {
1694
 
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
1695
 
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16);
1696
 
        }
1697
 
        if (!-- s->rfbi.pixels)
1698
 
            omap_rfbi_transfer_stop(s);
1699
 
        break;
1700
 
    case 0x58:  /* RFBI_READ */
1701
 
        TRACERFBI("RFBI_READ = 0x%08x", value);
1702
 
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1703
 
            s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
1704
 
        else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1705
 
            s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 1);
1706
 
        if (!-- s->rfbi.pixels)
1707
 
            omap_rfbi_transfer_stop(s);
1708
 
        break;
1709
 
 
1710
 
    case 0x5c:  /* RFBI_STATUS */
1711
 
        TRACERFBI("RFBI_STATUS = 0x%08x", value);
1712
 
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1713
 
            s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
1714
 
        else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1715
 
            s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 0);
1716
 
        if (!-- s->rfbi.pixels)
1717
 
            omap_rfbi_transfer_stop(s);
1718
 
        break;
1719
 
 
1720
 
    case 0x60:  /* RFBI_CONFIG0 */
1721
 
        TRACERFBI("RFBI_CONFIG0 = 0x%08x", value);
1722
 
        s->rfbi.config[0] = value & 0x003f1fff;
1723
 
        break;
1724
 
 
1725
 
    case 0x64:  /* RFBI_ONOFF_TIME0 */
1726
 
        TRACERFBI("RFBI_ONOFF_TIME0 = 0x%08x", value);
1727
 
        s->rfbi.time[0] = value & 0x3fffffff;
1728
 
        break;
1729
 
    case 0x68:  /* RFBI_CYCLE_TIME0 */
1730
 
        TRACERFBI("RFBI_CYCLE_TIME0 = 0x%08x", value);
1731
 
        s->rfbi.time[1] = value & 0x0fffffff;
1732
 
        break;
1733
 
    case 0x6c:  /* RFBI_DATA_CYCLE1_0 */
1734
 
        TRACERFBI("RFBI_DATA_CYCLE1_0 = 0x%08x", value);
1735
 
        s->rfbi.data[0] = value & 0x0f1f0f1f;
1736
 
        break;
1737
 
    case 0x70:  /* RFBI_DATA_CYCLE2_0 */
1738
 
        TRACERFBI("RFBI_DATA_CYCLE2_0 = 0x%08x", value);
1739
 
        s->rfbi.data[1] = value & 0x0f1f0f1f;
1740
 
        break;
1741
 
    case 0x74:  /* RFBI_DATA_CYCLE3_0 */
1742
 
        TRACERFBI("RFBI_DATA_CYCLE3_0 = 0x%08x", value);
1743
 
        s->rfbi.data[2] = value & 0x0f1f0f1f;
1744
 
        break;
1745
 
    case 0x78:  /* RFBI_CONFIG1 */
1746
 
        TRACERFBI("RFBI_CONFIG1 = 0x%08x", value);
1747
 
        s->rfbi.config[1] = value & 0x003f1fff;
1748
 
        break;
1749
 
 
1750
 
    case 0x7c:  /* RFBI_ONOFF_TIME1 */
1751
 
        TRACERFBI("RFBI_ONOFF_TIME1 = 0x%08x", value);
1752
 
        s->rfbi.time[2] = value & 0x3fffffff;
1753
 
        break;
1754
 
    case 0x80:  /* RFBI_CYCLE_TIME1 */
1755
 
        TRACERFBI("RFBI_CYCLE_TIME1 = 0x%08x", value);
1756
 
        s->rfbi.time[3] = value & 0x0fffffff;
1757
 
        break;
1758
 
    case 0x84:  /* RFBI_DATA_CYCLE1_1 */
1759
 
        TRACERFBI("RFBI_DATA_CYCLE1_1 = 0x%08x", value);
1760
 
        s->rfbi.data[3] = value & 0x0f1f0f1f;
1761
 
        break;
1762
 
    case 0x88:  /* RFBI_DATA_CYCLE2_1 */
1763
 
        TRACERFBI("RFBI_DATA_CYCLE2_1 = 0x%08x", value);
1764
 
        s->rfbi.data[4] = value & 0x0f1f0f1f;
1765
 
        break;
1766
 
    case 0x8c:  /* RFBI_DATA_CYCLE3_1 */
1767
 
        TRACERFBI("RFBI_DATA_CYCLE3_1 = 0x%08x", value);
1768
 
        s->rfbi.data[5] = value & 0x0f1f0f1f;
1769
 
        break;
1770
 
 
1771
 
    case 0x90:  /* RFBI_VSYNC_WIDTH */
1772
 
        TRACERFBI("RFBI_VSYNC_WIDTH = 0x%08x", value);
1773
 
        s->rfbi.vsync = value & 0xffff;
1774
 
        break;
1775
 
    case 0x94:  /* RFBI_HSYNC_WIDTH */
1776
 
        TRACERFBI("RFBI_HSYNC_WIDTH = 0x%08x", value);
1777
 
        s->rfbi.hsync = value & 0xffff;
1778
 
        break;
1779
 
 
1780
 
    default:
1781
 
        OMAP_BAD_REGV(addr, value);
1782
 
        break;
1783
 
    }
1784
 
}
1785
 
 
1786
 
static const MemoryRegionOps omap_rfbi_ops = {
1787
 
    .read = omap_rfbi_read,
1788
 
    .write = omap_rfbi_write,
1789
 
    .endianness = DEVICE_NATIVE_ENDIAN,
1790
 
};
1791
 
 
1792
 
static uint64_t omap_venc_read(void *opaque, hwaddr addr,
1793
 
                               unsigned size)
1794
 
{
1795
 
    if (size != 4) {
1796
 
        return omap_badwidth_read32(opaque, addr);
1797
 
    }
1798
 
 
1799
 
    switch (addr) {
1800
 
    case 0x00:  /* REV_ID */
1801
 
        return 0x2;
1802
 
    case 0x04:  /* STATUS */
1803
 
    case 0x08:  /* F_CONTROL */
1804
 
    case 0x10:  /* VIDOUT_CTRL */
1805
 
    case 0x14:  /* SYNC_CTRL */
1806
 
    case 0x1c:  /* LLEN */
1807
 
    case 0x20:  /* FLENS */
1808
 
    case 0x24:  /* HFLTR_CTRL */
1809
 
    case 0x28:  /* CC_CARR_WSS_CARR */
1810
 
    case 0x2c:  /* C_PHASE */
1811
 
    case 0x30:  /* GAIN_U */
1812
 
    case 0x34:  /* GAIN_V */
1813
 
    case 0x38:  /* GAIN_Y */
1814
 
    case 0x3c:  /* BLACK_LEVEL */
1815
 
    case 0x40:  /* BLANK_LEVEL */
1816
 
    case 0x44:  /* X_COLOR */
1817
 
    case 0x48:  /* M_CONTROL */
1818
 
    case 0x4c:  /* BSTAMP_WSS_DATA */
1819
 
    case 0x50:  /* S_CARR */
1820
 
    case 0x54:  /* LINE21 */
1821
 
    case 0x58:  /* LN_SEL */
1822
 
    case 0x5c:  /* L21__WC_CTL */
1823
 
    case 0x60:  /* HTRIGGER_VTRIGGER */
1824
 
    case 0x64:  /* SAVID__EAVID */
1825
 
    case 0x68:  /* FLEN__FAL */
1826
 
    case 0x6c:  /* LAL__PHASE_RESET */
1827
 
    case 0x70:  /* HS_INT_START_STOP_X */
1828
 
    case 0x74:  /* HS_EXT_START_STOP_X */
1829
 
    case 0x78:  /* VS_INT_START_X */
1830
 
    case 0x7c:  /* VS_INT_STOP_X__VS_INT_START_Y */
1831
 
    case 0x80:  /* VS_INT_STOP_Y__VS_INT_START_X */
1832
 
    case 0x84:  /* VS_EXT_STOP_X__VS_EXT_START_Y */
1833
 
    case 0x88:  /* VS_EXT_STOP_Y */
1834
 
    case 0x90:  /* AVID_START_STOP_X */
1835
 
    case 0x94:  /* AVID_START_STOP_Y */
1836
 
    case 0xa0:  /* FID_INT_START_X__FID_INT_START_Y */
1837
 
    case 0xa4:  /* FID_INT_OFFSET_Y__FID_EXT_START_X */
1838
 
    case 0xa8:  /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
1839
 
    case 0xb0:  /* TVDETGP_INT_START_STOP_X */
1840
 
    case 0xb4:  /* TVDETGP_INT_START_STOP_Y */
1841
 
    case 0xb8:  /* GEN_CTRL */
1842
 
    case 0xc4:  /* DAC_TST__DAC_A */
1843
 
    case 0xc8:  /* DAC_B__DAC_C */
1844
 
       return 0;
1845
 
    default:
1846
 
        break;
1847
 
    }
1848
 
    OMAP_BAD_REG(addr);
1849
 
    return 0;
1850
 
}
1851
 
 
1852
 
static void omap_venc_write(void *opaque, hwaddr addr,
1853
 
                            uint64_t value, unsigned size)
1854
 
{
1855
 
    if (size != 4) {
1856
 
        return omap_badwidth_write32(opaque, addr, size);
1857
 
    }
1858
 
 
1859
 
    switch (addr) {
1860
 
    case 0x00: /* REV_ID */
1861
 
    case 0x04: /* STATUS */
1862
 
        /* read-only, ignore */
1863
 
        break;
1864
 
    case 0x08:  /* F_CONTROL */
1865
 
    case 0x10:  /* VIDOUT_CTRL */
1866
 
    case 0x14:  /* SYNC_CTRL */
1867
 
    case 0x1c:  /* LLEN */
1868
 
    case 0x20:  /* FLENS */
1869
 
    case 0x24:  /* HFLTR_CTRL */
1870
 
    case 0x28:  /* CC_CARR_WSS_CARR */
1871
 
    case 0x2c:  /* C_PHASE */
1872
 
    case 0x30:  /* GAIN_U */
1873
 
    case 0x34:  /* GAIN_V */
1874
 
    case 0x38:  /* GAIN_Y */
1875
 
    case 0x3c:  /* BLACK_LEVEL */
1876
 
    case 0x40:  /* BLANK_LEVEL */
1877
 
    case 0x44:  /* X_COLOR */
1878
 
    case 0x48:  /* M_CONTROL */
1879
 
    case 0x4c:  /* BSTAMP_WSS_DATA */
1880
 
    case 0x50:  /* S_CARR */
1881
 
    case 0x54:  /* LINE21 */
1882
 
    case 0x58:  /* LN_SEL */
1883
 
    case 0x5c:  /* L21__WC_CTL */
1884
 
    case 0x60:  /* HTRIGGER_VTRIGGER */
1885
 
    case 0x64:  /* SAVID__EAVID */
1886
 
    case 0x68:  /* FLEN__FAL */
1887
 
    case 0x6c:  /* LAL__PHASE_RESET */
1888
 
    case 0x70:  /* HS_INT_START_STOP_X */
1889
 
    case 0x74:  /* HS_EXT_START_STOP_X */
1890
 
    case 0x78:  /* VS_INT_START_X */
1891
 
    case 0x7c:  /* VS_INT_STOP_X__VS_INT_START_Y */
1892
 
    case 0x80:  /* VS_INT_STOP_Y__VS_INT_START_X */
1893
 
    case 0x84:  /* VS_EXT_STOP_X__VS_EXT_START_Y */
1894
 
    case 0x88:  /* VS_EXT_STOP_Y */
1895
 
    case 0x90:  /* AVID_START_STOP_X */
1896
 
    case 0x94:  /* AVID_START_STOP_Y */
1897
 
    case 0xa0:  /* FID_INT_START_X__FID_INT_START_Y */
1898
 
    case 0xa4:  /* FID_INT_OFFSET_Y__FID_EXT_START_X */
1899
 
    case 0xa8:  /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
1900
 
    case 0xb0:  /* TVDETGP_INT_START_STOP_X */
1901
 
    case 0xb4:  /* TVDETGP_INT_START_STOP_Y */
1902
 
    case 0xb8:  /* GEN_CTRL */
1903
 
    case 0xc4:  /* DAC_TST__DAC_A */
1904
 
    case 0xc8:  /* DAC_B__DAC_C */
1905
 
        break;
1906
 
    default:
1907
 
        OMAP_BAD_REGV(addr, value);
1908
 
        break;
1909
 
    }
1910
 
}
1911
 
 
1912
 
static const MemoryRegionOps omap_venc_ops = {
1913
 
    .read = omap_venc_read,
1914
 
    .write = omap_venc_write,
1915
 
    .endianness = DEVICE_NATIVE_ENDIAN,
1916
 
};
1917
 
 
1918
 
static uint64_t omap_im3_read(void *opaque, hwaddr addr,
1919
 
                              unsigned size)
1920
 
{
1921
 
    if (size != 4) {
1922
 
        return omap_badwidth_read32(opaque, addr);
1923
 
    }
1924
 
 
1925
 
    switch (addr) {
1926
 
    case 0x0a8: /* SBIMERRLOGA */
1927
 
    case 0x0b0: /* SBIMERRLOG */
1928
 
    case 0x190: /* SBIMSTATE */
1929
 
    case 0x198: /* SBTMSTATE_L */
1930
 
    case 0x19c: /* SBTMSTATE_H */
1931
 
    case 0x1a8: /* SBIMCONFIG_L */
1932
 
    case 0x1ac: /* SBIMCONFIG_H */
1933
 
    case 0x1f8: /* SBID_L */
1934
 
    case 0x1fc: /* SBID_H */
1935
 
        return 0;
1936
 
 
1937
 
    default:
1938
 
        break;
1939
 
    }
1940
 
    OMAP_BAD_REG(addr);
1941
 
    return 0;
1942
 
}
1943
 
 
1944
 
static void omap_im3_write(void *opaque, hwaddr addr,
1945
 
                           uint64_t value, unsigned size)
1946
 
{
1947
 
    if (size != 4) {
1948
 
        return omap_badwidth_write32(opaque, addr, value);
1949
 
    }
1950
 
 
1951
 
    switch (addr) {
1952
 
    case 0x0b0: /* SBIMERRLOG */
1953
 
    case 0x190: /* SBIMSTATE */
1954
 
    case 0x198: /* SBTMSTATE_L */
1955
 
    case 0x19c: /* SBTMSTATE_H */
1956
 
    case 0x1a8: /* SBIMCONFIG_L */
1957
 
    case 0x1ac: /* SBIMCONFIG_H */
1958
 
        break;
1959
 
 
1960
 
    default:
1961
 
        OMAP_BAD_REGV(addr, value);
1962
 
        break;
1963
 
    }
1964
 
}
1965
 
 
1966
 
static const MemoryRegionOps omap_im3_ops = {
1967
 
    .read = omap_im3_read,
1968
 
    .write = omap_im3_write,
1969
 
    .endianness = DEVICE_NATIVE_ENDIAN,
1970
 
};
1971
 
 
1972
 
static void omap_dsi_push_rx_fifo(struct omap_dss_s *s, int ch, uint32_t value)
1973
 
{
1974
 
    int p;
1975
 
 
1976
 
    if (s->dsi.vc[ch].rx_fifo_len < OMAP_DSI_RX_FIFO_SIZE) {
1977
 
        p = s->dsi.vc[ch].rx_fifo_pos + s->dsi.vc[ch].rx_fifo_len;
1978
 
        if (p >= OMAP_DSI_RX_FIFO_SIZE)
1979
 
            p -= OMAP_DSI_RX_FIFO_SIZE;
1980
 
        s->dsi.vc[ch].rx_fifo[p] = value;
1981
 
        s->dsi.vc[ch].rx_fifo_len++;
1982
 
    } else {
1983
 
        TRACEDSI("vc%d rx fifo overflow!", ch);
1984
 
    }
1985
 
}
1986
 
 
1987
 
static uint32_t omap_dsi_pull_rx_fifo(struct omap_dss_s *s, int ch)
1988
 
{
1989
 
    int v = 0;
1990
 
 
1991
 
    if (!s->dsi.vc[ch].rx_fifo_len) {
1992
 
        TRACEDSI("vc%d rx fifo underflow!", ch);
1993
 
    } else {
1994
 
        v = s->dsi.vc[ch].rx_fifo[s->dsi.vc[ch].rx_fifo_pos++];
1995
 
        s->dsi.vc[ch].rx_fifo_len--;
1996
 
        if (s->dsi.vc[ch].rx_fifo_pos >= OMAP_DSI_RX_FIFO_SIZE)
1997
 
            s->dsi.vc[ch].rx_fifo_pos = 0;
1998
 
    }
1999
 
 
2000
 
    return v;
2001
 
}
2002
 
 
2003
 
static uint32_t omap_dsi_read(void *opaque, hwaddr addr)
2004
 
{
2005
 
    struct omap_dss_s *s = (struct omap_dss_s *)opaque;
2006
 
    uint32_t x, y;
2007
 
 
2008
 
    switch (addr) {
2009
 
    case 0x000: /* DSI_REVISION */
2010
 
        TRACEDSI("DSI_REVISION = 0x10");
2011
 
        return 0x10;
2012
 
    case 0x010: /* DSI_SYSCONFIG */
2013
 
        TRACEDSI("DSI_SYSCONFIG = 0x%04x", s->dsi.sysconfig);
2014
 
        return s->dsi.sysconfig;
2015
 
    case 0x014: /* DSI_SYSSTATUS */
2016
 
        TRACEDSI("DSI_SYSSTATUS = 0x01");
2017
 
        return 1; /* RESET_DONE */
2018
 
    case 0x018: /* DSI_IRQSTATUS */
2019
 
        TRACEDSI("DSI_IRQSTATUS = 0x%08x", s->dsi.irqst);
2020
 
        return s->dsi.irqst;
2021
 
    case 0x01c: /* DSI_IRQENABLE */
2022
 
        TRACEDSI("DSI_IRQENABLE = 0x%08x", s->dsi.irqen);
2023
 
        return s->dsi.irqen;
2024
 
    case 0x040: /* DSI_CTRL */
2025
 
        TRACEDSI("DSI_CTRL = 0x%08x", s->dsi.ctrl);
2026
 
        return s->dsi.ctrl;
2027
 
    case 0x048: /* DSI_COMPLEXIO_CFG1 */
2028
 
        TRACEDSI("DSI_COMPLEXIO_CFG1 = 0x%08x", s->dsi.complexio_cfg1);
2029
 
        return s->dsi.complexio_cfg1;
2030
 
    case 0x04c: /* DSI_COMPLEXIO_IRQSTATUS */
2031
 
        TRACEDSI("DSI_COMPLEXIO_IRQSTATUS = 0x%08x", s->dsi.complexio_irqst);
2032
 
        return s->dsi.complexio_irqst;
2033
 
    case 0x050: /* DSI_COMPLEXIO_IRQENABLE */
2034
 
        TRACEDSI("DSI_COMPLEXIO_IRQENABLE = 0x%08x", s->dsi.complexio_irqen);
2035
 
        return s->dsi.complexio_irqen;
2036
 
    case 0x054: /* DSI_CLK_CTRL */
2037
 
        TRACEDSI("DSI_CLK_CTRL = 0x%08x", s->dsi.clk_ctrl);
2038
 
        return s->dsi.clk_ctrl;
2039
 
    case 0x058: /* DSI_TIMING1 */
2040
 
        TRACEDSI("DSI_TIMING1 = 0x%08x", s->dsi.timing1);
2041
 
        return s->dsi.timing1;
2042
 
    case 0x05c: /* DSI_TIMING2 */
2043
 
        TRACEDSI("DSI_TIMING2 = 0x%08x", s->dsi.timing2);
2044
 
        return s->dsi.timing2;
2045
 
    case 0x060: /* DSI_VM_TIMING1 */
2046
 
        TRACEDSI("DSI_VM_TIMING1 = 0x%08x", s->dsi.vm_timing1);
2047
 
        return s->dsi.vm_timing1;
2048
 
    case 0x064: /* DSI_VM_TIMING2 */
2049
 
        TRACEDSI("DSI_VM_TIMING2 = 0x%08x", s->dsi.vm_timing2);
2050
 
        return s->dsi.vm_timing2;
2051
 
    case 0x068: /* DSI_VM_TIMING3 */
2052
 
        TRACEDSI("DSI_VM_TIMING3 = 0x%08x", s->dsi.vm_timing3);
2053
 
        return s->dsi.vm_timing3;
2054
 
    case 0x06c: /* DSI_CLK_TIMING */
2055
 
        TRACEDSI("DSI_CLK_TIMING = 0x%08x", s->dsi.clk_timing);
2056
 
        return s->dsi.clk_timing;
2057
 
    case 0x070: /* DSI_TX_FIFO_VC_SIZE */
2058
 
        TRACEDSI("DSI_TX_FIFO_VC_SIZE = 0x%08x", s->dsi.tx_fifo_vc_size);
2059
 
        return s->dsi.tx_fifo_vc_size;
2060
 
    case 0x074: /* DSI_RX_FIFO_VC_SIZE */
2061
 
        TRACEDSI("DSI_RX_FIFO_VC_SIZE = 0x%08x", s->dsi.rx_fifo_vc_size);
2062
 
        return s->dsi.rx_fifo_vc_size;
2063
 
    case 0x078: /* DSI_COMPLEXIO_CFG_2 */
2064
 
        TRACEDSI("DSI_COMPLEXIO_CFG_2 = 0x%08x", s->dsi.complexio_cfg2);
2065
 
        return s->dsi.complexio_cfg2;
2066
 
    case 0x07c: /* DSI_RX_FIFO_VC_FULLNESS */
2067
 
        TRACEDSI("DSI_RX_FIFO_VC_FULLNESS = 0x00");
2068
 
        return 0;
2069
 
    case 0x080: /* DSI_VM_TIMING4 */
2070
 
        TRACEDSI("DSI_VM_TIMING4 = 0x%08x", s->dsi.vm_timing4);
2071
 
        return s->dsi.vm_timing4;
2072
 
    case 0x084: /* DSI_TX_FIFO_VC_EMPTINESS */
2073
 
        TRACEDSI("DSI_TX_FIFO_VC_EMPTINESS = 0x7f7f7f7f");
2074
 
        return 0x7f7f7f7f;
2075
 
    case 0x088: /* DSI_VM_TIMING5 */
2076
 
        TRACEDSI("DSI_VM_TIMING5 = 0x%08x", s->dsi.vm_timing5);
2077
 
        return s->dsi.vm_timing5;
2078
 
    case 0x08c: /* DSI_VM_TIMING6 */
2079
 
        TRACEDSI("DSI_VM_TIMING6 = 0x%08x", s->dsi.vm_timing6);
2080
 
        return s->dsi.vm_timing6;
2081
 
    case 0x090: /* DSI_VM_TIMING7 */
2082
 
        TRACEDSI("DSI_VM_TIMING7 = 0x%08x", s->dsi.vm_timing7);
2083
 
        return s->dsi.vm_timing7;
2084
 
    case 0x094: /* DSI_STOPCLK_TIMING */
2085
 
        TRACEDSI("DSI_STOPCLK_TIMING = 0x%08x", s->dsi.stopclk_timing);
2086
 
        return s->dsi.stopclk_timing;
2087
 
    case 0x100 ... 0x17c: /* DSI_VCx_xxx */
2088
 
        x = (addr >> 5) & 3;
2089
 
        switch (addr & 0x1f) {
2090
 
        case 0x00: /* DSI_VCx_CTRL */
2091
 
            TRACEDSI("DSI_VC%d_CTRL = 0x%08x", x, s->dsi.vc[x].ctrl);
2092
 
            return s->dsi.vc[x].ctrl;
2093
 
        case 0x04: /* DSI_VCx_TE */
2094
 
            TRACEDSI("DSI_VC%d_TE = 0x%08x", x, s->dsi.vc[x].te);
2095
 
            return s->dsi.vc[x].te;
2096
 
        case 0x08: /* DSI_VCx_LONG_PACKET_HEADER */
2097
 
            /* write-only */
2098
 
            TRACEDSI("DSI_VC%d_LONG_PACKET_HEADER = 0", x);
2099
 
            return 0;
2100
 
        case 0x0c: /* DSI_VCx_LONG_PACKET_PAYLOAD */
2101
 
            /* write-only */
2102
 
            TRACEDSI("DSI_VC%d_LONG_PACKET_PAYLOAD = 0", x);
2103
 
            return 0;
2104
 
        case 0x10: /* DSI_VCx_SHORT_PACKET_HEADER */
2105
 
            if (s->dsi.vc[x].ctrl & (1 << 20)) { /* RX_FIFO_NOT_EMPTY */
2106
 
                y = omap_dsi_pull_rx_fifo(s, x);
2107
 
                TRACEDSI("DSI_VC%d_SHORT_PACKET_HEADER = 0x%08x", x, y);
2108
 
                if (!s->dsi.vc[x].rx_fifo_len)
2109
 
                    s->dsi.vc[x].ctrl &= ~(1 << 20); /* RX_FIFO_NOT_EMPTY */
2110
 
                return y;
2111
 
            }
2112
 
            TRACEDSI("vc%d rx fifo underflow!", x);
2113
 
            return 0;
2114
 
        case 0x18: /* DSI_VCx_IRQSTATUS */
2115
 
            TRACEDSI("DSI_VC%d_IRQSTATUS = 0x%08x", x, s->dsi.vc[x].irqst);
2116
 
            return s->dsi.vc[x].irqst;
2117
 
        case 0x1c: /* DSI_VCx_IRQENABLE */
2118
 
            TRACEDSI("DSI_VC%d_IRQENABLE = 0x%08x", x, s->dsi.vc[x].irqen);
2119
 
            return s->dsi.vc[x].irqen;
2120
 
        default:
2121
 
            OMAP_BAD_REG(addr);
2122
 
        }
2123
 
        break;
2124
 
    case 0x200: /* DSI_PHY_CFG0 */
2125
 
        TRACEDSI("DSI_PHY_CFG0 = 0x%08x", s->dsi.phy_cfg0);
2126
 
        return s->dsi.phy_cfg0;
2127
 
    case 0x204: /* DSI_PHY_CFG1 */
2128
 
        TRACEDSI("DSI_PHY_CFG1 = 0x%08x", s->dsi.phy_cfg1);
2129
 
        return s->dsi.phy_cfg1;
2130
 
    case 0x208: /* DSI_PHY_CFG2 */
2131
 
        TRACEDSI("DSI_PHY_CFG2 = 0x%08x", s->dsi.phy_cfg2);
2132
 
        return s->dsi.phy_cfg2;
2133
 
     case 0x214: /* DSI_PHY_CFG5 */
2134
 
        TRACEDSI("DSI_PHY_CFG5 = 0xfc000000");
2135
 
        return 0xfc000000; /* all resets done */
2136
 
    case 0x300: /* DSI_PLL_CONTROL */
2137
 
        TRACEDSI("DSI_PLL_CONTROL = 0x%08x", s->dsi.pll_control);
2138
 
        return s->dsi.pll_control;
2139
 
    case 0x304: /* DSI_PLL_STATUS */
2140
 
        x = 1; /* DSI_PLLCTRL_RESET_DONE */
2141
 
        if ((s->dsi.clk_ctrl >> 28) & 3) { /* DSI PLL control powered? */
2142
 
            if (((s->dsi.pll_config1 >> 1) & 0x7f) &&  /* DSI_PLL_REGN */
2143
 
                ((s->dsi.pll_config1 >> 8) & 0x7ff)) { /* DSI_PLL_REGM */
2144
 
                x |= 2; /* DSI_PLL_LOCK */
2145
 
            }
2146
 
        }
2147
 
        if ((s->dsi.pll_config2 >> 20) & 1) /* DSI_HSDIVBYPASS */
2148
 
            x |= (1 << 9);                  /* DSI_BYPASSACKZ */
2149
 
        if ((s->dsi.pll_config2 >> 18) & 1) /* DSI_PROTO_CLOCK_EN */
2150
 
            x |= (1 << 8);                  /* DSIPROTO_CLOCK_ACK */
2151
 
        if ((s->dsi.pll_config2 >> 16) & 1) /* DSS_CLOCK_EN */
2152
 
            x |= (1 << 7);                  /* DSS_CLOCK_ACK */
2153
 
        if (!((s->dsi.pll_config2 >> 13) & 1)) /* DSI_PLL_REFEN */
2154
 
            x |= (1 << 3);                     /* DSI_PLL_LOSSREF */
2155
 
        TRACEDSI("DSI_PLL_STATUS = 0x%08x", x);
2156
 
        return x;
2157
 
    case 0x308: /* DSI_PLL_GO */
2158
 
        TRACEDSI("DSI_PLL_GO = 0x%08x", s->dsi.pll_go);
2159
 
        return s->dsi.pll_go;
2160
 
    case 0x30c: /* DSI_PLL_CONFIGURATION1 */
2161
 
        TRACEDSI("DSI_PLL_CONFIGURATION1 = 0x%08x", s->dsi.pll_config1);
2162
 
        return s->dsi.pll_config1;
2163
 
    case 0x310: /* DSI_PLL_CONFIGURATION2 */
2164
 
        TRACEDSI("DSI_PLL_CONFIGURATION2 = 0x%08x", s->dsi.pll_config2);
2165
 
        return s->dsi.pll_config2;
2166
 
    default:
2167
 
        break;
2168
 
    }
2169
 
    OMAP_BAD_REG(addr);
2170
 
    return 0;
2171
 
}
2172
 
 
2173
 
static void omap_dsi_txdone(struct omap_dss_s *s, int ch, int bta)
2174
 
{
2175
 
    if (bta) {
2176
 
        s->dsi.vc[ch].irqst |= 0x20;       /* BTA_IRQ */
2177
 
        if (s->dsi.vc[ch].rx_fifo_len)
2178
 
            s->dsi.vc[ch].ctrl |= 1 << 20; /* RX_FIFO_NOT_EMPTY */
2179
 
    } else {
2180
 
        s->dsi.vc[ch].irqst |= 0x04;       /* PACKET_SENT_IRQ */
2181
 
    }
2182
 
    s->dsi.irqst |= 1 << ch;               /* VIRTUAL_CHANNELx_IRQ */
2183
 
    omap_dss_interrupt_update(s);
2184
 
}
2185
 
 
2186
 
static void omap_dsi_short_write(struct omap_dss_s *s, int ch)
2187
 
{
2188
 
    uint32_t data = s->dsi.vc[ch].sp_header;
2189
 
 
2190
 
    if (((data >> 6) & 0x03) != ch) {
2191
 
        TRACEDSI("error - vc%d != %d", ch, (data >> 6) & 0x03);
2192
 
    } else {
2193
 
        data = dsi_short_write(s->dsi.host, data);
2194
 
        /* responses cannot be all-zero so it is safe to use that
2195
 
         * as a no-reply value */
2196
 
        if (data) {
2197
 
            omap_dsi_push_rx_fifo(s, ch, data);
2198
 
        }
2199
 
        omap_dsi_txdone(s, ch, (s->dsi.vc[ch].ctrl & 0x04)); /* BTA_SHORT_EN */
2200
 
    }
2201
 
}
2202
 
 
2203
 
static void omap_dsi_long_write(struct omap_dss_s *s, int ch)
2204
 
{
2205
 
    uint32_t hdr = s->dsi.vc[ch].lp_header;
2206
 
 
2207
 
    /* TODO: implement packet footer sending (16bit checksum).
2208
 
     * Currently none is sent and receiver is supposed to not expect one */
2209
 
    if (((hdr >> 6) & 0x03) != ch) {
2210
 
        TRACEDSI("error - vc%d != %d", ch, (hdr >> 6) & 0x03);
2211
 
    } else {
2212
 
        dsi_long_write(s->dsi.host, hdr, s->dsi.vc[ch].lp_payload,
2213
 
                       s->dsi.vc[ch].lp_counter);
2214
 
        if ((s->dsi.vc[ch].te >> 30) & 3) {     /* TE_START | TE_EN */
2215
 
            /* TODO: do we really need to implement something for this?
2216
 
             * Should writes decrease the TE_SIZE counter, for example?
2217
 
             * For now, the TE transfers are completed immediately */
2218
 
        } else {
2219
 
            if (s->dsi.vc[ch].lp_counter > 0)
2220
 
                s->dsi.vc[ch].lp_counter -= 4;
2221
 
            if (s->dsi.vc[ch].lp_counter <= 0)
2222
 
                omap_dsi_txdone(s, ch, (s->dsi.vc[ch].ctrl & 0x08)); /* BTA_LONG_EN */
2223
 
        }
2224
 
    }
2225
 
}
2226
 
 
2227
 
static void omap_dsi_write(void *opaque, hwaddr addr,
2228
 
                           uint32_t value)
2229
 
{
2230
 
    struct omap_dss_s *s = (struct omap_dss_s *)opaque;
2231
 
    uint32_t x;
2232
 
 
2233
 
    switch (addr) {
2234
 
    case 0x000: /* DSI_REVISION */
2235
 
    case 0x014: /* DSI_SYSSTATUS */
2236
 
    case 0x07c: /* DSI_RX_FIFO_VC_FULLNESS */
2237
 
    case 0x084: /* DSI_RX_FIFO_VC_EMPTINESS */
2238
 
    case 0x214: /* DSI_PHY_CFG5 */
2239
 
    case 0x304: /* DSI_PLL_STATUS */
2240
 
        /* read-only, ignore */
2241
 
        break;
2242
 
    case 0x010: /* DSI_SYSCONFIG */
2243
 
        TRACEDSI("DSI_SYSCONFIG = 0x%08x", value);
2244
 
        if (value & 2) /* SOFT_RESET */
2245
 
            omap_dsi_reset(s);
2246
 
        else
2247
 
            s->dsi.sysconfig = value;
2248
 
        break;
2249
 
    case 0x018: /* DSI_IRQSTATUS */
2250
 
        TRACEDSI("DSI_IRQSTATUS = 0x%08x", value);
2251
 
        s->dsi.irqst &= ~(value & 0x1fc3b0);
2252
 
        omap_dss_interrupt_update(s);
2253
 
        break;
2254
 
    case 0x01c: /* DSI_IRQENABLE */
2255
 
        TRACEDSI("DSI_IRQENABLE = 0x%08x", value);
2256
 
        s->dsi.irqen = value & 0x1fc3b0;
2257
 
        omap_dss_interrupt_update(s);
2258
 
        break;
2259
 
    case 0x040: /* DSI_CTRL */
2260
 
        TRACEDSI("DSI_CTRL = 0x%08x", value);
2261
 
        s->dsi.ctrl = value & 0x7ffffff;
2262
 
        break;
2263
 
    case 0x048: /* DSI_COMPLEXIO_CFG_1 */
2264
 
        TRACEDSI("DSI_COMPLEXIO_CFG1 = 0x%08x", value);
2265
 
        value |= 1 << 29;    /* RESET_DONE */
2266
 
        value |= 1 << 21;    /* LDO_POWER_GOOD_STATE */
2267
 
        value &= ~(1 << 30); /* GOBIT */
2268
 
        /* copy PWR_CMD directly to PWR_STATUS */
2269
 
        value &= ~(3 << 25);
2270
 
        value |= (value >> 2) & (3 << 25);
2271
 
        /* TODO: notify screen refresh control about PWR_STATUS */
2272
 
        s->dsi.complexio_cfg1 = value;
2273
 
        break;
2274
 
    case 0x04c: /* DSI_COMPLEXIO_IRQSTATUS */
2275
 
        TRACEDSI("DSI_COMPLEXIO_IRQSTATUS = 0x%08x", value);
2276
 
        s->dsi.complexio_irqst &= ~(value & 0xc3f39ce7);
2277
 
        if (s->dsi.complexio_irqst & s->dsi.complexio_irqen)
2278
 
            s->dsi.irqst |= (1 << 10);  /* COMPLEXIO_ERR_IRQ */
2279
 
        else
2280
 
            s->dsi.irqst &= ~(1 << 10); /* COMPLEXIO_ERR_IRQ */
2281
 
        omap_dss_interrupt_update(s);
2282
 
        break;
2283
 
    case 0x050: /* DSI_COMPLEXIO_IRQENABLE */
2284
 
        TRACEDSI("DSI_COMPLEXIO_IRQENABLE = 0x%08x", value);
2285
 
        s->dsi.complexio_irqen = value & 0xc3f39ce7;
2286
 
        omap_dss_interrupt_update(s);
2287
 
        break;
2288
 
    case 0x054: /* DSI_CLK_CTRL */
2289
 
        TRACEDSI("DSI_CLK_CTRL = 0x%08x", value);
2290
 
        value &= 0xc03fffff;
2291
 
        /* copy PLL_PWR_CMD directly to PLL_PWR_STATUS */
2292
 
        value |= (value >> 2) & (3 << 28);
2293
 
        s->dsi.clk_ctrl = value;
2294
 
        break;
2295
 
    case 0x058: /* DSI_TIMING1 */
2296
 
        TRACEDSI("DSI_TIMING1 = 0x%08x", value);
2297
 
        value &= ~(1 << 15); /* deassert ForceTxStopMode signal */
2298
 
        s->dsi.timing1 = value;
2299
 
        break;
2300
 
    case 0x05c: /* DSI_TIMING2 */
2301
 
        TRACEDSI("DSI_TIMING2 = 0x%08x", value);
2302
 
        s->dsi.timing2 = value;
2303
 
        break;
2304
 
    case 0x060: /* DSI_VM_TIMING1 */
2305
 
        TRACEDSI("DSI_VM_TIMING1 = 0x%08x", value);
2306
 
        s->dsi.vm_timing1 = value;
2307
 
        break;
2308
 
    case 0x064: /* DSI_VM_TIMING2 */
2309
 
        TRACEDSI("DSI_VM_TIMING2 = 0x%08x", value);
2310
 
        s->dsi.vm_timing2 = value & 0x0fffffff;
2311
 
        break;
2312
 
    case 0x068: /* DSI_VM_TIMING3 */
2313
 
        TRACEDSI("DSI_VM_TIMING3 = 0x%08x", value);
2314
 
        s->dsi.vm_timing3 = value;
2315
 
        break;
2316
 
    case 0x06c: /* DSI_CLK_TIMING */
2317
 
        TRACEDSI("DSI_CLK_TIMING = 0x%08x", value);
2318
 
        s->dsi.clk_timing = value & 0xffff;
2319
 
        break;
2320
 
    case 0x070: /* DSI_TX_FIFO_VC_SIZE */
2321
 
        TRACEDSI("DSI_TX_FIFO_VC_SIZE = 0x%08x", value);
2322
 
        s->dsi.tx_fifo_vc_size = value & 0xf7f7f7f7;
2323
 
        break;
2324
 
    case 0x074: /* DSI_RX_FIFO_VC_SIZE */
2325
 
        TRACEDSI("DSI_RX_FIFO_VC_SIZE = 0x%08x", value);
2326
 
        s->dsi.rx_fifo_vc_size = value & 0xf7f7f7f7;
2327
 
        break;
2328
 
    case 0x078: /* DSI_COMPLEXIO_CFG_2 */
2329
 
        TRACEDSI("DSI_COMPLEXIO_CFG_2 = 0x%08x", value);
2330
 
        s->dsi.complexio_cfg2 = (value & 0xfffcffff)
2331
 
                                | (s->dsi.complexio_cfg2 & (3 << 16));
2332
 
        break;
2333
 
    case 0x080: /* DSI_VM_TIMING4 */
2334
 
        TRACEDSI("DSI_VM_TIMING4 = 0x%08x", value);
2335
 
        s->dsi.vm_timing4 = value;
2336
 
        break;
2337
 
    case 0x088: /* DSI_VM_TIMING5 */
2338
 
        TRACEDSI("DSI_VM_TIMING5 = 0x%08x", value);
2339
 
        s->dsi.vm_timing5 = value;
2340
 
        break;
2341
 
    case 0x08c: /* DSI_VM_TIMING6 */
2342
 
        TRACEDSI("DSI_VM_TIMING6 = 0x%08x", value);
2343
 
        s->dsi.vm_timing6 = value;
2344
 
        break;
2345
 
    case 0x090: /* DSI_VM_TIMING7 */
2346
 
        TRACEDSI("DSI_VM_TIMING7 = 0x%08x", value);
2347
 
        s->dsi.vm_timing7 = value;
2348
 
        break;
2349
 
    case 0x094: /* DSI_STOPCLK_TIMING */
2350
 
        TRACEDSI("DSI_STOPCLK_TIMING = 0x%08x", value);
2351
 
        s->dsi.stopclk_timing = value & 0xff;
2352
 
        break;
2353
 
    case 0x100 ... 0x17c: /* DSI_VCx_xxx */
2354
 
        x = (addr >> 5) & 3;
2355
 
        switch (addr & 0x1f) {
2356
 
        case 0x00: /* DSI_VCx_CTRL */
2357
 
            TRACEDSI("DSI_VC%d_CTRL = 0x%08x", x, value);
2358
 
            if (((value >> 27) & 7) != 4) /* DMA_RX_REQ_NB */
2359
 
                hw_error("%s: RX DMA mode not implemented", __FUNCTION__);
2360
 
            if (((value >> 21) & 7) != 4) /* DMA_TX_REQ_NB */
2361
 
                hw_error("%s: TX DMA mode not implemented", __FUNCTION__);
2362
 
            if (value & 1) { /* VC_EN */
2363
 
                s->dsi.vc[x].ctrl &= ~0x40;  /* BTA_EN */
2364
 
                s->dsi.vc[x].ctrl |= 0x8001; /* VC_BUSY | VC_EN */
2365
 
            } else {
2366
 
                /* clear VC_BUSY and VC_EN, assign writable bits */
2367
 
                s->dsi.vc[x].ctrl = (s->dsi.vc[x].ctrl & 0x114020) |
2368
 
                                    (value & 0x3fee039f);
2369
 
            }
2370
 
            if (value & 0x40) /* BTA_EN */
2371
 
                omap_dsi_txdone(s, x, 1);
2372
 
            break;
2373
 
        case 0x04: /* DSI_VCx_TE */
2374
 
            TRACEDSI("DSI_VC%d_TE = 0x%08x", x, value);
2375
 
            value &= 0xc0ffffff;
2376
 
            /* according to the OMAP3 TRM the TE_EN bit in this
2377
 
             * register is protected by VCx_CTRL VC_EN bit but
2378
 
             * let's forget that */
2379
 
            s->dsi.vc[x].te = value;
2380
 
            if (s->dispc.control & 1) /* LCDENABLE */
2381
 
                omap_dsi_transfer_start(s, x);
2382
 
            break;
2383
 
        case 0x08: /* DSI_VCx_LONG_PACKET_HEADER */
2384
 
            TRACEDSI("DSI_VC%d_LONG_PACKET_HEADER id=0x%02x, len=0x%04x, ecc=0x%02x",
2385
 
                     x, value & 0xff, (value >> 8) & 0xffff, (value >> 24) & 0xff);
2386
 
            s->dsi.vc[x].lp_header = value;
2387
 
            s->dsi.vc[x].lp_counter = (value >> 8) & 0xffff;
2388
 
            break;
2389
 
        case 0x0c: /* DSI_VCx_LONG_PACKET_PAYLOAD */
2390
 
            TRACEDSI("DSI_VC%d_LONG_PACKET_PAYLOAD = 0x%08x", x, value);
2391
 
            s->dsi.vc[x].lp_payload = value;
2392
 
            if ((s->dsi.vc[x].te >> 30) & 3) { /* TE_START | TE_EN */
2393
 
                int tx_dma = (s->dsi.vc[x].ctrl >> 21) & 7; /* DMA_TX_REQ_NB */
2394
 
                if (tx_dma < 4)
2395
 
                    qemu_irq_lower(s->dsi.drq[tx_dma]);
2396
 
            }
2397
 
            omap_dsi_long_write(s, x);
2398
 
            break;
2399
 
        case 0x10: /* DSI_VCx_SHORT_PACKET_HEADER */
2400
 
            TRACEDSI("DSI_VC%d_SHORT_PACKET_HEADER = 0x%08x", x, value);
2401
 
            s->dsi.vc[x].sp_header = value;
2402
 
            omap_dsi_short_write(s, x);
2403
 
            break;
2404
 
        case 0x18: /* DSI_VCx_IRQSTATUS */
2405
 
            TRACEDSI("DSI_VC%d_IRQSTATUS = 0x%08x", x, value);
2406
 
            s->dsi.vc[x].irqst &= ~(value & 0x1ff);
2407
 
            if (s->dsi.vc[x].irqst & s->dsi.vc[x].irqen)
2408
 
                s->dsi.irqst |= 1 << x;    /* VIRTUAL_CHANNELx_IRQ */
2409
 
            else
2410
 
                s->dsi.irqst &= ~(1 << x); /* VIRTUAL_CHANNELx_IRQ */
2411
 
            omap_dss_interrupt_update(s);
2412
 
            break;
2413
 
        case 0x1c: /* DSI_VCx_IRQENABLE */
2414
 
            TRACEDSI("DSI_VC%d_IRQENABLE = 0x%08x", x, value);
2415
 
            s->dsi.vc[x].irqen = value & 0x1ff;
2416
 
            omap_dss_interrupt_update(s);
2417
 
            break;
2418
 
        default:
2419
 
            OMAP_BAD_REGV(addr, value);
2420
 
            break;
2421
 
        }
2422
 
        break;
2423
 
    case 0x200: /* DSI_PHY_CFG0 */
2424
 
        TRACEDSI("DSI_PHY_CFG0 = 0x%08x", value);
2425
 
        s->dsi.phy_cfg0 = value;
2426
 
        break;
2427
 
    case 0x204: /* DSI_PHY_CFG1 */
2428
 
        TRACEDSI("DSI_PHY_CFG1 = 0x%08x", value);
2429
 
        s->dsi.phy_cfg1 = value;
2430
 
        break;
2431
 
    case 0x208: /* DSI_PHY_CFG2 */
2432
 
        TRACEDSI("DSI_PHY_CFG2 = 0x%08x", value);
2433
 
        if (s->mpu_model >= omap3630) {
2434
 
            value &= 0xff0000ff;
2435
 
        }
2436
 
        s->dsi.phy_cfg2 = value;
2437
 
        break;
2438
 
    case 0x300: /* DSI_PLL_CONTROL */
2439
 
        TRACEDSI("DSI_PLL_CONTROL = 0x%08x", value);
2440
 
        s->dsi.pll_control = value & 0x1f;
2441
 
        break;
2442
 
    case 0x308: /* DSI_PLL_GO */
2443
 
        TRACEDSI("DSI_PLL_GO = 0x%08x", value);
2444
 
        /* TODO: check if we need to update something here */
2445
 
        value &= ~1; /* mark it done */
2446
 
        s->dsi.pll_go = value & 1;
2447
 
        break;
2448
 
    case 0x30c: /* DSI_PLL_CONFIGURATION1 */
2449
 
        TRACEDSI("DSI_PLL_CONFIGURATION1 = 0x%08x", value);
2450
 
        s->dsi.pll_config1 = value & 0x7ffffff;
2451
 
        break;
2452
 
    case 0x310: /* DSI_PLL_CONFIGURATION2 */
2453
 
        TRACEDSI("DSI_PLL_CONFIGURATION2 = 0x%08x", value);
2454
 
        if (s->mpu_model < omap3630) {
2455
 
            value &= 0x1fffff;
2456
 
        } else {
2457
 
            value &= 0x1fffe1;
2458
 
        }
2459
 
        s->dsi.pll_config2 = value;
2460
 
        break;
2461
 
    default:
2462
 
        OMAP_BAD_REGV(addr, value);
2463
 
        break;
2464
 
    }
2465
 
}
2466
 
 
2467
 
static const MemoryRegionOps omap_dsi_ops = {
2468
 
    .old_mmio = {
2469
 
        .read = {
2470
 
            omap_badwidth_read32,
2471
 
            omap_badwidth_read32,
2472
 
            omap_dsi_read,
2473
 
        },
2474
 
        .write = {
2475
 
            omap_badwidth_write32,
2476
 
            omap_badwidth_write32,
2477
 
            omap_dsi_write,
2478
 
        },
2479
 
    },
2480
 
    .endianness = DEVICE_NATIVE_ENDIAN,
2481
 
};
2482
 
 
2483
 
static int omap_dss_init(SysBusDevice *dev)
2484
 
{
2485
 
    struct omap_dss_s *s = FROM_SYSBUS(struct omap_dss_s, dev);
2486
 
    sysbus_init_irq(dev, &s->irq);
2487
 
    sysbus_init_irq(dev, &s->drq); /* linetrigger */
2488
 
 
2489
 
    memory_region_init_io(&s->iomem_diss1, &omap_diss_ops, s,
2490
 
                          "omap.diss1", 0x400);
2491
 
    memory_region_init_io(&s->iomem_disc1, &omap_disc_ops, s,
2492
 
                          "omap.disc1", 0x400);
2493
 
    memory_region_init_io(&s->iomem_rfbi1, &omap_rfbi_ops, s,
2494
 
                          "omap.rfbi1", 0x400);
2495
 
    memory_region_init_io(&s->iomem_venc1, &omap_venc_ops, s,
2496
 
                          "omap.venc1", 0x400);
2497
 
    sysbus_init_mmio(dev, &s->iomem_diss1);
2498
 
    sysbus_init_mmio(dev, &s->iomem_disc1);
2499
 
    sysbus_init_mmio(dev, &s->iomem_rfbi1);
2500
 
    sysbus_init_mmio(dev, &s->iomem_venc1);
2501
 
 
2502
 
    if (s->mpu_model < omap2410) {
2503
 
        hw_error("%s: unsupported cpu type\n", __FUNCTION__);
2504
 
    } else if (s->mpu_model < omap3430) {
2505
 
        s->dispc.rev = 0x20;
2506
 
        memory_region_init_io(&s->iomem_im3, &omap_im3_ops, s,
2507
 
                              "omap.im3", 0x1000);
2508
 
        sysbus_init_mmio(dev, &s->iomem_im3);
2509
 
    } else {
2510
 
        s->dispc.rev = 0x30;
2511
 
        s->dispc.lcdframer = qemu_new_timer_ns(vm_clock, omap_dss_framedone, s);
2512
 
        s->dsi.host = dsi_init_host(&dev->qdev, "omap3_dsi",
2513
 
                                    omap_dsi_te_trigger,
2514
 
                                    omap_dss_linefn);
2515
 
        s->dsi.xfer_timer = qemu_new_timer_ns(vm_clock, omap_dsi_transfer_stop,
2516
 
                                           s);
2517
 
        memory_region_init_io(&s->iomem_dsi, &omap_dsi_ops, s,
2518
 
                              "omap.dsi", 0x400);
2519
 
        sysbus_init_mmio(dev, &s->iomem_dsi);
2520
 
        sysbus_init_irq(dev, &s->dsi.drq[0]);
2521
 
        sysbus_init_irq(dev, &s->dsi.drq[1]);
2522
 
        sysbus_init_irq(dev, &s->dsi.drq[2]);
2523
 
        sysbus_init_irq(dev, &s->dsi.drq[3]);
2524
 
    }
2525
 
    return 0;
2526
 
}
2527
 
 
2528
 
static Property omap_dss_properties[] = {
2529
 
    DEFINE_PROP_INT32("mpu_model", struct omap_dss_s, mpu_model, 0),
2530
 
    DEFINE_PROP_END_OF_LIST()
2531
 
};
2532
 
 
2533
 
static void omap_dss_class_init(ObjectClass *klass, void *data)
2534
 
{
2535
 
    DeviceClass *dc = DEVICE_CLASS(klass);
2536
 
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
2537
 
    k->init = omap_dss_init;
2538
 
    dc->reset = omap_dss_reset;
2539
 
    dc->props = omap_dss_properties;
2540
 
}
2541
 
 
2542
 
static TypeInfo omap_dss_info = {
2543
 
    .name = "omap_dss",
2544
 
    .parent = TYPE_SYS_BUS_DEVICE,
2545
 
    .instance_size = sizeof(struct omap_dss_s),
2546
 
    .class_init = omap_dss_class_init,
2547
 
};
2548
 
 
2549
 
static void omap_dss_register_types(void)
2550
 
{
2551
 
    type_register_static(&omap_dss_info);
2552
 
}
2553
 
 
2554
 
void omap_rfbi_attach(DeviceState *dev, int cs,
2555
 
                      const struct rfbi_chip_s *chip)
2556
 
{
2557
 
    struct omap_dss_s *s = FROM_SYSBUS(struct omap_dss_s,
2558
 
                                       SYS_BUS_DEVICE(dev));
2559
 
    if (cs < 0 || cs > 1) {
2560
 
        hw_error("%s: wrong CS %i\n", __FUNCTION__, cs);
2561
 
    }
2562
 
    if (s->rfbi.chip[cs]) {
2563
 
        TRACERFBI("warning - replacing previously attached "
2564
 
                  "RFBI chip on CS%d", cs);
2565
 
    }
2566
 
    s->rfbi.chip[cs] = chip;
2567
 
}
2568
 
 
2569
 
DSIHost *omap_dsi_host(DeviceState *dev)
2570
 
{
2571
 
    return FROM_SYSBUS(struct omap_dss_s,
2572
 
                       SYS_BUS_DEVICE(dev))->dsi.host;
2573
 
}
2574
 
 
2575
 
static const GraphicHwOps omap_lcd_panel_ops = {
2576
 
    .invalidate = omap_lcd_panel_invalidate_display,
2577
 
    .gfx_update = omap_lcd_panel_update_display,
2578
 
};
2579
 
 
2580
 
static const GraphicHwOps omap_digital_panel_ops = {
2581
 
    .invalidate = omap_dig_panel_invalidate_display,
2582
 
    .gfx_update = omap_dig_panel_update_display,
2583
 
};
2584
 
 
2585
 
void omap_lcd_panel_attach(DeviceState *dev)
2586
 
{
2587
 
    struct omap_dss_s *s = FROM_SYSBUS(struct omap_dss_s,
2588
 
                                       SYS_BUS_DEVICE(dev));
2589
 
    if (!s->lcd.attached) {
2590
 
        s->lcd.attached = 1;
2591
 
        s->lcd.invalidate = 1;
2592
 
        s->lcd.con = graphic_console_init(dev, &omap_lcd_panel_ops, s);
2593
 
    }
2594
 
}
2595
 
 
2596
 
void omap_digital_panel_attach(DeviceState *dev)
2597
 
{
2598
 
    struct omap_dss_s *s = FROM_SYSBUS(struct omap_dss_s,
2599
 
                                       SYS_BUS_DEVICE(dev));
2600
 
    if (!s->dig.attached) {
2601
 
        s->dig.attached = 1;
2602
 
        s->dig.invalidate = 1;
2603
 
        s->dig.con = graphic_console_init(dev, &omap_digital_panel_ops, s);
2604
 
    }
2605
 
}
2606
 
 
2607
 
type_init(omap_dss_register_types)