xref: /rk3399_ARM-atf/plat/imx/imx8m/imx_rdc.c (revision b47dddd061e92054c3b2096fc8aa9688bfef68d6)
1 /*
2  * Copyright (c) 2019, NXP. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 #include <lib/mmio.h>
10 
11 #include <imx_rdc.h>
12 
13 struct imx_uart {
14 	int index;
15 	unsigned int uart_base;
16 };
17 
18 static const struct imx_uart imx8m_uart_info[] = {
19 	{	/* UART 1 */
20 		.index = RDC_PDAP_UART1,
21 		.uart_base = IMX_UART1_BASE,
22 	}, {	/* UART 2 */
23 		.index = RDC_PDAP_UART2,
24 		.uart_base = IMX_UART2_BASE,
25 	}, {	/* UART 3 */
26 		.index = RDC_PDAP_UART3,
27 		.uart_base = IMX_UART3_BASE,
28 	}, {	/* UART 4 */
29 		.index = RDC_PDAP_UART4,
30 		.uart_base = IMX_UART4_BASE,
31 	}
32 };
33 
34 static int imx_rdc_uart_get_pdap_index(unsigned int uart_base)
35 {
36 	size_t i;
37 
38 	for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) {
39 		if (imx8m_uart_info[i].uart_base == uart_base) {
40 			return imx8m_uart_info[i].index;
41 		}
42 	}
43 
44 	return -ENODEV;
45 }
46 
47 static void imx_rdc_console_access_enable(struct imx_rdc_cfg *rdc_cfg,
48 				   unsigned int console_base)
49 {
50 	struct imx_rdc_cfg *rdc;
51 	int console_pdap_index;
52 
53 	console_pdap_index = imx_rdc_uart_get_pdap_index(console_base);
54 	if (console_pdap_index < 0) {
55 		return;
56 	}
57 
58 	for (rdc = rdc_cfg; rdc->type != RDC_INVALID; rdc++) {
59 		if (rdc->type != RDC_PDAP || rdc->index != console_pdap_index) {
60 			continue;
61 		}
62 
63 		if (rdc->index == console_pdap_index &&
64 		    rdc->setting.rdc_pdap == (D0R | D0W)) {
65 			return;
66 		}
67 
68 		if (rdc->index == console_pdap_index) {
69 			rdc->setting.rdc_pdap = D0R | D0W;
70 		}
71 	}
72 }
73 
74 void imx_rdc_init(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base)
75 {
76 	struct imx_rdc_cfg *rdc = rdc_cfg;
77 
78 	imx_rdc_console_access_enable(rdc, console_base);
79 
80 	while (rdc->type != RDC_INVALID) {
81 		switch (rdc->type) {
82 		case RDC_MDA:
83 			/* MDA config */
84 			mmio_write_32(MDAn(rdc->index), rdc->setting.rdc_mda);
85 			break;
86 		case RDC_PDAP:
87 			/* peripheral access permission config */
88 			mmio_write_32(PDAPn(rdc->index), rdc->setting.rdc_pdap);
89 			break;
90 		case RDC_MEM_REGION:
91 			/* memory region access permission config */
92 			mmio_write_32(MRSAn(rdc->index), rdc->setting.rdc_mem_region[0]);
93 			mmio_write_32(MREAn(rdc->index), rdc->setting.rdc_mem_region[1]);
94 			mmio_write_32(MRCn(rdc->index), rdc->setting.rdc_mem_region[2]);
95 			break;
96 		default:
97 			break;
98 		}
99 
100 		rdc++;
101 	}
102 }
103