~ubuntu-branches/ubuntu/saucy/qemu/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/linaro-patches-1.5.0/0045-OMAP-Refactor-DSS-DSI.patch/hw/display/omap_dss.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-05-28 08:18:30 UTC
  • mfrom: (1.8.2) (10.1.37 sid)
  • Revision ID: package-import@ubuntu.com-20130528081830-87xl2z9fq516a814
Tags: 1.5.0+dfsg-2ubuntu1
* Merge 1.5.0+dfs-2 from debian unstable.  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
    * 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.
  - Dropped patches:
    * 0001-fix-wrong-output-with-info-chardev-for-tcp-socket.patch
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * gridcentric patch - updated
    * linaro arm patches from qemu-linaro rebasing branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * OMAP2 Display Subsystem.
 
3
 *
 
4
 * Copyright (C) 2008 Nokia Corporation
 
5
 * Written by Andrzej Zaborowski <andrew@openedhand.com>
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License as
 
9
 * published by the Free Software Foundation; either version 2 or
 
10
 * (at your option) version 3 of the License.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License along
 
18
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
#include "hw/hw.h"
 
21
#include "ui/console.h"
 
22
#include "hw/arm/omap.h"
 
23
 
 
24
struct omap_dss_s {
 
25
    qemu_irq irq;
 
26
    qemu_irq drq;
 
27
    DisplayState *state;
 
28
    MemoryRegion iomem_diss1, iomem_disc1, iomem_rfbi1, iomem_venc1, iomem_im3;
 
29
 
 
30
    int autoidle;
 
31
    int control;
 
32
    int enable;
 
33
 
 
34
    struct omap_dss_panel_s {
 
35
        int enable;
 
36
        int nx;
 
37
        int ny;
 
38
 
 
39
        int x;
 
40
        int y;
 
41
    } dig, lcd;
 
42
 
 
43
    struct {
 
44
        uint32_t idlemode;
 
45
        uint32_t irqst;
 
46
        uint32_t irqen;
 
47
        uint32_t control;
 
48
        uint32_t config;
 
49
        uint32_t capable;
 
50
        uint32_t timing[4];
 
51
        int line;
 
52
        uint32_t bg[2];
 
53
        uint32_t trans[2];
 
54
 
 
55
        struct omap_dss_plane_s {
 
56
            int enable;
 
57
            int bpp;
 
58
            int posx;
 
59
            int posy;
 
60
            int nx;
 
61
            int ny;
 
62
 
 
63
            hwaddr addr[3];
 
64
 
 
65
            uint32_t attr;
 
66
            uint32_t tresh;
 
67
            int rowinc;
 
68
            int colinc;
 
69
            int wininc;
 
70
        } l[3];
 
71
 
 
72
        int invalidate;
 
73
        uint16_t palette[256];
 
74
    } dispc;
 
75
 
 
76
    struct {
 
77
        int idlemode;
 
78
        uint32_t control;
 
79
        int enable;
 
80
        int pixels;
 
81
        int busy;
 
82
        int skiplines;
 
83
        uint16_t rxbuf;
 
84
        uint32_t config[2];
 
85
        uint32_t time[4];
 
86
        uint32_t data[6];
 
87
        uint16_t vsync;
 
88
        uint16_t hsync;
 
89
        struct rfbi_chip_s *chip[2];
 
90
    } rfbi;
 
91
};
 
92
 
 
93
static void omap_dispc_interrupt_update(struct omap_dss_s *s)
 
94
{
 
95
    qemu_set_irq(s->irq, s->dispc.irqst & s->dispc.irqen);
 
96
}
 
97
 
 
98
static void omap_rfbi_reset(struct omap_dss_s *s)
 
99
{
 
100
    s->rfbi.idlemode = 0;
 
101
    s->rfbi.control = 2;
 
102
    s->rfbi.enable = 0;
 
103
    s->rfbi.pixels = 0;
 
104
    s->rfbi.skiplines = 0;
 
105
    s->rfbi.busy = 0;
 
106
    s->rfbi.config[0] = 0x00310000;
 
107
    s->rfbi.config[1] = 0x00310000;
 
108
    s->rfbi.time[0] = 0;
 
109
    s->rfbi.time[1] = 0;
 
110
    s->rfbi.time[2] = 0;
 
111
    s->rfbi.time[3] = 0;
 
112
    s->rfbi.data[0] = 0;
 
113
    s->rfbi.data[1] = 0;
 
114
    s->rfbi.data[2] = 0;
 
115
    s->rfbi.data[3] = 0;
 
116
    s->rfbi.data[4] = 0;
 
117
    s->rfbi.data[5] = 0;
 
118
    s->rfbi.vsync = 0;
 
119
    s->rfbi.hsync = 0;
 
120
}
 
121
 
 
122
void omap_dss_reset(struct omap_dss_s *s)
 
123
{
 
124
    s->autoidle = 0;
 
125
    s->control = 0;
 
126
    s->enable = 0;
 
127
 
 
128
    s->dig.enable = 0;
 
129
    s->dig.nx = 1;
 
130
    s->dig.ny = 1;
 
131
 
 
132
    s->lcd.enable = 0;
 
133
    s->lcd.nx = 1;
 
134
    s->lcd.ny = 1;
 
135
 
 
136
    s->dispc.idlemode = 0;
 
137
    s->dispc.irqst = 0;
 
138
    s->dispc.irqen = 0;
 
139
    s->dispc.control = 0;
 
140
    s->dispc.config = 0;
 
141
    s->dispc.capable = 0x161;
 
142
    s->dispc.timing[0] = 0;
 
143
    s->dispc.timing[1] = 0;
 
144
    s->dispc.timing[2] = 0;
 
145
    s->dispc.timing[3] = 0;
 
146
    s->dispc.line = 0;
 
147
    s->dispc.bg[0] = 0;
 
148
    s->dispc.bg[1] = 0;
 
149
    s->dispc.trans[0] = 0;
 
150
    s->dispc.trans[1] = 0;
 
151
 
 
152
    s->dispc.l[0].enable = 0;
 
153
    s->dispc.l[0].bpp = 0;
 
154
    s->dispc.l[0].addr[0] = 0;
 
155
    s->dispc.l[0].addr[1] = 0;
 
156
    s->dispc.l[0].addr[2] = 0;
 
157
    s->dispc.l[0].posx = 0;
 
158
    s->dispc.l[0].posy = 0;
 
159
    s->dispc.l[0].nx = 1;
 
160
    s->dispc.l[0].ny = 1;
 
161
    s->dispc.l[0].attr = 0;
 
162
    s->dispc.l[0].tresh = 0;
 
163
    s->dispc.l[0].rowinc = 1;
 
164
    s->dispc.l[0].colinc = 1;
 
165
    s->dispc.l[0].wininc = 0;
 
166
 
 
167
    omap_rfbi_reset(s);
 
168
    omap_dispc_interrupt_update(s);
 
169
}
 
