/*
 * 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 {
    target_phys_addr_t base;
    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 || !omap_lcd->state->depth)
        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[omap_lcd->state->depth];
        bpp = 2;
        break;

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

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

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

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

    /* Resolution */
    width = omap_lcd->width;
    if (width != omap_lcd->state->width ||
            omap_lcd->height != omap_lcd->state->height) {
        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 (!omap_lcd->state->depth)
        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 = omap_lcd->state->data;
    linesize = omap_lcd->state->linesize;

    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 && omap_lcd->state->data)
        ppm_save(filename, omap_lcd->state->data,
                omap_lcd->width, omap_lcd->height,
                omap_lcd->state->linesize);
}

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;
    int offset = addr - s->base;

    switch (offset) {
    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;
    int offset = addr - s->base;

    switch (offset) {
    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->base = base;
    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(s->base, 0x100, iomemtype);

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

    return s;
}
