行吧,我自己解决了,跟大家分享一下。
首先修改sun8iw11p1.dtsi文件中的uart0(调试串口)和uart2串口,确保二者使用相同的配置。

uart0: uart@1c28000 { compatible = "allwinner,sun8i-uart"; device_type = "uart0"; reg = <0x0 0x01c28000 0x0 0x400>; interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_UART0>, <&ccu CLK_APB2>, //新加 <&ccu CLK_PLL_PERIPH0_2X>; //新加 resets = <&ccu RST_BUS_UART0>; clock-frequency = <30000000>; //新加,需要将频率设置为30MHz uart0_port = <0>; uart0_type = <2>; sunxi,uart-fifosize = <64>; status = "okay"; }; ... ... uart2: uart@1c28800 { compatible = "allwinner,sun8i-uart"; device_type = "uart2"; reg = <0x0 0x01c28800 0x0 0x400>; interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_UART2>, <&ccu CLK_APB2>, //新加 <&ccu CLK_PLL_PERIPH0_2X>; //新加 resets = <&ccu RST_BUS_UART2>; clock-frequency = <30000000>; //新加 clock-names = "uart2"; uart2_port = <2>; uart2_type = <2>; sunxi,uart-fifosize = <64>; status = "okay"; };

随后修改bsp/drivers/uart/sunxi-uart.c文件中对于port->uartclk的最后配置信息,修改为从设备树中获取,即代码的2094行的逻辑需要被注释,转而通过设备树中的配置获取其clk信息(2092行代码为修改后的逻辑)。

2071 /* uart clk come from apb2, apb2 default clk is hosc. if change rate 2072 * needed, must switch apb2's source clk first and then set its rate 2073 * */ 2074 sw_uport->sclk = of_clk_get(np, 1); 2075 if (!IS_ERR(sw_uport->sclk)) { 2076 sw_uport->pclk = of_clk_get(np, 2); 2077 port->uartclk = clk_get_rate(sw_uport->sclk); 2078 /* config a fixed divider before switch source clk for apb2 */ 2079 clk_set_rate(sw_uport->sclk, port->uartclk/6); 2080 /* switch source clock for apb2 */ 2081 clk_set_parent(sw_uport->sclk, sw_uport->pclk); 2082 ret = of_property_read_u32(np, "clock-frequency", 2083 &port->uartclk); 2084 if (ret) { 2085 SERIAL_MSG("uart%d get clock-freq failed\n", pdev->id); 2086 return -EINVAL; 2087 } 2088 /* set apb2 clock frequency now */ 2089 clk_set_rate(sw_uport->sclk, port->uartclk); 2090 } 2091 2092 ret = of_property_read_u32(np, "clock-frequency", 2093 &port->uartclk); 2094 // port->uartclk = clk_get_rate(sw_uport->mclk); //原处理 2095 #else 2096 port->uartclk = 24000000; 2097 #endif 2098 2099 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2100 if (res == NULL) { 2101 dev_err(&pdev->dev, "uart%d error to get MEM resource\n", pdev->id); 2102 return -EINVAL; 2103 } 2104 port->mapbase = res->start;

按照上述方法修改后,A40i黑匣子的调试串口会出现一段正常一段乱码(uart2阶段)随后又恢复正常的现象。同时开机后可以同时实现uart2串口(/dev/ttyS2)在波特率9600,115200,230400情况下收发均正常,且无乱码。