170
 
 
171
static uint64_t omap_diss_read(void *opaque, hwaddr addr,
 
172
                               unsigned size)
 
173
{
 
174
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
 
175
 
 
176
    if (size != 4) {
 
177
        return omap_badwidth_read32(opaque, addr);
 
178
    }
 
179
 
 
180
    switch (addr) {
 
181
    case 0x00:  /* DSS_REVISIONNUMBER */
 
182
        return 0x20;
 
183
 
 
184
    case 0x10:  /* DSS_SYSCONFIG */
 
185
        return s->autoidle;
 
186
 
 
187
    case 0x14:  /* DSS_SYSSTATUS */
 
188
        return 1;                                               /* RESETDONE */
 
189
 
 
190
    case 0x40:  /* DSS_CONTROL */
 
191
        return s->control;
 
192
 
 
193
    case 0x50:  /* DSS_PSA_LCD_REG_1 */
 
194
    case 0x54:  /* DSS_PSA_LCD_REG_2 */
 
195
    case 0x58:  /* DSS_PSA_VIDEO_REG */
 
196
        /* TODO: fake some values when appropriate s->control bits are set */
 
197
        return 0;
 
198
 
 
199
    case 0x5c:  /* DSS_STATUS */
 
200
        return 1 + (s->control & 1);
 
201
 
 
202
    default:
 
203
        break;
 
204
    }
 
205
    OMAP_BAD_REG(addr);
 
206
    return 0;
 
207
}
 
208
 
 
209
static void omap_diss_write(void *opaque, hwaddr addr,
 
210
                            uint64_t value, unsigned size)
 
211
{
 
212
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
 
213
 
 
214
    if (size != 4) {
 
215
        return omap_badwidth_write32(opaque, addr, value);
 
216
    }
 
217
 
 
218
    switch (addr) {
 
219
    case 0x00:  /* DSS_REVISIONNUMBER */
 
220
    case 0x14:  /* DSS_SYSSTATUS */
 
221
    case 0x50:  /* DSS_PSA_LCD_REG_1 */
 
222
    case 0x54:  /* DSS_PSA_LCD_REG_2 */
 
223
    case 0x58:  /* DSS_PSA_VIDEO_REG */
 
224
    case 0x5c:  /* DSS_STATUS */
 
225
        OMAP_RO_REG(addr);
 
226
        break;
 
227
 
 
228
    case 0x10:  /* DSS_SYSCONFIG */
 
229
        if (value & 2)                                          /* SOFTRESET */
 
230
            omap_dss_reset(s);
 
231
        s->autoidle = value & 1;
 
232
        break;
 
233
 
 
234
    case 0x40:  /* DSS_CONTROL */
 
235
        s->control = value & 0x3dd;
 
236
        break;
 
237
 
 
238
    default:
 
239
        OMAP_BAD_REG(addr);
 
240
    }
 
241
}
 
242
 
 
243
static const MemoryRegionOps omap_diss_ops = {
 
244
    .read = omap_diss_read,
 
245
    .write = omap_diss_write,
 
246
    .endianness = DEVICE_NATIVE_ENDIAN,
 
247
};
 
248
 
 
249
static uint64_t omap_disc_read(void *opaque, hwaddr addr,
 
250
                               unsigned size)
 
251
{
 
252
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
 
253
 
 
254
    if (size != 4) {
 
255
        return omap_badwidth_read32(opaque, addr);
 
256
    }
 
257
 
 
258
    switch (addr) {
 
259
    case 0x000: /* DISPC_REVISION */
 
260
        return 0x20;
 
261
 
 
262
    case 0x010: /* DISPC_SYSCONFIG */
 
263
        return s->dispc.idlemode;
 
264
 
 
265
    case 0x014: /* DISPC_SYSSTATUS */
 
266
        return 1;                                               /* RESETDONE */
 
267
 
 
268
    case 0x018: /* DISPC_IRQSTATUS */
 
269
        return s->dispc.irqst;
 
270
 
 
271
    case 0x01c: /* DISPC_IRQENABLE */
 
272
        return s->dispc.irqen;
 
273
 
 
274
    case 0x040: /* DISPC_CONTROL */
 
275
        return s->dispc.control;
 
276
 
 
277
    case 0x044: /* DISPC_CONFIG */
 
278
        return s->dispc.config;
 
279
 
 
280
    case 0x048: /* DISPC_CAPABLE */
 
281
        return s->dispc.capable;
 
282
 
 
283
    case 0x04c: /* DISPC_DEFAULT_COLOR0 */
 
284
        return s->dispc.bg[0];
 
285
    case 0x050: /* DISPC_DEFAULT_COLOR1 */
 
286
        return s->dispc.bg[1];
 
287
    case 0x054: /* DISPC_TRANS_COLOR0 */
 
288
        return s->dispc.trans[0];
 
289
    case 0x058: /* DISPC_TRANS_COLOR1 */
 
290
        return s->dispc.trans[1];
 
291
 
 
292
    case 0x05c: /* DISPC_LINE_STATUS */
 
293
        return 0x7ff;
 
294
    case 0x060: /* DISPC_LINE_NUMBER */
 
295
        return s->dispc.line;
 
296
 
 
297
    case 0x064: /* DISPC_TIMING_H */
 
298
        return s->dispc.timing[0];
 
299
    case 0x068: /* DISPC_TIMING_V */
 
300
        return s->dispc.timing[1];
 
301
    case 0x06c: /* DISPC_POL_FREQ */
 
302
        return s->dispc.timing[2];
 
303
    case 0x070: /* DISPC_DIVISOR */
 
304
        return s->dispc.timing[3];
 
305
 
 
306
    case 0x078: /* DISPC_SIZE_DIG */
 
307
        return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1);
 
308
    case 0x07c: /* DISPC_SIZE_LCD */
 
309
        return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1);
 
