xref: /rk3399_ARM-atf/plat/imx/imx8m/imx8m_ccm.c (revision 9bb2a0c33734baf91cb37795ed63b5ef125b2b0e)
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