blob: de159565f827c58156e4be9fed328eb691fa65cc [file] [log] [blame]
/*
* Copyright (c) 2019, NXP. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <errno.h>
#include <lib/mmio.h>
#include <imx_rdc.h>
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++;
}
}