310
 
 
311
    case 0x080: /* DISPC_GFX_BA0 */
 
312
        return s->dispc.l[0].addr[0];
 
313
    case 0x084: /* DISPC_GFX_BA1 */
 
314
        return s->dispc.l[0].addr[1];
 
315
    case 0x088: /* DISPC_GFX_POSITION */
 
316
        return (s->dispc.l[0].posy << 16) | s->dispc.l[0].posx;
 
317
    case 0x08c: /* DISPC_GFX_SIZE */
 
318
        return ((s->dispc.l[0].ny - 1) << 16) | (s->dispc.l[0].nx - 1);
 
319
    case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
 
320
        return s->dispc.l[0].attr;
 
321
    case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
 
322
        return s->dispc.l[0].tresh;
 
323
    case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
 
324
        return 256;
 
325
    case 0x0ac: /* DISPC_GFX_ROW_INC */
 
326
        return s->dispc.l[0].rowinc;
 
327
    case 0x0b0: /* DISPC_GFX_PIXEL_INC */
 
328
        return s->dispc.l[0].colinc;
 
329
    case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
 
330
        return s->dispc.l[0].wininc;
 
331
    case 0x0b8: /* DISPC_GFX_TABLE_BA */
 
332
        return s->dispc.l[0].addr[2];
 
333
 
 
334
    case 0x0bc: /* DISPC_VID1_BA0 */
 
335
    case 0x0c0: /* DISPC_VID1_BA1 */
 
336
    case 0x0c4: /* DISPC_VID1_POSITION */
 
337
    case 0x0c8: /* DISPC_VID1_SIZE */
 
338
    case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
 
339
    case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
 
340
    case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */
 
341
    case 0x0d8: /* DISPC_VID1_ROW_INC */
 
342
    case 0x0dc: /* DISPC_VID1_PIXEL_INC */
 
343
    case 0x0e0: /* DISPC_VID1_FIR */
 
344
    case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
 
345
    case 0x0e8: /* DISPC_VID1_ACCU0 */
 
346
    case 0x0ec: /* DISPC_VID1_ACCU1 */
 
347
    case 0x0f0 ... 0x140:       /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
 
348
    case 0x14c: /* DISPC_VID2_BA0 */
 
349
    case 0x150: /* DISPC_VID2_BA1 */
 
350
    case 0x154: /* DISPC_VID2_POSITION */
 
351
    case 0x158: /* DISPC_VID2_SIZE */
 
352
    case 0x15c: /* DISPC_VID2_ATTRIBUTES */
 
353
    case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
 
354
    case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */
 
355
    case 0x168: /* DISPC_VID2_ROW_INC */
 
356
    case 0x16c: /* DISPC_VID2_PIXEL_INC */
 
357
    case 0x170: /* DISPC_VID2_FIR */
 
358
    case 0x174: /* DISPC_VID2_PICTURE_SIZE */
 
359
    case 0x178: /* DISPC_VID2_ACCU0 */
 
360
    case 0x17c: /* DISPC_VID2_ACCU1 */
 
361
    case 0x180 ... 0x1d0:       /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
 
362
    case 0x1d4: /* DISPC_DATA_CYCLE1 */
 
363
    case 0x1d8: /* DISPC_DATA_CYCLE2 */
 
364
    case 0x1dc: /* DISPC_DATA_CYCLE3 */
 
365
        return 0;
 
366
 
 
367
    default:
 
368
        break;
 
369
    }
 
370
    OMAP_BAD_REG(addr);
 
371
    return 0;
 
372
}
 
373
 
 
374
static void omap_disc_write(void *opaque, hwaddr addr,
 
375
                            uint64_t value, unsigned size)
 
