Using standard UARTs with mainline kernel

Hello,

We want to utilize the standard TK1 UARTs. However whenever the baud rate is set the following error occurs:

stty -F /dev/ttyTHS3 115200
stty: /dev/ttyTHS3: Input/output error

and dmesg states:

[ 2354.908929] serial-tegra 70006300.serial: configured baud rate is out of range by -6
[ 2354.916723] serial-tegra 70006300.serial: Failed to set baud rate
[ 2354.925069] serial-tegra 70006300.serial: Uart HW init failed, err = -5

This example worked well with the downstream kernel and BSP2.8. Do we need to manipulate the device tree? How can we use the UARTs with out setup?

Apalis TK1 V1.2A
Ixora V1.2A
BSP3.0 with mainline kernel 5.4

Regards

Hi @qojote ,

Unfortunately, the combination of BSP3.0 with mainline kernel 5.4 is not something Toradex supports out of the box.
If you have a look at our Embedded Linux Release Matrix you can see what Toradex supports.

I reproduced the same command with the BSP3.0 based on mainline kernel 4.14. And on my side, this command works without triggering an error.

Best Regards
Kevin

Hi,
The same error occurs when using the standard Toradex image for BSP5.4.0 TK1 mainline. So i guess its really related to the kernel version. A quick look into the patches for 4.14 recipe shows that there was a patch to add “nvidia,tegra30-hsuart” to the compatible string… but this is already part of the 5.4 device tree. Can you maybe point me into the right direction what needs to be done to get the UARTs working?
BR

Hi @qojote ,

I was able to reproduce the issue on BSP5.4 TK1 mainline.

We are currently looking into the issue. I will reach out to you again as soon as I have new about it.

Best Regards
Kevin

1 Like

Hi @qojote ,

this part of the driver below takes care of the tolerance range of the baudrate.

The tolerance is set to 0-4% or -2-4% depending on the serial controller. To make it work, one should configure the base clock at a rate that makes it possible to achieve the desired baudrate. Our team looked at the driver and it seems that it makes it possible to setup the clock base rate using the device tree.

You could try to setup the baudrate by setting “nvidia, adjust-baud-rates” property. The values setup there influence the “rate” variable in the tegra_set_baudrate function, and this variable is directly associated with the calculation that gives the error your seeing.

serial-tegra.c
1449         n_entries = of_property_count_u32_elems(np, "nvidia,adjust-baud-rates");                                                                         
1450         if (n_entries > 0) {                                                                                                                             
1451                 tup->n_adjustable_baud_rates = n_entries / 3;                                                                                            
1452                 tup->baud_tolerance =                                                                                                                    
1453                 devm_kzalloc(&pdev->dev, (tup->n_adjustable_baud_rates) *                                                                                
1454                              sizeof(*tup->baud_tolerance), GFP_KERNEL);                                                                                  
1455                 if (!tup->baud_tolerance)                                                                                                                
1456                         return -ENOMEM;                                                                                                                  
1457                 for (count = 0, index = 0; count < n_entries; count += 3,                                                                                
1458                      index++) {                                                                                                                          
1459                         ret =                                                                                                                            
1460                         of_property_read_u32_index(np,                                                                                                   
1461                                                    "nvidia,adjust-baud-rates",                                                                           
1462                                                    count, &pval);                                                                                        
1463                         if (!ret)                                                                                                                        
1464                                 tup->baud_tolerance[index].lower_range_baud =                                                                            
1465                                 pval;                                                                                                                    
1466                         ret =                                                                                                                            
1467                         of_property_read_u32_index(np,                                                                                                   
1468                                                    "nvidia,adjust-baud-rates",                                                                           
1469                                                    count + 1, &pval);                                                                                    
1470                         if (!ret)                                                                                                                        
1471                                 tup->baud_tolerance[index].upper_range_baud =                                                                            
1472                                 pval;                                                                                                                    
1473                         ret =                                                                                                                            
1474                         of_property_read_u32_index(np,                                                                                                   
1475                                                    "nvidia,adjust-baud-rates",                                                                           
1476                                                    count + 2, &pval);                                                                                    
1477                         if (!ret)                                                                                                                        
1478                                 tup->baud_tolerance[index].tolerance =                                                                                   
1479                                 (s32)pval;                                                                                                               
1480                 }

You can try to tweak the settings in this manner.

I hope this will help a bit.

Best Regards
Kevin

Hi @kevin.tx,
Thanks for your reply. Unfortunately i am not quite sure what needs to be done to get the UART working. As far as i unterstand the “nvidia, adjust-baud-rates” property can be some sort of a list, maybe something like “9600,115200…”? Where in the device tree i would have to make this addition? Is this a kernel boot param as well, e.g. can i set this property via editing the u-boot boot command?
BR

Hi @qojote ,

as I understood the people from R&D, it should not be necessary to make the addition yourself.

The code segment should show what calculations are made by the driver. So as an example suppose the desired baudrate is 115200 and the driver would add let’s say 5000 to the calculation. You should then enter 110200 as baudrate.

Can you try if this works?

Best Regards
Kevin

Hi @kevin.tx,
Unforunately all of my serial programs only accept common baud rates like 115200 and rejects e.g. 110200. Where does this magic number 5000 come from?
BR

Hi @qojote ,

the 5000 was just an example that the value you had to enter might differ from the ones you’re used to.

Your issue was escalated internally and our team is looking deeper into the issue.

Best Regards
Kevin

Hi @qojote ,

just to inform you there was a similar issue reported, and the user found a possible solution. You might want to give it a try and see if this works on your end too.

UART on TK1

Have a nice week.

Best Regards
Kevin

Hi guys,

I stumbled into this issue recently which was introduced with 5.4-rc1 and submitted a patch for this to the 5.4-stable and it will be merged with the upcoming 5.4.165 release, probably sometime next week.
It’s also already in 5.10 lts and current stable.

https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/stable-queue/+/0ab1d6d42323193367ea6a732e44087bbe1fda1f/queue-5.4/serial-tegra-change-lower-tolerance-baud-rate-limit-for-tegra20-and-tegra30.patch

BR

Patrik

Thank you for your feedback @pajo

BR, Janani