1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <devices_gen.h> 8#include <drivers/common.h> 9#include <drivers/uart.h> 10 11#include <elfloader_common.h> 12 13#define UART_WFIFO 0x0 14#define UART_STATUS 0xC 15#define UART_TX_FULL BIT(21) 16#define UART_REG(mmio, x) ((volatile uint32_t *)(mmio + (x))) 17 18static int meson_uart_putchar(struct elfloader_device *dev, unsigned int c) 19{ 20 volatile void *mmio = dev->region_bases[0]; 21 22 /* Wait to be able to transmit. */ 23 while ((*UART_REG(mmio, UART_STATUS) & UART_TX_FULL)); 24 25 /* Transmit. */ 26 *UART_REG(mmio, UART_WFIFO) = c; 27 28 return 0; 29} 30 31static int meson_uart_init(struct elfloader_device *dev, UNUSED void *match_data) 32{ 33 uart_set_out(dev); 34 return 0; 35} 36 37static const struct dtb_match_table meson_uart_matches[] = { 38 { .compatible = "amlogic,meson-gx-uart" }, 39 { .compatible = NULL /* sentinel */ }, 40}; 41 42static const struct elfloader_uart_ops meson_uart_ops = { 43 .putc = &meson_uart_putchar, 44}; 45 46static const struct elfloader_driver meson_uart = { 47 .match_table = meson_uart_matches, 48 .type = DRIVER_UART, 49 .init = &meson_uart_init, 50 .ops = &meson_uart_ops, 51}; 52 53ELFLOADER_DRIVER(meson_uart); 54