2 * OMAP2/3 Display Subsystem.
4 * Copyright (C) 2008,2009 Nokia Corporation
5 * OMAP2 support 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_DISPC
32 //#define OMAP_DSS_DEBUG_DISS
33 //#define OMAP_DSS_DEBUG_DSI
34 //#define OMAP_DSS_DEBUG_RFBI
35 //#define OMAP_DSS_DEBUG_VENC
38 #define TRACE(fmt,...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__)
39 #define LAYERNAME(n) ((!(n)) ? "GFX" : ((n)==1) ? "VID1" : "VID2")
40 #ifdef OMAP_DSS_DEBUG_DISPC
41 #define TRACEDISPC(fmt,...) TRACE(fmt, ##__VA_ARGS__)
43 #define TRACEDISPC(...)
45 #ifdef OMAP_DSS_DEBUG_DISS
46 #define TRACEDISS(fmt,...) TRACE(fmt, ##__VA_ARGS__)
48 #define TRACEDISS(...)
50 #ifdef OMAP_DSS_DEBUG_DSI
51 #define TRACEDSI(fmt,...) TRACE(fmt, ##__VA_ARGS__)
55 #ifdef OMAP_DSS_DEBUG_RFBI
56 #define TRACERFBI(fmt,...) TRACE(fmt, ##__VA_ARGS__)
58 #define TRACERFBI(...)
60 #ifdef OMAP_DSS_DEBUG_VENC
61 #define TRACEVENC(fmt,...) TRACE(fmt, ##__VA_ARGS__)
63 #define TRACEVENC(...)
67 #define TRACEDISPC(...)
68 #define TRACEDISS(...)
70 #define TRACERFBI(...)
71 #define TRACEVENC(...)
74 struct omap3_lcd_panel_s {
75 struct omap_dss_s *dss;
77 omap3_lcd_panel_fn_t line_fn;
91 struct omap_dss_panel_s {
99 struct omap3_lcd_panel_s *omap_lcd_panel[2];
113 uint32_t global_alpha;
118 struct omap_dss_plane_s {
130 target_phys_addr_t addr[3];
140 /* following for l1 & l2 only (VID1 and VID2) */
142 uint32_t fir_coef_h[8];
143 uint32_t fir_coef_hv[8];
144 uint32_t fir_coef_v[8];
145 uint32_t conv_coef[5];
146 uint32_t picture_size;
151 uint16_t palette[256];
167 struct rfbi_chip_s *chip[2];
171 /* protocol engine registers */
176 uint32_t complexio_cfg1;
177 uint32_t complexio_irqst;
178 uint32_t complexio_irqen;
186 uint32_t tx_fifo_vc_size;
187 uint32_t rx_fifo_vc_size;
201 /* pll controller registers */
202 uint32_t pll_control;
204 uint32_t pll_config1;
205 uint32_t pll_config2;
209 static void omap_dss_interrupt_update(struct omap_dss_s *s)
212 (s->dsi.irqst & s->dsi.irqen)
213 | (s->dsi.complexio_irqst & s->dsi.complexio_irqen)
214 | (s->dsi.vc[0].irqst & s->dsi.vc[0].irqen)
215 | (s->dsi.vc[1].irqst & s->dsi.vc[1].irqen)
216 | (s->dsi.vc[2].irqst & s->dsi.vc[2].irqen)
217 | (s->dsi.vc[3].irqst & s->dsi.vc[3].irqen)
218 | (s->dispc.irqst & s->dispc.irqen));
221 static void omap_dss_save_state(QEMUFile *f, void *opaque)
223 struct omap_dss_s *s = (struct omap_dss_s *)opaque;
226 qemu_put_sbe32(f, s->autoidle);
227 qemu_put_sbe32(f, s->control);
228 qemu_put_be32(f, s->sdi_control);
229 qemu_put_be32(f, s->pll_control);
230 qemu_put_sbe32(f, s->enable);
231 qemu_put_sbe32(f, s->dig.enable);
232 qemu_put_sbe32(f, s->dig.nx);
233 qemu_put_sbe32(f, s->dig.ny);
234 qemu_put_sbe32(f, s->dig.x);
235 qemu_put_sbe32(f, s->dig.y);
236 qemu_put_sbe32(f, s->lcd.enable);
237 qemu_put_sbe32(f, s->lcd.nx);
238 qemu_put_sbe32(f, s->lcd.ny);
239 qemu_put_sbe32(f, s->lcd.x);
240 qemu_put_sbe32(f, s->lcd.y);
241 qemu_put_be32(f, s->dispc.idlemode);
242 qemu_put_be32(f, s->dispc.irqst);
243 qemu_put_be32(f, s->dispc.irqen);
244 qemu_put_be32(f, s->dispc.control);
245 qemu_put_be32(f, s->dispc.config);
246 qemu_put_be32(f, s->dispc.capable);
247 qemu_put_be32(f, s->dispc.timing[0]);
248 qemu_put_be32(f, s->dispc.timing[1]);
249 qemu_put_be32(f, s->dispc.timing[2]);
250 qemu_put_be32(f, s->dispc.timing[3]);
251 qemu_put_sbe32(f, s->dispc.line);
252 qemu_put_be32(f, s->dispc.bg[0]);
253 qemu_put_be32(f, s->dispc.bg[1]);
254 qemu_put_be32(f, s->dispc.trans[0]);
255 qemu_put_be32(f, s->dispc.trans[1]);
256 qemu_put_be32(f, s->dispc.global_alpha);
257 qemu_put_be32(f, s->dispc.cpr_coef_r);
258 qemu_put_be32(f, s->dispc.cpr_coef_g);
259 qemu_put_be32(f, s->dispc.cpr_coef_b);
260 for (i = 0; i < 3; i++) {
261 qemu_put_sbe32(f, s->dispc.l[i].enable);
262 qemu_put_sbe32(f, s->dispc.l[i].bpp);
263 qemu_put_sbe32(f, s->dispc.l[i].posx);
264 qemu_put_sbe32(f, s->dispc.l[i].posy);
265 qemu_put_sbe32(f, s->dispc.l[i].nx);
266 qemu_put_sbe32(f, s->dispc.l[i].ny);
267 qemu_put_sbe32(f, s->dispc.l[i].rotation_flag);
268 qemu_put_sbe32(f, s->dispc.l[i].gfx_format);
269 qemu_put_sbe32(f, s->dispc.l[i].gfx_channel);
270 for (j = 0; j < 3; j++) {
271 #if TARGET_PHYS_ADDR_BITS == 32
272 qemu_put_be32(f, s->dispc.l[i].addr[j]);
273 #elif TARGET_PHYS_ADDR_BITS == 64
274 qemu_put_be64(f, s->dispc.l[i].addr[j]);
276 #error TARGET_PHYS_ADDR_BITS undefined
279 qemu_put_be32(f, s->dispc.l[i].attr);
280 qemu_put_be32(f, s->dispc.l[i].tresh);
281 qemu_put_sbe32(f, s->dispc.l[i].rowinc);
282 qemu_put_sbe32(f, s->dispc.l[i].colinc);
283 qemu_put_sbe32(f, s->dispc.l[i].wininc);
284 qemu_put_be32(f, s->dispc.l[i].preload);
285 qemu_put_be32(f, s->dispc.l[i].fir);
286 for (j = 0; j < 8; j++) {
287 qemu_put_be32(f, s->dispc.l[i].fir_coef_h[j]);
288 qemu_put_be32(f, s->dispc.l[i].fir_coef_hv[j]);
289 qemu_put_be32(f, s->dispc.l[i].fir_coef_v[j]);
291 qemu_put_be32(f, s->dispc.l[i].conv_coef[j]);
293 qemu_put_be32(f, s->dispc.l[i].picture_size);
294 qemu_put_be32(f, s->dispc.l[i].accu[0]);
295 qemu_put_be32(f, s->dispc.l[i].accu[1]);
297 qemu_put_sbe32(f, s->dispc.invalidate);
298 for (i = 0; i < 256; i++)
299 qemu_put_be16(f, s->dispc.palette[i]);
300 qemu_put_sbe32(f, s->rfbi.idlemode);
301 qemu_put_be32(f, s->rfbi.control);
302 qemu_put_sbe32(f, s->rfbi.enable);
303 qemu_put_sbe32(f, s->rfbi.pixels);
304 qemu_put_sbe32(f, s->rfbi.busy);
305 qemu_put_sbe32(f, s->rfbi.skiplines);
306 qemu_put_be16(f, s->rfbi.rxbuf);
307 for (i = 0; i < 6; i++) {
309 qemu_put_be32(f, s->rfbi.config[i]);
311 qemu_put_be32(f, s->rfbi.time[i]);
312 qemu_put_be32(f, s->rfbi.data[i]);
314 qemu_put_be16(f, s->rfbi.vsync);
315 qemu_put_be16(f, s->rfbi.hsync);
316 qemu_put_be32(f, s->dsi.sysconfig);
317 qemu_put_be32(f, s->dsi.irqst);
318 qemu_put_be32(f, s->dsi.irqen);
319 qemu_put_be32(f, s->dsi.ctrl);
320 qemu_put_be32(f, s->dsi.complexio_cfg1);
321 qemu_put_be32(f, s->dsi.complexio_irqst);
322 qemu_put_be32(f, s->dsi.complexio_irqen);
323 qemu_put_be32(f, s->dsi.clk_ctrl);
324 qemu_put_be32(f, s->dsi.timing1);
325 qemu_put_be32(f, s->dsi.timing2);
326 qemu_put_be32(f, s->dsi.vm_timing1);
327 qemu_put_be32(f, s->dsi.vm_timing2);
328 qemu_put_be32(f, s->dsi.vm_timing3);
329 qemu_put_be32(f, s->dsi.clk_timing);
330 qemu_put_be32(f, s->dsi.tx_fifo_vc_size);
331 qemu_put_be32(f, s->dsi.rx_fifo_vc_size);
332 for (i = 0; i < 4; i++) {
333 qemu_put_be32(f, s->dsi.vc[i].ctrl);
334 qemu_put_be32(f, s->dsi.vc[i].te);
335 qemu_put_be32(f, s->dsi.vc[i].lp_header);
336 qemu_put_be32(f, s->dsi.vc[i].lp_payload);
337 qemu_put_be32(f, s->dsi.vc[i].sp_header);
338 qemu_put_be32(f, s->dsi.vc[i].irqst);
339 qemu_put_be32(f, s->dsi.vc[i].irqen);
341 qemu_put_be32(f, s->dsi.phy_cfg0);
342 qemu_put_be32(f, s->dsi.phy_cfg1);
343 qemu_put_be32(f, s->dsi.phy_cfg2);
344 qemu_put_be32(f, s->dsi.pll_control);
345 qemu_put_be32(f, s->dsi.pll_go);
346 qemu_put_be32(f, s->dsi.pll_config1);
347 qemu_put_be32(f, s->dsi.pll_config2);
350 static int omap_dss_load_state(QEMUFile *f, void *opaque, int version_id)
352 struct omap_dss_s *s = (struct omap_dss_s *)opaque;
358 s->autoidle = qemu_get_sbe32(f);
359 s->control = qemu_get_sbe32(f);
360 s->sdi_control = qemu_get_be32(f);
361 s->pll_control = qemu_get_be32(f);
362 s->enable = qemu_get_sbe32(f);
363 s->dig.enable = qemu_get_sbe32(f);
364 s->dig.nx = qemu_get_sbe32(f);
365 s->dig.ny = qemu_get_sbe32(f);
366 s->dig.x = qemu_get_sbe32(f);
367 s->dig.y = qemu_get_sbe32(f);
368 s->lcd.enable = qemu_get_sbe32(f);
369 s->lcd.nx = qemu_get_sbe32(f);
370 s->lcd.ny = qemu_get_sbe32(f);
371 s->lcd.x = qemu_get_sbe32(f);
372 s->lcd.y = qemu_get_sbe32(f);
373 s->dispc.idlemode = qemu_get_be32(f);
374 s->dispc.irqst = qemu_get_be32(f);
375 s->dispc.irqen = qemu_get_be32(f);
376 s->dispc.control = qemu_get_be32(f);
377 s->dispc.config = qemu_get_be32(f);
378 s->dispc.capable = qemu_get_be32(f);
379 s->dispc.timing[0] = qemu_get_be32(f);
380 s->dispc.timing[1] = qemu_get_be32(f);
381 s->dispc.timing[2] = qemu_get_be32(f);
382 s->dispc.timing[3] = qemu_get_be32(f);
383 s->dispc.line = qemu_get_sbe32(f);
384 s->dispc.bg[0] = qemu_get_be32(f);
385 s->dispc.bg[1] = qemu_get_be32(f);
386 s->dispc.trans[0] = qemu_get_be32(f);
387 s->dispc.trans[1] = qemu_get_be32(f);
388 s->dispc.global_alpha = qemu_get_be32(f);
389 s->dispc.cpr_coef_r = qemu_get_be32(f);
390 s->dispc.cpr_coef_g = qemu_get_be32(f);
391 s->dispc.cpr_coef_b = qemu_get_be32(f);
392 for (i = 0; i < 3; i++) {
393 s->dispc.l[i].enable = qemu_get_sbe32(f);
394 s->dispc.l[i].bpp = qemu_get_sbe32(f);
395 s->dispc.l[i].posx = qemu_get_sbe32(f);
396 s->dispc.l[i].posy = qemu_get_sbe32(f);
397 s->dispc.l[i].nx = qemu_get_sbe32(f);
398 s->dispc.l[i].ny = qemu_get_sbe32(f);
399 s->dispc.l[i].rotation_flag = qemu_get_sbe32(f);
400 s->dispc.l[i].gfx_format = qemu_get_sbe32(f);
401 s->dispc.l[i].gfx_channel = qemu_get_sbe32(f);
402 for (j = 0; j < 3; j++) {
403 #if TARGET_PHYS_ADDR_BITS == 32
404 s->dispc.l[i].addr[j] = qemu_get_be32(f);
405 #elif TARGET_PHYS_ADDR_BITS == 64
406 s->dispc.l[i].addr[j] = qemu_get_be64(f);
408 #error TARGET_PHYS_ADDR_BITS undefined
411 s->dispc.l[i].attr = qemu_get_be32(f);
412 s->dispc.l[i].tresh = qemu_get_be32(f);
413 s->dispc.l[i].rowinc = qemu_get_sbe32(f);
414 s->dispc.l[i].colinc = qemu_get_sbe32(f);
415 s->dispc.l[i].wininc = qemu_get_sbe32(f);
416 s->dispc.l[i].preload = qemu_get_be32(f);
417 s->dispc.l[i].fir = qemu_get_be32(f);
418 for (j = 0; j < 8; j++) {
419 s->dispc.l[i].fir_coef_h[j] = qemu_get_be32(f);
420 s->dispc.l[i].fir_coef_hv[j] = qemu_get_be32(f);
421 s->dispc.l[i].fir_coef_v[j] = qemu_get_be32(f);
423 s->dispc.l[i].conv_coef[j] = qemu_get_be32(f);
425 s->dispc.l[i].picture_size = qemu_get_be32(f);
426 s->dispc.l[i].accu[0] = qemu_get_be32(f);
427 s->dispc.l[i].accu[1] = qemu_get_be32(f);
429 s->dispc.invalidate = qemu_get_sbe32(f);
430 for (i = 0; i < 256; i++)
431 s->dispc.palette[i] = qemu_get_be16(f);
432 s->rfbi.idlemode = qemu_get_sbe32(f);
433 s->rfbi.control = qemu_get_be32(f);
434 s->rfbi.enable = qemu_get_sbe32(f);
435 s->rfbi.pixels = qemu_get_sbe32(f);
436 s->rfbi.busy = qemu_get_sbe32(f);
437 s->rfbi.skiplines = qemu_get_sbe32(f);
438 s->rfbi.rxbuf = qemu_get_be16(f);
439 for (i = 0; i < 6; i++) {
441 s->rfbi.config[i] = qemu_get_be32(f);
443 s->rfbi.time[i] = qemu_get_be32(f);
444 s->rfbi.data[i] = qemu_get_be32(f);
446 s->rfbi.vsync = qemu_get_be16(f);
447 s->rfbi.hsync = qemu_get_be16(f);
448 s->dsi.sysconfig = qemu_get_be32(f);
449 s->dsi.irqst = qemu_get_be32(f);
450 s->dsi.irqen = qemu_get_be32(f);
451 s->dsi.ctrl = qemu_get_be32(f);
452 s->dsi.complexio_cfg1 = qemu_get_be32(f);
453 s->dsi.complexio_irqst = qemu_get_be32(f);
454 s->dsi.complexio_irqen = qemu_get_be32(f);
455 s->dsi.clk_ctrl = qemu_get_be32(f);
456 s->dsi.timing1 = qemu_get_be32(f);
457 s->dsi.timing2 = qemu_get_be32(f);
458 s->dsi.vm_timing1 = qemu_get_be32(f);
459 s->dsi.vm_timing2 = qemu_get_be32(f);
460 s->dsi.vm_timing3 = qemu_get_be32(f);
461 s->dsi.clk_timing = qemu_get_be32(f);
462 s->dsi.tx_fifo_vc_size = qemu_get_be32(f);
463 s->dsi.rx_fifo_vc_size = qemu_get_be32(f);
464 for (i = 0; i < 4; i++) {
465 s->dsi.vc[i].ctrl = qemu_get_be32(f);
466 s->dsi.vc[i].te = qemu_get_be32(f);
467 s->dsi.vc[i].lp_header = qemu_get_be32(f);
468 s->dsi.vc[i].lp_payload = qemu_get_be32(f);
469 s->dsi.vc[i].sp_header = qemu_get_be32(f);
470 s->dsi.vc[i].irqst = qemu_get_be32(f);
471 s->dsi.vc[i].irqen = qemu_get_be32(f);
473 s->dsi.phy_cfg0 = qemu_get_be32(f);
474 s->dsi.phy_cfg1 = qemu_get_be32(f);
475 s->dsi.phy_cfg2 = qemu_get_be32(f);
476 s->dsi.pll_control = qemu_get_be32(f);
477 s->dsi.pll_go = qemu_get_be32(f);
478 s->dsi.pll_config1 = qemu_get_be32(f);
479 s->dsi.pll_config2 = qemu_get_be32(f);
481 s->dispc.invalidate = 1; /* force refresh of display parameters */
482 if (s->omap_lcd_panel[0])
483 s->omap_lcd_panel[0]->invalidate = 1;
484 if (s->omap_lcd_panel[1])
485 s->omap_lcd_panel[1]->invalidate = 1;
487 omap_dss_interrupt_update(s);
492 static void omap_dsi_reset(struct omap_dss_s *s)
494 memset(&s->dsi, 0, sizeof(s->dsi));
495 s->dsi.sysconfig = 0x11;
497 s->dsi.complexio_cfg1 = 0x20000000;
498 s->dsi.timing1 = 0x7fff7fff;
499 s->dsi.timing2 = 0x7fff7fff;
500 s->dsi.clk_timing = 0x0101;
501 s->dsi.phy_cfg0 = 0x1a3c1a28;
502 s->dsi.phy_cfg1 = 0x420a1875;
503 s->dsi.phy_cfg2 = 0xb800001b;
506 static void omap_rfbi_reset(struct omap_dss_s *s)
508 s->rfbi.idlemode = 0;
512 s->rfbi.skiplines = 0;
514 s->rfbi.config[0] = 0x00310000;
515 s->rfbi.config[1] = 0x00310000;
530 void omap_dss_reset(struct omap_dss_s *s)
534 s->autoidle = 0x10; /* was 0 for OMAP2 but bit4 must be set for OMAP3 */
548 s->dispc.idlemode = 0;
551 s->dispc.control = 0;
553 s->dispc.capable = 0x161;
554 s->dispc.timing[0] = 0;
555 s->dispc.timing[1] = 0;
556 s->dispc.timing[2] = 0;
557 s->dispc.timing[3] = 0x00010002;
561 s->dispc.trans[0] = 0;
562 s->dispc.trans[1] = 0;
563 s->dispc.global_alpha = 0;
564 s->dispc.cpr_coef_r = 0;
565 s->dispc.cpr_coef_g = 0;
566 s->dispc.cpr_coef_b = 0;
568 for (i = 0; i < 3; i++) {
569 s->dispc.l[i].enable = 0;
570 s->dispc.l[i].bpp = 0;
571 s->dispc.l[i].addr[0] = 0;
572 s->dispc.l[i].addr[1] = 0;
573 s->dispc.l[i].addr[2] = 0;
574 s->dispc.l[i].posx = 0;
575 s->dispc.l[i].posy = 0;
576 s->dispc.l[i].nx = 1;
577 s->dispc.l[i].ny = 1;
578 s->dispc.l[i].attr = 0;
579 s->dispc.l[i].tresh = (s->dispc.rev < 0x30) ? 0 : 0x03ff03c0;
580 s->dispc.l[i].rowinc = 1;
581 s->dispc.l[i].colinc = 1;
582 s->dispc.l[i].wininc = 0;
583 s->dispc.l[i].preload = 0x100;
584 s->dispc.l[i].fir = 0;
585 s->dispc.l[i].picture_size = 0;
586 s->dispc.l[i].accu[0] = 0;
587 s->dispc.l[i].accu[1] = 0;
588 for (j = 0; j < 5; j++)
589 s->dispc.l[i].conv_coef[j] = 0;
590 for (j = 0; j < 8; j++) {
591 s->dispc.l[i].fir_coef_h[j] = 0;
592 s->dispc.l[i].fir_coef_hv[j] = 0;
593 s->dispc.l[i].fir_coef_v[j] = 0;
599 omap_dss_interrupt_update(s);
602 static uint32_t omap_diss_read(void *opaque, target_phys_addr_t addr)
604 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
608 case 0x00: /* DSS_REVISIONNUMBER */
609 TRACEDISS("DSS_REVISIONNUMBER: 0x20");
612 case 0x10: /* DSS_SYSCONFIG */
613 TRACEDISS("DSS_SYSCONFIG: 0x%08x", s->autoidle);
616 case 0x14: /* DSS_SYSSTATUS */
617 TRACEDISS("DSS_SYSSTATUS: 0x1");
618 return 1; /* RESETDONE */
620 case 0x18: /* DSS_IRQSTATUS */
621 TRACEDISS("DSS_IRQSTATUS: 0x%08x",
622 ((s->dsi.irqst & s->dsi.irqen) ? 2 : 0)
623 | ((s->dispc.irqst & s->dispc.irqen) ? 1 : 0));
624 return ((s->dsi.irqst & s->dsi.irqen) ? 2 : 0)
625 | ((s->dispc.irqst & s->dispc.irqen) ? 1 : 0);
627 case 0x40: /* DSS_CONTROL */
628 TRACEDISS("DSS_CONTROL: 0x%08x", s->control);
631 case 0x44: /* DSS_SDI_CONTROL */
632 TRACEDISS("DSS_SDI_CONTROL: 0x%08x", s->sdi_control);
633 return s->sdi_control;
635 case 0x48: /* DSS_PLL_CONTROL */
636 TRACEDISS("DSS_PLL_CONTROL: 0x%08x", s->pll_control);
637 return s->pll_control;
639 case 0x50: /* DSS_PSA_LCD_REG_1 */
640 case 0x54: /* DSS_PSA_LCD_REG_2 */
641 case 0x58: /* DSS_PSA_VIDEO_REG */
642 TRACEDISS("DSS_PSA_xxx: 0");
643 /* TODO: fake some values when appropriate s->control bits are set */
646 case 0x5c: /* DSS_SDI_STATUS */
647 /* TODO: check and implement missing OMAP3 bits */
648 TRACEDISS("DSS_STATUS: 0x%08x", 1 + (s->control & 1));
649 return 1 + (s->control & 1);
658 static void omap_diss_write(void *opaque, target_phys_addr_t addr,
661 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
664 case 0x00: /* DSS_REVISIONNUMBER */
665 case 0x14: /* DSS_SYSSTATUS */
666 case 0x18: /* DSS_IRQSTATUS */
667 case 0x50: /* DSS_PSA_LCD_REG_1 */
668 case 0x54: /* DSS_PSA_LCD_REG_2 */
669 case 0x58: /* DSS_PSA_VIDEO_REG */
670 case 0x5c: /* DSS_STATUS */
672 /*OMAP_RO_REGV(addr, value);*/
675 case 0x10: /* DSS_SYSCONFIG */
676 TRACEDISS("DSS_SYSCONFIG = 0x%08x", value);
677 if (value & 2) /* SOFTRESET */
679 s->autoidle = value & 0x19; /* was 0x01 for OMAP2 */
682 case 0x40: /* DSS_CONTROL */
683 TRACEDISS("DSS_CONTROL = 0x%08x", value);
684 s->control = value & 0x3ff; /* was 0x3dd for OMAP2 */
687 case 0x44: /* DSS_SDI_CONTROL */
688 TRACEDISS("DSS_SDI_CONTROL = 0x%08x", value);
689 s->sdi_control = value & 0x000ff80f;
692 case 0x48: /* DSS_PLL_CONTROL */
693 TRACEDISS("DSS_PLL_CONTROL = 0x%08x", value);
694 s->pll_control = value;
698 OMAP_BAD_REGV(addr, value);
703 static CPUReadMemoryFunc *omap_diss1_readfn[] = {
704 omap_badwidth_read32,
705 omap_badwidth_read32,
709 static CPUWriteMemoryFunc *omap_diss1_writefn[] = {
710 omap_badwidth_write32,
711 omap_badwidth_write32,
715 static uint32_t omap_disc_read(void *opaque, target_phys_addr_t addr)
717 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
721 case 0x000: /* DISPC_REVISION */
722 TRACEDISPC("DISPC_REVISION: 0x%08x", s->dispc.rev);
724 case 0x010: /* DISPC_SYSCONFIG */
725 TRACEDISPC("DISPC_SYSCONFIG: 0x%08x", s->dispc.idlemode);
726 return s->dispc.idlemode;
727 case 0x014: /* DISPC_SYSSTATUS */
728 TRACEDISPC("DISPC_SYSSTATUS: 1");
729 return 1; /* RESETDONE */
730 case 0x018: /* DISPC_IRQSTATUS */
731 TRACEDISPC("DISPC_IRQSTATUS: 0x%08x", s->dispc.irqst);
732 return s->dispc.irqst;
733 case 0x01c: /* DISPC_IRQENABLE */
734 TRACEDISPC("DISPC_IRQENABLE: 0x%08x", s->dispc.irqen);
735 return s->dispc.irqen;
736 case 0x040: /* DISPC_CONTROL */
737 TRACEDISPC("DISPC_CONTROL: 0x%08x", s->dispc.control);
738 return s->dispc.control;
739 case 0x044: /* DISPC_CONFIG */
740 TRACEDISPC("DISPC_CONFIG: 0x%08x", s->dispc.config);
741 return s->dispc.config;
742 case 0x048: /* DISPC_CAPABLE */
743 TRACEDISPC("DISPC_CAPABLE: 0x%08x", s->dispc.capable);
744 return s->dispc.capable;
745 case 0x04c: /* DISPC_DEFAULT_COLOR0 */
746 TRACEDISPC("DISPC_DEFAULT_COLOR0: 0x%08x", s->dispc.bg[0]);
747 return s->dispc.bg[0];
748 case 0x050: /* DISPC_DEFAULT_COLOR1 */
749 TRACEDISPC("DISPC_DEFAULT_COLOR0: 0x%08x", s->dispc.bg[1]);
750 return s->dispc.bg[1];
751 case 0x054: /* DISPC_TRANS_COLOR0 */
752 TRACEDISPC("DISPC_TRANS_COLOR0: 0x%08x", s->dispc.trans[0]);
753 return s->dispc.trans[0];
754 case 0x058: /* DISPC_TRANS_COLOR1 */
755 TRACEDISPC("DISPC_TRANS_COLOR0: 0x%08x", s->dispc.trans[1]);
756 return s->dispc.trans[1];
757 case 0x05c: /* DISPC_LINE_STATUS */
758 TRACEDISPC("DISPC_LINE_STATUS: 0x7ff");
760 case 0x060: /* DISPC_LINE_NUMBER */
761 TRACEDISPC("DISPC_LINE_NUMBER: 0x%08x", s->dispc.line);
762 return s->dispc.line;
763 case 0x064: /* DISPC_TIMING_H */
764 TRACEDISPC("DISPC_TIMING_H: 0x%08x", s->dispc.timing[0]);
765 return s->dispc.timing[0];
766 case 0x068: /* DISPC_TIMING_V */
767 TRACEDISPC("DISPC_TIMING_H: 0x%08x", s->dispc.timing[1]);
768 return s->dispc.timing[1];
769 case 0x06c: /* DISPC_POL_FREQ */
770 TRACEDISPC("DISPC_POL_FREQ: 0x%08x", s->dispc.timing[2]);
771 return s->dispc.timing[2];
772 case 0x070: /* DISPC_DIVISOR */
773 TRACEDISPC("DISPC_DIVISOR: 0x%08x", s->dispc.timing[3]);
774 return s->dispc.timing[3];
775 case 0x074: /* DISPC_GLOBAL_ALPHA */
776 TRACEDISPC("DISPC_GLOBAL_ALPHA: 0x%08x", s->dispc.global_alpha);
777 return s->dispc.global_alpha;
778 case 0x078: /* DISPC_SIZE_DIG */
779 TRACEDISPC("DISPC_SIZE_DIG: 0x%08x", ((s->dig.ny - 1) << 16) | (s->dig.nx - 1));
780 return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1);
781 case 0x07c: /* DISPC_SIZE_LCD */
782 TRACEDISPC("DISPC_SIZE_LCD: 0x%08x", ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1));
783 return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1);
784 case 0x14c: /* DISPC_VID2_BA0 */
786 case 0x0bc: /* DISPC_VID1_BA0 */
788 case 0x080: /* DISPC_GFX_BA0 */
789 TRACEDISPC("DISPC_%s_BA0: " OMAP_FMT_plx, LAYERNAME(n), s->dispc.l[n].addr[0]);
790 return s->dispc.l[n].addr[0];
791 case 0x150: /* DISPC_VID2_BA1 */
793 case 0x0c0: /* DISPC_VID1_BA1 */
795 case 0x084: /* DISPC_GFX_BA1 */
796 TRACEDISPC("DISPC_%s_BA1: " OMAP_FMT_plx, LAYERNAME(n), s->dispc.l[n].addr[1]);
797 return s->dispc.l[n].addr[1];
798 case 0x154: /* DISPC_VID2_POSITION */
800 case 0x0c4: /* DISPC_VID1_POSITION */
802 case 0x088: /* DISPC_GFX_POSITION */
803 TRACEDISPC("DISPC_%s_POSITION: 0x%08x", LAYERNAME(n),
804 (s->dispc.l[n].posy << 16) | s->dispc.l[n].posx);
805 return (s->dispc.l[n].posy << 16) | s->dispc.l[n].posx;
806 case 0x158: /* DISPC_VID2_SIZE */
808 case 0x0c8: /* DISPC_VID1_SIZE */
810 case 0x08c: /* DISPC_GFX_SIZE */
811 TRACEDISPC("DISPC_%s_SIZE: 0x%08x", LAYERNAME(n),
812 ((s->dispc.l[n].ny - 1) << 16) | (s->dispc.l[n].nx - 1));
813 return ((s->dispc.l[n].ny - 1) << 16) | (s->dispc.l[n].nx - 1);
814 case 0x15c: /* DISPC_VID2_ATTRIBUTES */
816 case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
818 case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
819 TRACEDISPC("DISPC_%s_ATTRIBUTES: 0x%08x", LAYERNAME(n),
821 return s->dispc.l[n].attr;
822 case 0x160: /* DISPC_VID2_FIFO_THRESHOLD */
824 case 0x0d0: /* DISPC_VID1_FIFO_THRESHOLD */
826 case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
827 TRACEDISPC("DISPC_%s_THRESHOLD: 0x%08x", LAYERNAME(n),
828 s->dispc.l[n].tresh);
829 return s->dispc.l[n].tresh;
830 case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */
832 case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */
834 case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
835 TRACEDISPC("DISPC_%s_FIFO_SIZE_STATUS: 0x%08x", LAYERNAME(n),
836 s->dispc.rev < 0x30 ? 256 : 1024);
837 return s->dispc.rev < 0x30 ? 256 : 1024;
838 case 0x168: /* DISPC_VID2_ROW_INC */
840 case 0x0d8: /* DISPC_VID1_ROW_INC */
842 case 0x0ac: /* DISPC_GFX_ROW_INC */
843 TRACEDISPC("DISPC_%s_ROW_INC: 0x%08x", LAYERNAME(n),
844 s->dispc.l[n].rowinc);
845 return s->dispc.l[n].rowinc;
846 case 0x16c: /* DISPC_VID2_PIXEL_INC */
848 case 0x0dc: /* DISPC_VID1_PIXEL_INC */
850 case 0x0b0: /* DISPC_GFX_PIXEL_INC */
851 TRACEDISPC("DISPC_%s_PIXEL_INC: 0x%08x", LAYERNAME(n),
852 s->dispc.l[n].colinc);
853 return s->dispc.l[n].colinc;
854 case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
855 TRACEDISPC("DISPC_GFX_WINDOW_SKIP: 0x%08x", s->dispc.l[0].wininc);
856 return s->dispc.l[0].wininc;
857 case 0x0b8: /* DISPC_GFX_TABLE_BA */
858 TRACEDISPC("DISPC_GFX_TABLE_BA: " OMAP_FMT_plx, s->dispc.l[0].addr[2]);
859 return s->dispc.l[0].addr[2];
860 case 0x170: /* DISPC_VID2_FIR */
862 case 0x0e0: /* DISPC_VID1_FIR */
864 TRACEDISPC("DISPC_%s_FIR: 0x%08x", LAYERNAME(n),
866 return s->dispc.l[n].fir;
867 case 0x174: /* DISPC_VID2_PICTURE_SIZE */
869 case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
871 TRACEDISPC("DISPC_%s_PICTURE_SIZE: 0x%08x", LAYERNAME(n),
872 s->dispc.l[n].picture_size);
873 return s->dispc.l[n].picture_size;
874 case 0x178: /* DISPC_VID2_ACCU0 */
875 case 0x17c: /* DISPC_VID2_ACCU1 */
877 case 0x0e8: /* DISPC_VID1_ACCU0 */
878 case 0x0ec: /* DISPC_VID1_ACCU1 */
880 TRACEDISPC("DISPC_%s_ACCU%d: 0x%08x", LAYERNAME(n),
881 (int)((addr >> 1) & 1), s->dispc.l[n].accu[(addr >> 1 ) & 1]);
882 return s->dispc.l[n].accu[(addr >> 1) & 1];
883 case 0x180 ... 0x1bc: /* DISPC_VID2_FIR_COEF */
885 case 0x0f0 ... 0x12c: /* DISPC_VID1_FIR_COEF */
888 TRACEDISPC("DISPC_%s_FIR_COEF_HV%d: 0x%08x", LAYERNAME(n),
889 (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8),
890 s->dispc.l[n].fir_coef_hv[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8]);
891 return s->dispc.l[n].fir_coef_hv[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8];
893 TRACEDISPC("DISPC_%s_FIR_COEF_H%d: 0x%08x", LAYERNAME(n),
894 (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8),
895 s->dispc.l[n].fir_coef_h[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8]);
896 return s->dispc.l[n].fir_coef_h[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8];
897 case 0x1c0 ... 0x1d0: /* DISPC_VID2_CONV_COEFi */
899 case 0x130 ... 0x140: /* DISPC_VID1_CONV_COEFi */
901 TRACEDISPC("DISPC_%s_CONV_COEF%d: 0x%08x", LAYERNAME(n),
902 (int)((addr - ((n > 1) ? 0x1c0 : 0x130)) / 4),
903 s->dispc.l[n].conv_coef[(addr - ((n > 1) ? 0x1c0 : 0x130)) / 4]);
904 return s->dispc.l[n].conv_coef[(addr - ((n > 1) ? 0x1c0 : 0x130)) / 4];
905 case 0x1d4: /* DISPC_DATA_CYCLE1 */
906 case 0x1d8: /* DISPC_DATA_CYCLE2 */
907 case 0x1dc: /* DISPC_DATA_CYCLE3 */
908 TRACEDISPC("DISPC_DATA_CYCLE%d: 0", (int)((addr - 0x1d4) / 4));
910 case 0x200 ... 0x21c: /* DISPC_VID2_FIR_COEF_Vi */
912 case 0x1e0 ... 0x1fc: /* DISPC_VID1_FIR_COEF_Vi */
914 TRACEDISPC("DISPC_%s_FIR_COEF_V%d: 0x%08x", LAYERNAME(n),
915 (int)((addr & 0x01f) / 4),
916 s->dispc.l[n].fir_coef_v[(addr & 0x01f) / 4]);
917 return s->dispc.l[n].fir_coef_v[(addr & 0x01f) / 4];
918 case 0x220: /* DISPC_CPR_COEF_R */
919 TRACEDISPC("DISPC_CPR_COEF_R: 0x%08x", s->dispc.cpr_coef_r);
920 return s->dispc.cpr_coef_r;
921 case 0x224: /* DISPC_CPR_COEF_G */
922 TRACEDISPC("DISPC_CPR_COEF_G: 0x%08x", s->dispc.cpr_coef_g);
923 return s->dispc.cpr_coef_g;
924 case 0x228: /* DISPC_CPR_COEF_B */
925 TRACEDISPC("DISPC_CPR_COEF_B: 0x%08x", s->dispc.cpr_coef_b);
926 return s->dispc.cpr_coef_b;
927 case 0x234: /* DISPC_VID2_PRELOAD */
929 case 0x230: /* DISPC_VID1_PRELOAD */
931 case 0x22c: /* DISPC_GFX_PRELOAD */
932 TRACEDISPC("DISPC_%s_PRELOAD: 0x%08x", LAYERNAME(n),
933 s->dispc.l[n].preload);
934 return s->dispc.l[n].preload;
942 static void omap_disc_write(void *opaque, target_phys_addr_t addr,
945 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
949 case 0x000: /* DISPC_REVISION */
950 case 0x014: /* DISPC_SYSSTATUS */
951 case 0x05c: /* DISPC_LINE_STATUS */
952 case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
954 /*OMAP_RO_REGV(addr, value);*/
956 case 0x010: /* DISPC_SYSCONFIG */
957 TRACEDISPC("DISPC_SYSCONFIG = 0x%08x", value);
958 if (value & 2) /* SOFTRESET */
960 s->dispc.idlemode = value & ((s->dispc.rev < 0x30) ? 0x301b : 0x331f);
962 case 0x018: /* DISPC_IRQSTATUS */
963 TRACEDISPC("DISPC_IRQSTATUS = 0x%08x", value);
964 s->dispc.irqst &= ~value;
965 omap_dss_interrupt_update(s);
967 case 0x01c: /* DISPC_IRQENABLE */
968 TRACEDISPC("DISPC_IRQENABLE = 0x%08x", value);
969 s->dispc.irqen = value & ((s->dispc.rev < 0x30) ? 0xffff : 0x1ffff);
970 omap_dss_interrupt_update(s);
972 case 0x040: /* DISPC_CONTROL */
973 TRACEDISPC("DISPC_CONTROL = 0x%08x", value);
974 if (s->dispc.rev < 0x30)
975 s->dispc.control = value & 0x07ff9fff;
977 s->dispc.control = (value & 0xffff9bff) | (s->dispc.control & 0x6000);
978 s->dig.enable = (value >> 1) & 1;
979 s->lcd.enable = (value >> 0) & 1;
980 if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */
981 if (~((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1))
982 fprintf(stderr, "%s: Overlay Optimization when no overlay "
983 "region effectively exists leads to "
984 "unpredictable behaviour!\n", __FUNCTION__);
985 if (value & (1 << 6)) { /* GODIGITAL */
986 /* XXX: Shadowed fields are:
1002 * s->dispc.l[0].addr[0]
1003 * s->dispc.l[0].addr[1]
1004 * s->dispc.l[0].addr[2]
1005 * s->dispc.l[0].posx
1006 * s->dispc.l[0].posy
1009 * s->dispc.l[0].tresh
1010 * s->dispc.l[0].rowinc
1011 * s->dispc.l[0].colinc
1012 * s->dispc.l[0].wininc
1013 * All they need to be loaded here from their shadow registers.
1015 s->dispc.control &= ~(1 << 6); /* GODIGITAL finished */
1017 if (value & (1 << 5)) { /* GOLCD */
1018 /* XXX: Likewise for LCD here. */
1019 s->dispc.control &= ~(1 << 5); /* GOLCD finished */
1021 s->dispc.invalidate = 1;
1023 case 0x044: /* DISPC_CONFIG */
1024 TRACEDISPC("DISPC_CONFIG = 0x%08x", value);
1025 s->dispc.config = value & 0x3fff;
1027 * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded
1028 * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded
1030 s->dispc.invalidate = 1;
1032 case 0x048: /* DISPC_CAPABLE */
1033 TRACEDISPC("DISPC_CAPABLE = 0x%08x", value);
1034 s->dispc.capable = value & 0x3ff;
1036 case 0x04c: /* DISPC_DEFAULT_COLOR0 */
1037 TRACEDISPC("DISPC_DEFAULT_COLOR0 = 0x%08x", value);
1038 s->dispc.bg[0] = value & 0xffffff;
1039 s->dispc.invalidate = 1;
1041 case 0x050: /* DISPC_DEFAULT_COLOR1 */
1042 TRACEDISPC("DISPC_DEFAULT_COLOR1 = 0x%08x", value);
1043 s->dispc.bg[1] = value & 0xffffff;
1044 s->dispc.invalidate = 1;
1046 case 0x054: /* DISPC_TRANS_COLOR0 */
1047 TRACEDISPC("DISPC_TRANS_COLOR0 = 0x%08x", value);
1048 s->dispc.trans[0] = value & 0xffffff;
1049 s->dispc.invalidate = 1;
1051 case 0x058: /* DISPC_TRANS_COLOR1 */
1052 TRACEDISPC("DISPC_TRANS_COLOR1 = 0x%08x", value);
1053 s->dispc.trans[1] = value & 0xffffff;
1054 s->dispc.invalidate = 1;
1056 case 0x060: /* DISPC_LINE_NUMBER */
1057 TRACEDISPC("DISPC_LINE_NUMBER = 0x%08x", value);
1058 s->dispc.line = value & 0x7ff;
1060 case 0x064: /* DISPC_TIMING_H */
1061 TRACEDISPC("DISPC_TIMING_H = 0x%08x", value);
1062 s->dispc.timing[0] = value & 0x0ff0ff3f;
1064 case 0x068: /* DISPC_TIMING_V */
1065 TRACEDISPC("DISPC_TIMING_V = 0x%08x", value);
1066 s->dispc.timing[1] = value & 0x0ff0ff3f;
1068 case 0x06c: /* DISPC_POL_FREQ */
1069 TRACEDISPC("DISPC_POL_FREQ = 0x%08x", value);
1070 s->dispc.timing[2] = value & 0x0003ffff;
1072 case 0x070: /* DISPC_DIVISOR */
1073 TRACEDISPC("DISPC_DIVISOR = 0x%08x", value);
1074 s->dispc.timing[3] = value & 0x00ff00ff;
1076 case 0x074: /* DISPC_GLOBAL_ALPHA */
1077 TRACEDISPC("DISPC_GLOBAL_ALPHA = 0x%08x", value);
1078 s->dispc.global_alpha = value & 0x00ff00ff;
1080 case 0x078: /* DISPC_SIZE_DIG */
1081 s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
1082 s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
1083 s->dispc.invalidate = 1;
1084 TRACEDISPC("DISPC_SIZE_DIG = 0x%08x (%dx%d)", value, s->dig.nx, s->dig.ny);
1086 case 0x07c: /* DISPC_SIZE_LCD */
1087 s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
1088 s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
1089 s->dispc.invalidate = 1;
1090 TRACEDISPC("DISPC_SIZE_LCD = 0x%08x (%dx%d)", value, s->lcd.nx, s->lcd.ny);
1092 case 0x14c: /* DISPC_VID2_BA0 */
1094 case 0x0bc: /* DISPC_VID1_BA0 */
1096 case 0x080: /* DISPC_GFX_BA0 */
1097 TRACEDISPC("DISPC_%s_BA0 = 0x%08x", LAYERNAME(n), value);
1098 s->dispc.l[n].addr[0] = (target_phys_addr_t) value;
1099 s->dispc.invalidate = 1;
1101 case 0x150: /* DISPC_VID2_BA1 */
1103 case 0x0c0: /* DISPC_VID1_BA1 */
1105 case 0x084: /* DISPC_GFX_BA1 */
1106 TRACEDISPC("DISPC_%s_BA1 = 0x%08x", LAYERNAME(n), value);
1107 s->dispc.l[n].addr[1] = (target_phys_addr_t) value;
1108 s->dispc.invalidate = 1;
1110 case 0x154: /* DISPC_VID2_POSITION */
1112 case 0x0c4: /* DISPC_VID1_POSITION */
1114 case 0x088: /* DISPC_GFX_POSITION */
1115 s->dispc.l[n].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */
1116 s->dispc.l[n].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */
1117 s->dispc.invalidate = 1;
1118 TRACEDISPC("DISPC_%s_POSITION = 0x%08x (%d,%d)", LAYERNAME(n),
1119 value, s->dispc.l[n].posx, s->dispc.l[n].posy);
1121 case 0x158: /* DISPC_VID2_SIZE */
1123 case 0x0c8: /* DISPC_VID1_SIZE */
1125 case 0x08c: /* DISPC_GFX_SIZE */
1126 s->dispc.l[n].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */
1127 s->dispc.l[n].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */
1128 TRACEDISPC("DISPC_%s_SIZE = 0x%08x (%dx%d)", LAYERNAME(n),
1129 value, s->dispc.l[n].nx, s->dispc.l[n].ny);
1130 s->dispc.invalidate = 1;
1133 case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
1134 TRACEDISPC("DISPC_GFX_ATTRIBUTES = 0x%08x", value);
1135 s->dispc.l[0].attr = value & 0xffff;
1136 if (value & (3 << 9))
1137 fprintf(stderr, "%s: Big-endian pixel format not supported\n",
1139 s->dispc.l[0].enable = value & 1;
1140 s->dispc.l[0].bpp = (value >> 1) & 0xf;
1141 s->dispc.l[0].rotation_flag = (value >> 12) & 0x3;
1142 s->dispc.l[0].gfx_format = (value >> 1) & 0xf;
1143 s->dispc.l[0].gfx_channel = (value >> 8) & 0x1;
1144 s->dispc.invalidate = 1;
1146 case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
1148 case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
1150 case 0x0a4: /* DISPC_GFX_FIFO_THRESHOLD */
1151 TRACEDISPC("DISPC_%s_FIFO_THRESHOLD = 0x%08x", LAYERNAME(n), value);
1152 s->dispc.l[n].tresh = value & ((s->dispc.rev < 0x30)
1153 ? 0x01ff01ff : 0x0fff0fff);
1155 case 0x168: /* DISPC_VID2_ROW_INC */
1157 case 0x0d8: /* DISPC_VID1_ROW_INC */
1159 case 0x0ac: /* DISPC_GFX_ROW_INC */
1160 TRACEDISPC("DISPC_%s_ROW_INC = 0x%08x", LAYERNAME(n), value);
1161 s->dispc.l[n].rowinc = value;
1162 s->dispc.invalidate = 1;
1164 case 0x16c: /* DISPC_VID2_PIXEL_INC */
1166 case 0x0dc: /* DISPC_VID1_PIXEL_INC */
1168 case 0x0b0: /* DISPC_GFX_PIXEL_INC */
1169 TRACEDISPC("DISPC_%s_PIXEL_INC = 0x%08x", LAYERNAME(n), value);
1170 s->dispc.l[n].colinc = value;
1171 s->dispc.invalidate = 1;
1173 case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
1174 TRACEDISPC("DISPC_GFX_WINDOW_SKIP = 0x%08x", value);
1175 s->dispc.l[0].wininc = value;
1177 case 0x0b8: /* DISPC_GFX_TABLE_BA */
1178 TRACEDISPC("DISPC_GFX_TABLE_BA = 0x%08x", value);
1179 s->dispc.l[0].addr[2] = (target_phys_addr_t) value;
1180 s->dispc.invalidate = 1;
1182 case 0x15c: /* DISPC_VID2_ATTRIBUTES */
1184 case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
1186 TRACEDISPC("DISPC_%s_ATTRIBUTES = 0x%08x", LAYERNAME(n), value);
1187 s->dispc.l[n].attr = value & 0x1fffffff;
1189 case 0x170: /* DISPC_VID2_FIR */
1191 case 0x0e0: /* DISPC_VID1_FIR */
1193 TRACEDISPC("DISPC_%s_FIR = 0x%08x", LAYERNAME(n), value);
1194 s->dispc.l[n].fir = value & 0x1fff1fff;
1196 case 0x174: /* DISPC_VID2_PICTURE_SIZE */
1198 case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
1200 TRACEDISPC("DISPC_%s_PICTURE_SIZE = 0x%08x", LAYERNAME(n), value);
1201 s->dispc.l[n].picture_size = value & 0x07ff07ff;
1203 case 0x178: /* DISPC_VID2_ACCU0 */
1204 case 0x17c: /* DISPC_VID2_ACCU1 */
1206 case 0x0e8: /* DISPC_VID1_ACCU0 */
1207 case 0x0ec: /* DISPC_VID1_ACCU1 */
1209 TRACEDISPC("DISPC_%s_ACCU%d = 0x%08x", LAYERNAME(n),
1210 (int)((addr >> 1) & 1), value);
1211 s->dispc.l[n].accu[(addr >> 1) & 1] = value & 0x03ff03ff;
1213 case 0x180 ... 0x1bc: /* DISPC_VID2_FIR_COEF */
1215 case 0x0f0 ... 0x12c: /* DISPC_VID1_FIR_COEF */
1218 TRACEDISPC("DISPC_%s_FIR_COEF_HV%d = 0x%08x", LAYERNAME(n),
1219 (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8), value);
1220 s->dispc.l[n].fir_coef_hv[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8] = value;
1222 TRACEDISPC("DISPC_%s_FIR_COEF_H%d = 0x%08x", LAYERNAME(n),
1223 (int)((addr - ((n > 1) ? 0x180 : 0xf0)) / 8), value);
1224 s->dispc.l[n].fir_coef_h[(addr - ((n > 1) ? 0x180 : 0xf0)) / 8] = value;
1227 case 0x1c0 ... 0x1d0: /* DISPC_VID2_CONV_COEFi */
1229 case 0x130 ... 0x140: /* DISPC_VID1_CONV_COEFi */
1231 TRACEDISPC("DISPC_%s_CONV_COEF%d = 0x%08x", LAYERNAME(n),
1232 (int)((addr - ((n > 1) ? 0x1c0 : 0x130)) / 4), value);
1233 s->dispc.l[n].conv_coef[(addr - ((n > 1) ? 0x1c0 : 0x130)) / 4] = value;
1235 case 0x1d4: /* DISPC_DATA_CYCLE1 */
1236 case 0x1d8: /* DISPC_DATA_CYCLE2 */
1237 case 0x1dc: /* DISPC_DATA_CYCLE3 */
1238 TRACEDISPC("DISPC_DATA_CYCLE%d = 0x%08x (ignored)",
1239 (int)((addr - 0x1d4) / 4), value);
1241 case 0x200 ... 0x21c: /* DISPC_VID2_FIR_COEF_Vi */
1243 case 0x1e0 ... 0x1fc: /* DISPC_VID1_FIR_COEF_Vi */
1245 TRACEDISPC("DISPC_%s_FIR_COEF_V%d = 0x%08x", LAYERNAME(n),
1246 (int)((addr & 0x01f) / 4), value);
1247 s->dispc.l[n].fir_coef_v[(addr & 0x01f) / 4] = value & 0x0000ffff;
1249 case 0x220: /* DISPC_CPR_COEF_R */
1250 TRACEDISPC("DISPC_CPR_COEF_R = 0x%08x", value);
1251 s->dispc.cpr_coef_r = value & 0xffbffbff;
1253 case 0x224: /* DISPC_CPR_COEF_G */
1254 TRACEDISPC("DISPC_CPR_COEF_G = 0x%08x", value);
1255 s->dispc.cpr_coef_g = value & 0xffbffbff;
1257 case 0x228: /* DISPC_CPR_COEF_B */
1258 TRACEDISPC("DISPC_CPR_COEF_B = 0x%08x", value);
1259 s->dispc.cpr_coef_b = value & 0xffbffbff;
1261 case 0x234: /* DISPC_VID2_PRELOAD */
1263 case 0x230: /* DISPC_VID1_PRELOAD */
1265 case 0x22c: /* DISPC_GFX_PRELOAD */
1266 TRACEDISPC("DISPC_%s_PRELOAD = 0x%08x", LAYERNAME(n), value);
1267 s->dispc.l[n].preload = value & 0x0fff;
1270 OMAP_BAD_REGV(addr, value);
1275 static CPUReadMemoryFunc *omap_disc1_readfn[] = {
1276 omap_badwidth_read32,
1277 omap_badwidth_read32,
1281 static CPUWriteMemoryFunc *omap_disc1_writefn[] = {
1282 omap_badwidth_write32,
1283 omap_badwidth_write32,
1287 static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
1292 /* TODO: in non-Bypass mode we probably need to just deassert the DRQ. */
1297 static void omap_rfbi_transfer_start(struct omap_dss_s *s)
1300 target_phys_addr_t len;
1301 target_phys_addr_t data_addr;
1303 static void *bounce_buffer;
1304 static target_phys_addr_t bounce_len;
1306 if (!s->rfbi.enable || s->rfbi.busy)
1309 if (s->rfbi.control & (1 << 1)) { /* BYPASS */
1310 /* TODO: in non-Bypass mode we probably need to just assert the
1311 * DRQ and wait for DMA to write the pixels. */
1312 fprintf(stderr, "%s: Bypass mode unimplemented\n", __FUNCTION__);
1316 if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */
1318 /* TODO: check that LCD output is enabled in DISPC. */
1322 len = s->rfbi.pixels * 2;
1324 data_addr = s->dispc.l[0].addr[0];
1325 data = cpu_physical_memory_map(data_addr, &len, 0);
1326 if (data && len != s->rfbi.pixels * 2) {
1327 cpu_physical_memory_unmap(data, len, 0, 0);
1329 len = s->rfbi.pixels * 2;
1332 if (len > bounce_len) {
1333 bounce_buffer = qemu_realloc(bounce_buffer, len);
1335 data = bounce_buffer;
1336 cpu_physical_memory_read(data_addr, data, len);
1342 /* TODO: negative values */
1343 pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2;
1345 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1346 s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);
1347 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1348 s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
1350 if (data != bounce_buffer) {
1351 cpu_physical_memory_unmap(data, len, 0, len);
1354 omap_rfbi_transfer_stop(s);
1357 s->dispc.irqst |= 1; /* FRAMEDONE */
1358 omap_dss_interrupt_update(s);
1361 static uint32_t omap_rfbi_read(void *opaque, target_phys_addr_t addr)
1363 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
1366 case 0x00: /* RFBI_REVISION */
1367 TRACERFBI("RFBI_REVISION: 0x10");
1370 case 0x10: /* RFBI_SYSCONFIG */
1371 TRACERFBI("RFBI_SYSCONFIG: 0x%08x", s->rfbi.idlemode);
1372 return s->rfbi.idlemode;
1374 case 0x14: /* RFBI_SYSSTATUS */
1375 TRACERFBI("RFBI_SYSSTATUS: 0x%08x", 1 | (s->rfbi.busy << 8));
1376 return 1 | (s->rfbi.busy << 8); /* RESETDONE */
1378 case 0x40: /* RFBI_CONTROL */
1379 TRACERFBI("RFBI_CONTROL: 0x%08x", s->rfbi.control);
1380 return s->rfbi.control;
1382 case 0x44: /* RFBI_PIXELCNT */
1383 TRACERFBI("RFBI_PIXELCNT: 0x%08x", s->rfbi.pixels);
1384 return s->rfbi.pixels;
1386 case 0x48: /* RFBI_LINE_NUMBER */
1387 TRACERFBI("RFBI_LINE_NUMBER: 0x%08x", s->rfbi.skiplines);
1388 return s->rfbi.skiplines;
1390 case 0x58: /* RFBI_READ */
1391 case 0x5c: /* RFBI_STATUS */
1392 TRACERFBI("RFBI_READ/STATUS: 0x%08x", s->rfbi.rxbuf);
1393 return s->rfbi.rxbuf;
1395 case 0x60: /* RFBI_CONFIG0 */
1396 TRACERFBI("RFBI_CONFIG0: 0x%08x", s->rfbi.config[0]);
1397 return s->rfbi.config[0];
1398 case 0x64: /* RFBI_ONOFF_TIME0 */
1399 TRACERFBI("RFBI_ONOFF_TIME0: 0x%08x", s->rfbi.time[0]);
1400 return s->rfbi.time[0];
1401 case 0x68: /* RFBI_CYCLE_TIME0 */
1402 TRACERFBI("RFBI_CYCLE_TIME0: 0x%08x", s->rfbi.time[1]);
1403 return s->rfbi.time[1];
1404 case 0x6c: /* RFBI_DATA_CYCLE1_0 */
1405 TRACERFBI("RFBI_DATA_CYCLE1_0: 0x%08x", s->rfbi.data[0]);
1406 return s->rfbi.data[0];
1407 case 0x70: /* RFBI_DATA_CYCLE2_0 */
1408 TRACERFBI("RFBI_DATA_CYCLE2_0: 0x%08x", s->rfbi.data[1]);
1409 return s->rfbi.data[1];
1410 case 0x74: /* RFBI_DATA_CYCLE3_0 */
1411 TRACERFBI("RFBI_DATA_CYCLE3_0: 0x%08x", s->rfbi.data[2]);
1412 return s->rfbi.data[2];
1414 case 0x78: /* RFBI_CONFIG1 */
1415 TRACERFBI("RFBI_CONFIG1: 0x%08x", s->rfbi.config[1]);
1416 return s->rfbi.config[1];
1417 case 0x7c: /* RFBI_ONOFF_TIME1 */
1418 TRACERFBI("RFBI_ONOFF_TIME1: 0x%08x", s->rfbi.time[2]);
1419 return s->rfbi.time[2];
1420 case 0x80: /* RFBI_CYCLE_TIME1 */
1421 TRACERFBI("RFBI_CYCLE_TIME1: 0x%08x", s->rfbi.time[3]);
1422 return s->rfbi.time[3];
1423 case 0x84: /* RFBI_DATA_CYCLE1_1 */
1424 TRACERFBI("RFBI_DATA_CYCLE1_1: 0x%08x", s->rfbi.data[3]);
1425 return s->rfbi.data[3];
1426 case 0x88: /* RFBI_DATA_CYCLE2_1 */
1427 TRACERFBI("RFBI_DATA_CYCLE2_1: 0x%08x", s->rfbi.data[4]);
1428 return s->rfbi.data[4];
1429 case 0x8c: /* RFBI_DATA_CYCLE3_1 */
1430 TRACERFBI("RFBI_DATA_CYCLE3_1: 0x%08x", s->rfbi.data[5]);
1431 return s->rfbi.data[5];
1433 case 0x90: /* RFBI_VSYNC_WIDTH */
1434 TRACERFBI("RFBI_VSYNC_WIDTH: 0x%08x", s->rfbi.vsync);
1435 return s->rfbi.vsync;
1436 case 0x94: /* RFBI_HSYNC_WIDTH */
1437 TRACERFBI("RFBI_HSYNC_WIDTH: 0x%08x", s->rfbi.hsync);
1438 return s->rfbi.hsync;
1444 static void omap_rfbi_write(void *opaque, target_phys_addr_t addr,
1447 struct omap_dss_s *s = (struct omap_dss_s *) opaque;
1450 case 0x10: /* RFBI_SYSCONFIG */
1451 TRACERFBI("RFBI_SYSCONFIG = 0x%08x", value);
1452 if (value & 2) /* SOFTRESET */
1454 s->rfbi.idlemode = value & 0x19;
1457 case 0x40: /* RFBI_CONTROL */
1458 TRACERFBI("RFBI_CONTROL = 0x%08x", value);
1459 s->rfbi.control = value & 0xf;
1460 s->rfbi.enable = value & 1;
1461 if (value & (1 << 4) && /* ITE */
1462 !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc))
1463 omap_rfbi_transfer_start(s);
1466 case 0x44: /* RFBI_PIXELCNT */
1467 TRACERFBI("RFBI_PIXELCNT = 0x%08x", value);
1468 s->rfbi.pixels = value;
1471 case 0x48: /* RFBI_LINE_NUMBER */
1472 TRACERFBI("RFBI_LINE_NUMBER = 0x%08x", value);
1473 s->rfbi.skiplines = value & 0x7ff;
1476 case 0x4c: /* RFBI_CMD */
1477 TRACERFBI("RFBI_CMD = 0x%08x", value);
1478 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1479 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff);
1480 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1481 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff);
1483 case 0x50: /* RFBI_PARAM */
1484 TRACERFBI("RFBI_PARAM = 0x%08x", value);
1485 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1486 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
1487 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1488 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
1490 case 0x54: /* RFBI_DATA */
1491 TRACERFBI("RFBI_DATA = 0x%08x", value);
1492 /* TODO: take into account the format set up in s->rfbi.config[?] and
1493 * s->rfbi.data[?], but special-case the most usual scenario so that
1494 * speed doesn't suffer. */
1495 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) {
1496 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
1497 s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16);
1499 if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) {
1500 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
1501 s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16);
1503 if (!-- s->rfbi.pixels)
1504 omap_rfbi_transfer_stop(s);
1506 case 0x58: /* RFBI_READ */
1507 TRACERFBI("RFBI_READ = 0x%08x", value);
1508 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1509 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
1510 else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1511 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
1512 if (!-- s->rfbi.pixels)
1513 omap_rfbi_transfer_stop(s);
1516 case 0x5c: /* RFBI_STATUS */
1517 TRACERFBI("RFBI_STATUS = 0x%08x", value);
1518 if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
1519 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
1520 else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
1521 s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
1522 if (!-- s->rfbi.pixels)
1523 omap_rfbi_transfer_stop(s);
1526 case 0x60: /* RFBI_CONFIG0 */
1527 TRACERFBI("RFBI_CONFIG0 = 0x%08x", value);
1528 s->rfbi.config[0] = value & 0x003f1fff;
1531 case 0x64: /* RFBI_ONOFF_TIME0 */
1532 TRACERFBI("RFBI_ONOFF_TIME0 = 0x%08x", value);
1533 s->rfbi.time[0] = value & 0x3fffffff;
1535 case 0x68: /* RFBI_CYCLE_TIME0 */
1536 TRACERFBI("RFBI_CYCLE_TIME0 = 0x%08x", value);
1537 s->rfbi.time[1] = value & 0x0fffffff;
1539 case 0x6c: /* RFBI_DATA_CYCLE1_0 */
1540 TRACERFBI("RFBI_DATA_CYCLE1_0 = 0x%08x", value);
1541 s->rfbi.data[0] = value & 0x0f1f0f1f;
1543 case 0x70: /* RFBI_DATA_CYCLE2_0 */
1544 TRACERFBI("RFBI_DATA_CYCLE2_0 = 0x%08x", value);
1545 s->rfbi.data[1] = value & 0x0f1f0f1f;
1547 case 0x74: /* RFBI_DATA_CYCLE3_0 */
1548 TRACERFBI("RFBI_DATA_CYCLE3_0 = 0x%08x", value);
1549 s->rfbi.data[2] = value & 0x0f1f0f1f;
1551 case 0x78: /* RFBI_CONFIG1 */
1552 TRACERFBI("RFBI_CONFIG1 = 0x%08x", value);
1553 s->rfbi.config[1] = value & 0x003f1fff;
1556 case 0x7c: /* RFBI_ONOFF_TIME1 */
1557 TRACERFBI("RFBI_ONOFF_TIME1 = 0x%08x", value);
1558 s->rfbi.time[2] = value & 0x3fffffff;
1560 case 0x80: /* RFBI_CYCLE_TIME1 */
1561 TRACERFBI("RFBI_CYCLE_TIME1 = 0x%08x", value);
1562 s->rfbi.time[3] = value & 0x0fffffff;
1564 case 0x84: /* RFBI_DATA_CYCLE1_1 */
1565 TRACERFBI("RFBI_DATA_CYCLE1_1 = 0x%08x", value);
1566 s->rfbi.data[3] = value & 0x0f1f0f1f;
1568 case 0x88: /* RFBI_DATA_CYCLE2_1 */
1569 TRACERFBI("RFBI_DATA_CYCLE2_1 = 0x%08x", value);
1570 s->rfbi.data[4] = value & 0x0f1f0f1f;
1572 case 0x8c: /* RFBI_DATA_CYCLE3_1 */
1573 TRACERFBI("RFBI_DATA_CYCLE3_1 = 0x%08x", value);
1574 s->rfbi.data[5] = value & 0x0f1f0f1f;
1577 case 0x90: /* RFBI_VSYNC_WIDTH */
1578 TRACERFBI("RFBI_VSYNC_WIDTH = 0x%08x", value);
1579 s->rfbi.vsync = value & 0xffff;
1581 case 0x94: /* RFBI_HSYNC_WIDTH */
1582 TRACERFBI("RFBI_HSYNC_WIDTH = 0x%08x", value);
1583 s->rfbi.hsync = value & 0xffff;
1587 OMAP_BAD_REGV(addr, value);
1592 static CPUReadMemoryFunc *omap_rfbi1_readfn[] = {
1593 omap_badwidth_read32,
1594 omap_badwidth_read32,
1598 static CPUWriteMemoryFunc *omap_rfbi1_writefn[] = {
1599 omap_badwidth_write32,
1600 omap_badwidth_write32,
1604 static uint32_t omap_venc_read(void *opaque, target_phys_addr_t addr)
1607 case 0x00: /* REV_ID */
1609 case 0x04: /* STATUS */
1610 case 0x08: /* F_CONTROL */
1611 case 0x10: /* VIDOUT_CTRL */
1612 case 0x14: /* SYNC_CTRL */
1613 case 0x1c: /* LLEN */
1614 case 0x20: /* FLENS */
1615 case 0x24: /* HFLTR_CTRL */
1616 case 0x28: /* CC_CARR_WSS_CARR */
1617 case 0x2c: /* C_PHASE */
1618 case 0x30: /* GAIN_U */
1619 case 0x34: /* GAIN_V */
1620 case 0x38: /* GAIN_Y */
1621 case 0x3c: /* BLACK_LEVEL */
1622 case 0x40: /* BLANK_LEVEL */
1623 case 0x44: /* X_COLOR */
1624 case 0x48: /* M_CONTROL */
1625 case 0x4c: /* BSTAMP_WSS_DATA */
1626 case 0x50: /* S_CARR */
1627 case 0x54: /* LINE21 */
1628 case 0x58: /* LN_SEL */
1629 case 0x5c: /* L21__WC_CTL */
1630 case 0x60: /* HTRIGGER_VTRIGGER */
1631 case 0x64: /* SAVID__EAVID */
1632 case 0x68: /* FLEN__FAL */
1633 case 0x6c: /* LAL__PHASE_RESET */
1634 case 0x70: /* HS_INT_START_STOP_X */
1635 case 0x74: /* HS_EXT_START_STOP_X */
1636 case 0x78: /* VS_INT_START_X */
1637 case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
1638 case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
1639 case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
1640 case 0x88: /* VS_EXT_STOP_Y */
1641 case 0x90: /* AVID_START_STOP_X */
1642 case 0x94: /* AVID_START_STOP_Y */
1643 case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
1644 case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
1645 case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
1646 case 0xb0: /* TVDETGP_INT_START_STOP_X */
1647 case 0xb4: /* TVDETGP_INT_START_STOP_Y */
1648 case 0xb8: /* GEN_CTRL */
1649 case 0xc4: /* DAC_TST__DAC_A */
1650 case 0xc8: /* DAC_B__DAC_C */
1660 static void omap_venc_write(void *opaque, target_phys_addr_t addr,
1664 case 0x00: /* REV_ID */
1665 case 0x04: /* STATUS */
1666 /* read-only, ignore */
1668 case 0x08: /* F_CONTROL */
1669 case 0x10: /* VIDOUT_CTRL */
1670 case 0x14: /* SYNC_CTRL */
1671 case 0x1c: /* LLEN */
1672 case 0x20: /* FLENS */
1673 case 0x24: /* HFLTR_CTRL */
1674 case 0x28: /* CC_CARR_WSS_CARR */
1675 case 0x2c: /* C_PHASE */
1676 case 0x30: /* GAIN_U */
1677 case 0x34: /* GAIN_V */
1678 case 0x38: /* GAIN_Y */
1679 case 0x3c: /* BLACK_LEVEL */
1680 case 0x40: /* BLANK_LEVEL */
1681 case 0x44: /* X_COLOR */
1682 case 0x48: /* M_CONTROL */
1683 case 0x4c: /* BSTAMP_WSS_DATA */
1684 case 0x50: /* S_CARR */
1685 case 0x54: /* LINE21 */
1686 case 0x58: /* LN_SEL */
1687 case 0x5c: /* L21__WC_CTL */
1688 case 0x60: /* HTRIGGER_VTRIGGER */
1689 case 0x64: /* SAVID__EAVID */
1690 case 0x68: /* FLEN__FAL */
1691 case 0x6c: /* LAL__PHASE_RESET */
1692 case 0x70: /* HS_INT_START_STOP_X */
1693 case 0x74: /* HS_EXT_START_STOP_X */
1694 case 0x78: /* VS_INT_START_X */
1695 case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
1696 case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
1697 case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
1698 case 0x88: /* VS_EXT_STOP_Y */
1699 case 0x90: /* AVID_START_STOP_X */
1700 case 0x94: /* AVID_START_STOP_Y */
1701 case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
1702 case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
1703 case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
1704 case 0xb0: /* TVDETGP_INT_START_STOP_X */
1705 case 0xb4: /* TVDETGP_INT_START_STOP_Y */
1706 case 0xb8: /* GEN_CTRL */
1707 case 0xc4: /* DAC_TST__DAC_A */
1708 case 0xc8: /* DAC_B__DAC_C */
1712 OMAP_BAD_REGV(addr, value);
1717 static CPUReadMemoryFunc *omap_venc1_readfn[] = {
1718 omap_badwidth_read32,
1719 omap_badwidth_read32,
1723 static CPUWriteMemoryFunc *omap_venc1_writefn[] = {
1724 omap_badwidth_write32,
1725 omap_badwidth_write32,
1729 static uint32_t omap_im3_read(void *opaque, target_phys_addr_t addr)
1732 case 0x0a8: /* SBIMERRLOGA */
1733 case 0x0b0: /* SBIMERRLOG */
1734 case 0x190: /* SBIMSTATE */
1735 case 0x198: /* SBTMSTATE_L */
1736 case 0x19c: /* SBTMSTATE_H */
1737 case 0x1a8: /* SBIMCONFIG_L */
1738 case 0x1ac: /* SBIMCONFIG_H */
1739 case 0x1f8: /* SBID_L */
1740 case 0x1fc: /* SBID_H */
1750 static void omap_im3_write(void *opaque, target_phys_addr_t addr,
1754 case 0x0b0: /* SBIMERRLOG */
1755 case 0x190: /* SBIMSTATE */
1756 case 0x198: /* SBTMSTATE_L */
1757 case 0x19c: /* SBTMSTATE_H */
1758 case 0x1a8: /* SBIMCONFIG_L */
1759 case 0x1ac: /* SBIMCONFIG_H */
1763 OMAP_BAD_REGV(addr, value);
1768 static CPUReadMemoryFunc *omap_im3_readfn[] = {
1769 omap_badwidth_read32,
1770 omap_badwidth_read32,
1774 static CPUWriteMemoryFunc *omap_im3_writefn[] = {
1775 omap_badwidth_write32,
1776 omap_badwidth_write32,
1780 static uint32_t omap_dsi_read(void *opaque, target_phys_addr_t addr)
1782 struct omap_dss_s *s = (struct omap_dss_s *)opaque;
1786 case 0x000: /* DSI_REVISION */
1787 TRACEDSI("DSI_REVISION = 0x10");
1789 case 0x010: /* DSI_SYSCONFIG */
1790 TRACEDSI("DSI_SYSCONFIG = 0x%04x", s->dsi.sysconfig);
1791 return s->dsi.sysconfig;
1792 case 0x014: /* DSI_SYSSTATUS */
1793 TRACEDSI("DSI_SYSSTATUS = 0x01");
1794 return 1; /* RESET_DONE */
1795 case 0x018: /* DSI_IRQSTATUS */
1796 TRACEDSI("DSI_IRQSTATUS = 0x%08x", s->dsi.irqst);
1797 return s->dsi.irqst;
1798 case 0x01c: /* DSI_IRQENABLE */
1799 TRACEDSI("DSI_IRQENABLE = 0x%08x", s->dsi.irqen);
1800 return s->dsi.irqen;
1801 case 0x040: /* DSI_CTRL */
1802 TRACEDSI("DSI_CTRL = 0x%08x", s->dsi.ctrl);
1804 case 0x048: /* DSI_COMPLEXIO_CFG1 */
1805 TRACEDSI("DSI_COMPLEXIO_CFG1 = 0x%08x", s->dsi.complexio_cfg1);
1806 return s->dsi.complexio_cfg1;
1807 case 0x04c: /* DSI_COMPLEXIO_IRQSTATUS */
1808 TRACEDSI("DSI_COMPLEXIO_IRQSTATUS = 0x%08x", s->dsi.complexio_irqst);
1809 return s->dsi.complexio_irqst;
1810 case 0x050: /* DSI_COMPLEXIO_IRQENABLE */
1811 TRACEDSI("DSI_COMPLEXIO_IRQENABLE = 0x%08x", s->dsi.complexio_irqen);
1812 return s->dsi.complexio_irqen;
1813 case 0x054: /* DSI_CLK_CTRL */
1814 TRACEDSI("DSI_CLK_CTRL = 0x%08x", s->dsi.clk_ctrl);
1815 return s->dsi.clk_ctrl;
1816 case 0x058: /* DSI_TIMING1 */
1817 TRACEDSI("DSI_TIMING1 = 0x%08x", s->dsi.timing1);
1818 return s->dsi.timing1;
1819 case 0x05c: /* DSI_TIMING2 */
1820 TRACEDSI("DSI_TIMING2 = 0x%08x", s->dsi.timing2);
1821 return s->dsi.timing2;
1822 case 0x060: /* DSI_VM_TIMING1 */
1823 TRACEDSI("DSI_VM_TIMING1 = 0x%08x", s->dsi.vm_timing1);
1824 return s->dsi.vm_timing1;
1825 case 0x064: /* DSI_VM_TIMING2 */
1826 TRACEDSI("DSI_VM_TIMING2 = 0x%08x", s->dsi.vm_timing2);
1827 return s->dsi.vm_timing2;
1828 case 0x068: /* DSI_VM_TIMING3 */
1829 TRACEDSI("DSI_VM_TIMING3 = 0x%08x", s->dsi.vm_timing3);
1830 return s->dsi.vm_timing3;
1831 case 0x06c: /* DSI_CLK_TIMING */
1832 TRACEDSI("DSI_CLK_TIMING = 0x%08x", s->dsi.clk_timing);
1833 return s->dsi.clk_timing;
1834 case 0x070: /* DSI_TX_FIFO_VC_SIZE */
1835 TRACEDSI("DSI_TX_FIFO_VC_SIZE = 0x%08x", s->dsi.tx_fifo_vc_size);
1836 return s->dsi.tx_fifo_vc_size;
1837 case 0x074: /* DSI_RX_FIFO_VC_SIZE */
1838 TRACEDSI("DSI_RX_FIFO_VC_SIZE = 0x%08x", s->dsi.rx_fifo_vc_size);
1839 return s->dsi.rx_fifo_vc_size;
1840 case 0x078: /* DSI_COMPLEXIO_CFG_2 */
1841 case 0x07c: /* DSI_RX_FIFO_VC_FULLNESS */
1842 case 0x080: /* DSI_VM_TIMING4 */
1843 case 0x084: /* DSI_TX_FIFO_VC_EMPTINESS */
1844 case 0x088: /* DSI_VM_TIMING5 */
1845 case 0x08c: /* DSI_VM_TIMING6 */
1846 case 0x090: /* DSI_VM_TIMING7 */
1847 case 0x094: /* DSI_STOPCLK_TIMING */
1850 case 0x100 ... 0x17c: /* DSI_VCx_xxx */
1851 x = (addr >> 6) & 3;
1852 switch (addr & 0x1f) {
1853 case 0x00: /* DSI_VCx_CTRL */
1854 TRACEDSI("DSI_VC%d_CTRL = 0x%08x", x, s->dsi.vc[x].ctrl);
1855 return s->dsi.vc[x].ctrl;
1856 case 0x04: /* DSI_VCx_TE */
1857 TRACEDSI("DSI_VC%d_TE = 0x%08x", x, s->dsi.vc[x].te);
1858 return s->dsi.vc[x].te;
1859 case 0x08: /* DSI_VCx_LONG_PACKET_HEADER */
1861 TRACEDSI("DSI_VC%d_LONG_PACKET_HEADER = 0", x);
1863 case 0x0c: /* DSI_VCx_LONG_PACKET_PAYLOAD */
1865 TRACEDSI("DSI_VC%d_LONG_PACKET_PAYLOAD = 0", x);
1867 case 0x10: /* DSI_VCx_SHORT_PACKET_HEADER */
1868 /* TODO: this should return value from RX FIFO */
1869 TRACEDSI("DSI_VC%d_SHORT_PACKET_HEADER = 0", x);
1871 case 0x18: /* DSI_VCx_IRQSTATUS */
1872 TRACEDSI("DSI_VC%d_IRQSTATUS = 0x%08x", x, s->dsi.vc[x].irqst);
1873 return s->dsi.vc[x].irqst;
1874 case 0x1c: /* DSI_VCx_IRQENABLE */
1875 TRACEDSI("DSI_VC%d_IRQENABLE = 0x%08x", x, s->dsi.vc[x].irqen);
1876 return s->dsi.vc[x].irqen;
1882 case 0x200: /* DSI_PHY_CFG0 */
1883 TRACEDSI("DSI_PHY_CFG0 = 0x%08x", s->dsi.phy_cfg0);
1884 return s->dsi.phy_cfg0;
1885 case 0x204: /* DSI_PHY_CFG1 */
1886 TRACEDSI("DSI_PHY_CFG1 = 0x%08x", s->dsi.phy_cfg1);
1887 return s->dsi.phy_cfg1;
1888 case 0x208: /* DSI_PHY_CFG2 */
1889 TRACEDSI("DSI_PHY_CFG2 = 0x%08x", s->dsi.phy_cfg2);
1890 return s->dsi.phy_cfg2;
1891 case 0x214: /* DSI_PHY_CFG5 */
1892 TRACEDSI("DSI_PHY_CFG5 = 0xfc000000");
1893 return 0xfc000000; /* all resets done */
1895 case 0x300: /* DSI_PLL_CONTROL */
1896 TRACEDSI("DSI_PLL_CONTROL = 0x%08x", s->dsi.pll_control);
1897 return s->dsi.pll_control;
1898 case 0x304: /* DSI_PLL_STATUS */
1899 x = 1; /* DSI_PLLCTRL_RESET_DONE */
1900 if ((s->dsi.clk_ctrl >> 28) & 3) { /* DSI PLL control powered? */
1901 if (((s->dsi.pll_config1 >> 1) & 0x7f) && /* DSI_PLL_REGN */
1902 ((s->dsi.pll_config1 >> 8) & 0x7ff)) { /* DSI_PLL_REGM */
1903 x |= 2; /* DSI_PLL_LOCK */
1906 if ((s->dsi.pll_config2 >> 20) & 1) /* DSI_HSDIVBYPASS */
1907 x |= (1 << 9); /* DSI_BYPASSACKZ */
1908 if (!((s->dsi.pll_config2 >> 13) & 1)) /* DSI_PLL_REFEN */
1909 x |= (1 << 3); /* DSI_PLL_LOSSREF */
1910 TRACEDSI("DSI_PLL_STATUS = 0x%08x", x);
1912 case 0x308: /* DSI_PLL_GO */
1913 TRACEDSI("DSI_PLL_GO = 0x%08x", s->dsi.pll_go);
1914 return s->dsi.pll_go;
1915 case 0x30c: /* DSI_PLL_CONFIGURATION1 */
1916 TRACEDSI("DSI_PLL_CONFIGURATION1 = 0x%08x", s->dsi.pll_config1);
1917 return s->dsi.pll_config1;
1918 case 0x310: /* DSI_PLL_CONFIGURATION2 */
1919 TRACEDSI("DSI_PLL_CONFIGURATION2 = 0x%08x", s->dsi.pll_config2);
1920 return s->dsi.pll_config2;
1929 static void omap_dsi_write(void *opaque, target_phys_addr_t addr,
1932 struct omap_dss_s *s = (struct omap_dss_s *)opaque;
1936 case 0x000: /* DSI_REVISION */
1937 case 0x014: /* DSI_SYSSTATUS */
1938 case 0x07c: /* DSI_RX_FIFO_VC_FULLNESS */
1939 case 0x084: /* DSI_RX_FIFO_VC_EMPTINESS */
1940 case 0x214: /* DSI_PHY_CFG5 */
1941 case 0x304: /* DSI_PLL_STATUS */
1942 /* read-only, ignore */
1944 case 0x010: /* DSI_SYSCONFIG */
1945 TRACEDSI("DSI_SYSCONFIG = 0x%08x", value);
1946 if (value & 2) /* SOFT_RESET */
1949 s->dsi.sysconfig = value;
1951 case 0x018: /* DSI_IRQSTATUS */
1952 TRACEDSI("DSI_IRQSTATUS = 0x%08x", value);
1953 s->dsi.irqst &= ~(value & 0x1fc3b0);
1955 case 0x01c: /* DSI_IRQENABLE */
1956 TRACEDSI("DSI_IRQENABLE = 0x%08x", value);
1957 s->dsi.irqen = value & 0x1fc3b0;
1959 case 0x040: /* DSI_CTRL */
1960 TRACEDSI("DSI_CTRL = 0x%08x", value);
1961 s->dsi.ctrl = value & 0x7ffffff;
1963 case 0x048: /* DSI_COMPLEXIO_CFG_1 */
1964 TRACEDSI("DSI_COMPLEXIO_CFG1 = 0x%08x", value);
1965 value |= 1 << 29; /* RESET_DONE */
1966 value |= 1 << 21; /* LDO_POWER_GOOD_STATE */
1967 /* copy PWR_CMD directly to PWR_STATUS */
1968 value &= ~(3 << 25);
1969 value |= (value >> 2) & (3 << 25);
1970 s->dsi.complexio_cfg1 = value;
1972 case 0x04c: /* DSI_COMPLEXIO_IRQSTATUS */
1973 TRACEDSI("DSI_COMPLEXIO_IRQSTATUS = 0x%08x", value);
1974 s->dsi.complexio_irqst &= ~(value & 0xc3f39ce7);
1975 if (s->dsi.complexio_irqst)
1976 s->dsi.irqst |= (1 << 10); /* COMPLEXIO_ERR_IRQ */
1978 s->dsi.irqst &= ~(1 << 10); /* COMPLEXIO_ERR_IRQ */
1980 case 0x050: /* DSI_COMPLEXIO_IRQENABLE */
1981 TRACEDSI("DSI_COMPLEXIO_IRQENABLE = 0x%08x", value);
1982 s->dsi.complexio_irqen = value & 0xc3f39ce7;
1984 case 0x054: /* DSI_CLK_CTRL */
1985 TRACEDSI("DSI_CLK_CTRL = 0x%08x", value);
1986 value &= 0xc03fffff;
1987 /* copy PLL_PWR_CMD directly to PLL_PWR_STATUS */
1988 value |= (value >> 2) & (3 << 28);
1989 s->dsi.clk_ctrl = value;
1991 case 0x058: /* DSI_TIMING1 */
1992 TRACEDSI("DSI_TIMING1 = 0x%08x", value);
1993 value &= ~(1 << 15); /* deassert ForceTxStopMode signal */
1994 s->dsi.timing1 = value;
1996 case 0x05c: /* DSI_TIMING2 */
1997 TRACEDSI("DSI_TIMING2 = 0x%08x", value);
1998 s->dsi.timing2 = value;
2000 case 0x060: /* DSI_VM_TIMING1 */
2001 TRACEDSI("DSI_VM_TIMING1 = 0x%08x", value);
2002 s->dsi.vm_timing1 = value;
2004 case 0x064: /* DSI_VM_TIMING2 */
2005 TRACEDSI("DSI_VM_TIMING2 = 0x%08x", value);
2006 s->dsi.vm_timing2 = value & 0x0fffffff;
2008 case 0x068: /* DSI_VM_TIMING3 */
2009 TRACEDSI("DSI_VM_TIMING3 = 0x%08x", value);
2010 s->dsi.vm_timing3 = value;
2012 case 0x06c: /* DSI_CLK_TIMING */
2013 TRACEDSI("DSI_CLK_TIMING = 0x%08x", value);
2014 s->dsi.clk_timing = value & 0xffff;
2016 case 0x070: /* DSI_TX_FIFO_VC_SIZE */
2017 TRACEDSI("DSI_TX_FIFO_VC_SIZE = 0x%08x", value);
2018 s->dsi.tx_fifo_vc_size = value & 0xf7f7f7f7;
2020 case 0x074: /* DSI_RX_FIFO_VC_SIZE */
2021 TRACEDSI("DSI_RX_FIFO_VC_SIZE = 0x%08x", value);
2022 s->dsi.rx_fifo_vc_size = value & 0xf7f7f7f7;
2024 case 0x078: /* DSI_COMPLEXIO_CFG_2 */
2025 case 0x080: /* DSI_VM_TIMING4 */
2026 case 0x088: /* DSI_VM_TIMING5 */
2027 case 0x08c: /* DSI_VM_TIMING6 */
2028 case 0x090: /* DSI_VM_TIMING7 */
2029 case 0x094: /* DSI_STOPCLK_TIMING */
2030 OMAP_BAD_REGV(addr, value);
2032 case 0x100 ... 0x17c: /* DSI_VCx_xxx */
2033 x = (addr >> 6) & 3;
2034 switch (addr & 0x1f) {
2035 case 0x00: /* DSI_VCx_CTRL */
2036 TRACEDSI("DSI_VC%d_CTRL = 0x%08x", x, value);
2037 if (value & 1) { /* VC_EN */
2038 s->dsi.vc[x].ctrl &= ~0x40; /* BTA_EN */
2039 s->dsi.vc[x].ctrl |= 0x1; /* VC_EN */
2041 s->dsi.vc[x].ctrl = (s->dsi.vc[x].ctrl & 0x11c020) |
2042 (value & 0x3fee039f);
2044 // if (value & 0x40) { /* BTA_EN */
2045 // s->dsi.irqst |= 1 << x; /* VIRTUAL_CHANNELx_IRQ */
2046 // s->dsi.vc[x].irqst |= 0x20; /* BTA_IRQ */
2047 // omap_dss_interrupt_update(s);
2050 case 0x04: /* DSI_VCx_TE */
2051 TRACEDSI("DSI_VC%d_TE = 0x%08x", x, value);
2052 value &= 0xc0ffffff;
2053 if (s->dsi.vc[x].ctrl & 1) { /* VC_EN */
2054 value &= ~(1 << 30); /* TE_EN */
2055 value |= s->dsi.vc[x].te & (1 << 30);
2057 s->dsi.vc[x].te = value;
2059 case 0x08: /* DSI_VCx_LONG_PACKET_HEADER */
2060 TRACEDSI("DSI_VC%d_LONG_PACKET_HEADER = 0x%08x", x, value);
2061 s->dsi.vc[x].lp_header = value;
2063 case 0x0c: /* DSI_VCx_LONG_PACKET_PAYLOAD */
2064 TRACEDSI("DSI_VC%d_LONG_PACKET_PAYLOAD = 0x%08x", x, value);
2065 s->dsi.vc[x].lp_payload = value;
2067 case 0x10: /* DSI_VCx_SHORT_PACKET_HEADER */
2068 TRACEDSI("DSI_VC%d_SHORT_PACKET_HEADER = 0x%08x", x, value);
2069 s->dsi.vc[x].sp_header = value;
2071 case 0x18: /* DSI_VCx_IRQSTATUS */
2072 TRACEDSI("DSI_VC%d_IRQSTATUS = 0x%08x", x, value);
2073 s->dsi.vc[x].irqst &= ~(value & 0x1ff);
2074 if (s->dsi.vc[x].irqst)
2075 s->dsi.irqst |= 1 << x; /* VIRTUAL_CHANNELx_IRQ */
2077 s->dsi.irqst &= ~(1 << x); /* VIRTUAL_CHANNELx_IRQ */
2079 case 0x1c: /* DSI_VCx_IRQENABLE */
2080 TRACEDSI("DSI_VC%d_IRQENABLE = 0x%08x", x, value);
2081 s->dsi.vc[x].irqen = value & 0x1ff;
2088 case 0x200: /* DSI_PHY_CFG0 */
2089 TRACEDSI("DSI_PHY_CFG0 = 0x%08x", value);
2090 s->dsi.phy_cfg0 = value;
2092 case 0x204: /* DSI_PHY_CFG1 */
2093 TRACEDSI("DSI_PHY_CFG1 = 0x%08x", value);
2094 s->dsi.phy_cfg1 = value;
2096 case 0x208: /* DSI_PHY_CFG2 */
2097 TRACEDSI("DSI_PHY_CFG2 = 0x%08x", value);
2098 s->dsi.phy_cfg2 = value;
2101 case 0x300: /* DSI_PLL_CONTROL */
2102 TRACEDSI("DSI_PLL_CONTROL = 0x%08x", value);
2103 s->dsi.pll_control = value & 0x1f;
2105 case 0x308: /* DSI_PLL_GO */
2106 TRACEDSI("DSI_PLL_GO = 0x%08x", value);
2107 /* TODO: check if we need to update something here */
2108 value &= ~1; /* mark it done */
2109 s->dsi.pll_go = value & 1;
2111 case 0x30c: /* DSI_PLL_CONFIGURATION1 */
2112 TRACEDSI("DSI_PLL_CONFIGURATION1 = 0x%08x", value);
2113 s->dsi.pll_config1 = value & 0x7ffffff;
2115 case 0x310: /* DSI_PLL_CONFIGURATION2 */
2116 TRACEDSI("DSI_PLL_CONFIGURATION2 = 0x%08x", value);
2117 s->dsi.pll_config2 = value & 0x1fffff;
2121 OMAP_BAD_REGV(addr, value);
2126 static CPUReadMemoryFunc *omap_dsi_readfn[] = {
2127 omap_badwidth_read32,
2128 omap_badwidth_read32,
2132 static CPUWriteMemoryFunc *omap_dsi_writefn[] = {
2133 omap_badwidth_write32,
2134 omap_badwidth_write32,
2138 struct omap_dss_s *omap_dss_init(struct omap_mpu_state_s *mpu,
2139 struct omap_target_agent_s *ta,
2140 qemu_irq irq, qemu_irq drq,
2141 omap_clk fck1, omap_clk fck2, omap_clk ck54m,
2142 omap_clk ick1, omap_clk ick2)
2145 int region_base = 0;
2146 struct omap_dss_s *s = (struct omap_dss_s *)
2147 qemu_mallocz(sizeof(struct omap_dss_s));
2152 iomemtype[0] = l4_register_io_memory(0, omap_diss1_readfn,
2153 omap_diss1_writefn, s);
2154 iomemtype[1] = l4_register_io_memory(0, omap_disc1_readfn,
2155 omap_disc1_writefn, s);
2156 iomemtype[2] = l4_register_io_memory(0, omap_rfbi1_readfn,
2157 omap_rfbi1_writefn, s);
2158 iomemtype[3] = l4_register_io_memory(0, omap_venc1_readfn,
2159 omap_venc1_writefn, s);
2161 if (cpu_class_omap3(mpu)) {
2162 s->dispc.rev = 0x30;
2165 iomemtype[4] = l4_register_io_memory(0, omap_dsi_readfn,
2166 omap_dsi_writefn, s);
2167 omap_l4_attach(ta, 0, iomemtype[4]);
2170 s->dispc.rev = 0x20;
2172 iomemtype[4] = cpu_register_io_memory(0, omap_im3_readfn,
2173 omap_im3_writefn, s);
2174 cpu_register_physical_memory(0x68000800, 0x1000, iomemtype[4]);
2177 omap_l4_attach(ta, region_base+0, iomemtype[0]); /* DISS */
2178 omap_l4_attach(ta, region_base+1, iomemtype[1]); /* DISC */
2179 omap_l4_attach(ta, region_base+2, iomemtype[2]); /* RFBI */
2180 omap_l4_attach(ta, region_base+3, iomemtype[3]); /* VENC */
2184 register_savevm("omap_dss", -1, 0,
2185 omap_dss_save_state, omap_dss_load_state, s);
2190 void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
2192 if (cs < 0 || cs > 1)
2193 hw_error("%s: wrong CS %i\n", __FUNCTION__, cs);
2194 s->rfbi.chip[cs] = chip;
2197 void omap3_lcd_panel_attach(struct omap_dss_s *dss,
2199 struct omap3_lcd_panel_s *lcd_panel)
2201 if (cs < 0 || cs > 1)
2202 cpu_abort(cpu_single_env, "%s: wrong CS %i\n", __FUNCTION__, cs);
2203 dss->omap_lcd_panel[cs] = lcd_panel;
2204 lcd_panel->dss = dss;
2207 /*omap3 lcd panel stuff*/
2210 #include "omap3_lcd_panel_template.h"
2212 #include "omap3_lcd_panel_template.h"
2214 #include "omap3_lcd_panel_template.h"
2216 #include "omap3_lcd_panel_template.h"
2218 #include "omap3_lcd_panel_template.h"
2220 /* Bytes(!) per pixel */
2221 static const int omap3_lcd_panel_bpp[0x10] = {
2222 0, /* 0x0: BITMAP1 (CLUT) */
2223 0, /* 0x1: BITMAP2 (CLUT) */
2224 0, /* 0x2: BITMAP4 (CLUT) */
2225 0, /* 0x3: BITMAP8 (CLUT) */
2226 2, /* 0x4: RGB12 (unpacked 16-bit container)*/
2227 2, /* 0x5: ARGB16 */
2229 0, /* 0x7: reserved */
2230 4, /* 0x8: RGB24 (unpacked in 32-bit container) */
2231 3, /* 0x9: RGB24 (packed in 24-bit container) */
2232 2, /* 0xa: YUV2 422 */
2233 2, /* 0xb: UYVY 422 */
2234 4, /* 0xc: ARGB32 */
2235 4, /* 0xd: RGBA32 */
2236 4, /* 0xe: RGBx32 (24-bit RGB aligned on MSB of the 32-bit container) */
2237 0, /* 0xf: reserved */
2240 static inline void omap3_lcd_panel_invalidate_display(void *opaque)
2242 struct omap3_lcd_panel_s *s = (struct omap3_lcd_panel_s *)opaque;
2246 static void omap3_lcd_panel_update_display(void *opaque)
2248 struct omap3_lcd_panel_s *s = (struct omap3_lcd_panel_s *)opaque;
2249 struct omap_dss_s *dss = s->dss;
2250 const uint32_t lcd_width = dss->lcd.nx;
2251 const uint32_t lcd_height = dss->lcd.ny;
2252 uint32_t graphic_width, graphic_height;
2253 uint32_t start_x, start_y;
2254 const uint32_t lcd_Bpp = omap3_lcd_panel_bpp[dss->dispc.l[0].gfx_format];
2256 uint32_t linesize, y;
2257 uint32_t copy_width, copy_height;
2258 uint8_t *src, *dest;
2259 target_phys_addr_t size;
2261 if (!dss->lcd.enable
2262 || dss->dispc.l[0].gfx_channel /* 24bit digital out */
2263 || ((dss->dispc.control & (1 << 11))) /* RFBI */
2267 /* check for setup changes since last visit only if flagged */
2268 if (dss->dispc.invalidate) {
2269 dss->dispc.invalidate = 0;
2270 if (lcd_width != ds_get_width(s->state)
2271 || lcd_height != ds_get_height(s->state)) {
2272 qemu_console_resize(s->state, lcd_width, lcd_height);
2275 int gf = dss->dispc.l[0].gfx_format;
2276 if (!(dss->dispc.l[0].rotation_flag)) { /* rotation*/
2277 switch (ds_get_bits_per_pixel(s->state)) {
2278 case 8: s->line_fn = omap3_lcd_panel_draw_fn_8[gf]; break;
2279 case 15: s->line_fn = omap3_lcd_panel_draw_fn_15[gf]; break;
2280 case 16: s->line_fn = omap3_lcd_panel_draw_fn_16[gf]; break;
2281 case 24: s->line_fn = omap3_lcd_panel_draw_fn_24[gf]; break;
2282 case 32: s->line_fn = omap3_lcd_panel_draw_fn_32[gf]; break;
2283 default: s->line_fn = 0; break;
2286 switch (ds_get_bits_per_pixel(s->state)) {
2287 case 8: s->line_fn = omap3_lcd_panel_draw_fn_r_8[gf]; break;
2288 case 15: s->line_fn = omap3_lcd_panel_draw_fn_r_15[gf]; break;
2289 case 16: s->line_fn = omap3_lcd_panel_draw_fn_r_16[gf]; break;
2290 case 24: s->line_fn = omap3_lcd_panel_draw_fn_r_24[gf]; break;
2291 case 32: s->line_fn = omap3_lcd_panel_draw_fn_r_32[gf]; break;
2292 default: s->line_fn = 0; break;
2298 "%s: line_fn is NULL - host bpp=%d, omap3 lcd gfx_format=%d\n",
2300 ds_get_bits_per_pixel(s->state),
2301 dss->dispc.l[0].gfx_format);
2306 graphic_width = dss->dispc.l[0].nx;
2307 graphic_height = dss->dispc.l[0].ny;
2308 start_x = dss->dispc.l[0].posx;
2309 start_y = dss->dispc.l[0].posy;
2311 dest = ds_get_data(s->state);
2312 linesize = ds_get_linesize(s->state);
2314 dss_Bpp = linesize / ds_get_width(s->state);
2316 dest += linesize * start_y;
2317 dest += start_x * dss_Bpp;
2319 if ((start_x + graphic_width) > lcd_width)
2320 copy_width = lcd_width - start_x;
2322 copy_width = graphic_width;
2323 copy_height = lcd_height > graphic_height ? graphic_height : lcd_height;
2325 size = copy_height * copy_width * lcd_Bpp;
2326 src = cpu_physical_memory_map(dss->dispc.l[0].addr[0], &size, 0);
2328 if (size == copy_height * copy_width * lcd_Bpp) {
2329 for (y = start_y; y < copy_height; y++) {
2330 s->line_fn(dest, src, copy_width * lcd_Bpp);
2331 src += graphic_width * lcd_Bpp;
2334 dpy_update(s->state, start_x, start_y, graphic_width, graphic_height);
2336 cpu_physical_memory_unmap(src, size, 0, size);
2340 dss->dispc.irqst |= 1; /* FRAMEDONE */
2341 omap_dss_interrupt_update(dss);
2344 void *omap3_lcd_panel_init()
2346 struct omap3_lcd_panel_s *s = (struct omap3_lcd_panel_s *) qemu_mallocz(sizeof(*s));
2348 s->state = graphic_console_init(omap3_lcd_panel_update_display,
2349 omap3_lcd_panel_invalidate_display,