Re: [PATCH] serial: 8250: Tolerate clock variance for max baud rate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sebastian,

On 26/02/15 08:51, Sebastian Andrzej Siewior wrote:
> On 02/26/2015 01:21 AM, James Hogan wrote:
>> When the UART clock is set slightly under 1.8432MHz, the 8250 driver
>> core doesn't permit the 115200 baud rate since it calculates the maximum
>> frequency to pass to uart_get_baud_rate by simply dividing the uart
>> clock by 16 which yields a value slightly under 115200, even though the
>> frequency is close enough for the UART to operate reliably.
>>
>> Therefore add some tolerance in the calculation of the maximum baud
>> rate, specifically +1/128th (~0.8%), to allow the 115200 baud rate to
>> be closen for a UART clock as low as 1.8149MHz. For an external divider
>> set as close as possible to 1.8432MHz, this should cover every possible
>> input frequency above 118.9MHz.
>>
>> Signed-off-by: James Hogan <james.hogan@xxxxxxxxxx>
>> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
>> Cc: Jiri Slaby <jslaby@xxxxxxx>
>> Cc: Anton Vorontsov <avorontsov@xxxxxxxxxxxxx>
>> Cc: Peter Hurley <peter@xxxxxxxxxxxxxxxxxx>
>> Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
>> Cc: linux-serial@xxxxxxxxxxxxxxx
>> ---
>> As far as I can tell from reading the link below, this tolerance should
>> be okay, and it definitely covers the range of input frequencies I
>> expect for my particular hardware. I'm open to better ways of handling
>> it though.
> 
> What is your hardware?

SoC is TZ1090 (metag based). UART clock is best derived from system
clock which would normally be somewhere between 180MHz and 240MHz, using
an integer divider.

> (1814900 + 1814900 / 128) / 16
>         114317
> It is not 115200 but close enough to get you the 115200 baud rate. It
> might make sense to increase the tolerance rather than increasing the
> the clock but it is up to Peter / Alan to decide.

One random example configuration I have here is:

# cat /sys/kernel/debug/clk/clk_summary
   clock                         enable_cnt  prepare_cnt        rate
--------------------------------------------------------------------
 xtal1                                    2            2    24576000
    sys_sw                                1            1    24576000
       sys_pll                            1            1   719965090
          sys_div                         1            1   719965090
             sys_x2_undeleted             1            1   719965090
                sys_undeleted             2            2   179991273
                   uart_sw                1            1   179991273
                      uart_en             1            1   179991273
                         uart             1            1     1836646

sys_undeleted  divide     uart    baud          error
    179991273      97  1855580  115973   774 =  0.67%
    179991273      98  1836646  114790  -410 = -0.36% (chosen)

At this sys_undeleted frequency, the difference between two consecutive
divider values is about 1183 Hz.
For round to closest, the max error is about 591.5 Hz = 0.513%.
For round up (i.e. increasing the clock), the max error is about 1183 Hz
= 1.03%.

So my reasoning is that rounding to closest and fixing 8250 driver to
accept it and getting as accurate a baud rate as possible is better than
having a less accurate baud rate and having to add a new rounding mode
to common clock muxes and dividers.

Note that AFAICT for faster input clocks the 8250 driver would accept a
115200 baud rate regardless of how inaccurate the resulting baud rate
would be after division, so arguably the tolerance could be much higher.

The serial core also calculates the divider with DIV_ROUND_CLOSEST, so
there is precedent for using that rounding mode right up through the
clock tree.

Cheers
James

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux