diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2013-02-05 12:59:04 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-04-08 18:13:13 +0200 |
commit | fc97bb5ba3e7239c0b6d24095df6784868dfebbf (patch) | |
tree | 6367fc217473184292a7eeee38c1b8e6a0db1573 /hw/omap_lcdc.c | |
parent | 34b8f63ea1aa0941f11c6c032f8e1716269a0449 (diff) |
hw: move display devices to hw/display/, configure via default-configs/
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/omap_lcdc.c')
-rw-r--r-- | hw/omap_lcdc.c | 493 |
1 files changed, 0 insertions, 493 deletions
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c deleted file mode 100644 index 4048cc102d..0000000000 --- a/hw/omap_lcdc.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * OMAP LCD controller. - * - * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. - */ -#include "hw/hw.h" -#include "ui/console.h" -#include "hw/arm/omap.h" -#include "hw/framebuffer.h" -#include "ui/pixel_ops.h" - -struct omap_lcd_panel_s { - MemoryRegion *sysmem; - MemoryRegion iomem; - qemu_irq irq; - QemuConsole *con; - - int plm; - int tft; - int mono; - int enable; - int width; - int height; - int interrupts; - uint32_t timing[3]; - uint32_t subpanel; - uint32_t ctrl; - - struct omap_dma_lcd_channel_s *dma; - uint16_t palette[256]; - int palette_done; - int frame_done; - int invalidate; - int sync_error; -}; - -static void omap_lcd_interrupts(struct omap_lcd_panel_s *s) -{ - if (s->frame_done && (s->interrupts & 1)) { - qemu_irq_raise(s->irq); - return; - } - - if (s->palette_done && (s->interrupts & 2)) { - qemu_irq_raise(s->irq); - return; - } - - if (s->sync_error) { - qemu_irq_raise(s->irq); - return; - } - - qemu_irq_lower(s->irq); -} - -#define draw_line_func drawfn - -#define DEPTH 8 -#include "hw/omap_lcd_template.h" -#define DEPTH 15 -#include "hw/omap_lcd_template.h" -#define DEPTH 16 -#include "hw/omap_lcd_template.h" -#define DEPTH 32 -#include "hw/omap_lcd_template.h" - -static draw_line_func draw_line_table2[33] = { - [0 ... 32] = NULL, - [8] = draw_line2_8, - [15] = draw_line2_15, - [16] = draw_line2_16, - [32] = draw_line2_32, -}, draw_line_table4[33] = { - [0 ... 32] = NULL, - [8] = draw_line4_8, - [15] = draw_line4_15, - [16] = draw_line4_16, - [32] = draw_line4_32, -}, draw_line_table8[33] = { - [0 ... 32] = NULL, - [8] = draw_line8_8, - [15] = draw_line8_15, - [16] = draw_line8_16, - [32] = draw_line8_32, -}, draw_line_table12[33] = { - [0 ... 32] = NULL, - [8] = draw_line12_8, - [15] = draw_line12_15, - [16] = draw_line12_16, - [32] = draw_line12_32, -}, draw_line_table16[33] = { - [0 ... 32] = NULL, - [8] = draw_line16_8, - [15] = draw_line16_15, - [16] = draw_line16_16, - [32] = draw_line16_32, -}; - -static void omap_update_display(void *opaque) -{ - struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque; - DisplaySurface *surface = qemu_console_surface(omap_lcd->con); - draw_line_func draw_line; - int size, height, first, last; - int width, linesize, step, bpp, frame_offset; - hwaddr frame_base; - - if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable || - !surface_bits_per_pixel(surface)) { - return; - } - - frame_offset = 0; - if (omap_lcd->plm != 2) { - cpu_physical_memory_read(omap_lcd->dma->phys_framebuffer[ - omap_lcd->dma->current_frame], - (void *)omap_lcd->palette, 0x200); - switch (omap_lcd->palette[0] >> 12 & 7) { - case 3 ... 7: - frame_offset += 0x200; - break; - default: - frame_offset += 0x20; - } - } - - /* Colour depth */ - switch ((omap_lcd->palette[0] >> 12) & 7) { - case 1: - draw_line = draw_line_table2[surface_bits_per_pixel(surface)]; - bpp = 2; - break; - - case 2: - draw_line = draw_line_table4[surface_bits_per_pixel(surface)]; - bpp = 4; - break; - - case 3: - draw_line = draw_line_table8[surface_bits_per_pixel(surface)]; - bpp = 8; - break; - - case 4 ... 7: - if (!omap_lcd->tft) - draw_line = draw_line_table12[surface_bits_per_pixel(surface)]; - else - draw_line = draw_line_table16[surface_bits_per_pixel(surface)]; - bpp = 16; - break; - - default: - /* Unsupported at the moment. */ - return; - } - - /* Resolution */ - width = omap_lcd->width; - if (width != surface_width(surface) || - omap_lcd->height != surface_height(surface)) { - qemu_console_resize(omap_lcd->con, - omap_lcd->width, omap_lcd->height); - surface = qemu_console_surface(omap_lcd->con); - omap_lcd->invalidate = 1; - } - - if (omap_lcd->dma->current_frame == 0) - size = omap_lcd->dma->src_f1_bottom - omap_lcd->dma->src_f1_top; - else - size = omap_lcd->dma->src_f2_bottom - omap_lcd->dma->src_f2_top; - - if (frame_offset + ((width * omap_lcd->height * bpp) >> 3) > size + 2) { - omap_lcd->sync_error = 1; - omap_lcd_interrupts(omap_lcd); - omap_lcd->enable = 0; - return; - } - - /* Content */ - frame_base = omap_lcd->dma->phys_framebuffer[ - omap_lcd->dma->current_frame] + frame_offset; - omap_lcd->dma->condition |= 1 << omap_lcd->dma->current_frame; - if (omap_lcd->dma->interrupts & 1) - qemu_irq_raise(omap_lcd->dma->irq); - if (omap_lcd->dma->dual) - omap_lcd->dma->current_frame ^= 1; - - if (!surface_bits_per_pixel(surface)) { - return; - } - - first = 0; - height = omap_lcd->height; - if (omap_lcd->subpanel & (1 << 31)) { - if (omap_lcd->subpanel & (1 << 29)) - first = (omap_lcd->subpanel >> 16) & 0x3ff; - else - height = (omap_lcd->subpanel >> 16) & 0x3ff; - /* TODO: fill the rest of the panel with DPD */ - } - - step = width * bpp >> 3; - linesize = surface_stride(surface); - framebuffer_update_display(surface, omap_lcd->sysmem, - frame_base, width, height, - step, linesize, 0, - omap_lcd->invalidate, - draw_line, omap_lcd->palette, - &first, &last); - if (first >= 0) { - dpy_gfx_update(omap_lcd->con, 0, first, width, last - first + 1); - } - omap_lcd->invalidate = 0; -} - -static void omap_ppm_save(const char *filename, uint8_t *data, - int w, int h, int linesize, Error **errp) -{ - FILE *f; - uint8_t *d, *d1; - unsigned int v; - int ret, y, x, bpp; - - f = fopen(filename, "wb"); - if (!f) { - error_setg(errp, "failed to open file '%s': %s", filename, - strerror(errno)); - return; - } - ret = fprintf(f, "P6\n%d %d\n%d\n", w, h, 255); - if (ret < 0) { - goto write_err; - } - d1 = data; - bpp = linesize / w; - for (y = 0; y < h; y ++) { - d = d1; - for (x = 0; x < w; x ++) { - v = *(uint32_t *) d; - switch (bpp) { - case 2: - ret = fputc((v >> 8) & 0xf8, f); - if (ret == EOF) { - goto write_err; - } - ret = fputc((v >> 3) & 0xfc, f); - if (ret == EOF) { - goto write_err; - } - ret = fputc((v << 3) & 0xf8, f); - if (ret == EOF) { - goto write_err; - } - break; - case 3: - case 4: - default: - ret = fputc((v >> 16) & 0xff, f); - if (ret == EOF) { - goto write_err; - } - ret = fputc((v >> 8) & 0xff, f); - if (ret == EOF) { - goto write_err; - } - ret = fputc((v) & 0xff, f); - if (ret == EOF) { - goto write_err; - } - break; - } - d += bpp; - } - d1 += linesize; - } -out: - fclose(f); - return; - -write_err: - error_setg(errp, "failed to write to file '%s': %s", filename, - strerror(errno)); - unlink(filename); - goto out; -} - -static void omap_screen_dump(void *opaque, const char *filename, bool cswitch, - Error **errp) -{ - struct omap_lcd_panel_s *omap_lcd = opaque; - DisplaySurface *surface = qemu_console_surface(omap_lcd->con); - - omap_update_display(opaque); - if (omap_lcd && surface_data(surface)) - omap_ppm_save(filename, surface_data(surface), - omap_lcd->width, omap_lcd->height, - surface_stride(surface), errp); -} - -static void omap_invalidate_display(void *opaque) { - struct omap_lcd_panel_s *omap_lcd = opaque; - omap_lcd->invalidate = 1; -} - -static void omap_lcd_update(struct omap_lcd_panel_s *s) { - if (!s->enable) { - s->dma->current_frame = -1; - s->sync_error = 0; - if (s->plm != 1) - s->frame_done = 1; - omap_lcd_interrupts(s); - return; - } - - if (s->dma->current_frame == -1) { - s->frame_done = 0; - s->palette_done = 0; - s->dma->current_frame = 0; - } - - if (!s->dma->mpu->port[s->dma->src].addr_valid(s->dma->mpu, - s->dma->src_f1_top) || - !s->dma->mpu->port[ - s->dma->src].addr_valid(s->dma->mpu, - s->dma->src_f1_bottom) || - (s->dma->dual && - (!s->dma->mpu->port[ - s->dma->src].addr_valid(s->dma->mpu, - s->dma->src_f2_top) || - !s->dma->mpu->port[ - s->dma->src].addr_valid(s->dma->mpu, - s->dma->src_f2_bottom)))) { - s->dma->condition |= 1 << 2; - if (s->dma->interrupts & (1 << 1)) - qemu_irq_raise(s->dma->irq); - s->enable = 0; - return; - } - - s->dma->phys_framebuffer[0] = s->dma->src_f1_top; - s->dma->phys_framebuffer[1] = s->dma->src_f2_top; - - if (s->plm != 2 && !s->palette_done) { - cpu_physical_memory_read( - s->dma->phys_framebuffer[s->dma->current_frame], - (void *)s->palette, 0x200); - s->palette_done = 1; - omap_lcd_interrupts(s); - } -} - -static uint64_t omap_lcdc_read(void *opaque, hwaddr addr, - unsigned size) -{ - struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque; - - switch (addr) { - case 0x00: /* LCD_CONTROL */ - return (s->tft << 23) | (s->plm << 20) | - (s->tft << 7) | (s->interrupts << 3) | - (s->mono << 1) | s->enable | s->ctrl | 0xfe000c34; - - case 0x04: /* LCD_TIMING0 */ - return (s->timing[0] << 10) | (s->width - 1) | 0x0000000f; - - case 0x08: /* LCD_TIMING1 */ - return (s->timing[1] << 10) | (s->height - 1); - - case 0x0c: /* LCD_TIMING2 */ - return s->timing[2] | 0xfc000000; - - case 0x10: /* LCD_STATUS */ - return (s->palette_done << 6) | (s->sync_error << 2) | s->frame_done; - - case 0x14: /* LCD_SUBPANEL */ - return s->subpanel; - - default: - break; - } - OMAP_BAD_REG(addr); - return 0; -} - -static void omap_lcdc_write(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque; - - switch (addr) { - case 0x00: /* LCD_CONTROL */ - s->plm = (value >> 20) & 3; - s->tft = (value >> 7) & 1; - s->interrupts = (value >> 3) & 3; - s->mono = (value >> 1) & 1; - s->ctrl = value & 0x01cff300; - if (s->enable != (value & 1)) { - s->enable = value & 1; - omap_lcd_update(s); - } - break; - - case 0x04: /* LCD_TIMING0 */ - s->timing[0] = value >> 10; - s->width = (value & 0x3ff) + 1; - break; - - case 0x08: /* LCD_TIMING1 */ - s->timing[1] = value >> 10; - s->height = (value & 0x3ff) + 1; - break; - - case 0x0c: /* LCD_TIMING2 */ - s->timing[2] = value; - break; - - case 0x10: /* LCD_STATUS */ - break; - - case 0x14: /* LCD_SUBPANEL */ - s->subpanel = value & 0xa1ffffff; - break; - - default: - OMAP_BAD_REG(addr); - } -} - -static const MemoryRegionOps omap_lcdc_ops = { - .read = omap_lcdc_read, - .write = omap_lcdc_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -void omap_lcdc_reset(struct omap_lcd_panel_s *s) -{ - s->dma->current_frame = -1; - s->plm = 0; - s->tft = 0; - s->mono = 0; - s->enable = 0; - s->width = 0; - s->height = 0; - s->interrupts = 0; - s->timing[0] = 0; - s->timing[1] = 0; - s->timing[2] = 0; - s->subpanel = 0; - s->palette_done = 0; - s->frame_done = 0; - s->sync_error = 0; - s->invalidate = 1; - s->subpanel = 0; - s->ctrl = 0; -} - -struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem, - hwaddr base, - qemu_irq irq, - struct omap_dma_lcd_channel_s *dma, - omap_clk clk) -{ - struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) - g_malloc0(sizeof(struct omap_lcd_panel_s)); - - s->irq = irq; - s->dma = dma; - s->sysmem = sysmem; - omap_lcdc_reset(s); - - memory_region_init_io(&s->iomem, &omap_lcdc_ops, s, "omap.lcdc", 0x100); - memory_region_add_subregion(sysmem, base, &s->iomem); - - s->con = graphic_console_init(omap_update_display, - omap_invalidate_display, - omap_screen_dump, NULL, s); - - return s; -} |