/*
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#include "hw.h"
#include "console.h"
#include "omap.h"

struct omap_lcd_panel_s {
    qemu_irq irq;
    DisplayState *state;
    QEMUConsole *console;
    ram_addr_t imif_base;
    ram_addr_t emiff_base;

    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);
}

#include "pixel_ops.h"

typedef void draw_line_func(
                uint8_t *d, const uint8_t *s, int width, const uint16_t *pal);

#define DEPTH 8
#include "omap_lcd_template.h"
#define DEPTH 15
#include "omap_lcd_template.h"
#define DEPTH 16
#include "omap_lcd_template.h"
#define DEPTH 32
#include "omap_lcd_template.h"

static draw_line_func *draw_line_table2[33] = {
    [0 ... 32]	= 0,
    [8]		= draw_line2_8,
    [15]	= draw_line2_15,
    [16]	= draw_line2_16,
    [32]	= draw_line2_32,
}, *draw_line_table4[33] = {
    [0 ... 32]	= 0,
    [8]		= draw_line4_8,
    [15]	= draw_line4_15,
    [16]	= draw_line4_16,
    [32]	= draw_line4_32,
}, *draw_line_table8[33] = {
    [0 ... 32]	= 0,
    [8]		= draw_line8_8,
    [15]	= draw_line8_15,
    [16]	= draw_line8_16,
    [32]	= draw_line8_32,
}, *draw_line_table12[33] = {
    [0 ... 32]	= 0,
    [8]		= draw_line12_8,
    [15]	= draw_line12_15,
    [16]	= draw_line12_16,
    [32]	= draw_line12_32,
}, *draw_line_table16[33] = {
    [0 ... 32]	= 0,
    [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;
    draw_line_func *draw_line;
    int size, dirty[2], minline, maxline, height;
    int line, width, linesize, step, bpp, frame_offset;
    ram_addr_t frame_base, scanline, newline, x;
    uint8_t *s, *d;

    if (!omap_lcd || omap_lcd->plm == 1 ||
                    !omap_lcd->enable || !ds_get_bits_per_pixel(omap_lcd->state))
        return;

    frame_offset = 0;
    if (omap_lcd->plm != 2) {
        memcpy(omap_lcd->palette, phys_ram_base +
                        omap_lcd->dma->phys_framebuffer[
                        omap_lcd->dma->current_frame], 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[ds_get_bits_per_pixel(omap_lcd->state)];
        bpp = 2;
        break;

    case 2:
        draw_line = draw_line_table4[ds_get_bits_per_pixel(omap_lcd->state)];
        bpp = 4;
        break;

    case 3:
        draw_line = draw_line_table8[ds_get_bits_per_pixel(omap_lcd->state)];
        bpp = 8;
        break;

    case 4 ... 7:
        if (!omap_lcd->tft)
            draw_line = draw_line_table12[ds_get_bits_per_pixel(omap_lcd->state)];
        else
            draw_line = draw_line_table16[ds_get_bits_per_pixel(omap_lcd->state)];
        bpp = 16;
        break;

    default:
        /* Unsupported at the moment.  */
        return;
    }

    /* Resolution */
    width = omap_lcd->width;
    if (width != ds_get_width(omap_lcd->state) ||
            omap_lcd->height != ds_get_height(omap_lcd->state)) {
        qemu_console_resize(omap_lcd->console,
                            omap_lcd->width, omap_lcd->height);
        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 (!ds_get_bits_per_pixel(omap_lcd->state))
        return;

    line = 0;
    height = omap_lcd->height;
    if (omap_lcd->subpanel & (1 << 31)) {
        if (omap_lcd->subpanel & (1 << 29))
            line = (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;
    scanline = frame_base + step * line;
    s = (uint8_t *) (phys_ram_base + scanline);
    d = ds_get_data(omap_lcd->state);
    linesize = ds_get_linesize(omap_lcd->state);

    dirty[0] = dirty[1] =
            cpu_physical_memory_get_dirty(scanline, VGA_DIRTY_FLAG);
    minline = height;
    maxline = line;
    for (; line < height; line ++) {
        newline = scanline + step;
        for (x = scanline + TARGET_PAGE_SIZE; x < newline;
                        x += TARGET_PAGE_SIZE) {
            dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
            dirty[0] |= dirty[1];
        }
        if (dirty[0] || omap_lcd->invalidate) {
            draw_line(d, s, width, omap_lcd->palette);
            if (line < minline)
                minline = line;
            maxline = line + 1;
        }
        scanline = newline;
        dirty[0] = dirty[1];
        s += step;
        d += linesize;
    }

    if (maxline >= minline) {
        dpy_update(omap_lcd->state, 0, minline, width, maxline);
        cpu_physical_memory_reset_dirty(frame_base + step * minline,
                        frame_base + step * maxline, VGA_DIRTY_FLAG);
    }
}

static int ppm_save(const char *filename, uint8_t *data,
                int w, int h, int linesize)
{
    FILE *f;
    uint8_t *d, *d1;
    unsigned int v;
    int y, x, bpp;

    f = fopen(filename, "wb");
    if (!f)
        return -1;
    fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
    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:
                fputc((v >> 8) & 0xf8, f);
                fputc((v >> 3) & 0xfc, f);
                fputc((v << 3) & 0xf8, f);
                break;
            case 3:
            case 4:
            default:
                fputc((v >> 16) & 0xff, f);
                fputc((v >> 8) & 0xff, f);
                fputc((v) & 0xff, f);
                break;
            }
            d += bpp;
        }
        d1 += linesize;
    }
    fclose(f);
    return 0;
}

