/*
 * Syborg Framebuffer
 *
 * Copyright (c) 2009 CodeSourcery
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "sysbus.h"
#include "console.h"
#include "syborg.h"
#include "framebuffer.h"

//#define DEBUG_SYBORG_FB

#ifdef DEBUG_SYBORG_FB
#define DPRINTF(fmt, ...) \
do { printf("syborg_fb: " fmt , ## __VA_ARGS__); } while (0)
#define BADF(fmt, ...) \
do { fprintf(stderr, "syborg_fb: error: " fmt , ## __VA_ARGS__); \
    exit(1);} while (0)
#else
#define DPRINTF(fmt, ...) do {} while(0)
#define BADF(fmt, ...) \
do { fprintf(stderr, "syborg_fb: error: " fmt , ## __VA_ARGS__);} while (0)
#endif

enum {
    FB_ID               = 0,
    FB_BASE             = 1,
    FB_HEIGHT           = 2,
    FB_WIDTH            = 3,
    FB_ORIENTATION      = 4,
    FB_BLANK            = 5,
    FB_INT_MASK         = 6,
    FB_INTERRUPT_CAUSE  = 7,
    FB_BPP              = 8,
    FB_COLOR_ORDER      = 9,
    FB_BYTE_ORDER       = 10,
    FB_PIXEL_ORDER      = 11,
    FB_ROW_PITCH        = 12,
    FB_ENABLED          = 13,
    FB_PALETTE_START    = 0x400 >> 2,
    FB_PALETTE_END   = FB_PALETTE_START+256-1,
};

#define FB_INT_VSYNC            (1U << 0)
#define FB_INT_BASE_UPDATE_DONE (1U << 1)

typedef struct {
    SysBusDevice busdev;
    MemoryRegion iomem;
    DisplayState *ds;
    /*QEMUConsole *console;*/
    uint32_t need_update : 1;
    uint32_t need_int : 1;
    uint32_t enabled : 1;
    uint32_t int_status;
    uint32_t int_enable;
    qemu_irq irq;

    uint32_t base;
    uint32_t pitch;
    uint32_t rows;
    uint32_t cols;
    int blank;
    int bpp;
    int rgb; /* 0 = BGR, 1 = RGB */
    int endian; /* 0 = Little, 1 = Big */
    uint32_t raw_palette[256];
    uint32_t palette[256];
} SyborgFBState;

enum {
    BPP_SRC_1,
    BPP_SRC_2,
    BPP_SRC_4,
    BPP_SRC_8,
    BPP_SRC_16,
    BPP_SRC_32,
    /* TODO: Implement these.  */
    BPP_SRC_15 = -1,
    BPP_SRC_24 = -2
};

#include "pixel_ops.h"

#define BITS 8
#include "pl110_template.h"
#define BITS 15
#include "pl110_template.h"
#define BITS 16
#include "pl110_template.h"
#define BITS 24
#include "pl110_template.h"
#define BITS 32
#include "pl110_template.h"

/* Update interrupts.  */
static void syborg_fb_update(SyborgFBState *s)
{
    if ((s->int_status & s->int_enable) != 0) {
        DPRINTF("Raise IRQ\n");
        qemu_irq_raise(s->irq);
    } else {
        DPRINTF("Lower IRQ\n");
        qemu_irq_lower(s->irq);
    }
}

static int syborg_fb_enabled(const SyborgFBState *s)
{
    return s->enabled;
}

static void syborg_fb_update_palette(SyborgFBState *s)
{
    int n, i;
    uint32_t raw;
    unsigned int r, g, b;

    switch (s->bpp) {
    case BPP_SRC_1: n = 2; break;
    case BPP_SRC_2: n = 4; break;
    case BPP_SRC_4: n = 16; break;
    case BPP_SRC_8: n = 256; break;
    default: return;
    }

    for (i = 0; i < n; i++) {
        raw = s->raw_palette[i];
        r = (raw >> 16) & 0xff;
        g = (raw >> 8) & 0xff;
        b = raw & 0xff;
        switch (ds_get_bits_per_pixel(s->ds)) {
        case 8:
            s->palette[i] = rgb_to_pixel8(r, g, b);
            break;
        case 15:
            s->palette[i] = rgb_to_pixel15(r, g, b);
            break;
        case 16:
            s->palette[i] = rgb_to_pixel16(r, g, b);
            break;
        case 24:
        case 32:
            s->palette[i] = rgb_to_pixel32(r, g, b);
            break;
        default:
            abort();
        }
    }

}

