1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Qualcomm GENI serial engine UART driver 4 * 5 * Copyright (c) 2025, Linaro Limited 6 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 7 */ 8 9 #include <drivers/qcom_geni_uart.h> 10 #include <io.h> 11 12 #define GENI_STATUS_REG 0x40 13 #define GENI_STATUS_REG_CMD_ACTIVE BIT(0) 14 #define GENI_TX_FIFO_REG 0x700 15 #define GENI_TX_TRANS_LEN_REG 0x270 16 #define GENI_M_CMD0_REG 0x600 17 18 #define GENI_M_CMD_TX 0x8000000 19 #define GENI_TIMEOUT_US 1000000 20 21 static void qcom_geni_uart_putc(struct serial_chip *chip, int ch) 22 { 23 struct qcom_geni_uart_data *pd = 24 container_of(chip, struct qcom_geni_uart_data, chip); 25 vaddr_t base = io_pa_or_va(&pd->base, GENI_UART_REG_SIZE); 26 uint64_t timer = timeout_init_us(GENI_TIMEOUT_US); 27 28 while (io_read32(base + GENI_STATUS_REG) & GENI_STATUS_REG_CMD_ACTIVE) 29 if (timeout_elapsed(timer)) 30 return; 31 32 io_write32(base + GENI_TX_TRANS_LEN_REG, 1); 33 io_write32(base + GENI_M_CMD0_REG, GENI_M_CMD_TX); 34 io_write32(base + GENI_TX_FIFO_REG, ch); 35 } 36 37 static const struct serial_ops qcom_geni_uart_ops = { 38 .putc = qcom_geni_uart_putc, 39 }; 40 DECLARE_KEEP_PAGER(qcom_geni_uart_ops); 41 42 void qcom_geni_uart_init(struct qcom_geni_uart_data *pd, paddr_t base) 43 { 44 pd->base.pa = base; 45 pd->chip.ops = &qcom_geni_uart_ops; 46 47 /* 48 * Do nothing, debug uart is shared with normal world, everything 49 * for debug uart initialization is done in the bootloader. 50 */ 51 } 52