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