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