376
{
 
377
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
 
378
 
 
379
    if (size != 4) {
 
380
        return omap_badwidth_write32(opaque, addr, value);
 
381
    }
 
382
 
 
383
    switch (addr) {
 
384
    case 0x010: /* DISPC_SYSCONFIG */
 
385
        if (value & 2)                                          /* SOFTRESET */
 
386
            omap_dss_reset(s);
 
387
        s->dispc.idlemode = value & 0x301b;
 
388
        break;
 
389
 
 
390
    case 0x018: /* DISPC_IRQSTATUS */
 
391
        s->dispc.irqst &= ~value;
 
392
        omap_dispc_interrupt_update(s);
 
393
        break;
 
394
 
 
395
    case 0x01c: /* DISPC_IRQENABLE */
 
396
        s->dispc.irqen = value & 0xffff;
 
397
        omap_dispc_interrupt_update(s);
 
398
        break;
 
399
 
 
400
    case 0x040: /* DISPC_CONTROL */
 
401
        s->dispc.control = value & 0x07ff9fff;
 
402
        s->dig.enable = (value >> 1) & 1;
 
403
        s->lcd.enable = (value >> 0) & 1;
 
404
        if (value & (1 << 12))                  /* OVERLAY_OPTIMIZATION */
 
405
            if (!((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) {
 
406
                fprintf(stderr, "%s: Overlay Optimization when no overlay "
 
407
                        "region effectively exists leads to "
 
408
                        "unpredictable behaviour!\n", __func__);
 
409
            }
 
410
        if (value & (1 << 6)) {                         /* GODIGITAL */
 
411
            /* XXX: Shadowed fields are:
 
412
             * s->dispc.config
 
413
             * s->dispc.capable
 
414
             * s->dispc.bg[0]
 
415
             * s->dispc.bg[1]
 
416
             * s->dispc.trans[0]
 
417
             * s->dispc.trans[1]
 
418
             * s->dispc.line
 
419
             * s->dispc.timing[0]
 
420
             * s->dispc.timing[1]
 
421
             * s->dispc.timing[2]
 
422
             * s->dispc.timing[3]
 
423
             * s->lcd.nx
 
424
             * s->lcd.ny
 
425
             * s->dig.nx
 
426
             * s->dig.ny
 
427
             * s->dispc.l[0].addr[0]
 
428
             * s->dispc.l[0].addr[1]
 
429
             * s->dispc.l[0].addr[2]
 
430
             * s->dispc.l[0].posx
 
431
             * s->dispc.l[0].posy
 
432
             * s->dispc.l[0].nx
 
433
             * s->dispc.l[0].ny
 
434
             * s->dispc.l[0].tresh
 
435
             * s->dispc.l[0].rowinc
 
436
             * s->dispc.l[0].colinc
 
437
             * s->dispc.l[0].wininc
 
438
             * All they need to be loaded here from their shadow registers.
 
439
             */
 
440
        }
 
441
        if (value & (1 << 5)) {                         /* GOLCD */
 
442
             /* XXX: Likewise for LCD here.  */
 
443
        }
 
444
        s->dispc.invalidate = 1;
 
445
        break;
 
446
 
 
447
    case 0x044: /* DISPC_CONFIG */
 
448
        s->dispc.config = value & 0x3fff;
 
449
        /* XXX:
 
450
         * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded
 
451
         * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded
 
452
         */
 
453
        s->dispc.invalidate = 1;
 
454
        break;
 
455
 
 
456
    case 0x048: /* DISPC_CAPABLE */
 
457
        s->dispc.capable = value & 0x3ff;
 
458
        break;
 
459
 
 
460
    case 0x04c: /* DISPC_DEFAULT_COLOR0 */
 
461
        s->dispc.bg[0] = value & 0xffffff;
 
462
        s->dispc.invalidate = 1;
 
463
        break;
 
464
    case 0x050: /* DISPC_DEFAULT_COLOR1 */
 
465
        s->dispc.bg[1] = value & 0xffffff;
 
466
        s->dispc.invalidate = 1;
 
467
        break;
 
468
    case 0x054: /* DISPC_TRANS_COLOR0 */
 
469
        s->dispc.trans[0] = value & 0xffffff;
 
470
        s->dispc.invalidate = 1;
 
471
        break;
 
472
    case 0x058: /* DISPC_TRANS_COLOR1 */
 
473
        s->dispc.trans[1] = value & 0xffffff;
 
474
        s->dispc.invalidate = 1;
 
475
        break;
 
476
 
 
477
    case 0x060: /* DISPC_LINE_NUMBER */
 
478
        s->dispc.line = value & 0x7ff;
 
479
        break;
 
480
 
 
481
    case 0x064: /* DISPC_TIMING_H */
 
482
        s->dispc.timing[0] = value & 0x0ff0ff3f;
 
483
        break;
 
484
    case 0x068: /* DISPC_TIMING_V */
 
485
        s->dispc.timing[1] = value & 0x0ff0ff3f;
 
486
        break;
 
487
    case 0x06c: /* DISPC_POL_FREQ */
 
488
        s->dispc.timing[2] = value & 0x0003ffff;
 
489
        break;
 
490
    case 0x070: /* DISPC_DIVISOR */
 
491
        s->dispc.timing[3] = value & 0x00ff00ff;
 
492
        break;
 
493
 
 
494
    case 0x078: /* DISPC_SIZE_DIG */
 
495
        s->dig.nx = ((value >>  0) & 0x7ff) + 1;                /* PPL */
 
496
        s->dig.ny = ((value >> 16) & 0x7ff) + 1;                /* LPP */
 
497
        s->dispc.invalidate = 1;
 
498
        break;
 
499
    case 0x07c: /* DISPC_SIZE_LCD */
 
500
        s->lcd.nx = ((value >>  0) & 0x7ff) + 1;                /* PPL */
 
501
        s->lcd.ny = ((value >> 16) & 0x7ff) + 1;                /* LPP */
 
502
        s->dispc.invalidate = 1;
 
503
        break;
 
504
    case 0x080: /* DISPC_GFX_BA0 */
 
505
        s->dispc.l[0].addr[0] = (hwaddr) value;
 
506
        s->dispc.invalidate = 1;
 
507
        break;
 
508
    case 0x084: /* DISPC_GFX_BA1 */
 
509
        s->dispc.l[0].addr[1] = (hwaddr) value;
 
510
        s->dispc.invalidate = 1;
 
511
        break;
 
512
    case 0x088: /* DISPC_GFX_POSITION */
 
513
        s->dispc.l[0].posx = ((value >>  0) & 0x7ff);           /* GFXPOSX */
 
514
        s->dispc.l[0].posy = ((value >> 16) & 0x7ff);           /* GFXPOSY */
 
515
        s->dispc.invalidate = 1;
 
516
        break;
 
517
    case 0x08c: /* DISPC_GFX_SIZE */
 
518
        s->dispc.l[0].nx = ((value >>  0) & 0x7ff) + 1;         /* GFXSIZEX */
 
519
        s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1;         /* GFXSIZEY */
 
520
        s->dispc.invalidate = 1;
 
521
        break;
 
522
    case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
 
523
        s->dispc.l[0].attr = value & 0x7ff;
 
524
        if (value & (3 << 9))
 
525
            fprintf(stderr, "%s: Big-endian pixel format not supported\n",
 
526
                            __FUNCTION__);
 
527
        s->dispc.l[0].enable = value & 1;
 
528
        s->dispc.l[0].bpp = (value >> 1) & 0xf;
 
529
        s->dispc.invalidate = 1;
 
530
        break;
 
531
    case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
 
532
        s->dispc.l[0].tresh = value & 0x01ff01ff;
 
533
        break;
 
534
    case 0x0ac: /* DISPC_GFX_ROW_INC */
 
535
        s->dispc.l[0].rowinc = value;
 
536
        s->dispc.invalidate = 1;
 
537
        break;
 
538
    case 0x0b0: /* DISPC_GFX_PIXEL_INC */
 
539
        s->dispc.l[0].colinc = value;
 
540
        s->dispc.invalidate = 1;
 
541
        break;
 
542
    case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
 
543
        s->dispc.l[0].wininc = value;
 
544
        break;
 
545
    case 0x0b8: /* DISPC_GFX_TABLE_BA */
 
546
        s->dispc.l[0].addr[2] = (hwaddr) value;
 
547
        s->dispc.invalidate = 1;
 
548
        break;
 
549
 
 
550
    case 0x0bc: /* DISPC_VID1_BA0 */
 
551
    case 0x0c0: /* DISPC_VID1_BA1 */
 
552
    case 0x0c4: /* DISPC_VID1_POSITION */
 
553
    case 0x0c8: /* DISPC_VID1_SIZE */
 
554
    case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
 
555
    case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
 
556
    case 0x0d8: /* DISPC_VID1_ROW_INC */
 
557
    case 0x0dc: /* DISPC_VID1_PIXEL_INC */
 
558
    case 0x0e0: /* DISPC_VID1_FIR */
 
559
    case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
 
560
    case 0x0e8: /* DISPC_VID1_ACCU0 */
 
561
    case 0x0ec: /* DISPC_VID1_ACCU1 */
 
562
    case 0x0f0 ... 0x140:       /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
 
563
    case 0x14c: /* DISPC_VID2_BA0 */
 
564
    case 0x150: /* DISPC_VID2_BA1 */
 
565
    case 0x154: /* DISPC_VID2_POSITION */
 
566
    case 0x158: /* DISPC_VID2_SIZE */
 
567
    case 0x15c: /* DISPC_VID2_ATTRIBUTES */
 
568
    case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
 
569
    case 0x168: /* DISPC_VID2_ROW_INC */
 
570
    case 0x16c: /* DISPC_VID2_PIXEL_INC */
 
571
    case 0x170: /* DISPC_VID2_FIR */
 
572
    case 0x174: /* DISPC_VID2_PICTURE_SIZE */
 
573
    case 0x178: /* DISPC_VID2_ACCU0 */
 
574
    case 0x17c: /* DISPC_VID2_ACCU1 */
 
575
    case 0x180 ... 0x1d0:       /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
 
576
    case 0x1d4: /* DISPC_DATA_CYCLE1 */
 
577
    case 0x1d8: /* DISPC_DATA_CYCLE2 */
 
578
    case 0x1dc: /* DISPC_DATA_CYCLE3 */
 
579
        break;
 
580
 
 
581
    default:
 
582
        OMAP_BAD_REG(addr);
 
583
    }
 
584
}
 
585
 
 
586
static const MemoryRegionOps omap_disc_ops = {
 
587
    .read = omap_disc_read,
 
588
    .write = omap_disc_write,
 
589
    .endianness = DEVICE_NATIVE_ENDIAN,
 
590
};
 
591
 
 
592
static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
 
593
{
 
594
    if (!s->rfbi.busy)
 
595
        return;
 
596
 
 
597
    /* TODO: in non-Bypass mode we probably need to just deassert the DRQ.  */
 
598
 
 
599
    s->rfbi.busy = 0;
 
600
}
 
601
 
 
602
static void omap_rfbi_transfer_start(struct omap_dss_s *s)
 
603
{
 
604
    void *data;
 
605
    hwaddr len;
 
606
    hwaddr data_addr;
 
607
    int pitch;
 
608
    static void *bounce_buffer;
 
609
    static hwaddr bounce_len;
 
610
 
 
611
    if (!s->rfbi.enable || s->rfbi.busy)
 
612
        return;
 
613
 
 
614
    if (s->rfbi.control & (1 << 1)) {                           /* BYPASS */
 
615
        /* TODO: in non-Bypass mode we probably need to just assert the
 
616
         * DRQ and wait for DMA to write the pixels.  */
 
617
        fprintf(stderr, "%s: Bypass mode unimplemented\n", __FUNCTION__);
 
618
        return;
 
619
    }
 
620
 
 
621
    if (!(s->dispc.control & (1 << 11)))                        /* RFBIMODE */
 
622
        return;
 
623
    /* TODO: check that LCD output is enabled in DISPC.  */
 
624
 
 
625
    s->rfbi.busy = 1;
 
626
 
 
627
    len = s->rfbi.pixels * 2;
 
628
 
 
629
    data_addr = s->dispc.l[0].addr[0];
 
630
    data = cpu_physical_memory_map(data_addr, &len, 0);
 
631
    if (data && len != s->rfbi.pixels * 2) {
 
632
        cpu_physical_memory_unmap(data, len, 0, 0);
 
633
        data = NULL;
 
634
        len = s->rfbi.pixels * 2;
 
635
    }
 
636
    if (!data) {
 
637
        if (len > bounce_len) {
 
638
            bounce_buffer = g_realloc(bounce_buffer, len);
 
639
        }
 
640
        data = bounce_buffer;
 
641
        cpu_physical_memory_read(data_addr, data, len);
 
642
    }
 
643
 
 
644
    /* TODO bpp */
 
645
    s->rfbi.pixels = 0;
 
646
 
 
647
    /* TODO: negative values */
 
648
    pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2;
 
649
 
 
650
    if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
 
651
        s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);
 
652
    if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
 
653
        s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
 
654
 
 
655
    if (data != bounce_buffer) {
 
656
        cpu_physical_memory_unmap(data, len, 0, len);
 
657
    }
 
658
 
 
659
    omap_rfbi_transfer_stop(s);
 
660
 
 
661
    /* TODO */
 
662
    s->dispc.irqst |= 1;                                        /* FRAMEDONE */
 
663
    omap_dispc_interrupt_update(s);
 
664
}
 
665
 
 
666
static uint64_t omap_rfbi_read(void *opaque, hwaddr addr,
 
667
                               unsigned size)
 
668
{
 
669
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
 
670
 
 
671
    if (size != 4) {
 
672
        return omap_badwidth_read32(opaque, addr);
 
673
    }
 
674
 
 
675
    switch (addr) {
 
676
    case 0x00:  /* RFBI_REVISION */
 
677
        return 0x10;
 
678
 
 
679
    case 0x10:  /* RFBI_SYSCONFIG */
 
680
        return s->rfbi.idlemode;
 
681
 
 
682
    case 0x14:  /* RFBI_SYSSTATUS */
 
683
        return 1 | (s->rfbi.busy << 8);                         /* RESETDONE */
 
684
 
 
685
    case 0x40:  /* RFBI_CONTROL */
 
686
        return s->rfbi.control;
 
687
 
 
688
    case 0x44:  /* RFBI_PIXELCNT */
 
689
        return s->rfbi.pixels;
 
690
 
 
691
    case 0x48:  /* RFBI_LINE_NUMBER */
 
692
        return s->rfbi.skiplines;
 
693
 
 
694
    case 0x58:  /* RFBI_READ */
 
695
    case 0x5c:  /* RFBI_STATUS */
 
696
        return s->rfbi.rxbuf;
 
697
 
 
698
    case 0x60:  /* RFBI_CONFIG0 */
 
699
        return s->rfbi.config[0];
 
700
    case 0x64:  /* RFBI_ONOFF_TIME0 */
 
701
        return s->rfbi.time[0];
 
702
    case 0x68:  /* RFBI_CYCLE_TIME0 */
 
703
        return s->rfbi.time[1];
 
704
    case 0x6c:  /* RFBI_DATA_CYCLE1_0 */
 
705
        return s->rfbi.data[0];
 
706
    case 0x70:  /* RFBI_DATA_CYCLE2_0 */
 
707
        return s->rfbi.data[1];
 
708
    case 0x74:  /* RFBI_DATA_CYCLE3_0 */
 
709
        return s->rfbi.data[2];
 
710
 
 
711
    case 0x78:  /* RFBI_CONFIG1 */
 
712
        return s->rfbi.config[1];
 
713
    case 0x7c:  /* RFBI_ONOFF_TIME1 */
 
714
        return s->rfbi.time[2];
 
715
    case 0x80:  /* RFBI_CYCLE_TIME1 */
 
716
        return s->rfbi.time[3];
 
717
    case 0x84:  /* RFBI_DATA_CYCLE1_1 */
 
718
        return s->rfbi.data[3];
 
719
    case 0x88:  /* RFBI_DATA_CYCLE2_1 */
 
720
        return s->rfbi.data[4];
 
721
    case 0x8c:  /* RFBI_DATA_CYCLE3_1 */
 
722
        return s->rfbi.data[5];
 
723
 
 
724
    case 0x90:  /* RFBI_VSYNC_WIDTH */
 
725
        return s->rfbi.vsync;
 
726
    case 0x94:  /* RFBI_HSYNC_WIDTH */
 
727
        return s->rfbi.hsync;
 
728
    }
 
729
    OMAP_BAD_REG(addr);
 
730
    return 0;
 
731
}
 
732
 
 
733
static void omap_rfbi_write(void *opaque, hwaddr addr,
 
734
                            uint64_t value, unsigned size)
 
735
{
 
736
    struct omap_dss_s *s = (struct omap_dss_s *) opaque;
 
737
 
 
738
    if (size != 4) {
 
739
        return omap_badwidth_write32(opaque, addr, value);
 
740
    }
 
741
 
 
742
    switch (addr) {
 
743
    case 0x10:  /* RFBI_SYSCONFIG */
 
744
        if (value & 2)                                          /* SOFTRESET */
 
745
            omap_rfbi_reset(s);
 
746
        s->rfbi.idlemode = value & 0x19;
 
747
        break;
 
748
 
 
749
    case 0x40:  /* RFBI_CONTROL */
 
750
        s->rfbi.control = value & 0xf;
 
751
        s->rfbi.enable = value & 1;
 
752
        if (value & (1 << 4) &&                                 /* ITE */
 
753
                        !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc))
 
754
            omap_rfbi_transfer_start(s);
 
755
        break;
 
756
 
 
757
    case 0x44:  /* RFBI_PIXELCNT */
 
758
        s->rfbi.pixels = value;
 
759
        break;
 
760
 
 
761
    case 0x48:  /* RFBI_LINE_NUMBER */
 
762
        s->rfbi.skiplines = value & 0x7ff;
 
763
        break;
 
764
 
 
765
    case 0x4c:  /* RFBI_CMD */
 
766
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
 
767
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff);
 
768
        if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
 
769
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff);
 
