Hi,
We are currently developing an embedded product using an IMX8MM processor. We are basing the software solution on the IMX8MM EVK and are looking to change the default Linux serial port from UART2 to UART4. We have managed to modify all of the software required to get Linux to output through the new port, however with the modifications xtest fails presumably because it requires UART4 to communicate with the secure processor. Is it possible to change the default mode of communication to another UART or to use some other form of IPC such as shared memory?
Many thanks in advance for your help.
Ben Taylor
So to add some additional information the issue appears to be caused when the bootloader reconfigures the IOMUX to use UART4 instead of UART2, we are currently modifying the serial_mxc.c driver in the following way in order to change the IOMUX. Is it anticipated this would cause any issues with the xtest?
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 476df258..941a14bb 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -110,52 +110,68 @@
#define TXTL 2 /* reset default */
#define RXTL 1 /* reset default */
+#define CCGR_UART4 0x44C0
+#define SW_PAD_CTL_PAD_UART4_RXD 0x04B4
+#define SW_MUX_CTL_PAD_UART4_RXD 0x024C
+#define UART4_RXD_SELECT_INPUT 0x050C
+#define SW_PAD_CTL_PAD_UART4_TXD 0x04B8
+#define SW_MUX_CTL_PAD_UART4_TXD 0x0250
+#define SAI6_RX_SYNC_SELECT_INPUT 0x0518
+
DECLARE_GLOBAL_DATA_PTR;
struct mxc_uart {
- u32 rxd;
- u32 spare0[15];
+ u32 rxd; //RX_DATA 0x0 UARTx_URXD
+ u32 spare0[15]; //?
- u32 txd;
- u32 spare1[15];
+ u32 txd; //TX_DATA 0x40 UARTx_UTXD
+ u32 spare1[15]; //Reseved
- u32 cr1;
- u32 cr2;
- u32 cr3;
- u32 cr4;
+ u32 cr1; // 0x80 UARTx_UCR1
+ u32 cr2; // 0x84 UARTx_UCR2
+ u32 cr3; // 0x88 UARTx_UCR3
+ u32 cr4; // 0x8C UARTx_UCR4
- u32 fcr;
- u32 sr1;
- u32 sr2;
- u32 esc;
+ u32 fcr; // 0x90 UARTx_UFCR
+ u32 sr1; // 0x94 UARTx_USR1
+ u32 sr2; // 0x98 UARTx_USR2
+ u32 esc; // 0x9C UARTx_UESC
- u32 tim;
- u32 bir;
- u32 bmr;
- u32 brc;
+ u32 tim; // 0xA0 UARTx_UTIM
+ u32 bir; // 0xA4 UARTx_UBIR
+ u32 bmr; // 0xA8 UARTx_UBMR
+ u32 brc; // 0xAC UARTx_UBRC
- u32 onems;
- u32 ts;
+ u32 onems; // 0xB0 UARTx_ONEMS
+ u32 ts; // 0xB4 UARTx_UTS
};
static void _mxc_serial_init(struct mxc_uart *base, int use_dte)
{
- writel(0, &base->cr1);
- writel(0, &base->cr2);
+ writel(0x3, CCM_BASE_ADDR + CCGR_UART4); //write to CCM
+ writel(0x140, IOMUXC_BASE_ADDR + SW_PAD_CTL_PAD_UART4_RXD); //write to IOMUXC
+ writel(0x0, IOMUXC_BASE_ADDR + SW_MUX_CTL_PAD_UART4_RXD); //write to IOMUC
+ writel(0x2, IOMUXC_BASE_ADDR + UART4_RXD_SELECT_INPUT); //write to IOMUXC
+ writel(0x140, IOMUXC_BASE_ADDR + SW_PAD_CTL_PAD_UART4_TXD); //write to IOMUXC
+ writel(0x0, IOMUXC_BASE_ADDR + SW_MUX_CTL_PAD_UART4_TXD); //write to IOMUXC
+ writel(0xFF, RDC_BASE_ADDR + SAI6_RX_SYNC_SELECT_INPUT); //write to RDC
+
+ writel(0, &base->cr1); //clear cr1
+ writel(0, &base->cr2); //clear cr2 this includes SRST
- while (!(readl(&base->cr2) & UCR2_SRST));
+ while (!(readl(&base->cr2) & UCR2_SRST)); //wait for the software reset to go low
- if (use_dte)
+ if (use_dte) //always false
writel(0x404 | UCR3_ADNIMP, &base->cr3);
else
- writel(0x704 | UCR3_ADNIMP, &base->cr3);
+ writel(0x704 | UCR3_ADNIMP, &base->cr3);//write to UCR3
- writel(0x704 | UCR3_ADNIMP, &base->cr3);
- writel(0x8000, &base->cr4);
- writel(0x2b, &base->esc);
- writel(0, &base->tim);
+ writel(0x704 | UCR3_ADNIMP, &base->cr3); //write to UCR3 again
+ writel(0x8000, &base->cr4); //32 characters in the RxFIFO (maximum)
+ writel(0x2b, &base->esc); // IR Special Case&TransmitComplete Interrupt Enable&Enable ORE interrupt&Enable RDR interrupt
+ writel(0, &base->tim); //UART Escape Timer 2ms
- writel(0, &base->ts);
+ writel(0, &base->ts); //issue software reset
}
static void _mxc_serial_setbrg(struct mxc_uart *base, unsigned long clk,
@@ -164,18 +180,18 @@ static void _mxc_serial_setbrg(struct mxc_uart *base, unsigned long clk,
u32 tmp;
tmp = RFDIV << UFCR_RFDIV_SHF;
- if (use_dte)
+ if (use_dte) //always false
tmp |= UFCR_DCEDTE;
else
- tmp |= (TXTL << UFCR_TXTL_SHF) | (RXTL << UFCR_RXTL_SHF);
- writel(tmp, &base->fcr);
+ tmp |= (TXTL << UFCR_TXTL_SHF) | (RXTL << UFCR_RXTL_SHF);//set up RXTL and TXTl
+ writel(tmp, &base->fcr);// write the values
- writel(0xf, &base->bir);
- writel(clk / (2 * baudrate), &base->bmr);
+ writel(0xf, &base->bir); //set the incremental numerator.
+ writel(clk / (2 * baudrate), &base->bmr); //set BRM Modulator Register.
writel(UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST,
- &base->cr2);
- writel(UCR1_UARTEN, &base->cr1);
+ &base->cr2); //set these values in UARTx_UCR2
+ writel(UCR1_UARTEN, &base->cr1); //enable the UART
}
#if !CONFIG_IS_ENABLED(DM_SERIAL)
@@ -196,14 +212,14 @@ static void mxc_serial_setbrg(void)
_mxc_serial_setbrg(mxc_base, clk, gd->baudrate, false);
}
-static int mxc_serial_getc(void)
+static int mxc_serial_getc(void)//read the rx data register
{
while (readl(&mxc_base->ts) & UTS_RXEMPTY)
WATCHDOG_RESET();
return (readl(&mxc_base->rxd) & URXD_RX_DATA); /* mask out status from upper word */
}
-static void mxc_serial_putc(const char c)
+static void mxc_serial_putc(const char c) //write the tx data register
{
/* If \n, also do \r */
if (c == '\n')
@@ -258,7 +274,7 @@ __weak struct serial_device *default_serial_console(void)
{
return &mxc_serial_drv;
}
-#endif
+#endif //!DM_SERIAL
#if CONFIG_IS_ENABLED(DM_SERIAL)
@@ -347,7 +363,7 @@ static const struct udevice_id mxc_serial_ids[] = {
{ .compatible = "fsl,imx6q-uart" },
{ }
};
-#endif
+#endif //OF_CONTROL
U_BOOT_DRIVER(serial_mxc) = {
.name = "serial_mxc",
@@ -356,14 +372,14 @@ U_BOOT_DRIVER(serial_mxc) = {
.of_match = mxc_serial_ids,
.ofdata_to_platdata = mxc_serial_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct mxc_serial_platdata),
-#endif
+#endif //OF_CONTROL
.probe = mxc_serial_probe,
.ops = &mxc_serial_ops,
#if !CONFIG_IS_ENABLED(OF_CONTROL)
.flags = DM_FLAG_PRE_RELOC,
-#endif
+#endif //OF_CONTROL
};
-#endif
+#endif //DM_SERIAL
#ifdef CONFIG_DEBUG_UART_MXC
#include <debug_uart.h>
@@ -389,4 +405,4 @@ static inline void _debug_uart_putc(int ch)
DEBUG_UART_FUNCS
-#endif
+#endif //CONFIG_DEBUG_UART_MXC