2 * OMAP2 Display Subsystem.
4 * Copyright (C) 2008 Nokia Corporation
5 * Written by Andrzej Zaborowski <andrew@openedhand.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 or
10 * (at your option) version 3 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "qemu-common.h"
28 #include "pixel_ops.h"
30 #define OMAP_DSS_DEBUG
31 //#define OMAP_DSS_DEBUG_REG
34 #define TRACE(fmt,...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
39 #ifdef OMAP_DSS_DEBUG_REG
40 #define TRACEREG(fmt,...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
41 #define LAYERNAME(n) ((!(n)) ? "GFX" : ((n)==1) ? "VID1" : "VID2")
46 struct omap3_lcd_panel_s {
47 struct omap_dss_s *dss;
49 omap3_lcd_panel_fn_t *line_fn_tab[2];
50 omap3_lcd_panel_fn_t line_fn;
65 struct omap_dss_panel_s {
73 struct omap3_lcd_panel_s *omap_lcd_panel[2];
87 uint32_t global_alpha;
92 struct omap_dss_plane_s {
104 target_phys_addr_t addr[3];
114 /* following for l1 & l2 only (VID1 and VID2) */
116 uint32_t fir_coef_h[8];
117 uint32_t fir_coef_hv[8];
118 uint32_t fir_coef_v[8];
119 uint32_t conv_coef[5];
120 uint32_t picture_size;
125 uint16_t palette[256];
141 struct rfbi_chip_s *chip[2];
150 static void omap_dss_interrupt_update(struct omap_dss_s *s)
153 (s->dsi.irqst & s->dsi.irqen)
154 | (s->dispc.irqst & s->dispc.irqen));
157 static void omap_dss_save_state(QEMUFile *f, void *opaque)
159 struct omap_dss_s *s = (struct omap_dss_s *)opaque;
162 qemu_put_sbe32(f, s->autoidle);
163 qemu_put_sbe32(f, s->control);
164 qemu_put_be32(f, s->sdi_control);
165 qemu_put_be32(f, s->pll_control);
166 qemu_put_sbe32(f, s->enable);
167 qemu_put_sbe32(f, s->dig.enable);
168 qemu_put_sbe32(f, s->dig.nx);
169 qemu_put_sbe32(f, s->dig.ny);
170 qemu_put_sbe32(f, s->dig.x);
171 qemu_put_sbe32(f, s->dig.y);
172 qemu_put_sbe32(f, s->lcd.enable);
173 qemu_put_sbe32(f, s->lcd.nx);
174 qemu_put_sbe32(f, s->lcd.ny);
175 qemu_put_sbe32(f, s->lcd.x);
176 qemu_put_sbe32(f, s->lcd.y);
177 qemu_put_be32(f, s->dispc.idlemode);
178 qemu_put_be32(f, s->dispc.irqst);
179 qemu_put_be32(f, s->dispc.irqen);
180 qemu_put_be32(f, s->dispc.control);
181 qemu_put_be32(f, s->dispc.config);
182 qemu_put_be32(f, s->dispc.capable);
183 qemu_put_be32(f, s->dispc.timing[0]);
184 qemu_put_be32(f, s->dispc.timing[1]);
185 qemu_put_be32(f, s->dispc.timing[2]);
186 qemu_put_be32(f, s->dispc.timing[3]);
187 qemu_put_sbe32(f, s->dispc.line);
188 qemu_put_be32(f, s->dispc.bg[0]);
189 qemu_put_be32(f, s->dispc.bg[1]);
190 qemu_put_be32(f, s->dispc.trans[0]);
191 qemu_put_be32(f, s->dispc.trans[1]);
192 qemu_put_be32(f, s->dispc.global_alpha);
193 qemu_put_be32(f, s->dispc.cpr_coef_r);
194 qemu_put_be32(f, s->dispc.cpr_coef_g);
195 qemu_put_be32(f, s->dispc.cpr_coef_b);
196 for (i = 0; i < 3; i++) {
197 qemu_put_sbe32(f, s->dispc.l[i].enable);
198 qemu_put_sbe32(f, s->dispc.l[i].bpp);
199 qemu_put_sbe32(f, s->dispc.l[i].posx);
200 qemu_put_sbe32(f, s->dispc.l[i].posy);
201 qemu_put_sbe32(f, s->dispc.l[i].nx);
202 qemu_put_sbe32(f, s->dispc.l[i].ny);
203 qemu_put_sbe32(f, s->dispc.l[i].rotation_flag);
204 qemu_put_sbe32(f, s->dispc.l[i].gfx_format);
205 qemu_put_sbe32(f, s->dispc.l[i].gfx_channel);
206 for (j = 0; j < 3; j++) {
207 #if TARGET_PHYS_ADDR_BITS == 32
208 qemu_put_be32(f, s->dispc.l[i].addr[j]);
209 #elif TARGET_PHYS_ADDR_BITS == 64
210 qemu_put_be64(f, s->dispc.l[i].addr[j]);
212 #error TARGET_PHYS_ADDR_BITS undefined
215 qemu_put_be32(f, s->dispc.l[i].attr);
216 qemu_put_be32(f, s->dispc.l[i].tresh);
217 qemu_put_sbe32(f, s->dispc.l[i].rowinc);
218 qemu_put_sbe32(f, s->dispc.l[i].colinc);
219 qemu_put_sbe32(f, s->dispc.l[i].wininc);
220 qemu_put_be32(f, s->dispc.l[i].preload);
221 qemu_put_be32(f, s->dispc.l[i].fir);
222 for (j = 0; j < 8; j++) {
223 qemu_put_be32(f, s->dispc.l[i].fir_coef_h[j]);
224 qemu_put_be32(f, s->dispc.l[i].fir_coef_hv[j]);
225 qemu_put_be32(f, s->dispc.l[i].fir_coef_v[j]);
227 qemu_put_be32(f, s->dispc.l[i].conv_coef[j]);
229 qemu_put_be32(f, s->dispc.l[i].picture_size);
230 qemu_put_be32(f, s->dispc.l[i].accu[0]);
231 qemu_put_be32(f, s->dispc.l[i].accu[1]);
233 qemu_put_sbe32(f, s->dispc.invalidate);
234 for (i = 0; i < 256; i++)
235 qemu_put_be16(f, s->dispc.palette[i]);
236 qemu_put_sbe32(f, s->rfbi.idlemode);
237 qemu_put_be32(f, s->rfbi.control);
238 qemu_put_sbe32(f, s->rfbi.enable);
239 qemu_put_sbe32(f, s->rfbi.pixels);
240 qemu_put_sbe32(f, s->rfbi.busy);
241 qemu_put_sbe32(f, s->rfbi.skiplines);
242 qemu_put_be16(f, s->rfbi.rxbuf);
243 for (i = 0; i < 6; i++) {
245 qemu_put_be32(f, s->rfbi.config[i]);
247 qemu_put_be32(f, s->rfbi.time[i]);
248 qemu_put_be32(f, s->rfbi.data[i]);
250 qemu_put_be16(f, s->rfbi.vsync);
251 qemu_put_be16(f, s->rfbi.hsync);
252 qemu_put_be32(f, s->dsi.irqst);
253 qemu_put_be32(f, s->dsi.irqen);
256 static int omap_dss_load_state(QEMUFile *f, void *opaque, int version_id)
258 struct omap_dss_s *s = (struct omap_dss_s *)opaque;
264 s->autoidle = qemu_get_sbe32(f);
265 s->control = qemu_get_sbe32(f);
266 s->sdi_control = qemu_get_be32(f);
267 s->pll_control = qemu_get_be32(f);
268 s->enable = qemu_get_sbe32(f);
269 s->dig.enable = qemu_get_sbe32(f);
270 s->dig.nx = qemu_get_sbe32(f);
271 s->dig.ny = qemu_get_sbe32(f);
272 s->dig.x = qemu_get_sbe32(f);
273 s->dig.y = qemu_get_sbe32(f);
274 s->lcd.enable = qemu_get_sbe32(f);
275 s->lcd.nx = qemu_get_sbe32(f);
276 s->lcd.ny = qemu_get_sbe32(f);
277 s->lcd.x = qemu_get_sbe32(f);
278 s->lcd.y = qemu_get_sbe32(f);
279 s->dispc.idlemode = qemu_get_be32(f);
280 s->dispc.irqst = qemu_get_be32(f);
281 s->dispc.irqen = qemu_get_be32(f);
282 s->dispc.control = qemu_get_be32(f);
283 s->dispc.config = qemu_get_be32(f);
284 s->dispc.capable = qemu_get_be32(f);
285 s->dispc.timing[0] = qemu_get_be32(f);
286 s->dispc.timing[1] = qemu_get_be32(f);
287 s->dispc.timing[2] = qemu_get_be32(f);
288 s->dispc.timing[3] = qemu_get_be32(f);
289 s->dispc.line = qemu_get_sbe32(f);
290 s->dispc.bg[0] = qemu_get_be32(f);
291 s->dispc.bg[1] = qemu_get_be32(f);
292 s->dispc.trans[0] = qemu_get_be32(f);
293 s->dispc.trans[1] = qemu_get_be32(f);
294 s->dispc.global_alpha = qemu_get_be32(f);
295 s->dispc.cpr_coef_r = qemu_get_be32(f);
296 s->dispc.cpr_coef_g = qemu_get_be32(f);
297 s->dispc.cpr_coef_b = qemu_get_be32(f);
298 for (i = 0; i < 3; i++) {
299 s->dispc.l[i].enable = qemu_get_sbe32(f);
300 s->dispc.l[i].bpp = qemu_get_sbe32(f);
301 s->dispc.l[i].posx = qemu_get_sbe32(f);
302 s->dispc.l[i].posy = qemu_get_sbe32(f);
303 s->dispc.l[i].nx = qemu_get_sbe32(f);
304 s->dispc.l[i].ny = qemu_get_sbe32(f);
305 s->dispc.l[i].rotation_flag = qemu_get_sbe32(f);
306 s->dispc.l[i].gfx_format = qemu_get_sbe32(f);
307 s->dispc.l[i].gfx_channel = qemu_get_sbe32(f);
308 for (j = 0; j < 3; j++) {
309 #if TARGET_PHYS_ADDR_BITS == 32
310 s->dispc.l[i].addr[j] = qemu_get_be32(f);
311 #elif TARGET_PHYS_ADDR_BITS == 64
312 s->dispc.l[i].addr[j] = qemu_get_be64(f);
314 #error TARGET_PHYS_ADDR_BITS undefined
317 s->dispc.l[i].attr = qemu_get_be32(f);
318 s->dispc.l[i].tresh = qemu_get_be32(f);
319 s->dispc.l[i].rowinc = qemu_get_sbe32(f);
320 s->dispc.l[i].colinc = qemu_get_sbe32(f);
321 s->dispc.l[i].wininc = qemu_get_sbe32(f);
322 s->dispc.l[i].preload = qemu_get_be32(f);
323 s->dispc.l[i].fir = qemu_get_be32(f);
324 for (j = 0; j < 8; j++) {
325 s->dispc.l[i].fir_coef_h[j] = qemu_get_be32(f);
326 s->dispc.l[i].fir_coef_hv[j] = qemu_get_be32(f);
327 s->dispc.l[i].fir_coef_v[j] = qemu_get_be32(f);
329 s->dispc.l[i].conv_coef[j] = qemu_get_be32(f);
331 s->dispc.l[i].picture_size = qemu_get_be32(f);
332 s->dispc.l[i].accu[0] = qemu_get_be32(f);
333 s->dispc.l[i].accu[1] = qemu_get_be32(f);
335 s->dispc.invalidate = qemu_get_sbe32(f);
336 for (i = 0; i < 256; i++)
337 s->dispc.palette[i] = qemu_get_be16(f);
338 s->rfbi.idlemode = qemu_get_sbe32(f);
339 s->rfbi.control = qemu_get_be32(f);
340 s->rfbi.enable = qemu_get_sbe32(f);
341 s->rfbi.pixels = qemu_get_sbe32(f);
342 s->rfbi.busy = qemu_get_sbe32(f);
343 s->rfbi.skiplines = qemu_get_sbe32(f);
344 s->rfbi.rxbuf = qemu_get_be16(f);
345 for (i = 0; i < 6; i++) {
347 s->rfbi.config[i] = qemu_get_be32(f);
349 s->rfbi.time[i] = qemu_get_be32(f);
350 s->rfbi.data[i] = qemu_get_be32(f);
352 s->rfbi.vsync = qemu_get_be16(f);
353 s->rfbi.hsync = qemu_get_be16(f);
354 s->dsi.irqst = qemu_get_be32(f);
355 s->dsi.irqen = qemu_get_be32(f);
357 s->dispc.invalidate = 1; /* force refresh of display parameters */
358 if (s->omap_lcd_panel[0])
359 s->omap_lcd_panel[0]->invalidate = 1;
360 if (s->omap_lcd_panel[1])
361 s->omap_lcd_panel[1]->invalidate = 1;
363 omap_dss_interrupt_update(s);
368 static void omap_rfbi_reset(struct omap_dss_s *s)
370 s->rfbi.idlemode = 0;
374 s->rfbi.skiplines = 0;
376 s->rfbi.config[0] = 0x00310000;
377 s->rfbi.config[1] = 0x00310000;
392 void omap_dss_reset(struct omap_dss_s *s)
396 s->autoidle = 0x10; /* was 0 for OMAP2 but bit4 must be set for OMAP3 */
410 s->dispc.idlemode = 0;
413 s->dispc.control = 0;
415 s->dispc.capable = 0x161;
416 s->dispc.timing[0] = 0;
417 s->dispc.timing[1] = 0;
418 s->dispc.timing[2] = 0;
419 s->dispc.timing[3] = 0x00010002;
423 s->dispc.trans[0] = 0;
424 s->dispc.trans[1] = 0;
425 s->dispc.global_alpha = 0;
426 s->dispc.cpr_coef_r = 0;
427 s->dispc.cpr_coef_g = 0;
428 s->dispc.cpr_coef_b = 0;
430 for (i = 0; i < 3; i++) {
431 s->dispc.l[i].enable = 0;
432 s->dispc.l[i].bpp = 0;
433 s->dispc.l[i].addr[0] = 0;
434 s->dispc.l[i].addr[1] = 0;
435 s->dispc.l[i].addr[2] = 0;
436 s->dispc.l[i].posx = 0;
437 s->dispc.l[i].posy = 0;
438 s->dispc.l[i].nx = 1;
439 s->dispc.l[i].ny = 1;
440 s->dispc.l[i].attr = 0;
441 s->dispc.l[i].tresh = (s->dispc.rev < 0x30) ? 0 : 0x03ff03c0;
442 s->dispc.l[i].rowinc = 1;
443 s->dispc.l[i].colinc = 1;
444 s->dispc.l[i].wininc = 0;
445 s->dispc.l[i].preload = 0x100;
446 s->dispc.l[i].fir = 0;
447 s->dispc.l[i].picture_size = 0;
448 s->dispc.l[i].accu[0] = 0;
449 s->dispc.l[i].accu[1] = 0;
450 for (j = 0; j < 5; j++)
451 s->dispc.l[i].conv_coef[j] = 0;
452 for (j = 0; j < 8; j++) {
453 s->dispc.l[i].fir_coef_h[j] = 0;
454 s->dispc.l[i].fir_coef_hv[j] = 0;
455 s->dispc.l[i].fir_coef_v[j] = 0;
463 omap_dss_interrupt_update(s);
466 static uint32_t omap_diss_read(void *opaque, target_phys_addr_t addr)
468 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
472 case 0x00: /* DSS_REVISIONNUMBER */
473 TRACEREG("DSS_REVISIONNUMBER: 0x20");
476 case 0x10: /* DSS_SYSCONFIG */
477 TRACEREG("DSS_SYSCONFIG: 0x%08x", s->autoidle);
480 case 0x14: /* DSS_SYSSTATUS */
481 TRACEREG("DSS_SYSSTATUS: 0x1");
482 return 1; /* RESETDONE */
484 case 0x18: /* DSS_IRQSTATUS */
485 TRACEREG("DSS_IRQSTATUS: 0x%08x",
486 ((s->dsi.irqst & s->dsi.irqen) ? 2 : 0)
487 | ((s->dispc.irqst & s->dispc.irqen) ? 1 : 0));
488 return ((s->dsi.irqst & s->dsi.irqen) ? 2 : 0)
489 | ((s->dispc.irqst & s->dispc.irqen) ? 1 : 0);
491 case 0x40: /* DSS_CONTROL */
492 TRACEREG("DSS_CONTROL: 0x%08x", s->control);
495 case 0x44: /* DSS_SDI_CONTROL */
496 TRACEREG("DSS_SDI_CONTROL: 0x%08x", s->sdi_control);
497 return s->sdi_control;
499 case 0x48: /* DSS_PLL_CONTROL */
500 TRACEREG("DSS_PLL_CONTROL: 0x%08x", s->pll_control);
501 return s->pll_control;
503 case 0x50: /* DSS_PSA_LCD_REG_1 */
504 case 0x54: /* DSS_PSA_LCD_REG_2 */
505 case 0x58: /* DSS_PSA_VIDEO_REG */
506 TRACEREG("DSS_PSA_xxx: 0");
507 /* TODO: fake some values when appropriate s->control bits are set */
510 case 0x5c: /* DSS_SDI_STATUS */
511 /* TODO: check and implement missing OMAP3 bits */
512 TRACEREG("DSS_STATUS: 0x%08x", 1 + (s->control & 1));
513 return 1 + (s->control & 1);
522 static void omap_diss_write(void *opaque, target_phys_addr_t addr,
525 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
528 case 0x00: /* DSS_REVISIONNUMBER */
529 case 0x14: /* DSS_SYSSTATUS */
530 case 0x18: /* DSS_IRQSTATUS */
531 case 0x50: /* DSS_PSA_LCD_REG_1 */
532 case 0x54: /* DSS_PSA_LCD_REG_2 */
533 case 0x58: /* DSS_PSA_VIDEO_REG */
534 case 0x5c: /* DSS_STATUS */
536 /*OMAP_RO_REGV(addr, value);*/
539 case 0x10: /* DSS_SYSCONFIG */
540 TRACEREG("DSS_SYSCONFIG = 0x%08x", value);
541 if (value & 2) /* SOFTRESET */
543 s->autoidle = value & 0x19; /* was 0x01 for OMAP2 */
546 case 0x40: /* DSS_CONTROL */
547 TRACEREG("DSS_CONTROL = 0x%08x", value);
548 s->control = value & 0x3ff; /* was 0x3dd for OMAP2 */
551 case 0x44: /* DSS_SDI_CONTROL */
552 TRACEREG("DSS_SDI_CONTROL = 0x%08x", value);
553 s->sdi_control = value & 0x000ff80f;
556 case 0x48: /* DSS_PLL_CONTROL */
557 TRACEREG("DSS_PLL_CONTROL = 0x%08x", value);
558 s->pll_control = value;
562 OMAP_BAD_REGV(addr, value);
567 static CPUReadMemoryFunc *omap_diss1_readfn[] = {
568 omap_badwidth_read32,
569 omap_badwidth_read32,
573 static CPUWriteMemoryFunc *omap_diss1_writefn[] = {
574 omap_badwidth_write32,
575 omap_badwidth_write32,
579 static uint32_t omap_disc_read(void *opaque, target_phys_addr_t addr)
581 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
585 case 0x000: /* DISPC_REVISION */
586 TRACEREG("DISPC_REVISION: 0x%08x", s->dispc.rev);
588 case 0x010: /* DISPC_SYSCONFIG */
589 TRACEREG("DISPC_SYSCONFIG: 0x%08x", s->dispc.idlemode);
590 return s->dispc.idlemode;
591 case 0x014: /* DISPC_SYSSTATUS */
592 TRACEREG("DISPC_SYSSTATUS: 1");
593 return 1; /* RESETDONE */
594 case 0x018: /* DISPC_IRQSTATUS */
595 TRACEREG("DISPC_IRQSTATUS: 0x%08x", s->dispc.irqst);
596 return s->dispc.irqst;
597 case 0x01c: /* DISPC_IRQENABLE */
598 TRACEREG("DISPC_IRQENABLE: 0x%08x", s->dispc.irqen);
599 return s->dispc.irqen;
600 case 0x040: /* DISPC_CONTROL */
601 TRACEREG("DISPC_CONTROL: 0x%08x", s->dispc.control);
602 return s->dispc.control;
603 case 0x044: /* DISPC_CONFIG */
604 TRACEREG("DISPC_CONFIG: 0x%08x", s->dispc.config);
605 return s->dispc.config;
606 case 0x048: /* DISPC_CAPABLE */
607 TRACEREG("DISPC_CAPABLE: 0x%08x", s->dispc.capable);
608 return s->dispc.capable;
609 case 0x04c: /* DISPC_DEFAULT_COLOR0 */
610 TRACEREG("DISPC_DEFAULT_COLOR0: 0x%08x", s->dispc.bg[0]);
611 return s->dispc.bg[0];
612 case 0x050: /* DISPC_DEFAULT_COLOR1 */
613 TRACEREG("DISPC_DEFAULT_COLOR0: 0x%08x", s->dispc.bg[1]);
614 return s->dispc.bg[1];
615 case 0x054: /* DISPC_TRANS_COLOR0 */
616 TRACEREG("DISPC_TRANS_COLOR0: 0x%08x", s->dispc.trans[0]);
617 return s->dispc.trans[0];
618 case 0x058: /* DISPC_TRANS_COLOR1 */
619 TRACEREG("DISPC_TRANS_COLOR0: 0x%08x", s->dispc.trans[1]);
620 return s->dispc.trans[1];
621 case 0x05c: /* DISPC_LINE_STATUS */
622 TRACEREG("DISPC_LINE_STATUS: 0x7ff");
624 case 0x060: /* DISPC_LINE_NUMBER */
625 TRACEREG("DISPC_LINE_NUMBER: 0x%08x", s->dispc.line);
626 return s->dispc.line;
627 case 0x064: /* DISPC_TIMING_H */
628 TRACEREG("DISPC_TIMING_H: 0x%08x", s->dispc.timing[0]);
629 return s->dispc.timing[0];
630 case 0x068: /* DISPC_TIMING_V */
631 TRACEREG("DISPC_TIMING_H: 0x%08x", s->dispc.timing[1]);
632 return s->dispc.timing[1];
633 case 0x06c: /* DISPC_POL_FREQ */
634 TRACEREG("DISPC_POL_FREQ: 0x%08x", s->dispc.timing[2]);
635 return s->dispc.timing[2];
636 case 0x070: /* DISPC_DIVISOR */
637 TRACEREG("DISPC_DIVISOR: 0x%08x", s->dispc.timing[3]);
638 return s->dispc.timing[3];
639 case 0x074: /* DISPC_GLOBAL_ALPHA */
640 TRACEREG("DISPC_GLOBAL_ALPHA: 0x%08x", s->dispc.global_alpha);
641 return s->dispc.global_alpha;
642 case 0x078: /* DISPC_SIZE_DIG */
643 TRACEREG("DISPC_SIZE_DIG: 0x%08x", ((s->dig.ny - 1) << 16) | (s->dig.nx - 1));
644 return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1);
645 case 0x07c: /* DISPC_SIZE_LCD */
646 TRACEREG("DISPC_SIZE_LCD: 0x%08x", ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1));
647 return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1);
648 case 0x14c: /* DISPC_VID2_BA0 */
650 case 0x0bc: /* DISPC_VID1_BA0 */
652 case 0x080: /* DISPC_GFX_BA0 */
653 TRACEREG("DISPC_%s_BA0: 0x%08x", LAYERNAME(n), s->dispc.l[n].addr[0]);
654 return s->dispc.l[n].addr[0];
655 case 0x150: /* DISPC_VID2_BA1 */
657 case 0x0c0: /* DISPC_VID1_BA1 */
659 case 0x084: /* DISPC_GFX_BA1 */
660 TRACEREG("DISPC_%s_BA1: 0x%08x", LAYERNAME(n), s->dispc.l[n].addr[1]);
661 return s->dispc.l[n].addr[1];
662 case 0x154: /* DISPC_VID2_POSITION */
664 case 0x0c4: /* DISPC_VID1_POSITION */
666 case 0x088: /* DISPC_GFX_POSITION */
667 TRACEREG("DISPC_%s_POSITION: 0x%08x", LAYERNAME(n),
668 (s->dispc.l[n].posy << 16) | s->dispc.l[n].posx);
669 return (s->dispc.l[n].posy << 16) | s->dispc.l[n].posx;
670 case 0x158: /* DISPC_VID2_SIZE */
672 case 0x0c8: /* DISPC_VID1_SIZE */
674 case 0x08c: /* DISPC_GFX_SIZE */
675 TRACEREG("DISPC_%s_SIZE: 0x%08x", LAYERNAME(n),
676 ((s->dispc.l[n].ny - 1) << 16) | (s->dispc.l[n].nx - 1));
677 return ((s->dispc.l[n].ny - 1) << 16) | (s->dispc.l[n].nx - 1);
678 case 0x15c: /* DISPC_VID2_ATTRIBUTES */
680 case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
682 case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
683 TRACEREG("DISPC_%s_ATTRIBUTES: 0x%08x", LAYERNAME(n),
685 return s->dispc.l[n].attr;
686 case 0x160: /* DISPC_VID2_FIFO_THRESHOLD */
688 case 0x0d0: /* DISPC_VID1_FIFO_THRESHOLD */
690 case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
691 TRACEREG("DISPC_%s_THRESHOLD: 0x%08x", LAYERNAME(n),
692 s->dispc.l[n].tresh);
693 return s->dispc.l[n].tresh;
694 case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */
696 case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */
698 case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
699 TRACEREG("DISPC_%s_FIFO_SIZE_STATUS: 0x%08x", LAYERNAME(n),
700 s->dispc.rev < 0x30 ? 256 : 1024);
701 return s->dispc.rev < 0x30 ? 256 : 1024;
702 case 0x168: /* DISPC_VID2_ROW_INC */
704 case 0x0d8: /* DISPC_VID1_ROW_INC */
706 case 0x0ac: /* DISPC_GFX_ROW_INC */
707 TRACEREG("DISPC_%s_ROW_INC: 0x%08x", LAYERNAME(n),
708 s->dispc.l[n].rowinc);
709 return s->dispc.l[n].rowinc;
710 case 0x16c: /* DISPC_VID2_PIXEL_INC */
712 case 0x0dc: /* DISPC_VID1_PIXEL_INC */
714 case 0x0b0: /* DISPC_GFX_PIXEL_INC */
715 TRACEREG("DISPC_%s_PIXEL_INC: 0x%08x", LAYERNAME(n),
716 s->dispc.l[n].colinc);
717 return s->dispc.l[n].colinc;
718 case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
719 TRACEREG("DISPC_GFX_WINDOW_SKIP: 0x%08x", s->dispc.l[0].wininc);
720 return s->dispc.l[0].wininc;
721 case 0x0b8: /* DISPC_GFX_TABLE_BA */
722 TRACEREG("DISPC_GFX_TABLE_BA: 0x%08x", s->dispc.l[0].addr[2]);
723 return s->dispc.l[0].addr[2];
724 case 0x170: /* DISPC_VID2_FIR */
726 case 0x0e0: /* DISPC_VID1_FIR */
728 TRACEREG("DISPC_%s_FIR: 0x%08x", LAYERNAME(n),
730 return s->dispc.l[n].fir;
731 case 0x174: /* DISPC_VID2_PICTURE_SIZE */
733 case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
735 TRACEREG("DISPC_%s_PICTURE_SIZE: 0x%08x", LAYERNAME(n),
736 s->dispc.l[n].picture_size);
737 return s->dispc.l[n].picture_size;
738 case 0x178: /* DISPC_VID2_ACCU0 */
739 case 0x17c: /* DISPC_VID2_ACCU1 */
741 case 0x0e8: /* DISPC_VID1_ACCU0 */
742 case 0x0ec: /* DISPC_VID1_ACCU1 */
744 TRACEREG("DISPC_%s_ACCU%d: 0x%08x", LAYERNAME(n),
745 (addr >> 1) & 1, s->dispc.l[n].accu[(addr >> 1 ) & 1]);
746 return s->dispc.l[n].accu[(addr >> 1) & 1];
747 case 0x180 ... 0x1bc: /* DISPC_VID2_FIR_COEF */
749 case 0x0f0 ... 0x12c: /* DISPC_VID1_FIR_COEF */
752 TRACEREG("DISPC_%s_FIR_COEF_HV%d: 0x%08x", LAYERNAME(n),
753 (addr - ((n > 1) ? 0x180 : 0xf0)) / 8,
754 s->dispc.l[n].fir_coef_hv[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8]);
755 return s->dispc.l[n].fir_coef_hv[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8];
757 TRACEREG("DISPC_%s_FIR_COEF_H%d: 0x%08x", LAYERNAME(n),
758 (addr - ((n > 1) ? 0x180 : 0xf0)) / 8,
759 s->dispc.l[n].fir_coef_h[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8]);
760 return s->dispc.l[n].fir_coef_h[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8];
761 case 0x1c0 ... 0x1d0: /* DISPC_VID2_CONV_COEFi */
763 case 0x130 ... 0x140: /* DISPC_VID1_CONV_COEFi */
765 TRACEREG("DISPC_%s_CONV_COEF%d: 0x%08x", LAYERNAME(n),
766 (addr - ((n > 1) ? 0x1c0 : 0x130)) / 4,
767 s->dispc.l[n].conv_coef[(addr - ((n > 1) ? 0x1c0 : 0x130)) / 4]);
768 return s->dispc.l[n].conv_coef[(addr - ((n > 1) ? 0x1c0 : 0x130)) / 4];
769 case 0x1d4: /* DISPC_DATA_CYCLE1 */
770 case 0x1d8: /* DISPC_DATA_CYCLE2 */
771 case 0x1dc: /* DISPC_DATA_CYCLE3 */
772 TRACEREG("DISPC_DATA_CYCLE%d: 0", (addr - 0x1d4) / 4);
774 case 0x200 ... 0x21c: /* DISPC_VID2_FIR_COEF_Vi */
776 case 0x1e0 ... 0x1fc: /* DISPC_VID1_FIR_COEF_Vi */
778 TRACEREG("DISPC_%s_FIR_COEF_V%d: 0x%08x", LAYERNAME(n),
780 s->dispc.l[n].fir_coef_v[(addr & 0x01f) / 4]);
781 return s->dispc.l[n].fir_coef_v[(addr & 0x01f) / 4];
782 case 0x220: /* DISPC_CPR_COEF_R */
783 TRACEREG("DISPC_CPR_COEF_R: 0x%08x", s->dispc.cpr_coef_r);
784 return s->dispc.cpr_coef_r;
785 case 0x224: /* DISPC_CPR_COEF_G */
786 TRACEREG("DISPC_CPR_COEF_G: 0x%08x", s->dispc.cpr_coef_g);
787 return s->dispc.cpr_coef_g;
788 case 0x228: /* DISPC_CPR_COEF_B */
789 TRACEREG("DISPC_CPR_COEF_B: 0x%08x", s->dispc.cpr_coef_b);
790 return s->dispc.cpr_coef_b;
791 case 0x234: /* DISPC_VID2_PRELOAD */
793 case 0x230: /* DISPC_VID1_PRELOAD */
795 case 0x22c: /* DISPC_GFX_PRELOAD */
796 TRACEREG("DISPC_%s_PRELOAD: 0x%08x", LAYERNAME(n),
797 s->dispc.l[n].preload);
798 return s->dispc.l[n].preload;
806 static void omap_disc_write(void *opaque, target_phys_addr_t addr,
809 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
813 case 0x000: /* DISPC_REVISION */
814 case 0x014: /* DISPC_SYSSTATUS */
815 case 0x05c: /* DISPC_LINE_STATUS */
816 case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
818 /*OMAP_RO_REGV(addr, value);*/
820 case 0x010: /* DISPC_SYSCONFIG */
821 TRACEREG("DISPC_SYSCONFIG = 0x%08x", value);
822 if (value & 2) /* SOFTRESET */
824 s->dispc.idlemode = value & ((s->dispc.rev < 0x30) ? 0x301b : 0x331f);
826 case 0x018: /* DISPC_IRQSTATUS */
827 TRACEREG("DISPC_IRQSTATUS = 0x%08x", value);
828 s->dispc.irqst &= ~value;
829 omap_dss_interrupt_update(s);
831 case 0x01c: /* DISPC_IRQENABLE */
832 TRACEREG("DISPC_IRQENABLE = 0x%08x", value);
833 s->dispc.irqen = value & ((s->dispc.rev < 0x30) ? 0xffff : 0x1ffff);
834 omap_dss_interrupt_update(s);
836 case 0x040: /* DISPC_CONTROL */
837 TRACEREG("DISPC_CONTROL = 0x%08x", value);
838 if (s->dispc.rev < 0x30)
839 s->dispc.control = value & 0x07ff9fff;
841 s->dispc.control = (value & 0xffff9bff) | (s->dispc.control & 0x6000);
842 s->dig.enable = (value >> 1) & 1;
843 s->lcd.enable = (value >> 0) & 1;
844 if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */
845 if (~((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1))
846 fprintf(stderr, "%s: Overlay Optimization when no overlay "
847 "region effectively exists leads to "
848 "unpredictable behaviour!\n", __FUNCTION__);
849 if (value & (1 << 6)) { /* GODIGITAL */
850 /* XXX: Shadowed fields are:
866 * s->dispc.l[0].addr[0]
867 * s->dispc.l[0].addr[1]
868 * s->dispc.l[0].addr[2]
873 * s->dispc.l[0].tresh
874 * s->dispc.l[0].rowinc
875 * s->dispc.l[0].colinc
876 * s->dispc.l[0].wininc
877 * All they need to be loaded here from their shadow registers.
879 s->dispc.control &= ~(1 << 6); /* GODIGITAL finished */
881 if (value & (1 << 5)) { /* GOLCD */
882 /* XXX: Likewise for LCD here. */
883 s->dispc.control &= ~(1 << 5); /* GOLCD finished */
885 s->dispc.invalidate = 1;
887 case 0x044: /* DISPC_CONFIG */
888 TRACEREG("DISPC_CONFIG = 0x%08x", value);
889 s->dispc.config = value & 0x3fff;
891 * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded
892 * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded
894 s->dispc.invalidate = 1;
896 case 0x048: /* DISPC_CAPABLE */
897 TRACEREG("DISPC_CAPABLE = 0x%08x", value);
898 s->dispc.capable = value & 0x3ff;
900 case 0x04c: /* DISPC_DEFAULT_COLOR0 */
901 TRACEREG("DISPC_DEFAULT_COLOR0 = 0x%08x", value);
902 s->dispc.bg[0] = value & 0xffffff;
903 s->dispc.invalidate = 1;
905 case 0x050: /* DISPC_DEFAULT_COLOR1 */
906 TRACEREG("DISPC_DEFAULT_COLOR1 = 0x%08x", value);
907 s->dispc.bg[1] = value & 0xffffff;
908 s->dispc.invalidate = 1;
910 case 0x054: /* DISPC_TRANS_COLOR0 */
911 TRACEREG("DISPC_TRANS_COLOR0 = 0x%08x", value);
912 s->dispc.trans[0] = value & 0xffffff;
913 s->dispc.invalidate = 1;
915 case 0x058: /* DISPC_TRANS_COLOR1 */
916 TRACEREG("DISPC_TRANS_COLOR1 = 0x%08x", value);
917 s->dispc.trans[1] = value & 0xffffff;
918 s->dispc.invalidate = 1;
920 case 0x060: /* DISPC_LINE_NUMBER */
921 TRACEREG("DISPC_LINE_NUMBER = 0x%08x", value);
922 s->dispc.line = value & 0x7ff;
924 case 0x064: /* DISPC_TIMING_H */
925 TRACEREG("DISPC_TIMING_H = 0x%08x", value);
926 s->dispc.timing[0] = value & 0x0ff0ff3f;
928 case 0x068: /* DISPC_TIMING_V */
929 TRACEREG("DISPC_TIMING_V = 0x%08x", value);
930 s->dispc.timing[1] = value & 0x0ff0ff3f;
932 case 0x06c: /* DISPC_POL_FREQ */
933 TRACEREG("DISPC_POL_FREQ = 0x%08x", value);
934 s->dispc.timing[2] = value & 0x0003ffff;
936 case 0x070: /* DISPC_DIVISOR */
937 TRACEREG("DISPC_DIVISOR = 0x%08x", value);
938 s->dispc.timing[3] = value & 0x00ff00ff;
940 case 0x074: /* DISPC_GLOBAL_ALPHA */
941 TRACEREG("DISPC_GLOBAL_ALPHA = 0x%08x", value);
942 s->dispc.global_alpha = value & 0x00ff00ff;
944 case 0x078: /* DISPC_SIZE_DIG */
945 s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
946 s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
947 s->dispc.invalidate = 1;
948 TRACEREG("DISPC_SIZE_DIG = 0x%08x (%dx%d)", value, s->dig.nx, s->dig.ny);
950 case 0x07c: /* DISPC_SIZE_LCD */
951 s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
952 s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
953 s->dispc.invalidate = 1;
954 TRACEREG("DISPC_SIZE_LCD = 0x%08x (%dx%d)", value, s->lcd.nx, s->lcd.ny);
956 case 0x14c: /* DISPC_VID2_BA0 */
958 case 0x0bc: /* DISPC_VID1_BA0 */
960 case 0x080: /* DISPC_GFX_BA0 */
961 TRACEREG("DISPC_%s_BA0 = 0x%08x", LAYERNAME(n), value);
962 s->dispc.l[n].addr[0] = (target_phys_addr_t) value;
963 s->dispc.invalidate = 1;
965 case 0x150: /* DISPC_VID2_BA1 */
967 case 0x0c0: /* DISPC_VID1_BA1 */
969 case 0x084: /* DISPC_GFX_BA1 */
970 TRACEREG("DISPC_%s_BA1 = 0x%08x", LAYERNAME(n), value);
971 s->dispc.l[n].addr[1] = (target_phys_addr_t) value;
972 s->dispc.invalidate = 1;
974 case 0x154: /* DISPC_VID2_POSITION */
976 case 0x0c4: /* DISPC_VID1_POSITION */
978 case 0x088: /* DISPC_GFX_POSITION */
979 s->dispc.l[n].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */
980 s->dispc.l[n].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */
981 s->dispc.invalidate = 1;
982 TRACEREG("DISPC_%s_POSITION = 0x%08x (%d,%d)", LAYERNAME(n),
983 value, s->dispc.l[n].posx, s->dispc.l[n].posy);
985 case 0x158: /* DISPC_VID2_SIZE */
987 case 0x0c8: /* DISPC_VID1_SIZE */
989 case 0x08c: /* DISPC_GFX_SIZE */
990 s->dispc.l[n].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */
991 s->dispc.l[n].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */
992 TRACEREG("DISPC_%s_SIZE = 0x%08x (%dx%d)", LAYERNAME(n),
993 value, s->dispc.l[n].nx, s->dispc.l[n].ny);
994 s->dispc.invalidate = 1;
997 case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
998 TRACEREG("DISPC_GFX_ATTRIBUTES = 0x%08x", value);
999 s->dispc.l[0].attr = value & 0xffff;
1000 if (value & (3 << 9))
1001 fprintf(stderr, "%s: Big-endian pixel format not supported\n",
1003 s->dispc.l[0].enable = value & 1;
1004 s->dispc.l[0].bpp = (value >> 1) & 0xf;
1005 s->dispc.l[0].rotation_flag = (value >> 12) & 0x3;
1006 s->dispc.l[0].gfx_format = (value >> 1) & 0xf;
1007 s->dispc.l[0].gfx_channel = (value >> 8) & 0x1;
1008 s->dispc.invalidate = 1;
1010 case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
1012 case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
1014 case 0x0a4: /* DISPC_GFX_FIFO_THRESHOLD */
1015 TRACEREG("DISPC_%s_FIFO_THRESHOLD = 0x%08x", LAYERNAME(n), value);
1016 s->dispc.l[n].tresh = value & ((s->dispc.rev < 0x30)
1017 ? 0x01ff01ff : 0x0fff0fff);
1019 case 0x168: /* DISPC_VID2_ROW_INC */
1021 case 0x0d8: /* DISPC_VID1_ROW_INC */
1023 case 0x0ac: /* DISPC_GFX_ROW_INC */
1024 TRACEREG("DISPC_%s_ROW_INC = 0x%08x", LAYERNAME(n), value);
1025 s->dispc.l[n].rowinc = value;
1026 s->dispc.invalidate = 1;
1028 case 0x16c: /* DISPC_VID2_PIXEL_INC */
1030 case 0x0dc: /* DISPC_VID1_PIXEL_INC */
1032 case 0x0b0: /* DISPC_GFX_PIXEL_INC */
1033 TRACEREG("DISPC_%s_PIXEL_INC = 0x%08x", LAYERNAME(n), value);
1034 s->dispc.l[n].colinc = value;
1035 s->dispc.invalidate = 1;
1037 case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
1038 TRACEREG("DISPC_GFX_WINDOW_SKIP = 0x%08x", value);
1039 s->dispc.l[0].wininc = value;
1041 case 0x0b8: /* DISPC_GFX_TABLE_BA */
1042 TRACEREG("DISPC_GFX_TABLE_BA = 0x%08x", value);
1043 s->dispc.l[0].addr[2] = (target_phys_addr_t) value;
1044 s->dispc.invalidate = 1;
1046 case 0x15c: /* DISPC_VID2_ATTRIBUTES */
1048 case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
1050 TRACEREG("DISPC_%s_ATTRIBUTES = 0x%08x", LAYERNAME(n), value);
1051 s->dispc.l[n].attr = value & 0x1fffffff;
1053 case 0x170: /* DISPC_VID2_FIR */
1055 case 0x0e0: /* DISPC_VID1_FIR */
1057 TRACEREG("DISPC_%s_FIR = 0x%08x", LAYERNAME(n), value);
1058 s->dispc.l[n].fir = value & 0x1fff1fff;
1060 case 0x174: /* DISPC_VID2_PICTURE_SIZE */
1062 case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
1064 TRACEREG("DISPC_%s_PICTURE_SIZE = 0x%08x", LAYERNAME(n), value);
1065 s->dispc.l[n].picture_size = value & 0x07ff07ff;
1067 case 0x178: /* DISPC_VID2_ACCU0 */
1068 case 0x17c: /* DISPC_VID2_ACCU1 */
1070 case 0x0e8: /* DISPC_VID1_ACCU0 */
1071 case 0x0ec: /* DISPC_VID1_ACCU1 */
1073 TRACEREG("DISPC_%s_ACCU%d = 0x%08x", LAYERNAME(n),
1074 (addr >> 1) & 1, value);
1075 s->dispc.l[n].accu[(addr >> 1) & 1] = value & 0x03ff03ff;
1077 case 0x180 ... 0x1bc: /* DISPC_VID2_FIR_COEF */
1079 case 0x0f0 ... 0x12c: /* DISPC_VID1_FIR_COEF */
1082 TRACEREG("DISPC_%s_FIR_COEF_HV%d = 0x%08x", LAYERNAME(n),
1083 (addr - ((n > 1) ? 0x180 : 0xf0)) / 8, value);
1084 s->dispc.l[n].fir_coef_hv[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8] = value;
1086 TRACEREG("DISPC_%s_FIR_COEF_H%d = 0x%08x", LAYERNAME(n),
1087 (addr - ((n > 1) ? 0x180 : 0xf0)) / 8, value);
1088 s->dispc.l[n].fir_coef_h[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8] = value;
1091 case 0x1c0 ... 0x1d0: /* DISPC_VID2_CONV_COEFi */
1093 case 0x130 ... 0x140: /* DISPC_VID1_CONV_COEFi */
1095 TRACEREG("DISPC_%s_CONV_COEF%d = 0x%08x", LAYERNAME(n),
1096 (addr - ((n > 1) ? 0x1c0 : 0x130)) / 4, value);
1097 s->dispc.l[n].conv_coef[(addr - ((n > 1) ? 0x1c0 : 0x130)) / 4] = value;
1099 case 0x1d4: /* DISPC_DATA_CYCLE1 */
1100 case 0x1d8: /* DISPC_DATA_CYCLE2 */
1101 case 0x1dc: /* DISPC_DATA_CYCLE3 */
1102 TRACEREG("DISPC_DATA_CYCLE%d = 0x%08x (ignored)", (addr - 0x1d4) / 4, value);
1104 case 0x200 ... 0x21c: /* DISPC_VID2_FIR_COEF_Vi */
1106 case 0x1e0 ... 0x1fc: /* DISPC_VID1_FIR_COEF_Vi */
1108 TRACEREG("DISPC_%s_FIR_COEF_V%d = 0x%08x", LAYERNAME(n),
1109 (addr & 0x01f) / 4, value);
1110 s->dispc.l[n].fir_coef_v[(addr & 0x01f) / 4] = value & 0x0000ffff;
1112 case 0x220: /* DISPC_CPR_COEF_R */
1113 TRACEREG("DISPC_CPR_COEF_R = 0x%08x", value);
1114 s->dispc.cpr_coef_r = value & 0xffbffbff;
1116 case 0x224: /* DISPC_CPR_COEF_G */
1117 TRACEREG("DISPC_CPR_COEF_G = 0x%08x", value);
1118 s->dispc.cpr_coef_g = value & 0xffbffbff;
1120 case 0x228: /* DISPC_CPR_COEF_B */
1121 TRACEREG("DISPC_CPR_COEF_B = 0x%08x", value);
1122 s->dispc.cpr_coef_b = value & 0xffbffbff;
1124 case 0x234: /* DISPC_VID2_PRELOAD */
1126 case 0x230: /* DISPC_VID1_PRELOAD */
1128 case 0x22c: /* DISPC_GFX_PRELOAD */
1129 TRACEREG("DISPC_%s_PRELOAD = 0x%08x", LAYERNAME(n), value);
1130 s->dispc.l[n].preload = value & 0x0fff;
1133 OMAP_BAD_REGV(addr, value);
1138 static CPUReadMemoryFunc *omap_disc1_readfn[] = {
1139 omap_badwidth_read32,
1140 omap_badwidth_read32,
1144 static CPUWriteMemoryFunc *omap_disc1_writefn[] = {
1145 omap_badwidth_write32,
1146 omap_badwidth_write32,
1150 static void *omap_rfbi_get_buffer(struct omap_dss_s *s)
1152 target_phys_addr_t fb;
1156 fb = s->dispc.l[0].addr[0];
1158 pd = cpu_get_physical_page_desc(fb);
1159 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
1161 cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n",
1164 return phys_ram_base +
1165 (pd & TARGET_PAGE_MASK) +
1166 (fb & ~TARGET_PAGE_MASK);
1169 static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
1174 /* TODO: in non-Bypass mode we probably need to just deassert the DRQ. */
1179 static void omap_rfbi_transfer_start(struct omap_dss_s *s)
1185 if (!s->rfbi.enable || s->rfbi.busy)
1188 if (s->rfbi.control & (1 << 1)) { /* BYPASS */
1189 /* TODO: in non-Bypass mode we probably need to just assert the
1190 * DRQ and wait for DMA to write the pixels. */
1191 fprintf(stderr, "%s: Bypass mode unimplemented\n", __FUNCTION__);
1195 if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */
1197 /* TODO: check that LCD output is enabled in DISPC. */
1201 data = omap_rfbi_get_buffer(s);
1204 len = s->rfbi.pixels * 2;
1207 /* TODO: negative values */
1208 pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2;
1210 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1211 s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);
1212 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1213 s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
1215 omap_rfbi_transfer_stop(s);
1218 s->dispc.irqst |= 1; /* FRAMEDONE */
1219 omap_dss_interrupt_update(s);
1222 static uint32_t omap_rfbi_read(void *opaque, target_phys_addr_t addr)
1224 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
1227 case 0x00: /* RFBI_REVISION */
1228 TRACEREG("RFBI_REVISION: 0x10");
1231 case 0x10: /* RFBI_SYSCONFIG */
1232 TRACEREG("RFBI_SYSCONFIG: 0x%08x", s->rfbi.idlemode);
1233 return s->rfbi.idlemode;
1235 case 0x14: /* RFBI_SYSSTATUS */
1236 TRACEREG("RFBI_SYSSTATUS: 0x%08x", 1 | (s->rfbi.busy << 8));
1237 return 1 | (s->rfbi.busy << 8); /* RESETDONE */
1239 case 0x40: /* RFBI_CONTROL */
1240 TRACEREG("RFBI_CONTROL: 0x%08x", s->rfbi.control);
1241 return s->rfbi.control;
1243 case 0x44: /* RFBI_PIXELCNT */
1244 TRACEREG("RFBI_PIXELCNT: 0x%08x", s->rfbi.pixels);
1245 return s->rfbi.pixels;
1247 case 0x48: /* RFBI_LINE_NUMBER */
1248 TRACEREG("RFBI_LINE_NUMBER: 0x%08x", s->rfbi.skiplines);
1249 return s->rfbi.skiplines;
1251 case 0x58: /* RFBI_READ */
1252 case 0x5c: /* RFBI_STATUS */
1253 TRACEREG("RFBI_READ/STATUS: 0x%08x", s->rfbi.rxbuf);
1254 return s->rfbi.rxbuf;
1256 case 0x60: /* RFBI_CONFIG0 */
1257 TRACEREG("RFBI_CONFIG0: 0x%08x", s->rfbi.config[0]);
1258 return s->rfbi.config[0];
1259 case 0x64: /* RFBI_ONOFF_TIME0 */
1260 TRACEREG("RFBI_ONOFF_TIME0: 0x%08x", s->rfbi.time[0]);
1261 return s->rfbi.time[0];
1262 case 0x68: /* RFBI_CYCLE_TIME0 */
1263 TRACEREG("RFBI_CYCLE_TIME0: 0x%08x", s->rfbi.time[1]);
1264 return s->rfbi.time[1];
1265 case 0x6c: /* RFBI_DATA_CYCLE1_0 */
1266 TRACEREG("RFBI_DATA_CYCLE1_0: 0x%08x", s->rfbi.data[0]);
1267 return s->rfbi.data[0];
1268 case 0x70: /* RFBI_DATA_CYCLE2_0 */
1269 TRACEREG("RFBI_DATA_CYCLE2_0: 0x%08x", s->rfbi.data[1]);
1270 return s->rfbi.data[1];
1271 case 0x74: /* RFBI_DATA_CYCLE3_0 */
1272 TRACEREG("RFBI_DATA_CYCLE3_0: 0x%08x", s->rfbi.data[2]);
1273 return s->rfbi.data[2];
1275 case 0x78: /* RFBI_CONFIG1 */
1276 TRACEREG("RFBI_CONFIG1: 0x%08x", s->rfbi.config[1]);
1277 return s->rfbi.config[1];
1278 case 0x7c: /* RFBI_ONOFF_TIME1 */
1279 TRACEREG("RFBI_ONOFF_TIME1: 0x%08x", s->rfbi.time[2]);
1280 return s->rfbi.time[2];
1281 case 0x80: /* RFBI_CYCLE_TIME1 */
1282 TRACEREG("RFBI_CYCLE_TIME1: 0x%08x", s->rfbi.time[3]);
1283 return s->rfbi.time[3];
1284 case 0x84: /* RFBI_DATA_CYCLE1_1 */
1285 TRACEREG("RFBI_DATA_CYCLE1_1: 0x%08x", s->rfbi.data[3]);
1286 return s->rfbi.data[3];
1287 case 0x88: /* RFBI_DATA_CYCLE2_1 */
1288 TRACEREG("RFBI_DATA_CYCLE2_1: 0x%08x", s->rfbi.data[4]);
1289 return s->rfbi.data[4];
1290 case 0x8c: /* RFBI_DATA_CYCLE3_1 */
1291 TRACEREG("RFBI_DATA_CYCLE3_1: 0x%08x", s->rfbi.data[5]);
1292 return s->rfbi.data[5];
1294 case 0x90: /* RFBI_VSYNC_WIDTH */
1295 TRACEREG("RFBI_VSYNC_WIDTH: 0x%08x", s->rfbi.vsync);
1296 return s->rfbi.vsync;
1297 case 0x94: /* RFBI_HSYNC_WIDTH */
1298 TRACEREG("RFBI_HSYNC_WIDTH: 0x%08x", s->rfbi.hsync);
1299 return s->rfbi.hsync;
1305 static void omap_rfbi_write(void *opaque, target_phys_addr_t addr,
1308 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
1311 case 0x10: /* RFBI_SYSCONFIG */
1312 TRACEREG("RFBI_SYSCONFIG = 0x%08x", value);
1313 if (value & 2) /* SOFTRESET */
1315 s->rfbi.idlemode = value & 0x19;
1318 case 0x40: /* RFBI_CONTROL */
1319 TRACEREG("RFBI_CONTROL = 0x%08x", value);
1320 s->rfbi.control = value & 0xf;
1321 s->rfbi.enable = value & 1;
1322 if (value & (1 << 4) && /* ITE */
1323 !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc))
1324 omap_rfbi_transfer_start(s);
1327 case 0x44: /* RFBI_PIXELCNT */
1328 TRACEREG("RFBI_PIXELCNT = 0x%08x", value);
1329 s->rfbi.pixels = value;
1332 case 0x48: /* RFBI_LINE_NUMBER */
1333 TRACEREG("RFBI_LINE_NUMBER = 0x%08x", value);
1334 s->rfbi.skiplines = value & 0x7ff;
1337 case 0x4c: /* RFBI_CMD */
1338 TRACEREG("RFBI_CMD = 0x%08x", value);
1339 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1340 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff);
1341 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1342 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff);
1344 case 0x50: /* RFBI_PARAM */
1345 TRACEREG("RFBI_PARAM = 0x%08x", value);
1346 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1347 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
1348 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1349 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
1351 case 0x54: /* RFBI_DATA */
1352 TRACEREG("RFBI_DATA = 0x%08x", value);
1353 /* TODO: take into account the format set up in s->rfbi.config[?] and
1354 * s->rfbi.data[?], but special-case the most usual scenario so that
1355 * speed doesn't suffer. */
1356 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) {
1357 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
1358 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16);
1360 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) {
1361 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
1362 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16);
1364 if (!-- s->rfbi.pixels)
1365 omap_rfbi_transfer_stop(s);
1367 case 0x58: /* RFBI_READ */
1368 TRACEREG("RFBI_READ = 0x%08x", value);
1369 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1370 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
1371 else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1372 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
1373 if (!-- s->rfbi.pixels)
1374 omap_rfbi_transfer_stop(s);
1377 case 0x5c: /* RFBI_STATUS */
1378 TRACEREG("RFBI_STATUS = 0x%08x", value);
1379 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1380 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
1381 else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1382 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
1383 if (!-- s->rfbi.pixels)
1384 omap_rfbi_transfer_stop(s);
1387 case 0x60: /* RFBI_CONFIG0 */
1388 TRACEREG("RFBI_CONFIG0 = 0x%08x", value);
1389 s->rfbi.config[0] = value & 0x003f1fff;
1392 case 0x64: /* RFBI_ONOFF_TIME0 */
1393 TRACEREG("RFBI_ONOFF_TIME0 = 0x%08x", value);
1394 s->rfbi.time[0] = value & 0x3fffffff;
1396 case 0x68: /* RFBI_CYCLE_TIME0 */
1397 TRACEREG("RFBI_CYCLE_TIME0 = 0x%08x", value);
1398 s->rfbi.time[1] = value & 0x0fffffff;
1400 case 0x6c: /* RFBI_DATA_CYCLE1_0 */
1401 TRACEREG("RFBI_DATA_CYCLE1_0 = 0x%08x", value);
1402 s->rfbi.data[0] = value & 0x0f1f0f1f;
1404 case 0x70: /* RFBI_DATA_CYCLE2_0 */
1405 TRACEREG("RFBI_DATA_CYCLE2_0 = 0x%08x", value);
1406 s->rfbi.data[1] = value & 0x0f1f0f1f;
1408 case 0x74: /* RFBI_DATA_CYCLE3_0 */
1409 TRACEREG("RFBI_DATA_CYCLE3_0 = 0x%08x", value);
1410 s->rfbi.data[2] = value & 0x0f1f0f1f;
1412 case 0x78: /* RFBI_CONFIG1 */
1413 TRACEREG("RFBI_CONFIG1 = 0x%08x", value);
1414 s->rfbi.config[1] = value & 0x003f1fff;
1417 case 0x7c: /* RFBI_ONOFF_TIME1 */
1418 TRACEREG("RFBI_ONOFF_TIME1 = 0x%08x", value);
1419 s->rfbi.time[2] = value & 0x3fffffff;
1421 case 0x80: /* RFBI_CYCLE_TIME1 */
1422 TRACEREG("RFBI_CYCLE_TIME1 = 0x%08x", value);
1423 s->rfbi.time[3] = value & 0x0fffffff;
1425 case 0x84: /* RFBI_DATA_CYCLE1_1 */
1426 TRACEREG("RFBI_DATA_CYCLE1_1 = 0x%08x", value);
1427 s->rfbi.data[3] = value & 0x0f1f0f1f;
1429 case 0x88: /* RFBI_DATA_CYCLE2_1 */
1430 TRACEREG("RFBI_DATA_CYCLE2_1 = 0x%08x", value);
1431 s->rfbi.data[4] = value & 0x0f1f0f1f;
1433 case 0x8c: /* RFBI_DATA_CYCLE3_1 */
1434 TRACEREG("RFBI_DATA_CYCLE3_1 = 0x%08x", value);
1435 s->rfbi.data[5] = value & 0x0f1f0f1f;
1438 case 0x90: /* RFBI_VSYNC_WIDTH */
1439 TRACEREG("RFBI_VSYNC_WIDTH = 0x%08x", value);
1440 s->rfbi.vsync = value & 0xffff;
1442 case 0x94: /* RFBI_HSYNC_WIDTH */
1443 TRACEREG("RFBI_HSYNC_WIDTH = 0x%08x", value);
1444 s->rfbi.hsync = value & 0xffff;
1448 OMAP_BAD_REGV(addr, value);
1453 static CPUReadMemoryFunc *omap_rfbi1_readfn[] = {
1454 omap_badwidth_read32,
1455 omap_badwidth_read32,
1459 static CPUWriteMemoryFunc *omap_rfbi1_writefn[] = {
1460 omap_badwidth_write32,
1461 omap_badwidth_write32,
1465 static uint32_t omap_venc_read(void *opaque, target_phys_addr_t addr)
1468 case 0x00: /* REV_ID */
1470 case 0x04: /* STATUS */
1471 case 0x08: /* F_CONTROL */
1472 case 0x10: /* VIDOUT_CTRL */
1473 case 0x14: /* SYNC_CTRL */
1474 case 0x1c: /* LLEN */
1475 case 0x20: /* FLENS */
1476 case 0x24: /* HFLTR_CTRL */
1477 case 0x28: /* CC_CARR_WSS_CARR */
1478 case 0x2c: /* C_PHASE */
1479 case 0x30: /* GAIN_U */
1480 case 0x34: /* GAIN_V */
1481 case 0x38: /* GAIN_Y */
1482 case 0x3c: /* BLACK_LEVEL */
1483 case 0x40: /* BLANK_LEVEL */
1484 case 0x44: /* X_COLOR */
1485 case 0x48: /* M_CONTROL */
1486 case 0x4c: /* BSTAMP_WSS_DATA */
1487 case 0x50: /* S_CARR */
1488 case 0x54: /* LINE21 */
1489 case 0x58: /* LN_SEL */
1490 case 0x5c: /* L21__WC_CTL */
1491 case 0x60: /* HTRIGGER_VTRIGGER */
1492 case 0x64: /* SAVID__EAVID */
1493 case 0x68: /* FLEN__FAL */
1494 case 0x6c: /* LAL__PHASE_RESET */
1495 case 0x70: /* HS_INT_START_STOP_X */
1496 case 0x74: /* HS_EXT_START_STOP_X */
1497 case 0x78: /* VS_INT_START_X */
1498 case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
1499 case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
1500 case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
1501 case 0x88: /* VS_EXT_STOP_Y */
1502 case 0x90: /* AVID_START_STOP_X */
1503 case 0x94: /* AVID_START_STOP_Y */
1504 case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
1505 case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
1506 case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
1507 case 0xb0: /* TVDETGP_INT_START_STOP_X */
1508 case 0xb4: /* TVDETGP_INT_START_STOP_Y */
1509 case 0xb8: /* GEN_CTRL */
1510 case 0xc4: /* DAC_TST__DAC_A */
1511 case 0xc8: /* DAC_B__DAC_C */
1521 static void omap_venc_write(void *opaque, target_phys_addr_t addr,
1525 case 0x00: /* REV_ID */
1526 case 0x04: /* STATUS */
1527 /* read-only, ignore */
1529 case 0x08: /* F_CONTROL */
1530 case 0x10: /* VIDOUT_CTRL */
1531 case 0x14: /* SYNC_CTRL */
1532 case 0x1c: /* LLEN */
1533 case 0x20: /* FLENS */
1534 case 0x24: /* HFLTR_CTRL */
1535 case 0x28: /* CC_CARR_WSS_CARR */
1536 case 0x2c: /* C_PHASE */
1537 case 0x30: /* GAIN_U */
1538 case 0x34: /* GAIN_V */
1539 case 0x38: /* GAIN_Y */
1540 case 0x3c: /* BLACK_LEVEL */
1541 case 0x40: /* BLANK_LEVEL */
1542 case 0x44: /* X_COLOR */
1543 case 0x48: /* M_CONTROL */
1544 case 0x4c: /* BSTAMP_WSS_DATA */
1545 case 0x50: /* S_CARR */
1546 case 0x54: /* LINE21 */
1547 case 0x58: /* LN_SEL */
1548 case 0x5c: /* L21__WC_CTL */
1549 case 0x60: /* HTRIGGER_VTRIGGER */
1550 case 0x64: /* SAVID__EAVID */
1551 case 0x68: /* FLEN__FAL */
1552 case 0x6c: /* LAL__PHASE_RESET */
1553 case 0x70: /* HS_INT_START_STOP_X */
1554 case 0x74: /* HS_EXT_START_STOP_X */
1555 case 0x78: /* VS_INT_START_X */
1556 case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
1557 case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
1558 case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
1559 case 0x88: /* VS_EXT_STOP_Y */
1560 case 0x90: /* AVID_START_STOP_X */
1561 case 0x94: /* AVID_START_STOP_Y */
1562 case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
1563 case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
1564 case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
1565 case 0xb0: /* TVDETGP_INT_START_STOP_X */
1566 case 0xb4: /* TVDETGP_INT_START_STOP_Y */
1567 case 0xb8: /* GEN_CTRL */
1568 case 0xc4: /* DAC_TST__DAC_A */
1569 case 0xc8: /* DAC_B__DAC_C */
1573 OMAP_BAD_REGV(addr, value);
1578 static CPUReadMemoryFunc *omap_venc1_readfn[] = {
1579 omap_badwidth_read32,
1580 omap_badwidth_read32,
1584 static CPUWriteMemoryFunc *omap_venc1_writefn[] = {
1585 omap_badwidth_write32,
1586 omap_badwidth_write32,
1590 static uint32_t omap_im3_read(void *opaque, target_phys_addr_t addr)
1593 case 0x0a8: /* SBIMERRLOGA */
1594 case 0x0b0: /* SBIMERRLOG */
1595 case 0x190: /* SBIMSTATE */
1596 case 0x198: /* SBTMSTATE_L */
1597 case 0x19c: /* SBTMSTATE_H */
1598 case 0x1a8: /* SBIMCONFIG_L */
1599 case 0x1ac: /* SBIMCONFIG_H */
1600 case 0x1f8: /* SBID_L */
1601 case 0x1fc: /* SBID_H */
1611 static void omap_im3_write(void *opaque, target_phys_addr_t addr,
1615 case 0x0b0: /* SBIMERRLOG */
1616 case 0x190: /* SBIMSTATE */
1617 case 0x198: /* SBTMSTATE_L */
1618 case 0x19c: /* SBTMSTATE_H */
1619 case 0x1a8: /* SBIMCONFIG_L */
1620 case 0x1ac: /* SBIMCONFIG_H */
1624 OMAP_BAD_REGV(addr, value);
1629 static CPUReadMemoryFunc *omap_im3_readfn[] = {
1630 omap_badwidth_read32,
1631 omap_badwidth_read32,
1635 static CPUWriteMemoryFunc *omap_im3_writefn[] = {
1636 omap_badwidth_write32,
1637 omap_badwidth_write32,
1641 static uint32_t omap_dsi_read(void *opaque, target_phys_addr_t addr)
1644 case 0x000: /* DSI_REVISION */
1646 case 0x014: /* DSI_SYSSTATUS */
1647 return 1; /* RESET_DONE */
1648 case 0x010: /* DSI_SYSCONFIG */
1649 case 0x018: /* DSI_IRQSTATUS */
1650 case 0x01c: /* DSI_IRQENABLE */
1651 case 0x040: /* DSI_CTRL */
1652 case 0x048: /* DSI_COMPLEXIO_CFG_1 */
1653 case 0x04c: /* DSI_COMPLEXIO_IRQ_STATUS */
1654 case 0x050: /* DSI_COMPLEXIO_IRQ_ENABLE */
1655 case 0x054: /* DSI_CLK_CTRL */
1656 case 0x058: /* DSI_TIMING1 */
1657 case 0x05c: /* DSI_TIMING2 */
1658 case 0x060: /* DSI_VM_TIMING1 */
1659 case 0x064: /* DSI_VM_TIMING2 */
1660 case 0x068: /* DSI_VM_TIMING3 */
1661 case 0x06c: /* DSI_CLK_TIMING */
1662 case 0x070: /* DSI_TX_FIFO_VC_SIZE */
1663 case 0x074: /* DSI_RX_FIFO_VC_SIZE */
1664 case 0x078: /* DSI_COMPLEXIO_CFG_2 */
1665 case 0x07c: /* DSI_RX_FIFO_VC_FULLNESS */
1666 case 0x080: /* DSI_VM_TIMING4 */
1667 case 0x084: /* DSI_TX_FIFO_VC_EMPTINESS */
1668 case 0x088: /* DSI_VM_TIMING5 */
1669 case 0x08c: /* DSI_VM_TIMING6 */
1670 case 0x090: /* DSI_VM_TIMING7 */
1671 case 0x094: /* DSI_STOPCLK_TIMING */
1672 case 0x100: /* DSI_VC0_CTRL */
1673 case 0x104: /* DSI_VC0_TE */
1674 case 0x108: /* DSI_VC0_LONG_PACKET_HEADER */
1675 case 0x10c: /* DSI_VC0_LONG_PACKET_PAYLOAD */
1676 case 0x110: /* DSI_VC0_SHORT_PACKET_HEADER */
1677 case 0x118: /* DSI_VC0_IRQSTATUS */
1678 case 0x11c: /* DSI_VC0_IRQENABLE */
1679 case 0x120: /* DSI_VC1_CTRL */
1680 case 0x124: /* DSI_VC1_TE */
1681 case 0x128: /* DSI_VC1_LONG_PACKET_HEADER */
1682 case 0x12c: /* DSI_VC1_LONG_PACKET_PAYLOAD */
1683 case 0x130: /* DSI_VC1_SHORT_PACKET_HEADER */
1684 case 0x138: /* DSI_VC1_IRQSTATUS */
1685 case 0x13c: /* DSI_VC1_IRQENABLE */
1686 case 0x140: /* DSI_VC2_CTRL */
1687 case 0x144: /* DSI_VC2_TE */
1688 case 0x148: /* DSI_VC2_LONG_PACKET_HEADER */
1689 case 0x14c: /* DSI_VC2_LONG_PACKET_PAYLOAD */
1690 case 0x150: /* DSI_VC2_SHORT_PACKET_HEADER */
1691 case 0x158: /* DSI_VC2_IRQSTATUS */
1692 case 0x15c: /* DSI_VC2_IRQENABLE */
1693 case 0x160: /* DSI_VC3_CTRL */
1694 case 0x164: /* DSI_VC3_TE */
1695 case 0x168: /* DSI_VC3_LONG_PACKET_HEADER */
1696 case 0x16c: /* DSI_VC3_LONG_PACKET_PAYLOAD */
1697 case 0x170: /* DSI_VC3_SHORT_PACKET_HEADER */
1698 case 0x178: /* DSI_VC3_IRQSTATUS */
1699 case 0x17c: /* DSI_VC3_IRQENABLE */
1701 case 0x200: /* DSI_PHY_CFG0 */
1702 case 0x204: /* DSI_PHY_CFG1 */
1703 case 0x208: /* DSI_PHY_CFG2 */
1704 case 0x214: /* DSI_PHY_CFG5 */
1706 case 0x300: /* DSI_PLL_CONTROL */
1707 case 0x304: /* DSI_PLL_STATUS */
1708 case 0x308: /* DSI_PLL_GO */
1709 case 0x30c: /* DSI_PLL_CONFIGURATION1 */
1710 case 0x310: /* DSI_PLL_CONFIGURATION2 */
1713 "%s: DSI register " OMAP_FMT_plx " not implemented!\n",
1714 __FUNCTION__, addr);
1724 static void omap_dsi_write(void *opaque, target_phys_addr_t addr,
1728 case 0x000: /* DSI_REVISION */
1729 case 0x014: /* DSI_SYSSTATUS */
1730 case 0x07c: /* DSI_RX_FIFO_VC_FULLNESS */
1731 case 0x084: /* DSI_RX_FIFO_VC_EMPTINESS */
1732 case 0x214: /* DSI_PHY_CFG5 */
1733 case 0x304: /* DSI_PLL_STATUS */
1734 /* read-only, ignore */
1736 case 0x010: /* DSI_SYSCONFIG */
1737 case 0x018: /* DSI_IRQSTATUS */
1738 case 0x01c: /* DSI_IRQENABLE */
1739 case 0x040: /* DSI_CTRL */
1740 case 0x048: /* DSI_COMPLEXIO_CFG_1 */
1741 case 0x04c: /* DSI_COMPLEXIO_IRQ_STATUS */
1742 case 0x050: /* DSI_COMPLEXIO_IRQ_ENABLE */
1743 case 0x054: /* DSI_CLK_CTRL */
1744 case 0x058: /* DSI_TIMING1 */
1745 case 0x05c: /* DSI_TIMING2 */
1746 case 0x060: /* DSI_VM_TIMING1 */
1747 case 0x064: /* DSI_VM_TIMING2 */
1748 case 0x068: /* DSI_VM_TIMING3 */
1749 case 0x06c: /* DSI_CLK_TIMING */
1750 case 0x070: /* DSI_TX_FIFO_VC_SIZE */
1751 case 0x074: /* DSI_RX_FIFO_VC_SIZE */
1752 case 0x078: /* DSI_COMPLEXIO_CFG_2 */
1753 case 0x080: /* DSI_VM_TIMING4 */
1754 case 0x088: /* DSI_VM_TIMING5 */
1755 case 0x08c: /* DSI_VM_TIMING6 */
1756 case 0x090: /* DSI_VM_TIMING7 */
1757 case 0x094: /* DSI_STOPCLK_TIMING */
1758 case 0x100: /* DSI_VC0_CTRL */
1759 case 0x104: /* DSI_VC0_TE */
1760 case 0x108: /* DSI_VC0_LONG_PACKET_HEADER */
1761 case 0x10c: /* DSI_VC0_LONG_PACKET_PAYLOAD */
1762 case 0x110: /* DSI_VC0_SHORT_PACKET_HEADER */
1763 case 0x118: /* DSI_VC0_IRQSTATUS */
1764 case 0x11c: /* DSI_VC0_IRQENABLE */
1765 case 0x120: /* DSI_VC1_CTRL */
1766 case 0x124: /* DSI_VC1_TE */
1767 case 0x128: /* DSI_VC1_LONG_PACKET_HEADER */
1768 case 0x12c: /* DSI_VC1_LONG_PACKET_PAYLOAD */
1769 case 0x130: /* DSI_VC1_SHORT_PACKET_HEADER */
1770 case 0x138: /* DSI_VC1_IRQSTATUS */
1771 case 0x13c: /* DSI_VC1_IRQENABLE */
1772 case 0x140: /* DSI_VC2_CTRL */
1773 case 0x144: /* DSI_VC2_TE */
1774 case 0x148: /* DSI_VC2_LONG_PACKET_HEADER */
1775 case 0x14c: /* DSI_VC2_LONG_PACKET_PAYLOAD */
1776 case 0x150: /* DSI_VC2_SHORT_PACKET_HEADER */
1777 case 0x158: /* DSI_VC2_IRQSTATUS */
1778 case 0x15c: /* DSI_VC2_IRQENABLE */
1779 case 0x160: /* DSI_VC3_CTRL */
1780 case 0x164: /* DSI_VC3_TE */
1781 case 0x168: /* DSI_VC3_LONG_PACKET_HEADER */
1782 case 0x16c: /* DSI_VC3_LONG_PACKET_PAYLOAD */
1783 case 0x170: /* DSI_VC3_SHORT_PACKET_HEADER */
1784 case 0x178: /* DSI_VC3_IRQSTATUS */
1785 case 0x17c: /* DSI_VC3_IRQENABLE */
1787 case 0x200: /* DSI_PHY_CFG0 */
1788 case 0x204: /* DSI_PHY_CFG1 */
1789 case 0x208: /* DSI_PHY_CFG2 */
1791 case 0x300: /* DSI_PLL_CONTROL */
1792 case 0x308: /* DSI_PLL_GO */
1793 case 0x30c: /* DSI_PLL_CONFIGURATION1 */
1794 case 0x310: /* DSI_PLL_CONFIGURATION2 */
1797 "%s: DSI register " OMAP_FMT_plx " not implemented!\n",
1798 __FUNCTION__, addr);
1802 OMAP_BAD_REGV(addr, value);
1807 static CPUReadMemoryFunc *omap_dsi_readfn[] = {
1808 omap_badwidth_read32,
1809 omap_badwidth_read32,
1813 static CPUWriteMemoryFunc *omap_dsi_writefn[] = {
1814 omap_badwidth_write32,
1815 omap_badwidth_write32,
1819 struct omap_dss_s *omap_dss_init(struct omap_mpu_state_s *mpu,
1820 struct omap_target_agent_s *ta,
1821 qemu_irq irq, qemu_irq drq,
1822 omap_clk fck1, omap_clk fck2, omap_clk ck54m,
1823 omap_clk ick1, omap_clk ick2)
1826 int region_base = 0;
1827 struct omap_dss_s *s = (struct omap_dss_s *)
1828 qemu_mallocz(sizeof(struct omap_dss_s));
1833 iomemtype[0] = l4_register_io_memory(0, omap_diss1_readfn,
1834 omap_diss1_writefn, s);
1835 iomemtype[1] = l4_register_io_memory(0, omap_disc1_readfn,
1836 omap_disc1_writefn, s);
1837 iomemtype[2] = l4_register_io_memory(0, omap_rfbi1_readfn,
1838 omap_rfbi1_writefn, s);
1839 iomemtype[3] = l4_register_io_memory(0, omap_venc1_readfn,
1840 omap_venc1_writefn, s);
1842 if (cpu_class_omap3(mpu)) {
1843 s->dispc.rev = 0x30;
1845 iomemtype[4] = l4_register_io_memory(0, omap_dsi_readfn,
1846 omap_dsi_writefn, s);
1847 omap_l4_attach(ta, 0, iomemtype[4]);
1850 s->dispc.rev = 0x20;
1852 iomemtype[4] = cpu_register_io_memory(0, omap_im3_readfn,
1853 omap_im3_writefn, s);
1854 cpu_register_physical_memory(0x68000800, 0x1000, iomemtype[4]);
1857 omap_l4_attach(ta, region_base+0, iomemtype[0]); /* DISS */
1858 omap_l4_attach(ta, region_base+1, iomemtype[1]); /* DISC */
1859 omap_l4_attach(ta, region_base+2, iomemtype[2]); /* RFBI */
1860 omap_l4_attach(ta, region_base+3, iomemtype[3]); /* VENC */
1865 s->state = graphic_console_init(omap_update_display,
1866 omap_invalidate_display, omap_screen_dump, s);
1869 register_savevm("omap_dss", -1, 0,
1870 omap_dss_save_state, omap_dss_load_state, s);
1875 void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
1877 if (cs < 0 || cs > 1)
1878 cpu_abort(cpu_single_env, "%s: wrong CS %i\n", __FUNCTION__, cs);
1879 s->rfbi.chip[cs] = chip;
1882 void omap3_lcd_panel_attach(struct omap_dss_s *dss,
1884 struct omap3_lcd_panel_s *lcd_panel)
1886 if (cs < 0 || cs > 1)
1887 cpu_abort(cpu_single_env, "%s: wrong CS %i\n", __FUNCTION__, cs);
1888 dss->omap_lcd_panel[cs] = lcd_panel;
1889 lcd_panel->dss = dss;
1892 /*omap3 lcd panel stuff*/
1894 /* Bytes(!) per pixel */
1895 static const int omap3_lcd_panel_bpp[0x10] = {
1896 0, /* 0x0: BITMAP1 (CLUT) */
1897 0, /* 0x1: BITMAP2 (CLUT) */
1898 0, /* 0x2: BITMAP4 (CLUT) */
1899 0, /* 0x3: BITMAP8 (CLUT) */
1900 2, /* 0x4: RGB12 (unpacked 16-bit container)*/
1901 2, /* 0x5: ARGB16 */
1903 0, /* 0x7: reserved */
1904 4, /* 0x8: RGB24 (unpacked in 32-bit container) */
1905 3, /* 0x9: RGB24 (packed in 24-bit container) */
1906 2, /* 0xa: YUV2 422 */
1907 2, /* 0xb: UYVY 422 */
1908 4, /* 0xc: ARGB32 */
1909 4, /* 0xd: RGBA32 */
1910 4, /* 0xe: RGBx32 (24-bit RGB aligned on MSB of the 32-bit container) */
1911 0, /* 0xf: reserved */
1914 static inline void omap3_lcd_panel_invalidate_display(void *opaque)
1916 struct omap3_lcd_panel_s *s = (struct omap3_lcd_panel_s *)opaque;
1920 static void omap3_lcd_panel_update_display(void *opaque)
1922 struct omap3_lcd_panel_s *s = (struct omap3_lcd_panel_s *)opaque;
1923 struct omap_dss_s *dss = s->dss;
1924 const uint32_t lcd_width = dss->lcd.nx;
1925 const uint32_t lcd_height = dss->lcd.ny;
1926 uint32_t graphic_width, graphic_height;
1927 uint32_t start_x, start_y;
1928 const uint32_t lcd_Bpp = omap3_lcd_panel_bpp[dss->dispc.l[0].gfx_format];
1930 uint32_t linesize, y;
1931 uint32_t copy_width, copy_height;
1932 uint8_t *src, *dest;
1934 if (!dss->lcd.enable
1935 || dss->dispc.l[0].gfx_channel /* 24bit digital out */
1936 || ((dss->dispc.control & (1 << 11))) /* RFBI */
1940 /* check for setup changes since last visit only if flagged */
1941 if (dss->dispc.invalidate) {
1942 dss->dispc.invalidate = 0;
1943 if (!(dss->dispc.l[0].rotation_flag)) { /* rotation*/
1944 s->line_fn = s->line_fn_tab[0][dss->dispc.l[0].gfx_format];
1946 fprintf(stderr, "%s: rotation is not supported \n", __FUNCTION__);
1951 "%s: line_fn is NULL - unsupported gfx_format (%d)\n",
1952 __FUNCTION__, dss->dispc.l[0].gfx_format);
1955 if (lcd_width != ds_get_width(s->state)
1956 || lcd_height != ds_get_height(s->state)) {
1957 qemu_console_resize(s->state, lcd_width, lcd_height);
1963 graphic_width = dss->dispc.l[0].nx;
1964 graphic_height = dss->dispc.l[0].ny;
1965 start_x = dss->dispc.l[0].posx;
1966 start_y = dss->dispc.l[0].posy;
1968 /*use the rfbi function*/
1969 src = (uint8_t *)omap_rfbi_get_buffer(dss);
1970 dest = ds_get_data(s->state);
1971 linesize = ds_get_linesize(s->state);
1973 dss_Bpp = linesize / ds_get_width(s->state);
1975 dest += linesize * start_y;
1976 dest += start_x * dss_Bpp;
1978 if ((start_x + graphic_width) > lcd_width)
1979 copy_width = lcd_width - start_x;
1981 copy_width = graphic_width;
1982 copy_height = lcd_height>graphic_height ? graphic_height:lcd_height;
1984 for (y = start_y; y < copy_height; y++) {
1985 s->line_fn(dest, src, copy_width * lcd_Bpp);
1986 src += graphic_width * lcd_Bpp;
1990 dpy_update(s->state, start_x, start_y, graphic_width, graphic_height);
1993 dss->dispc.irqst |= 1; /* FRAMEDONE */
1994 omap_dss_interrupt_update(dss);
1999 #include "omap3_lcd_panel_template.h"
2001 #include "omap3_lcd_panel_template.h"
2003 #include "omap3_lcd_panel_template.h"
2005 #include "omap3_lcd_panel_template.h"
2007 #include "omap3_lcd_panel_template.h"
2009 void *omap3_lcd_panel_init()
2011 struct omap3_lcd_panel_s *s = (struct omap3_lcd_panel_s *) qemu_mallocz(sizeof(*s));
2013 s->state = graphic_console_init(omap3_lcd_panel_update_display,
2014 omap3_lcd_panel_invalidate_display,
2017 switch (ds_get_bits_per_pixel(s->state)) {
2019 s->line_fn_tab[0] = s->line_fn_tab[1] =
2020 qemu_mallocz(sizeof(omap3_lcd_panel_fn_t) * 0x10);
2023 s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_8;
2024 s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_8;
2027 s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_15;
2028 s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_15;
2031 s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_16;
2032 s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_16;
2035 s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_24;
2036 s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_24;
2039 s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_32;
2040 s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_32;
2043 fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);