770
        break;
 
771
    case 0x50:  /* RFBI_PARAM */
 
772
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
 
773
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
 
774
        if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
 
775
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
 
776
        break;
 
777
    case 0x54:  /* RFBI_DATA */
 
778
        /* TODO: take into account the format set up in s->rfbi.config[?] and
 
779
         * s->rfbi.data[?], but special-case the most usual scenario so that
 
780
         * speed doesn't suffer.  */
 
781
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) {
 
782
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
 
783
            s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16);
 
784
        }
 
785
        if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) {
 
786
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
 
787
            s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16);
 
788
        }
 
789
        if (!-- s->rfbi.pixels)
 
790
            omap_rfbi_transfer_stop(s);
 
791
        break;
 
792
    case 0x58:  /* RFBI_READ */
 
793
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
 
794
            s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
 
795
        else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
 
796
            s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 1);
 
797
        if (!-- s->rfbi.pixels)
 
798
            omap_rfbi_transfer_stop(s);
 
799
        break;
 
800
 
 
801
    case 0x5c:  /* RFBI_STATUS */
 
802
        if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
 
803
            s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
 
804
        else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
 
805
            s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 0);
 
806
        if (!-- s->rfbi.pixels)
 
807
            omap_rfbi_transfer_stop(s);
 
808
        break;
 
