Licheepi-zero uart高速时钟设置

项目使用到licheepi的uart接口,外接使用921600频率的uart设备,后应用程序中设置波特率后发现程序乱码,后查到内核uart时钟为24M导致分频后偏差比较大。

在V3S的uart是挂在APB2下面的,需修改APB2时钟,而目前的内核默认使用的一般是uboot设置的时钟配置,一般使用clk_ops->get_parent获取寄存器中的数据,这是便是父时钟节点。
然后使用clk_ops->recalc_rate获取时钟频率。

而寄存器中的值一般是在uboot时期设置好的,clk_ops->set_parent一般在启动初始化时候未使用。

然后是修改,因为设备同时使用921600 和 115200 两个频率,即取两个频率的最大公约数的倍数。 然后我们选定120M作为APB2时钟。
修改uboot的arch/arm/mach-sunxi/clock_sun6i.c,

void clock_init_uart(void)
{
#if CONFIG_CONS_INDEX < 5
        struct sunxi_ccm_reg *const ccm =
                (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;

        /* uart clock source is apb2 */
        writel(APB2_CLK_SRC_PLL6 |                   
          APB2_CLK_RATE_N_1|               
               APB2_CLK_RATE_M(5),        
               &ccm->apb2_div);
      ....
  }

上面APB2_CLK_SRC_PLL6 为2,即使用PLL_PERIPH0时钟,其值为600M,
APB2 = 600 / 1/5 = 120M

然后再修改include/configs/sunxi-common.h

#define CONFIG_SYS_NS16550_CLK         120000000
#ifndef CONFIG_DM_SERIAL

最后在修改内核里面的APB2时钟设置 (为什么要设置呢? 因为内核只读取uboot的父时钟作为基准,这里读取的值是2 ,即使用PLL_PERIPH0时钟)
修改 内核里 drivers/clk/sunxi-ng/ccu-sun8i-v3s.c

static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
                 0, 4,  /* M */
                 16, 1, /* P */
                 24, 2, /* mux */
                 0);

OK,修改完成,虽然频率有点偏差,但是不影响正常使用。

附: 内核读取时钟方式:

    ccu: clock@01c20000 {
        compatible = "allwinner,sun8i-v3s-ccu";
        reg = <0x01c20000 0x400>;
        clocks = <&osc24M>, <&osc32k>;
        clock-names = "hosc", "losc";
        #clock-cells = <1>;
        #reset-cells = <1>;
    };

    uart0: serial@01c28000 {
        compatible = "snps,dw-apb-uart";
        reg = <0x01c28000 0x400>;
        interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
        reg-shift = <2>;
        reg-io-width = <4>;
        clocks = <&ccu CLK_BUS_UART0>;
        resets = <&ccu RST_BUS_UART0>;
        status = "disabled";
    };

驱动中则使用上述的clock-names属性作为clk_get()或devm_clk_get()的第二个参数来申请时钟,譬如获取第2个时钟
devm_clk_get(pctl->dev, “hosc”)

clocks = <&ccu CLK_BUS_UART0> 里的CLK_BUS_UART0这个index是与相应时钟驱动中ccu的表的顺序对应的,这里定义在include/dt-bindings/clock/sun8i-v3s-ccu.h,一般dts里有显示包含文件。一般devm_clk_get也可以根据这个index来查找。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值