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