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