Hi Petr, per you comments it seems there is a dependency on uboot which is a bit unexpected to me.
Based on what you mention, one guess I have is uboot is passing initialized uart channel and linux, just changes baud rate but never inits the registers from the channel.
So I would check:
- where in uboot the uart channel is initialized (selected with CONFIG_SYS_UART_PORT)
- check if there is any of this code in the linux kernel low level uart driver initialization (perhaps where baud rate is changed gives a clue) check if this is done for every instance or not.
If there is no such code on linux kernel, then it means it relies on uboot... a quick fix would be adding some register writes on uboot (besides the pin init) to properly initialize the channel.
I may be able to take a look into this tomorrow but wanted to share with you because maybe you do better progress than me.
For your reference, some of the code we use to initialize UART on bare metal... this is what needs to be found on similar form on any of the uboot or linux code.
void uart_init(unsigned long int clkspeed, unsigned long int baud)
{
uint16 sbr, brfa;
/* Enable the pins for the selected UART */
if(UART_PORT==UART0) //UART0
{
//CCM->CCGR0 |= CCM_CCGR0_CG7(1); //Ungate UART0 clock
IOMUXC->SINGLE.PTB10 = 0x001011A2; //TX
IOMUXC->SINGLE.PTB11 = 0x001011A1; //RX
}
if(UART_PORT==UART1) //UART1
{
CCM->CCGR0 |= CCM_CCGR0_CG8(1); //Ungate UART1 clock
IOMUXC->SINGLE.PTB4 = 0x002011A2; //TX
IOMUXC->SINGLE.PTB5 = 0x002011A1; //RX
IOMUXC->SCI_FLX1_IPP_IND_SCI_RX_SELECT_INPUT=0; //Select PTB5 as RX input
}
if(UART_PORT==UART2) //UART2
{
CCM->CCGR0 |= CCM_CCGR0_CG9(1); //Ungate UART2 clock
IOMUXC->SINGLE.PTB6 = 0x007011A2; //TX
IOMUXC->SINGLE.PTB7 = 0x007011A1; //RX
IOMUXC->SCI_FLX2_IPP_IND_SCI_RX_SELECT_INPUT=0; //Select PTB7 as RX input
}
UART_PORT->MODEM=0; //Need to clear MODEM register in case BootROM sets it
/* Make sure that the transmitter and receiver are disabled while we
* change settings->
*/
UART_PORT->C2 &= ~UART_C2_RE_MASK;
UART_PORT->C2 &= ~UART_C2_TE_MASK;
/* Configure the UART for 8-bit mode, no parity */
UART_PORT->C1 = 0x00; /* We need all default settings, so entire register is cleared */
/* Calculate baud settings */
sbr = (uint16)((clkspeed*1000)/(baud * 16));
UART_PORT->BDH |= UART_BDH_SBR((sbr & 0x1F00) >> 8);
UART_PORT->BDL = UART_BDL_SBR((uint8)(sbr & 0x00FF));
/* Determine if a fractional divider is needed to get closer to the baud rate */
brfa = (((clkspeed*32000)/(baud * 16)) - (sbr * 32));
UART_PORT->C4 &= ~UART_C4_BRFA_MASK;
UART_PORT->C4 |= UART_C4_BRFA(brfa);
/* Enable receiver and transmitter */
UART_PORT->C2 |= UART_C2_RE_MASK;
UART_PORT->C2 |= UART_C2_TE_MASK;
}