809
 
 
810
    case 0x60:  /* RFBI_CONFIG0 */
 
811
        s->rfbi.config[0] = value & 0x003f1fff;
 
812
        break;
 
813
 
 
814
    case 0x64:  /* RFBI_ONOFF_TIME0 */
 
815
        s->rfbi.time[0] = value & 0x3fffffff;
 
816
        break;
 
817
    case 0x68:  /* RFBI_CYCLE_TIME0 */
 
818
        s->rfbi.time[1] = value & 0x0fffffff;
 
819
        break;
 
820
    case 0x6c:  /* RFBI_DATA_CYCLE1_0 */
 
821
        s->rfbi.data[0] = value & 0x0f1f0f1f;
 
822
        break;
 
823
    case 0x70:  /* RFBI_DATA_CYCLE2_0 */
 
824
        s->rfbi.data[1] = value & 0x0f1f0f1f;
 
825
        break;
 
826
    case 0x74:  /* RFBI_DATA_CYCLE3_0 */
 
827
        s->rfbi.data[2] = value & 0x0f1f0f1f;
 
828
        break;
 
829
    case 0x78:  /* RFBI_CONFIG1 */
 
830
        s->rfbi.config[1] = value & 0x003f1fff;
 
831
        break;
 
832
 
 
833
    case 0x7c:  /* RFBI_ONOFF_TIME1 */
 
834
        s->rfbi.time[2] = value & 0x3fffffff;
 
835
        break;
 
836
    case 0x80:  /* RFBI_CYCLE_TIME1 */
 
837
        s->rfbi.time[3] = value & 0x0fffffff;
 
838
        break;
 
839
    case 0x84:  /* RFBI_DATA_CYCLE1_1 */
 
840
        s->rfbi.data[3] = value & 0x0f1f0f1f;
 
841
        break;
 
842
    case 0x88:  /* RFBI_DATA_CYCLE2_1 */
 
