/*
 * 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;
    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 = 18;
    } else {
        bpp_offset = 0;
    }
    if (s->endian) {
        bpp_offset += 6;
    }

    fn = fntable[s->bpp + 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 uint32_t syborg_fb_read(void *opaque, target_phys_addr_t offset)
{
    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,
                            uint32_t val)
{
    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 CPUReadMemoryFunc * const syborg_fb_readfn[] = {
    syborg_fb_read,
    syborg_fb_read,
    syborg_fb_read
};

static CPUWriteMemoryFunc * const syborg_fb_writefn[] = {
    syborg_fb_write,
    syborg_fb_write,
    syborg_fb_write
};

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 void syborg_fb_init(SysBusDevice *dev)
{
    SyborgFBState *s = FROM_SYSBUS(SyborgFBState, dev);
    int iomemtype;

    sysbus_init_irq(dev, &s->irq);
    iomemtype = cpu_register_io_memory(syborg_fb_readfn,
                                       syborg_fb_writefn, s);
    sysbus_init_mmio(dev, 0x1000, iomemtype);

    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("syborg_framebuffer", -1, 1,
                    syborg_fb_save, syborg_fb_load, s);
}

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)
