行吧,我自己解决了,跟大家分享一下。
首先修改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情况下收发均正常,且无乱码。