843
        s->rfbi.data[4] = value & 0x0f1f0f1f;
 
844
        break;
 
845
    case 0x8c:  /* RFBI_DATA_CYCLE3_1 */
 
846
        s->rfbi.data[5] = value & 0x0f1f0f1f;
 
847
        break;
 
848
 
 
849
    case 0x90:  /* RFBI_VSYNC_WIDTH */
 
850
        s->rfbi.vsync = value & 0xffff;
 
851
        break;
 
852
    case 0x94:  /* RFBI_HSYNC_WIDTH */
 
853
        s->rfbi.hsync = value & 0xffff;
 
854
        break;
 
855
 
 
856
    default:
 
857
        OMAP_BAD_REG(addr);
 
858
    }
 
859
}
 
860
 
 
861
static const MemoryRegionOps omap_rfbi_ops = {
 
862
    .read = omap_rfbi_read,
 
863
    .write = omap_rfbi_write,
 
864
    .endianness = DEVICE_NATIVE_ENDIAN,
 
865
};
 
866
 
 
867
static uint64_t omap_venc_read(void *opaque, hwaddr addr,
 
868
                               unsigned size)
 
869
{
 
870
    if (size != 4) {
 
871
        return omap_badwidth_read32(opaque, addr);
 
872
    }
 
873
 
 
874
    switch (addr) {
 
875
    case 0x00:  /* REV_ID */
 
876
    case 0x04:  /* STATUS */
 
877
    case 0x08:  /* F_CONTROL */
 
878
    case 0x10:  /* VIDOUT_CTRL */
 
879
    case 0x14:  /* SYNC_CTRL */
 
880
    case 0x1c:  /* LLEN */
 
881
    case 0x20:  /* FLENS */
 
882
    case 0x24:  /* HFLTR_CTRL */
 
883
    case 0x28:  /* CC_CARR_WSS_CARR */
 
884
    case 0x2c:  /* C_PHASE */
 
885
    case 0x30:  /* GAIN_U */
 
886
    case 0x34:  /* GAIN_V */
 
887
    case 0x38:  /* GAIN_Y */
 
888
    case 0x3c:  /* BLACK_LEVEL */
 
889
    case 0x40:  /* BLANK_LEVEL */
 
890
    case 0x44:  /* X_COLOR */
 
891
    case 0x48:  /* M_CONTROL */
 
892
    case 0x4c:  /* BSTAMP_WSS_DATA */
 
893
    case 0x50:  /* S_CARR */
 
894
    case 0x54:  /* LINE21 */
 
895
    case 0x58:  /* LN_SEL */
 
896
    case 0x5c:  /* L21__WC_CTL */
 
897
    case 0x60:  /* HTRIGGER_VTRIGGER */
 
898
    case 0x64:  /* SAVID__EAVID */
 
899
    case 0x68:  /* FLEN__FAL */
 
900
    case 0x6c:  /* LAL__PHASE_RESET */
 
901
    case 0x70:  /* HS_INT_START_STOP_X */
 
902
    case 0x74:  /* HS_EXT_START_STOP_X */
 
903
    case 0x78:  /* VS_INT_START_X */
 
904
    case 0x7c:  /* VS_INT_STOP_X__VS_INT_START_Y */
 
905
    case 0x80:  /* VS_INT_STOP_Y__VS_INT_START_X */
 
906
    case 0x84:  /* VS_EXT_STOP_X__VS_EXT_START_Y */
 
907
    case 0x88:  /* VS_EXT_STOP_Y */
 
908
    case 0x90:  /* AVID_START_STOP_X */
 
909
    case 0x94:  /* AVID_START_STOP_Y */
 
910
    case 0xa0:  /* FID_INT_START_X__FID_INT_START_Y */
 
911
    case 0xa4:  /* FID_INT_OFFSET_Y__FID_EXT_START_X */
 
912
    case 0xa8:  /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
 
913
    case 0xb0:  /* TVDETGP_INT_START_STOP_X */
 
914
    case 0xb4:  /* TVDETGP_INT_START_STOP_Y */
 
915
    case 0xb8:  /* GEN_CTRL */
 
916
    case 0xc4:  /* DAC_TST__DAC_A */
 
917
    case 0xc8:  /* DAC_B__DAC_C */
 
918
        return 0;
 
919
 
 
920
    default:
 
921
        break;
 
922
    }
 
923
    OMAP_BAD_REG(addr);
 
924
    return 0;
 
925
}
 
926
 
 
927
static void omap_venc_write(void *opaque, hwaddr addr,
 
928
                            uint64_t value, unsigned size)
 
929
{
 
930
    if (size != 4) {
 
931
        return omap_badwidth_write32(opaque, addr, size);
 
932
    }
 
933
 
 
934
    switch (addr) {
 
935
    case 0x08:  /* F_CONTROL */
 
936
    case 0x10:  /* VIDOUT_CTRL */
 
937
    case 0x14:  /* SYNC_CTRL */
 
938
    case 0x1c:  /* LLEN */
 
939
    case 0x20:  /* FLENS */
 
940
    case 0x24:  /* HFLTR_CTRL */
 
941
    case 0x28:  /* CC_CARR_WSS_CARR */
 
942
    case 0x2c:  /* C_PHASE */
 
943
    case 0x30:  /* GAIN_U */
 
944
    case 0x34:  /* GAIN_V */
 
945
    case 0x38:  /* GAIN_Y */
 
946
    case 0x3c:  /* BLACK_LEVEL */
 
947
    case 0x40:  /* BLANK_LEVEL */
 
948
    case 0x44:  /* X_COLOR */
 
949
    case 0x48:  /* M_CONTROL */
 
950
    case 0x4c:  /* BSTAMP_WSS_DATA */
 
951
    case 0x50:  /* S_CARR */
 
952
    case 0x54:  /* LINE21 */
 
953
    case 0x58:  /* LN_SEL */
 
954
    case 0x5c:  /* L21__WC_CTL */
 
955
    case 0x60:  /* HTRIGGER_VTRIGGER */
 
956
    case 0x64:  /* SAVID__EAVID */
 
957
    case 0x68:  /* FLEN__FAL */
 
958
    case 0x6c:  /* LAL__PHASE_RESET */
 
959
    case 0x70:  /* HS_INT_START_STOP_X */
 
960
    case 0x74:  /* HS_EXT_START_STOP_X */
 
961
    case 0x78:  /* VS_INT_START_X */
 
962
    case 0x7c:  /* VS_INT_STOP_X__VS_INT_START_Y */
 
963
    case 0x80:  /* VS_INT_STOP_Y__VS_INT_START_X */
 
964
    case 0x84:  /* VS_EXT_STOP_X__VS_EXT_START_Y */
 
965
    case 0x88:  /* VS_EXT_STOP_Y */
 
966
    case 0x90:  /* AVID_START_STOP_X */
 
967
    case 0x94:  /* AVID_START_STOP_Y */
 
968
    case 0xa0:  /* FID_INT_START_X__FID_INT_START_Y */
 
969
    case 0xa4:  /* FID_INT_OFFSET_Y__FID_EXT_START_X */
 
970
    case 0xa8:  /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
 
971
    case 0xb0:  /* TVDETGP_INT_START_STOP_X */
 
972
    case 0xb4:  /* TVDETGP_INT_START_STOP_Y */
 
973
    case 0xb8:  /* GEN_CTRL */
 
974
    case 0xc4:  /* DAC_TST__DAC_A */
 
975
    case 0xc8:  /* DAC_B__DAC_C */
 
976
        break;
 
977
 
 
978
    default:
 
979
        OMAP_BAD_REG(addr);
 
980
    }
 
981
}
 
