/* * Copyright (c) 2019, NXP. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include struct imx_uart { int index; unsigned int uart_base; }; static const struct imx_uart imx8m_uart_info[] = { { /* UART 1 */ .index = RDC_PDAP_UART1, .uart_base = IMX_UART1_BASE, }, { /* UART 2 */ .index = RDC_PDAP_UART2, .uart_base = IMX_UART2_BASE, }, { /* UART 3 */ .index = RDC_PDAP_UART3, .uart_base = IMX_UART3_BASE, }, { /* UART 4 */ .index = RDC_PDAP_UART4, .uart_base = IMX_UART4_BASE, } }; static int imx_rdc_uart_get_pdap_index(unsigned int uart_base) { size_t i; for (i = 0; i < ARRAY_SIZE(imx8m_uart_info); i++) { if (imx8m_uart_info[i].uart_base == uart_base) { return imx8m_uart_info[i].index; } } return -ENODEV; } static void imx_rdc_console_access_enable(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base) { struct imx_rdc_cfg *rdc; int console_pdap_index; console_pdap_index = imx_rdc_uart_get_pdap_index(console_base); if (console_pdap_index < 0) { return; } for (rdc = rdc_cfg; rdc->type != RDC_INVALID; rdc++) { if (rdc->type != RDC_PDAP || rdc->index != console_pdap_index) { continue; } if (rdc->index == console_pdap_index && rdc->setting.rdc_pdap == (D0R | D0W)) { return; } if (rdc->index == console_pdap_index) { rdc->setting.rdc_pdap = D0R | D0W; } } } void imx_rdc_init(struct imx_rdc_cfg *rdc_cfg, unsigned int console_base) { struct imx_rdc_cfg *rdc = rdc_cfg; imx_rdc_console_access_enable(rdc, console_base); while (rdc->type != RDC_INVALID) { switch (rdc->type) { case RDC_MDA: /* MDA config */ mmio_write_32(MDAn(rdc->index), rdc->setting.rdc_mda); break; case RDC_PDAP: /* peripheral access permission config */ mmio_write_32(PDAPn(rdc->index), rdc->setting.rdc_pdap); break; case RDC_MEM_REGION: /* memory region access permission config */ mmio_write_32(MRSAn(rdc->index), rdc->setting.rdc_mem_region[0]); mmio_write_32(MREAn(rdc->index), rdc->setting.rdc_mem_region[1]); mmio_write_32(MRCn(rdc->index), rdc->setting.rdc_mem_region[2]); break; default: break; } rdc++; } }