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