/* Copyright 2018 SiFive, Inc */
/* SPDX-License-Identifier: Apache-2.0 */

#include <metal/machine/platform.h>

#ifdef METAL_SIFIVE_UART0

#include <metal/drivers/sifive_uart0.h>
#include <metal/machine.h>

/* TXDATA Fields */
#define UART_TXEN               (1 <<  0)
#define UART_TXFULL             (1 << 31)

/* RXDATA Fields */
#define UART_RXEN               (1 <<  0)
#define UART_RXEMPTY            (1 << 31)

/* TXCTRL Fields */
#define UART_NSTOP              (1 <<  1)
#define UART_TXCNT(count)       ((0x7 & count) << 16)

/* IP Fields */
#define UART_TXWM               (1 <<  0)

#define UART_REG(offset)   (((unsigned long)control_base + offset))
#define UART_REGB(offset)  (__METAL_ACCESS_ONCE((__metal_io_u8  *)UART_REG(offset)))
#define UART_REGW(offset)  (__METAL_ACCESS_ONCE((__metal_io_u32 *)UART_REG(offset)))

struct metal_interrupt *
__metal_driver_sifive_uart0_interrupt_controller(struct metal_uart *uart)
{
    return __metal_driver_sifive_uart0_interrupt_parent(uart);
}

int __metal_driver_sifive_uart0_get_interrupt_id(struct metal_uart *uart)
{
    return (__metal_driver_sifive_uart0_interrupt_line(uart) + METAL_INTERRUPT_ID_GL0);
}


int __metal_driver_sifive_uart0_txready(struct metal_uart *uart)
{
  long control_base = __metal_driver_sifive_uart0_control_base(uart);

  return !((UART_REGW(METAL_SIFIVE_UART0_TXDATA) & UART_TXFULL));
}


int __metal_driver_sifive_uart0_putc(struct metal_uart *uart, int c)
{
    long control_base = __metal_driver_sifive_uart0_control_base(uart);

    while (!__metal_driver_sifive_uart0_txready(uart)) {
		/* wait */
    }
    UART_REGW(METAL_SIFIVE_UART0_TXDATA) = c;
    return 0;
}


int __metal_driver_sifive_uart0_getc(struct metal_uart *uart, int *c)
{
    uint32_t ch;
    long control_base = __metal_driver_sifive_uart0_control_base(uart);
    /* No seperate status register, we get status and the byte at same time */
    ch = UART_REGW(METAL_SIFIVE_UART0_RXDATA);;
    if( ch & UART_RXEMPTY ){
      *c = -1; /* aka: EOF in most of the world */
    } else {
      *c = ch & 0x0ff;
    }
    return 0;
}


int __metal_driver_sifive_uart0_get_baud_rate(struct metal_uart *guart)
{
    struct __metal_driver_sifive_uart0 *uart = (void *)guart;
    return uart->baud_rate;
}

int __metal_driver_sifive_uart0_set_baud_rate(struct metal_uart *guart, int baud_rate)
{
    struct __metal_driver_sifive_uart0 *uart = (void *)guart;
    long control_base = __metal_driver_sifive_uart0_control_base(guart);
    struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart);

    uart->baud_rate = baud_rate;

    if (clock != NULL) {
        long clock_rate = clock->vtable->get_rate_hz(clock);
        UART_REGW(METAL_SIFIVE_UART0_DIV) = clock_rate / baud_rate - 1;
        UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXEN;
        UART_REGW(METAL_SIFIVE_UART0_RXCTRL) |= UART_RXEN;
    }
    return 0;
}

static void pre_rate_change_callback_func(void *priv)
{
    struct __metal_driver_sifive_uart0 *uart = priv;
    long control_base = __metal_driver_sifive_uart0_control_base((struct metal_uart *)priv);
    struct metal_clock *clock = __metal_driver_sifive_uart0_clock((struct metal_uart *)priv);

    /* Detect when the TXDATA is empty by setting the transmit watermark count
     * to one and waiting until an interrupt is pending */

    UART_REGW(METAL_SIFIVE_UART0_TXCTRL) &= ~(UART_TXCNT(0x7));
    UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXCNT(1);

    while((UART_REGW(METAL_SIFIVE_UART0_IP) & UART_TXWM) == 0) ;

    /* When the TXDATA clears, the UART is still shifting out the last byte.
     * Calculate the time we must drain to finish transmitting and then wait
     * that long. */

    long bits_per_symbol = (UART_REGW(METAL_SIFIVE_UART0_TXCTRL) & (1 << 1)) ? 9 : 10;
    long clk_freq = clock->vtable->get_rate_hz(clock);
    long cycles_to_wait = bits_per_symbol * clk_freq / uart->baud_rate;

    for(volatile long x = 0; x < cycles_to_wait; x++)
        __asm__("nop");
}

static void post_rate_change_callback_func(void *priv)
{
    struct __metal_driver_sifive_uart0 *uart = priv;
    metal_uart_set_baud_rate(&uart->uart, uart->baud_rate);
}

void __metal_driver_sifive_uart0_init(struct metal_uart *guart, int baud_rate)
{
    struct __metal_driver_sifive_uart0 *uart = (void *)(guart);
    struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart);
    struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_uart0_pinmux(guart);

    if(clock != NULL) {
        uart->pre_rate_change_callback.callback = &pre_rate_change_callback_func;
        uart->pre_rate_change_callback.priv = guart;
        metal_clock_register_pre_rate_change_callback(clock, &(uart->pre_rate_change_callback));

        uart->post_rate_change_callback.callback = &post_rate_change_callback_func;
        uart->post_rate_change_callback.priv = guart;
        metal_clock_register_post_rate_change_callback(clock, &(uart->post_rate_change_callback));
    }

    metal_uart_set_baud_rate(&(uart->uart), baud_rate);

    if (pinmux != NULL) {
        long pinmux_output_selector = __metal_driver_sifive_uart0_pinmux_output_selector(guart);
        long pinmux_source_selector = __metal_driver_sifive_uart0_pinmux_source_selector(guart);
        pinmux->gpio.vtable->enable_io(
            (struct metal_gpio *) pinmux,
            pinmux_output_selector,
            pinmux_source_selector
        );
    }
}

__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_uart0) = {
    .uart.init          = __metal_driver_sifive_uart0_init,
    .uart.putc          = __metal_driver_sifive_uart0_putc,
    .uart.getc          = __metal_driver_sifive_uart0_getc,
    .uart.get_baud_rate = __metal_driver_sifive_uart0_get_baud_rate,
    .uart.set_baud_rate = __metal_driver_sifive_uart0_set_baud_rate,
    .uart.controller_interrupt = __metal_driver_sifive_uart0_interrupt_controller,
    .uart.get_interrupt_id     = __metal_driver_sifive_uart0_get_interrupt_id,
};

#endif /* METAL_SIFIVE_UART0 */

typedef int no_empty_translation_units;
