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