Linux下时钟框架实践---一款芯片的时钟树配置

本文详细介绍了在Linux下配置和验证时钟框架的过程,包括编写时钟provider驱动,如晶振、PLL、Mux、Divider和Gate,以及consumer如何使用时钟。通过clk_summary验证时钟树,并在设备驱动中应用时钟。
摘要由CSDN通过智能技术生成

关键词:时钟、PLL、Mux、Divider、Gate、clk_summary等。

时钟和电源是各种设备的基础设施,整个时钟框架可以抽象为几种基本的元器件:负责提供晶振

Linux内核提供了良好的CCF(Common Clock Framework),框架的两端一个是provider,一个是consumer。

provider指的是提供时钟模块,包括晶振、PLL、Mux、Divider、Gate等,consumer指的是使用这些时钟的模块。

 

1. Linux时钟框架基础

相关文档对时钟框架做了详细的介绍:《Linux common clock framework(1)_概述》、《Linux common clock framework(2)_clock provider》、《Linux common clock framework(3)_实现逻辑分析》以及《Common Clock Framework系统结构》。

这里简单罗列一下相关知识。

1.1 编写时钟provider驱动

provider包含基本硬件元素:Oscillator/Crystal-提供时钟晶振、PLL-倍频、Mux-多路选择、Divider-分频器、Gate-控制开关,还有Fixed-Divider-固定分频器。

这些硬件都可以抽象成一种类型的时钟,所有类型的时钟都可以通过struct clk_hw描述。

struct clk_hw {
    struct clk_core *core;
    struct clk *clk;
    const struct clk_init_data *init;
};

struct clk_core {
    const char        *name;
    const struct clk_ops    *ops;
    struct clk_hw        *hw;
    struct module        *owner;
    struct clk_core        *parent;
    const char        **parent_names;
    struct clk_core        **parents;
    u8            num_parents;
    u8            new_parent_index;
    unsigned long        rate;
    unsigned long        req_rate;
    unsigned long        new_rate;
    struct clk_core        *new_parent;
    struct clk_core        *new_child;
    unsigned long        flags;
    bool            orphan;
    unsigned int        enable_count;
    unsigned int        prepare_count;
    unsigned long        min_rate;
    unsigned long        max_rate;
    unsigned long        accuracy;
    int            phase;
    struct hlist_head    children;
    struct hlist_node    child_node;
    struct hlist_head    clks;
    unsigned int        notifier_count;
#ifdef CONFIG_DEBUG_FS
    struct dentry        *dentry;
    struct hlist_node    debug_node;
#endif
    struct kref        ref;
};
struct clk_init_data {
    const char        *name;
    const struct clk_ops    *ops;
    const char        * const *parent_names;
    u8            num_parents;
    unsigned long        flags;
};
struct clk_ops { int (*prepare)(struct clk_hw *hw); void (*unprepare)(struct clk_hw *hw); int (*is_prepared)(struct clk_hw *hw); void (*unprepare_unused)(struct clk_hw *hw); int (*enable)(struct clk_hw *hw); void (*disable)(struct clk_hw *hw); int (*is_enabled)(struct clk_hw *hw); void (*disable_unused)(struct clk_hw *hw); unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate); int (*determine_rate)(struct clk_hw *hw, struct clk_rate_request *req); int (*set_parent)(struct clk_hw *hw, u8 index); u8 (*get_parent)(struct clk_hw *hw); int (*set_rate)(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate); int (*set_rate_and_parent)(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index); unsigned long (*recalc_accuracy)(struct clk_hw *hw, unsigned long parent_accuracy); int (*get_phase)(struct clk_hw *hw); int (*set_phase)(
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值