1df730d94SMarco Felsch /*
2df730d94SMarco Felsch * Copyright (c) 2023, Pengutronix. All rights reserved.
3df730d94SMarco Felsch *
4df730d94SMarco Felsch * SPDX-License-Identifier: BSD-3-Clause
5df730d94SMarco Felsch */
6df730d94SMarco Felsch
7df730d94SMarco Felsch #include <lib/mmio.h>
8df730d94SMarco Felsch #include <platform_def.h>
9df730d94SMarco Felsch
10df730d94SMarco Felsch #define UCR1 0x80
11df730d94SMarco Felsch #define UCR1_UARTEN BIT(0)
12df730d94SMarco Felsch #define DOMAIN0_RUNNING(d) (((d) & 0x3) != 0)
13df730d94SMarco Felsch
14df730d94SMarco Felsch static struct imx_uart {
15df730d94SMarco Felsch unsigned int ccm_reg;
16df730d94SMarco Felsch unsigned int uart_base;
17df730d94SMarco Felsch } imx8m_uart_info[] = {
18df730d94SMarco Felsch { /* UART 1 */
19df730d94SMarco Felsch .ccm_reg = 0x4490,
20*89345562SDario Binacchi .uart_base = IMX_UART1_BASE,
21df730d94SMarco Felsch }, { /* UART 2 */
22df730d94SMarco Felsch .ccm_reg = 0x44a0,
23*89345562SDario Binacchi .uart_base = IMX_UART2_BASE,
24df730d94SMarco Felsch }, { /* UART 3 */
25df730d94SMarco Felsch .ccm_reg = 0x44b0,
26*89345562SDario Binacchi .uart_base = IMX_UART3_BASE,
27df730d94SMarco Felsch }, { /* UART 4 */
28df730d94SMarco Felsch .ccm_reg = 0x44c0,
29*89345562SDario Binacchi .uart_base = IMX_UART4_BASE,
30df730d94SMarco Felsch }
31df730d94SMarco Felsch };
32df730d94SMarco Felsch
imx8m_uart_get_base(void)33df730d94SMarco Felsch unsigned int imx8m_uart_get_base(void)
34df730d94SMarco Felsch {
35df730d94SMarco Felsch unsigned int i;
36df730d94SMarco Felsch
37df730d94SMarco Felsch for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
38df730d94SMarco Felsch uint32_t val;
39df730d94SMarco Felsch
40df730d94SMarco Felsch /*
41df730d94SMarco Felsch * At least check that the clock-gate is ungated before we
42df730d94SMarco Felsch * access the UART register.
43df730d94SMarco Felsch */
44df730d94SMarco Felsch val = mmio_read_32(IMX_CCM_BASE + imx8m_uart_info[i].ccm_reg);
45df730d94SMarco Felsch if (DOMAIN0_RUNNING(val)) {
46df730d94SMarco Felsch val = mmio_read_32(imx8m_uart_info[i].uart_base + UCR1);
47df730d94SMarco Felsch if (val & UCR1_UARTEN) {
48df730d94SMarco Felsch return imx8m_uart_info[i].uart_base;
49df730d94SMarco Felsch }
50df730d94SMarco Felsch }
51df730d94SMarco Felsch }
52df730d94SMarco Felsch
53df730d94SMarco Felsch /*
54df730d94SMarco Felsch * We should return an error and inform the user but we can't do it
55df730d94SMarco Felsch * this early.
56df730d94SMarco Felsch */
57df730d94SMarco Felsch return 0;
58df730d94SMarco Felsch }
59