static void syborg_fb_update_display(void *opaque)
{
    SyborgFBState *s = (SyborgFBState *)opaque;
    drawfn* fntable;
    drawfn fn;
    int dest_width;
    int src_width;
    int bpp_offset;
    int first;
    int last;

    if (!syborg_fb_enabled(s))
        return;

    switch (ds_get_bits_per_pixel(s->ds)) {
    case 0:
        return;
    case 8:
        fntable = pl110_draw_fn_8;
        dest_width = 1;
        break;
    case 15:
        fntable = pl110_draw_fn_15;
        dest_width = 2;
        break;
    case 16:
        fntable = pl110_draw_fn_16;
        dest_width = 2;
        break;
    case 24:
        fntable = pl110_draw_fn_24;
        dest_width = 3;
        break;
    case 32:
        fntable = pl110_draw_fn_32;
        dest_width = 4;
        break;
    default:
        fprintf(stderr, "syborg_fb: Bad color depth\n");
        exit(1);
    }

    if (s->need_int) {
        s->int_status |= FB_INT_BASE_UPDATE_DONE;
        syborg_fb_update(s);
        s->need_int = 0;
    }

    if (s->rgb) {
        bpp_offset = 24;
    } else {
        bpp_offset = 0;
    }
    if (s->endian) {
        bpp_offset += 8;
    }
    /* Our bpp constants mostly match the PL110/PL111 but
     * not for the 16 bit case
     */
    switch (s->bpp) {
    case BPP_SRC_16:
        bpp_offset += 6;
        break;
    default:
        bpp_offset += s->bpp;
    }
    fn = fntable[bpp_offset];

    if (s->pitch) {
        src_width = s->pitch;
    } else {
        src_width = s->cols;
        switch (s->bpp) {
        case BPP_SRC_1:
            src_width >>= 3;
            break;
        case BPP_SRC_2:
            src_width >>= 2;
            break;
        case BPP_SRC_4:
            src_width >>= 1;
            break;
        case BPP_SRC_8:
            break;
        case BPP_SRC_15:
        case BPP_SRC_16:
            src_width <<= 1;
            break;
        case BPP_SRC_24:
            src_width *= 3;
            break;
        case BPP_SRC_32:
            src_width <<= 2;
            break;
        }
    }
    dest_width *= s->cols;
    first = 0;
    /* TODO: Implement blanking.  */
    if (!s->blank) {
        if (s->need_update && s->bpp <= BPP_SRC_8) {
            syborg_fb_update_palette(s);
        }
        framebuffer_update_display(s->ds,
                                   s->base, s->cols, s->rows,
                                   src_width, dest_width, 0,
                                   s->need_update,
                                   fn, s->palette,
                                   &first, &last);
        if (first >= 0) {
            dpy_update(s->ds, 0, first, s->cols, last - first + 1);
        }

        s->int_status |= FB_INT_VSYNC;
        syborg_fb_update(s);
    }

    s->need_update = 0;
}

static void syborg_fb_invalidate_display(void * opaque)
{
    SyborgFBState *s = (SyborgFBState *)opaque;
    s->need_update = 1;
}

static uint64_t syborg_fb_read(void *opaque, target_phys_addr_t offset,
                               unsigned size)
{
    SyborgFBState *s = opaque;

    DPRINTF("read reg %d\n", (int)offset);
    offset &= 0xfff;
    switch (offset >> 2) {
    case FB_ID:
        return SYBORG_ID_FRAMEBUFFER;

    case FB_BASE:
        return s->base;

    case FB_HEIGHT:
        return s->rows;

    case FB_WIDTH:
        return s->cols;

    case FB_ORIENTATION:
        return 0;

    case FB_BLANK:
        return s->blank;

    case FB_INT_MASK:
        return s->int_enable;

    case FB_INTERRUPT_CAUSE:
        return s->int_status;

    case FB_BPP:
        switch (s->bpp) {
        case BPP_SRC_1: return 1;
        case BPP_SRC_2: return 2;
        case BPP_SRC_4: return 4;
        case BPP_SRC_8: return 8;
        case BPP_SRC_15: return 15;
        case BPP_SRC_16: return 16;
        case BPP_SRC_24: return 24;
        case BPP_SRC_32: return 32;
        default: return 0;
        }

    case FB_COLOR_ORDER:
        return s->rgb;

    case FB_BYTE_ORDER:
        return s->endian;

    case FB_PIXEL_ORDER:
        return 0;

    case FB_ROW_PITCH:
        return s->pitch;

    case FB_ENABLED:
        return s->enabled;

    default:
        if ((offset >> 2) >= FB_PALETTE_START
            && (offset >> 2) <= FB_PALETTE_END) {
            return s->raw_palette[(offset >> 2) - FB_PALETTE_START];
        } else {
            cpu_abort (cpu_single_env, "syborg_fb_read: Bad offset %x\n",
                         (int)offset);
        }
        return 0;
    }
}

