/*
 * Copyright 2019 The Hafnium Authors.
 *
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file or at
 * https://opensource.org/licenses/BSD-3-Clause.
 */

#include "hf/io.h"
#include "hf/mm.h"
#include "hf/mpool.h"
#include "hf/plat/console.h"

/* clang-format off */

#define GPFSEL1               IO32_C(GPIO_BASE + 0x4)

#define AUX_ENABLES           IO32_C(AUX_BASE + 0x4)
#define AUX_MU_IO_REG         IO32_C(AUX_BASE + 0x40)
#define AUX_MU_IER_REG        IO32_C(AUX_BASE + 0x44)
#define AUX_MU_LCR_REG        IO32_C(AUX_BASE + 0x4c)
#define AUX_MU_MCR_REG        IO32_C(AUX_BASE + 0x50)
#define AUX_MU_LSR_REG        IO32_C(AUX_BASE + 0x54)
#define AUX_MU_CNTL_REG       IO32_C(AUX_BASE + 0x60)
#define AUX_MU_BAUD_REG       IO32_C(AUX_BASE + 0x68)

#define AUX_MU_LSR_TX_EMPTY   (UINT32_C(1) << 5)
#define AUX_MU_LSR_TX_IDLE    (UINT32_C(1) << 6)

#define MHZ_TO_HZ             UINT32_C(1000000)

/* clang-format on */

void plat_console_init(void)
{
	uint32_t selector;

	selector = io_read32(GPFSEL1);
	/* Set GPIO14 to function 5. */
	selector &= ~(7 << 12);
	selector |= 2 << 12;
	/* Set GPIO15 to function 5 */
	selector &= ~(7 << 15);
	selector |= 2 << 15;
	io_write32(GPFSEL1, selector);

	/*
	 * With 8-times oversampling, baudrate is calculated as:
	 *   baudrate = system_clock_freq / (8 * (baudrate_reg + 1))
	 * Therefore:
	 *   baudrate_reg = (system_clock_freq / (8 * baudrate)) -1
	 */
	uint32_t system_clock_freq = UINT32_C(CORE_FREQ_MHZ) * MHZ_TO_HZ;
	uint32_t oversampled_baudrate = UINT32_C(8) * UINT32_C(BAUDRATE);
	uint32_t baudrate_reg =
		(system_clock_freq / oversampled_baudrate) - UINT32_C(1);

	/* Enable Mini UART and access to its registers. */
	io_write32(AUX_ENABLES, 1);
	/* Disable auto flow control and disable receiver and transmitter. */
	io_write32(AUX_MU_CNTL_REG, 0);
	/* Disable receive and transmit interrupts. */
	io_write32(AUX_MU_IER_REG, 0);
	/* Enable 8 bit mode. */
	io_write32(AUX_MU_LCR_REG, 3);
	/* Set RTS line to be always high. */
	io_write32(AUX_MU_MCR_REG, 0);
	/* Set baud rate. */
	io_write32(AUX_MU_BAUD_REG, baudrate_reg);
	/* Enable transmitter and receiver. */
	io_write32(AUX_MU_CNTL_REG, 3);

	memory_ordering_barrier();
}

void plat_console_mm_init(struct mm_stage1_locked stage1_locked,
			  struct mpool *ppool)
{
	mm_identity_map(stage1_locked, pa_init(GPIO_BASE),
			pa_add(pa_init(GPIO_BASE), PAGE_SIZE),
			MM_MODE_R | MM_MODE_W | MM_MODE_D, ppool);
	mm_identity_map(stage1_locked, pa_init(AUX_BASE),
			pa_add(pa_init(AUX_BASE), PAGE_SIZE),
			MM_MODE_R | MM_MODE_W | MM_MODE_D, ppool);
}

void plat_console_putchar(char c)
{
	/* Print a carriage-return as well. */
	if (c == '\n') {
		plat_console_putchar('\r');
	}

	/* Wait for the transmitter to be ready to accept a byte. */
	while ((io_read32(AUX_MU_LSR_REG) & AUX_MU_LSR_TX_EMPTY) == 0) {
	}

	/* Write data to transmitter FIFO. */
	memory_ordering_barrier();
	io_write32(AUX_MU_IO_REG, c);
	memory_ordering_barrier();

	/* Wait until the transmitter is no longer busy. */
	while ((io_read32(AUX_MU_LSR_REG) & AUX_MU_LSR_TX_IDLE) == 0) {
	}
}

char plat_console_getchar(void)
{
	/* Wait for the transmitter to be ready to deliver a byte. */
	while (!(io_read32(AUX_MU_LSR_REG) & 0x1)) {
	}

	/* Read data from transmitter FIFO. */
	return (char)(io_read32(AUX_MU_IO_REG) & 0xff);
}
