xref: /rk3399_ARM-atf/plat/imx/imx8m/imx_rdc.c (revision ad1f6288b7c046d16e7dd7b36b080610915d9bb7)
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 
imx_rdc_uart_get_pdap_index(unsigned int uart_base)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 
imx_rdc_console_access_enable(struct imx_rdc_cfg * rdc_cfg,unsigned int console_base)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 }
69 
imx_rdc_init(struct imx_rdc_cfg * rdc_cfg,unsigned int console_base)70 void imx_rdc_init(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base)
71 {
72 	struct imx_rdc_cfg *rdc = rdc_cfg;
73 
74 	imx_rdc_console_access_enable(rdc, console_base);
75 
76 	while (rdc->type != RDC_INVALID) {
77 		switch (rdc->type) {
78 		case RDC_MDA:
79 			/* MDA config */
80 			mmio_write_32(MDAn(rdc->index), rdc->setting.rdc_mda);
81 			break;
82 		case RDC_PDAP:
83 			/* peripheral access permission config */
84 			mmio_write_32(PDAPn(rdc->index), rdc->setting.rdc_pdap);
85 			break;
86 		case RDC_MEM_REGION:
87 			/* memory region access permission config */
88 			mmio_write_32(MRSAn(rdc->index), rdc->setting.rdc_mem_region[0]);
89 			mmio_write_32(MREAn(rdc->index), rdc->setting.rdc_mem_region[1]);
90 			mmio_write_32(MRCn(rdc->index), rdc->setting.rdc_mem_region[2]);
91 			break;
92 		default:
93 			break;
94 		}
95 
96 		rdc++;
97 	}
98 }
99