xref: /optee_os/core/drivers/qcom_geni_uart.c (revision bcfbef15234d9eeaab2654123192c257a2b16655)
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