Edit online

设计说明

3 Mar 2025
Read time: 2 minute(s)

源码说明

内核的时钟驱动框架位于 linux-5.10/drivers/clk 目录下,CMU 的底层驱动位于/drivers/clk/artinchip/目录下。

ArtInChip 的目录结构如下图所示:

文件

说明

clk-aic.h

aic 公用头文件

clk-aic.c

CMU 各个时钟的初始化,注册文件

clk-disp.c

显示模块的时钟文件

clk-fixed-parent-mod.c

只有一个父时钟源的时钟文件

clk-multi-parent-mod.c

具有多个父时钟源的时钟文件

clk-pll.c

PLL 时钟文件

Clock

按照 CCF 框架,时钟分为下列类别:
  • fixed rate clock

  • gate clock

  • divider clock

  • mux clock

  • fixed clock

  • composite clock

时钟树中的每一个 divider、gate、mux 都需要定义一个 hw 结构体。CMU 模块中有大量 gate 和 divider,因此为了代码的简洁性和易用性,CMU 的驱动并未严格按照 CCF 框架编写。CMU 驱动模块将时钟分为多种类型,且每种分类都有一个对应的自定义结构体,用来实现各种时钟操作:
注: 关于时钟分类和时钟树的描述,可查看下列时钟树章节cmu-design-guide-lb-luban.html#concept_nmr_yn3_pzb__section_itz_c44_mdc
  • 在 fixed parent module 的结构体中,定义了模块的 bus_gate 和 module_gate,以及该类型时钟的分频系数,相当于综合了 CCF 框架中的 gate 和 divider。

  • 在 multiple parent module 的结构体中定义了 gate,mux 以及分频系数,相当于综合了 CCF 框架中的 gate,divider 和 mux。

1. 各时钟类型支持的 API 接口

类型

fixed rate clock

fixed parent clock

multi parent clock

disp clock

pll clock

clk_prepare

clk_prepare_enable

clk_unprepare

clk_disable_unprepare

clk_set_rate

-

clk_get_rate

clk_round_rate

-

clk_set_parent

-

-

-

-

clk_get_parent

-

-

-

-

recalc_rate

Reset

CMU 模块的 reset 驱动实现基于内核提供的 framework。其实现过程是创建并填充内核提供的 controller 设备结构体(struct reset_controller_dev),并调用相应的接口:
  • reset_controller_register

  • reset_controller_unregister

注册或注销。reset controller 的结构体如下:
struct reset_controller_dev {
        const struct reset_control_ops *ops;
        struct module *owner;
        struct list_head list;
        struct list_head reset_control_head;
        struct device *dev;
        struct device_node *of_node;
        int of_reset_n_cells;
        int (*of_xlate)(struct reset_controller_dev *rcdev,
                    const struct of_phandle_args *reset_spec);
        unsigned int nr_resets;
};

驱动实现过程主要是对 ops 结构体中的函数指针进行填充,基本上是 reset 驱动的所有工作量。在 CMU 模块的 reset 驱动中,实现了对 assert 和 deassert 及 status 三个函数指针的填充。