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