blob: d9182fe4ca19a4957442d97a40455e425ed7e00c [file] [log] [blame] [edit]
/*
* Copyright 2017, DornerWorks
* Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/
/*
* This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
* a DARPA SBIR, Contract Number D16PC00107.
*
* Approved for Public Release, Distribution Unlimited.
*/
#include <devices_gen.h>
#include <drivers/common.h>
#include <drivers/uart.h>
#include <elfloader_common.h>
/*
* UART Hardware Constants
*/
#define XUARTPS_CR 0x00
#define XUARTPS_SR 0x2C
#define XUARTPS_FIFO 0x30
#define XUARTPS_SR_TXEMPTY (1U << 3)
#define XUARTPS_CR_TX_EN (1U << 4)
#define XUARTPS_CR_TX_DIS (1U << 5)
#define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x)))
static int xilinx_uart_putchar(struct elfloader_device *dev, unsigned int c)
{
volatile void *mmio = dev->region_bases[0];
/* Wait to be able to transmit. */
while (!(*UART_REG(mmio, XUARTPS_SR) & XUARTPS_SR_TXEMPTY));
/* Transmit. */
*UART_REG(mmio, XUARTPS_FIFO) = c;
return 0;
}
static int xilinx_uart_init(struct elfloader_device *dev, UNUSED void *match_data)
{
volatile void *mmio = dev->region_bases[0];
uint32_t v = *UART_REG(mmio, XUARTPS_CR);
v |= XUARTPS_CR_TX_EN;
v &= ~XUARTPS_CR_TX_DIS;
*UART_REG(mmio, XUARTPS_CR) = v;
uart_set_out(dev);
return 0;
}
static const struct dtb_match_table xilinx_uart_matches[] = {
{ .compatible = "xlnx,xuartps" },
{ .compatible = NULL /* sentinel */ },
};
static const struct elfloader_uart_ops xilinx_uart_ops = {
.putc = &xilinx_uart_putchar,
};
static const struct elfloader_driver xilinx_uart = {
.match_table = xilinx_uart_matches,
.type = DRIVER_UART,
.init = &xilinx_uart_init,
.ops = &xilinx_uart_ops,
};
ELFLOADER_DRIVER(xilinx_uart);