• OK335xS Linux kernel check clock 24M hacking


    /******************************************************************************
     *              OK335xS Linux kernel check clock 24M hacking
     * 声明:
     *     由于需要确认kernel中的时钟和引脚配置的时钟是否一致,于是需要去跟踪内核
     * 中的代码是如何对引脚配置时钟进行识别,并对其进行相关配置的额。
     *
     *                                            2016-1-5 深圳 南山平山村 曾剑锋
     *****************************************************************************/
    
    
    MACHINE_START(AM335XEVM, "am335xevm")
        /* Maintainer: Texas Instruments */
        .atag_offset    = 0x100,
        .map_io         = am335x_evm_map_io,
        .init_early     = am33xx_init_early,    ---------------+
        .init_irq       = ti81xx_init_irq,                     |
        .handle_irq     = omap3_intc_handle_irq,               |
        .timer          = &omap3_am33xx_timer,                 |
        .init_machine   = am335x_evm_init,                     |
    MACHINE_END                                                |
                                                               |
    void __init am33xx_init_early(void)         <--------------+
    {
        omap2_set_globals_am33xx();
        omap3xxx_check_revision();
        am33xx_check_features();
        omap_common_init_early();
        am33xx_voltagedomains_init();
        omap44xx_prminst_init();
        am33xx_powerdomains_init();
        omap44xx_cminst_init();
        am33xx_clockdomains_init();
        am33xx_hwmod_init();
        omap_hwmod_init_postsetup();
        omap3xxx_clk_init();                    --------------+
    }                                                         |
                                                              |
    int __init omap3xxx_clk_init(void)          <-------------+
    {
        struct omap_clk *c;
        u32 cpu_clkflg = 0;
    
        /*
         * 3505 must be tested before 3517, since 3517 returns true
         * for both AM3517 chips and AM3517 family chips, which
         * includes 3505.  Unfortunately there's no obvious family
         * test for 3517/3505 :-(
         */
        if (cpu_is_omap3505()) {
            cpu_mask = RATE_IN_34XX;
            cpu_clkflg = CK_3505;
        } else if (cpu_is_omap3517()) {
            cpu_mask = RATE_IN_34XX;
            cpu_clkflg = CK_3517;
        } else if (cpu_is_omap3505()) {
            cpu_mask = RATE_IN_34XX;
            cpu_clkflg = CK_3505;
        } else if (cpu_is_omap3630()) {
            cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
            cpu_clkflg = CK_36XX;
        } else if (cpu_is_ti816x()) {
            cpu_mask = RATE_IN_TI816X;
            cpu_clkflg = CK_TI816X;
        } else if (cpu_is_am33xx()) {
            am33xx_clk_init();                      ---------------------------+
            return 0;                                                          |
        } else if (cpu_is_ti814x()) {                                          |
            cpu_mask = RATE_IN_TI814X;                                         |
        } else if (cpu_is_omap34xx()) {                                        |
            if (omap_rev() == OMAP3430_REV_ES1_0) {                            |
                cpu_mask = RATE_IN_3430ES1;                                    |
                cpu_clkflg = CK_3430ES1;                                       |
            } else {                                                           |
                /*                                                             |
                 * Assume that anything that we haven't matched yet            |
                 * has 3430ES2-type clocks.                                    |
                 */                                                            |
                cpu_mask = RATE_IN_3430ES2PLUS;                                |
                cpu_clkflg = CK_3430ES2PLUS;                                   |
            }                                                                  |
        } else {                                                               |
            WARN(1, "clock: could not identify OMAP3 variant
    ");              |
        }                                                                      |
        ......                                                                 |
    }                                                                          |
                                                                               |
    int __init am33xx_clk_init(void)                   <-----------------------+
    {
        struct omap_clk *c;
        u32 cpu_clkflg;
    
        if (cpu_is_am33xx()) {
            cpu_mask = RATE_IN_AM33XX;
            cpu_clkflg = CK_AM33XX;
        }
    
        clk_init(&omap2_clk_functions);                ------------------------+
                                                                               |
        for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++)--*---+
            clk_preinit(c->lk.clk);                                            |   |
                                                                               |   |
        for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++)  |   |
            if (c->cpu & cpu_clkflg) {                                         |   |
                clkdev_add(&c->lk);                                            |   |
                clk_register(c->lk.clk);                                       |   |
                omap2_init_clk_clkdm(c->lk.clk);               ----------------*-+ |
            }                                                                  | | |
                                                                               | | |
        recalculate_root_clocks();                                             | | |
                                                                               | | |
        /*                                                                     | | |
         * Only enable those clocks we will need, let the drivers              | | |
         * enable other clocks as necessary                                    | | |
         */                                                                    | | |
        clk_enable_init_clocks();                     -------------------------*-*-*-+
                                                                               | | | |
        return 0;                                                              | | | |
    }                                                                          | | | |
                                                                               | | | |
                                                                               | | | |
    /* Common data */                                                          | | | |
                                                                               | | | |
    struct clk_functions omap2_clk_functions = {            <------------------+ | | |
        .clk_enable            = omap2_clk_enable,                             | | | |
        .clk_disable        = omap2_clk_disable,                               | | | |
        .clk_round_rate        = omap2_clk_round_rate,                         | | | |
        .clk_set_rate        = omap2_clk_set_rate,                             | | | |
        .clk_set_parent        = omap2_clk_set_parent,                         | | | |
        .clk_disable_unused    = omap2_clk_disable_unused,                     | | | |
    #ifdef CONFIG_CPU_FREQ                                                     | | | |
        /* These will be removed when the OPP code is integrated */            | | | |
        .clk_init_cpufreq_table    = omap2_clk_init_cpufreq_table,             | | | |
        .clk_exit_cpufreq_table    = omap2_clk_exit_cpufreq_table,             | | | |
    #endif                                                                     | | | |
    };                                                                         | | | |
                                                                               | | | |
    static struct clk_functions *arch_clock;                     --------------*-*-*-*-+
    int __init clk_init(struct clk_functions * custom_clocks)    <-------------+ | | | |
    {                                                                            | | | |
        if (!custom_clocks) {                                                    | | | |
            pr_err("No custom clock functions registered
    ");                    | | | |
            BUG();                                                               | | | |
        }                                                                        | | | |
                                                                                 | | | |
        arch_clock = custom_clocks;                                              | | | |
                                                                                 | | | |
        return 0;                                                                | | | |
    }                                                                            | | | |
                                                                                 | | | |
    void omap2_init_clk_clkdm(struct clk *clk)        <--------------------------+ | | |
    {                                                                              | | |
        struct clockdomain *clkdm;                                                 | | |
                                                                                   | | |
        if (!clk->clkdm_name)                                                      | | |
            return;                                                                | | |
                                                                                   | | |
        clkdm = clkdm_lookup(clk->clkdm_name);              -------+               | | |
        if (clkdm) {                                               |               | | |
            printk("clock: associated clk %s to clkdm %s
    ",       |               | | |
                 clk->name, clk->clkdm_name);                      |               | | |
            pr_debug("clock: associated clk %s to clkdm %s
    ",     |               | | |
                 clk->name, clk->clkdm_name);                      |               | | |
            clk->clkdm = clkdm;                                    |               | | |
        } else {                                                   |               | | |
            pr_debug("clock: could not associate clk %s to "       |               | | |
                 "clkdm %s
    ", clk->name, clk->clkdm_name);        |               | | |
        }                                                          |               | | |
    }                                                              |               | | |
                                                                   |               | | |
    struct clockdomain *clkdm_lookup(const char *name)      <------+               | | |
    {                                                                              | | |
        struct clockdomain *clkdm, *temp_clkdm;                                    | | |
                                                                                   | | |
        if (!name)                                                                 | | |
            return NULL;                                                           | | |
                                                                                   | | |
        clkdm = NULL;                                                              | | |
                                                                                   | | |
        list_for_each_entry(temp_clkdm, &clkdm_list, node) {                       | | |
            if (!strcmp(name, temp_clkdm->name)) {                                 | | |
                clkdm = temp_clkdm;                                                | | |
                break;                                                             | | |
            }                                                                      | | |
        }                                                                          | | |
                                                                                   | | |
        return clkdm;                                                              | | |
    }                                                                              | | |
                                                                                   | | |
                                                                                   | | |
    /*                                                                             | | |
     * clkdev         +----------------------------------------------------------+ | | |
     */               |                                                          | | | |
    static struct omap_clk am33xx_clks[] = {                     <---------------*-+ | |
        ......                                                                   |   | |
        CLK(NULL,    "clk_rc32k_ck",        &clk_rc32k_ck,    CK_AM33XX),        |   | |
        CLK(NULL,    "virt_19_2m_ck",    &virt_19_2m_ck,    CK_AM33XX),          |   | |
        CLK(NULL,    "virt_24m_ck",        &virt_24m_ck,    CK_AM33XX),          |   | |
        CLK(NULL,    "virt_25m_ck",        &virt_25m_ck,    CK_AM33XX),          |   | |
        CLK(NULL,    "virt_26m_ck",        &virt_26m_ck,    CK_AM33XX),          |   | |
        CLK(NULL,    "sys_clkin_ck",        &sys_clkin_ck,    CK_AM33XX),  ----+ |   | |
        CLK(NULL,    "tclkin_ck",        &tclkin_ck,    CK_AM33XX),            | |   | |
        CLK(NULL,    "dpll_core_ck",        &dpll_core_ck,        CK_AM33XX),  | |   | |
        CLK(NULL,    "dpll_core_x2_ck",    &dpll_core_x2_ck,    CK_AM33XX),    | |   | |
        CLK(NULL,    "dpll_core_m4_ck",    &dpll_core_m4_ck,    CK_AM33XX),    | |   | |
        CLK(NULL,    "dpll_core_m5_ck",    &dpll_core_m5_ck,    CK_AM33XX),    | |   | |
        CLK(NULL,    "dpll_core_m6_ck",    &dpll_core_m6_ck,    CK_AM33XX),    | |   | |
        CLK(NULL,    "sysclk1_ck",        &sysclk1_ck,    CK_AM33XX),          | |   | |
        CLK(NULL,    "sysclk2_ck",        &sysclk2_ck,    CK_AM33XX),          | |   | |
        ......                                                                 | |   | |
    };   |                                                                     | |   | |
         +-----------------------------------------+                           | |   | |
    struct omap_clk {                              |             <-------------*-+   | |
        u16                        cpu;            |                           |     | |
        struct clk_lookup        lk;               |                           |     | |
    };                                             |                           |     | |
                                                   |                           |     | |
    #define CLK(dev, con, ck, cp)            <----+                           |     | |
        {                                                                     |     | |
             .cpu = cp,                                                       |     | |
            .lk = {                                                           |     | |
                .dev_id = dev,                                                |     | |
                .con_id = con,                                                |     | |
                .clk = ck,                                                    |     | |
            },                                                                |     | |
        }                                                                      |     | |
                                                                               |     | |
    /* sys_clk_in */                                                           |     | |
    static struct clk sys_clkin_ck = {                      <------------------+     | |
        .name        = "sys_clkin_ck",                                               | |
        .parent        = &virt_24m_ck,                                               | |
        .init        = &omap2_init_clksel_parent,           ----------------------+  | |
    /**                                                                           |  | |
     * +------------------------------------------------------------------------+ |  | |
     * |        Table 9-14. control_status Register Field Descriptions          | |  | |
     * +-------+----------+------------+----------------------------------------+ |  | |
     * | Bit   | Field    | Type Reset | Description                            | |  | |
     * +-------+----------+------------+----------------------------------------+ |  | |
     * | 23-22 | sysboot1 | R/W 0h     | Used to select crystal clock frequency.| |  | |
     * |       |          |            | See SYSBOOT Configuration Pins.        | |  | |
     * |       |          |            | Reset value is from SYSBOOT[15:14].    | |  | |
     * +-------+----------+------------+----------------------------------------+ |  | |
     */                                                                           |  | |
        .clksel_reg    = AM33XX_CTRL_REGADDR(0x40),    /* CONTROL_STATUS */       |  | |
        .clksel_mask    = (0x3 << 22),                                            |  | |
        .clksel        = sys_clkin_sel,       -----------+                        |  | |
        .ops        = &clkops_null,           -----------*-----+                  |  | |
        .recalc        = &omap2_clksel_recalc,           |     |                  |  | |
    };                                                   |     |                  |  | |
                                                         |     |                  |  | |
    /* Oscillator clock */                               |     |                  |  | |
    /* 19.2, 24, 25 or 26 MHz */                         |     |                  |  | |
    static const struct clksel sys_clkin_sel[] = {  <----+     |                  |  | |
        { .parent = &virt_19_2m_ck, .rates = div_1_0_rates },  |                  |  | |
        { .parent = &virt_24m_ck, .rates = div_1_1_rates },    |   ------+        |  | |
        { .parent = &virt_25m_ck, .rates = div_1_2_rates },    |         |        |  | |
        { .parent = &virt_26m_ck, .rates = div_1_3_rates },    |         |        |  | |
        { .parent = NULL },                  |                 |         |        |  | |
    };                                       |                 |         |        |  | |
                                             |                 |         |        |  | |
    static struct clk virt_24m_ck = {        |        <--------*---------+        |  | |
        .name        = "virt_24m_ck",        |                 |                  |  | |
        .rate        = 24000000,             |                 |                  |  | |
        .ops        = &clkops_null,          |                 |                  |  | |
    };                                       |                 |                  |  | |
                                             v                 |                  |  | |
    static const struct clksel_rate div_1_1_rates[] = {        |                  |  | |
        { .div = 1, .val = 1, .flags = RATE_IN_AM33XX },       |                  |  | |
        { .div = 0 },                                          |                  |  | |
    };                                                         |                  |  | |
                                                               |                  |  | |
    const struct clkops clkops_null = {             <----------+                  |  | |
        .enable        = clkll_enable_null,                                       |  | |
        .disable    = clkll_disable_null,                                         |  | |
    };                                                                            |  | |
                                                                                  |  | |
                                                                                  |  | |
    // 到目前为止都不知道哪里调用了这个函数,因为这个函数是用来判断系统接入的晶振 |  | |
    // 大小的,没跟踪到到底是谁调用了该函数。                                     |  | |
    void omap2_init_clksel_parent(struct clk *clk)           <--------------------+  | |
    {                                                                                | |
        const struct clksel *clks;                                                   | |
        const struct clksel_rate *clkr;                                              | |
        u32 r, found = 0;                                                            | |
                                                                                     | |
        if (!clk->clksel || !clk->clksel_mask)                                       | |
            return;                                                                  | |
                                                                                     | |
        r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;                         | |
        r >>= __ffs(clk->clksel_mask);                                               | |
                                                                                     | |
        for (clks = clk->clksel; clks->parent && !found; clks++) {                   | |
            for (clkr = clks->rates; clkr->div && !found; clkr++) {                  | |
                if (!(clkr->flags & cpu_mask))                                       | |
                    continue;                                                        | |
                                                                                     | |
                if (clkr->val == r) {                                                | |
                    if (clk->parent != clks->parent) {                               | |
                        pr_debug("clock: inited %s parent "                          | |
                             "to %s (was %s)
    ",                                     | |
                             clk->name, clks->parent->name,                          | |
                             ((clk->parent) ?                                        | |
                              clk->parent->name : "NULL"));                          | |
                        clk_reparent(clk, clks->parent);         ------------+       | |
                    };                                                       |       | |
                    found = 1;                                               |       | |
                }                                                            |       | |
            }                                                                |       | |
        }                                                                    |       | |
                                                                             |       | |
        printk("zengjf ckeck function calling [%s].
    ", __func__);           |       | |
        /* This indicates a data error */                                    |       | |
        WARN(!found, "clock: %s: init parent: could not find regval %0x
    ",  |       | |
             clk->name, r);                                                  |       | |
                                                                             |       | |
        return;                                                              |       | |
    }                                                                        |       | |
                                                                             |       | |
    int clk_reparent(struct clk *c, struct clk *parent)          <-----------+       | |
    {                                                                                | |
        c->parent = parent;                                                          | |
        return 0;                                                                    | |
    }                                                                                | |
                                                                                     | |
    void clk_enable_init_clocks(void)                            <-------------------+ |
    {                                                                                  |
        struct clk *clkp;                                                              |
                                                                                       |
        list_for_each_entry(clkp, &clocks, node) {                                     |
            if (clkp->flags & ENABLE_ON_INIT)                                          |
                clk_enable(clkp);                                -------+              |
        }                                                               |              |
    }                                                                   |              |
                                                                        |              |
    /*                                                                  |              |
     * Standard clock functions defined in include/linux/clk.h          |              |
     */                                                                 |              |
                                                                        |              |
    int clk_enable(struct clk *clk)                              <------+              |
    {                                                                                  |
        unsigned long flags;                                                           |
        int ret;                                                                       |
                                                                                       |
        if (clk == NULL || IS_ERR(clk))                                                |
            return -EINVAL;                                                            |
                                                                                       |
        if (!arch_clock || !arch_clock->clk_enable)                                    |
            return -EINVAL;                                                            |
                                                                                       |
        spin_lock_irqsave(&clockfw_lock, flags);                                       |
        ret = arch_clock->clk_enable(clk);                      <----------------------+
        spin_unlock_irqrestore(&clockfw_lock, flags);
    
        return ret;
    }
    EXPORT_SYMBOL(clk_enable);
  • 相关阅读:
    localStorage和sessionStorage区别(包括同源的定义)
    跨域问题实践总结! 上(JSONP/document.domain/window.name)
    7月11日计划
    图形验证码知识点整理 Object.prototype.toString.call()等
    学习日报 7-10(验证码)
    Mysql安装与主从配置
    windows service编程
    Entity Framework——常见报错总结
    Entity Framework——读写分离
    Entity Framework——执行sql语句
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/5102882.html
Copyright © 2020-2023  润新知