static void omap_screen_dump(void *opaque, const char *filename) {
    struct omap_lcd_panel_s *omap_lcd = opaque;
    omap_update_display(opaque);
    if (omap_lcd && ds_get_data(omap_lcd->state))
        ppm_save(filename, ds_get_data(omap_lcd->state),
                omap_lcd->width, omap_lcd->height,
                ds_get_linesize(omap_lcd->state));
}

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;
    }

     if (s->dma->src == imif) {
        /* Framebuffers are in SRAM */
        s->dma->phys_framebuffer[0] = s->imif_base +
                s->dma->src_f1_top - OMAP_IMIF_BASE;

        s->dma->phys_framebuffer[1] = s->imif_base +
                s->dma->src_f2_top - OMAP_IMIF_BASE;
    } else {
        /* Framebuffers are in RAM */
        s->dma->phys_framebuffer[0] = s->emiff_base +
                s->dma->src_f1_top - OMAP_EMIFF_BASE;

        s->dma->phys_framebuffer[1] = s->emiff_base +
                s->dma->src_f2_top - OMAP_EMIFF_BASE;
    }

    if (s->plm != 2 && !s->palette_done) {
        memcpy(s->palette, phys_ram_base +
                s->dma->phys_framebuffer[s->dma->current_frame], 0x200);
        s->palette_done = 1;
        omap_lcd_interrupts(s);
    }
}

static uint32_t omap_lcdc_read(void *opaque, target_phys_addr_t addr)
{
    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, target_phys_addr_t addr,
                uint32_t value)
{
    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 CPUReadMemoryFunc *omap_lcdc_readfn[] = {
    omap_lcdc_read,
    omap_lcdc_read,
    omap_lcdc_read,
};

static CPUWriteMemoryFunc *omap_lcdc_writefn[] = {
    omap_lcdc_write,
    omap_lcdc_write,
    omap_lcdc_write,
};

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(target_phys_addr_t base, qemu_irq irq,
                struct omap_dma_lcd_channel_s *dma, DisplayState *ds,
                ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk)
{
    int iomemtype;
    struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *)
            qemu_mallocz(sizeof(struct omap_lcd_panel_s));

    s->irq = irq;
    s->dma = dma;
    s->state = ds;
    s->imif_base = imif_base;
    s->emiff_base = emiff_base;
    omap_lcdc_reset(s);

    iomemtype = cpu_register_io_memory(0, omap_lcdc_readfn,
                    omap_lcdc_writefn, s);
    cpu_register_physical_memory(base, 0x100, iomemtype);

    s->console = graphic_console_init(ds, omap_update_display,
                                      omap_invalidate_display,
                                      omap_screen_dump, NULL, s);

    return s;
}
