How do I change the IMX6 UART clock speed

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How do I change the IMX6 UART clock speed

Jump to solution
6,720 Views
sivaalagarsamy
Contributor II

Hi,

I have a IMX6 quad core development board. I am running Yocto linux on it. I need a custom baud rate of 1041667 on a serial port to talk to a device. With the current UART clock speed of 80MHz, I won't be able to get that particular speed. If I can change the UART clock to 50MHz, the base baud rate will be 3125000 and with a custom divisor of 3, I will get the 1041667 baud rate.
I understand that the UART clock speed is derived from a main clock that is used for CPU and other subsytem.  Where do I start looking to change the clock speed for the UART? 

Thanks,

Siva

Labels (4)
Tags (5)
1 Solution
2,196 Views
johnw
Contributor III

To answer your question - I did some checking - I don't think the input  to the UART module clock is flexible.  Meaning, it comes from PLL3 which is used to create the 480MHz USB clock, and is divided down to 80 MHz for the input to the UART (integer divided by 6).  This is per the reference manual of the chip - look for "CCM Clock Tree".  PLL3's output is fixed at 20x the input clock to the SOC (usually 24 MHz), so this is 480 MHz.

The baud rate generator for the chip is really flexible, though, so you really shouldn't need to change the input clock to the UART module to achieve the desired baud rate.  You should be able to get the exact rate you need using the binary rate multiplier in the UART (BRM).  That appears to have the ability to multiply/divide the reference clock using a 16-bit numerator and denominator.

Module Clock             80

Reference Clock          26.66666667

Reference Clock Divider  3

UBMR                     1599

UBIR                     999

Calculated Baud Rate     1.041666667

Desired Baud Rate        1.041666667

16x desired baud rate    16.66666667

Ratio                    1.6

I hope this helps.

View solution in original post

4 Replies
2,196 Views
letan
Contributor III

wiringBone/UART.cpp at master · AbhraneelBera/wiringBone · GitHub

This uses termios2 to set the custom baudrate

0 Kudos
2,197 Views
johnw
Contributor III

To answer your question - I did some checking - I don't think the input  to the UART module clock is flexible.  Meaning, it comes from PLL3 which is used to create the 480MHz USB clock, and is divided down to 80 MHz for the input to the UART (integer divided by 6).  This is per the reference manual of the chip - look for "CCM Clock Tree".  PLL3's output is fixed at 20x the input clock to the SOC (usually 24 MHz), so this is 480 MHz.

The baud rate generator for the chip is really flexible, though, so you really shouldn't need to change the input clock to the UART module to achieve the desired baud rate.  You should be able to get the exact rate you need using the binary rate multiplier in the UART (BRM).  That appears to have the ability to multiply/divide the reference clock using a 16-bit numerator and denominator.

Module Clock             80

Reference Clock          26.66666667

Reference Clock Divider  3

UBMR                     1599

UBIR                     999

Calculated Baud Rate     1.041666667

Desired Baud Rate        1.041666667

16x desired baud rate    16.66666667

Ratio                    1.6

I hope this helps.

2,196 Views
sivaalagarsamy
Contributor II

Thanks for the information. I started looking into the linux serial driver to see why the custom baud rate was not working. The driver does calculate the right numerator and denominator for a given buad rate and sets it in the UBMR and UBIR registers. The only problem I see is that the driver calls  uart_get_baud_rate function in the serial_core.c which in turn calls "tty_termios_baud_rate" in tty_ioctl.c. This function has a #ifdef BOTHER to allow custom baud rate. This BOTHER is not defined for the freescale kernel. 

tty_ioctl.c:

305 speed_t tty_termios_baud_rate(struct ktermios *termios)

306 {

307  unsigned int cbaud;

308

309  cbaud = termios->c_cflag & CBAUD;

310

311 #ifdef BOTHER

312   /* Magic token for arbitrary speed via c_ispeed/c_ospeed */

313  if (cbaud == BOTHER)

314  return termios->c_ospeed;

315 #endif

316  if (cbaud & CBAUDEX) {

317  cbaud &= ~CBAUDEX;

318

319  if (cbaud < 1 || cbaud + 15 > n_baud_table)

320   termios->c_cflag &= ~CBAUDEX;

321  else

322  cbaud += 15;

323  }

324  return baud_table[cbaud];

325 }

0 Kudos
2,196 Views
letan
Contributor III

Hello Mr.Siva,

Could you please show me how we can fix this?

I am looking forward to your respond!

Thanks,

Tan

0 Kudos