982
 
 
983
static const MemoryRegionOps omap_venc_ops = {
 
984
    .read = omap_venc_read,
 
985
    .write = omap_venc_write,
 
986
    .endianness = DEVICE_NATIVE_ENDIAN,
 
987
};
 
988
 
 
989
static uint64_t omap_im3_read(void *opaque, hwaddr addr,
 
990
                              unsigned size)
 
991
{
 
992
    if (size != 4) {
 
993
        return omap_badwidth_read32(opaque, addr);
 
994
    }
 
995
 
 
996
    switch (addr) {
 
997
    case 0x0a8: /* SBIMERRLOGA */
 
998
    case 0x0b0: /* SBIMERRLOG */
 
999
    case 0x190: /* SBIMSTATE */
 
1000
    case 0x198: /* SBTMSTATE_L */
 
1001
    case 0x19c: /* SBTMSTATE_H */
 
1002
    case 0x1a8: /* SBIMCONFIG_L */
 
1003
    case 0x1ac: /* SBIMCONFIG_H */
 
1004
    case 0x1f8: /* SBID_L */
 
1005
    case 0x1fc: /* SBID_H */
 
1006
        return 0;
 
1007
 
 
1008
    default:
 
1009
        break;
 
1010
    }
 
1011
    OMAP_BAD_REG(addr);
 
1012
    return 0;
 
1013
}
 
1014
 
 
1015
static void omap_im3_write(void *opaque, hwaddr addr,
 
1016
                           uint64_t value, unsigned size)
 
1017
{
 
1018
    if (size != 4) {
 
1019
        return omap_badwidth_write32(opaque, addr, value);
 
1020
    }
 
1021
 
 
1022
    switch (addr) {
 
1023
    case 0x0b0: /* SBIMERRLOG */
 
1024
    case 0x190: /* SBIMSTATE */
 
1025
    case 0x198: /* SBTMSTATE_L */
 
1026
    case 0x19c: /* SBTMSTATE_H */
 
1027
    case 0x1a8: /* SBIMCONFIG_L */
 
1028
    case 0x1ac: /* SBIMCONFIG_H */
 
1029
        break;
 
1030
 
 
1031
    default:
 
1032
        OMAP_BAD_REG(addr);
 
1033
    }
 
1034
}
 
1035
 
 
1036
static const MemoryRegionOps omap_im3_ops = {
 
1037
    .read = omap_im3_read,
 
1038
    .write = omap_im3_write,
 
1039
    .endianness = DEVICE_NATIVE_ENDIAN,
 
1040
};
 
1041
 
 
1042
struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
 
1043
                MemoryRegion *sysmem,
 
1044
                hwaddr l3_base,
 
1045
                qemu_irq irq, qemu_irq drq,
 
1046
                omap_clk fck1, omap_clk fck2, omap_clk ck54m,
 
1047
                omap_clk ick1, omap_clk ick2)
 
1048
{
 
1049
    struct omap_dss_s *s = (struct omap_dss_s *)
 
1050
            g_malloc0(sizeof(struct omap_dss_s));
 
1051
 
 
1052
    s->irq = irq;
 
1053
    s->drq = drq;
 
1054
    omap_dss_reset(s);
 
1055
 
 
1056
    memory_region_init_io(&s->iomem_diss1, &omap_diss_ops, s, "omap.diss1",
 
1057
                          omap_l4_region_size(ta, 0));
 
1058
    memory_region_init_io(&s->iomem_disc1, &omap_disc_ops, s, "omap.disc1",
 
1059
                          omap_l4_region_size(ta, 1));
 
1060
    memory_region_init_io(&s->iomem_rfbi1, &omap_rfbi_ops, s, "omap.rfbi1",
 
1061
                          omap_l4_region_size(ta, 2));
 
1062
    memory_region_init_io(&s->iomem_venc1, &omap_venc_ops, s, "omap.venc1",
 
1063
                          omap_l4_region_size(ta, 3));
 
1064
    memory_region_init_io(&s->iomem_im3, &omap_im3_ops, s,
 
1065
                          "omap.im3", 0x1000);
 
1066
 
 
1067
    omap_l4_attach(ta, 0, &s->iomem_diss1);
 
1068
    omap_l4_attach(ta, 1, &s->iomem_disc1);
 
1069
    omap_l4_attach(ta, 2, &s->iomem_rfbi1);
 
1070
    omap_l4_attach(ta, 3, &s->iomem_venc1);
 
1071
    memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3);
 
1072
 
 
1073
#if 0
 
1074
    s->state = graphic_console_init(omap_update_display,
 
1075
                                    omap_invalidate_display, omap_screen_dump, s);
 
1076
#endif
 
1077
 
 
1078
    return s;
 
1079
}
 
1080
 
 
1081
void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
 
1082
{
 
1083
    if (cs < 0 || cs > 1)
 
1084
        hw_error("%s: wrong CS %i\n", __FUNCTION__, cs);
 
1085
    s->rfbi.chip[cs] = chip;
 
1086
}