static void syborg_fb_write(void *opaque, target_phys_addr_t offset,
                            uint64_t val, unsigned size)
{
    SyborgFBState *s = opaque;

    DPRINTF("write reg %d = %d\n", (int)offset, val);
    s->need_update = 1;
    offset &= 0xfff;
    switch (offset >> 2) {
    case FB_BASE:
        s->base = val;
        s->need_int = 1;
        s->need_update = 1;
        syborg_fb_update(s);
        break;

    case FB_HEIGHT:
        s->rows = val;
        break;

    case FB_WIDTH:
        s->cols = val;
        break;

    case FB_ORIENTATION:
        /* TODO: Implement rotation.  */
        break;

    case FB_BLANK:
        s->blank = val & 1;
        break;

    case FB_INT_MASK:
        s->int_enable = val;
        syborg_fb_update(s);
        break;

    case FB_INTERRUPT_CAUSE:
        s->int_status &= ~val;
        syborg_fb_update(s);
        break;

    case FB_BPP:
        switch (val) {
        case 1: val = BPP_SRC_1; break;
        case 2: val = BPP_SRC_2; break;
        case 4: val = BPP_SRC_4; break;
        case 8: val = BPP_SRC_8; break;
        /* case 15: val = BPP_SRC_15; break; */
        case 16: val = BPP_SRC_16; break;
        /* case 24: val = BPP_SRC_24; break; */
        case 32: val = BPP_SRC_32; break;
        default: val = s->bpp; break;
        }
        s->bpp = val;
        break;

    case FB_COLOR_ORDER:
        s->rgb = (val != 0);
        break;

    case FB_BYTE_ORDER:
        s->endian = (val != 0);
        break;

    case FB_PIXEL_ORDER:
        /* TODO: Implement this.  */
        break;

    case FB_ROW_PITCH:
        s->pitch = val;
        break;

    case FB_ENABLED:
        s->enabled = val;
        break;

    default:
        if ((offset >> 2) >= FB_PALETTE_START
            && (offset >> 2) <= FB_PALETTE_END) {
            s->raw_palette[(offset >> 2) - FB_PALETTE_START] = val;
        } else {
            cpu_abort (cpu_single_env, "syborg_fb_write: Bad offset %x\n",
                      (int)offset);
        }
        break;
    }
}

static const MemoryRegionOps syborg_fb_ops = {
    .read = syborg_fb_read,
    .write = syborg_fb_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void syborg_fb_save(QEMUFile *f, void *opaque)
{
    SyborgFBState *s = opaque;
    int i;

    qemu_put_be32(f, s->need_int);
    qemu_put_be32(f, s->int_status);
    qemu_put_be32(f, s->int_enable);
    qemu_put_be32(f, s->enabled);
    qemu_put_be32(f, s->base);
    qemu_put_be32(f, s->pitch);
    qemu_put_be32(f, s->rows);
    qemu_put_be32(f, s->cols);
    qemu_put_be32(f, s->bpp);
    qemu_put_be32(f, s->rgb);
    for (i = 0; i < 256; i++) {
        qemu_put_be32(f, s->raw_palette[i]);
    }
}

static int syborg_fb_load(QEMUFile *f, void *opaque, int version_id)
{
    SyborgFBState *s = opaque;
    int i;

    if (version_id != 1)
        return -EINVAL;

    s->need_int = qemu_get_be32(f);
    s->int_status = qemu_get_be32(f);
    s->int_enable = qemu_get_be32(f);
    s->enabled = qemu_get_be32(f);
    s->base = qemu_get_be32(f);
    s->pitch = qemu_get_be32(f);
    s->rows = qemu_get_be32(f);
    s->cols = qemu_get_be32(f);
    s->bpp = qemu_get_be32(f);
    s->rgb = qemu_get_be32(f);
    for (i = 0; i < 256; i++) {
        s->raw_palette[i] = qemu_get_be32(f);
    }
    s->need_update = 1;

    return 0;
}

static int syborg_fb_init(SysBusDevice *dev)
{
    SyborgFBState *s = FROM_SYSBUS(SyborgFBState, dev);

    sysbus_init_irq(dev, &s->irq);
    memory_region_init_io(&s->iomem, &syborg_fb_ops, s,
                          "framebuffer", 0x1000);
    sysbus_init_mmio_region(dev, &s->iomem);

    s->ds = graphic_console_init(syborg_fb_update_display,
                                 syborg_fb_invalidate_display,
                                 NULL, NULL, s);

    if (s->cols != 0 && s->rows != 0) {
        qemu_console_resize(s->ds, s->cols, s->rows);
    }

    if (!s->cols)
        s->cols = ds_get_width(s->ds);
    if (!s->rows)
        s->rows = ds_get_height(s->ds);

    register_savevm(&dev->qdev, "syborg_framebuffer", -1, 1,
                    syborg_fb_save, syborg_fb_load, s);
    return 0;
}

static SysBusDeviceInfo syborg_fb_info = {
    .init = syborg_fb_init,
    .qdev.name  = "syborg,framebuffer",
    .qdev.size  = sizeof(SyborgFBState),
    .qdev.props = (Property[]) {
        DEFINE_PROP_UINT32("width",  SyborgFBState, cols, 0),
        DEFINE_PROP_UINT32("height", SyborgFBState, rows, 0),
        DEFINE_PROP_END_OF_LIST(),
    }
};

static void syborg_fb_register_devices(void)
{
    sysbus_register_withprop(&syborg_fb_info);
}

device_init(syborg_fb_register_devices)
