/*
 * TI OMAP processors UART emulation.
 *
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
 * Copyright (C) 2007-2009 Nokia Corporation
 *
 * 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 or
 * (at your option) version 3 of the License.
 *
 * 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 "sysemu/char.h"
#include "hw/hw.h"
#include "hw/arm/omap.h"
#include "hw/char/serial.h"
#include "exec/address-spaces.h"

/* UARTs */
struct omap_uart_s {
    MemoryRegion iomem;
    hwaddr base;
    SerialState *serial; /* TODO */
    struct omap_target_agent_s *ta;
    omap_clk fclk;
    qemu_irq irq;

    uint8_t eblr;
    uint8_t syscontrol;
    uint8_t wkup;
    uint8_t cfps;
    uint8_t mdr[2];
    uint8_t scr;
    uint8_t clksel;
};

void omap_uart_reset(struct omap_uart_s *s)
{
    s->eblr = 0x00;
    s->syscontrol = 0;
    s->wkup = 0x3f;
    s->cfps = 0x69;
    s->clksel = 0;
}

struct omap_uart_s *omap_uart_init(hwaddr base,
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
                qemu_irq txdma, qemu_irq rxdma,
                const char *label, CharDriverState *chr)
{
    struct omap_uart_s *s = (struct omap_uart_s *)
            g_malloc0(sizeof(struct omap_uart_s));

    s->base = base;
    s->fclk = fclk;
    s->irq = irq;
    s->serial = serial_mm_init(get_system_memory(), base, 2, irq,
                               omap_clk_getrate(fclk)/16,
                               chr ?: qemu_chr_new(label, "null", NULL),
                               DEVICE_NATIVE_ENDIAN);
    return s;
}

static uint64_t omap_uart_read(void *opaque, hwaddr addr,
                               unsigned size)
{
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;

    if (size == 4) {
        return omap_badwidth_read8(opaque, addr);
    }

    switch (addr) {
    case 0x20:	/* MDR1 */
        return s->mdr[0];
    case 0x24:	/* MDR2 */
        return s->mdr[1];
    case 0x40:	/* SCR */
        return s->scr;
    case 0x44:	/* SSR */
        return 0x0;
    case 0x48:	/* EBLR (OMAP2) */
        return s->eblr;
    case 0x4C:	/* OSC_12M_SEL (OMAP1) */
        return s->clksel;
    case 0x50:	/* MVR */
        return 0x30;
    case 0x54:	/* SYSC (OMAP2) */
        return s->syscontrol;
    case 0x58:	/* SYSS (OMAP2) */
        return 1;
    case 0x5c:	/* WER (OMAP2) */
        return s->wkup;
    case 0x60:	/* CFPS (OMAP2) */
        return s->cfps;
    }

    OMAP_BAD_REG(addr);
    return 0;
}

static void omap_uart_write(void *opaque, hwaddr addr,
                            uint64_t value, unsigned size)
{
    struct omap_uart_s *s = (struct omap_uart_s *) opaque;

    if (size == 4) {
        return omap_badwidth_write8(opaque, addr, value);
    }

    switch (addr) {
    case 0x20:	/* MDR1 */
        s->mdr[0] = value & 0x7f;
        break;
    case 0x24:	/* MDR2 */
        s->mdr[1] = value & 0xff;
        break;
    case 0x40:	/* SCR */
        s->scr = value & 0xff;
        break;
    case 0x48:	/* EBLR (OMAP2) */
        s->eblr = value & 0xff;
        break;
    case 0x4C:	/* OSC_12M_SEL (OMAP1) */
        s->clksel = value & 1;
        break;
    case 0x44:	/* SSR */
    case 0x50:	/* MVR */
    case 0x58:	/* SYSS (OMAP2) */
        OMAP_RO_REG(addr);
        break;
    case 0x54:	/* SYSC (OMAP2) */
        s->syscontrol = value & 0x1d;
        if (value & 2)
            omap_uart_reset(s);
        break;
    case 0x5c:	/* WER (OMAP2) */
        s->wkup = value & 0x7f;
        break;
    case 0x60:	/* CFPS (OMAP2) */
        s->cfps = value & 0xff;
        break;
    default:
        OMAP_BAD_REG(addr);
    }
}

static const MemoryRegionOps omap_uart_ops = {
    .read = omap_uart_read,
    .write = omap_uart_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem,
                struct omap_target_agent_s *ta,
                qemu_irq irq, omap_clk fclk, omap_clk iclk,
                qemu_irq txdma, qemu_irq rxdma,
                const char *label, CharDriverState *chr)
{
    hwaddr base = omap_l4_attach(ta, 0, NULL);
    struct omap_uart_s *s = omap_uart_init(base, irq,
                    fclk, iclk, txdma, rxdma, label, chr);

    memory_region_init_io(&s->iomem, NULL, &omap_uart_ops, s, "omap.uart", 0x100);

    s->ta = ta;

    memory_region_add_subregion(sysmem, base + 0x20, &s->iomem);

    return s;
}

void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
{
    /* TODO: Should reuse or destroy current s->serial */
    s->serial = serial_mm_init(get_system_memory(), s->base, 2, s->irq,
                               omap_clk_getrate(s->fclk) / 16,
                               chr ?: qemu_chr_new("null", "null", NULL),
                               DEVICE_NATIVE_ENDIAN);
}
