NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

Clock Framework User Guide

From Texas Instruments Wiki
Jump to: navigation, search

Introduction[edit]

This document provides details about clock generation and distribution in hardware, Clock tree implementation in software, Enabling, disabling and changing rate of a clock.

Software Implementation[edit]

Hardware connections are mimicked in software to create complete network of clocks called the Clock Tree.
Parent clock: The clock which provides source
Child clock: A clock to which source is provided
Sibling clock: Clocks drawing source from same parent clock

  • Clock data structure
struct clk {
        struct list_head        node;
        const struct clkops     *ops;
        const char              *name;
        struct clk              *parent;
        struct list_head        children;
        struct list_head        sibling;        /* node for children */
        ......... Many fields are omitted here......
        unsigned long           rate;
        unsigned long           (*recalc)(struct clk *);
        int                     (*set_rate)(struct clk *, unsigned long);
        long                    (*round_rate)(struct clk *, unsigned long);
       ...................................
        s8                      usecount;
       ...................................
};

NOTE: Refer to <linux_kernel>/arch/arm/plat-omap/include/plat/clock.h for description of each field.

Usage[edit]

  • For all of the following operations include clk.h,
#include <linux/clk.h>

Enabling And Disabling Clock[edit]

Acquire/Get clock Pointer[edit]

  • To get a pointer the the clock structure
struct clk *clkp;
clkp = clk_get(dev_id,clk_name);
if(!clkp)
     pr_err("clk_get failed\n");
  • dev_id of some clocks may be NULL in that case pass NULL in place of dev_id

NOTE: Refer to <kernel_installation>/arch/arm/mach-omap2/clock814x_data.c or <kernel_installation>/arch/arm/mach-omap2/clock816x_data.c to find whether the device id of a clock is NULL or valid string.You can find this info in ti814x_clks[] array, where in the first field is dev_id and second field is clock name. clkp = clk_get(NULL,clk_name);

  • Example
struct clk *clkp;

clkp = clk_get(NULL,"gem_fck");
if(!clkp)
     pr_err("clk_get failed for gem_fck\n");

Release/Put clock Pointer[edit]

  • To free the pointer to the clock structure, use the clock pointer(clkp) acquired through clk_get(),
clk_put(clkp);

Enable Clock[edit]

  • A clock must be enabled before using it as a source of clock to any module,to enable the clock, use the clock pointer(clkp) acquired through clk_get(),
clk_enable(clkp);

Disable Clock[edit]

  • A clock can be disabled when the clock is no longer required by any modules or its children clocks,to disable the clock, use the clock pointer(clkp) acquired through clk_get(),
clk_disable(clkp);

Change Clock Rate[edit]

Get clock current rate[edit]

  • To get the current frequency/rate of the clock, use the clock pointer(clkp) acquired through clk_get(),
u32 clk_rate;
clk_rate = clk_get_rate(clkp);

Change clock rate[edit]

Note: From release 04.01.00.06 for ti814x /04.00.01.13 for ti816x, a clock must be acquired and enabled before changing the rate, enabling the clock will increment the use-count and avoid conflicts such as multiple users setting the rate.
Call to set_rate will return with failure if either the use-count is zero or greater than one thus preventing users from changing rate of the clocks that could affect other users.

  • To see if the rate you are targetting is possible for the clock or not, use clk_round_rate() with the clock pointer(clkp) acquired through clk_get(), pass target rate in Hz,.
 
rounded_rate = clk_round_rate(clkp, target_rate);

Now call set_rate, remember set_rate takes clock frequency in '''Hz''' only;

ret = clk_set_rate(clkp, rounded_rate);
  • Below is an example code showing how to change rate of gem_ick
struct clk *clk;
unsigned long rate;
int ret;

clk = clk_get(NULL, "gem_ick");

rate = clk_get_rate(clk);

rounded_rate = clk_round_rate(clk, 600000000);

ret = clk_set_rate(clk, rounded_rate);

  • Changing clock rate may be un-successful in following cases:
- Clock is drawing source from a fixed rate clock source(e.g. OSC0,OSC1,XREF etc)
- Clock is in use by more than one modules/children, usecount > 1
- Clock source is in use by more than one children.

Change clock Parent[edit]

  • Currently change parent is not supported through clock frame work((at run time))

Alternatively, this can be done from uboot command prompt as below:
1. Load uboot, wait for 1st stage to complete
2. Interrupt the autoboot of 2nd stage (countdown from 3-0)
3. Find the clockselection register corresponding to the clk whose parent needs to be changed, refer to TRM/PRCM doc
4. write the value corresponding to new parent to the register
ex:

to write to a reg:# mw 0x481c50c4 0x3
to read from a reg:# md 0x481c50c4 1
for help:# help

Browsing DebugFs for Clock configuration[edit]

Clock tree from debugfs[edit]

Details of clocks such as rate,usecount and flags can be viewed through debugfs entries of the clocks. To access these details one has to mount the debugfs root directory first,follow the steps below to mount debugfs and view clock details:

1. Create a directory to mount the debugfs root or use /sys/kernel/debug

 $ mount -t debugfs debugfs /sys/kernel/debug 

2. Change to clock directory under debugfs,clock entries arranged exactly same as clock tree, ie. root clock -> child clock & sibling clocks, to see the details,

 $ cd /sys/kernel/debug/clock
 root@ti8168-evm:/sys/kernel/debug/clock# ls

ex:

 root@ti8168-evm:~# cd /sys/kernel/debug/clock/
 root@ti8168-evm:/sys/kernel/debug/clock# ls osc0_clkin_ck/dsp_dpll_ck/gem_fck/
 flags  rate  usecount
 root@ti8168-evm:/sys/kernel/debug/clock# cd osc0_clkin_ck/dsp_dpll_ck/gem_fck/
 root@ti8168-evm:/sys/kernel/debug/clock/osc0_clkin_ck/dsp_dpll_ck/gem_fck# cat rate
 500000000

Finding a clock[edit]

  • To find a clock, ex: "gem_ick"
root@ti8168-evm:/sys/kernel/debug/clock# ls -lR | grep gem_ick

Using Script to dump details[edit]

The shell script given below can be used to browse the clock tree for debugging purposes.

#!/bin/sh
#  Clock tree browser
#  Version: 1.0
#  Copyright (C) {2011} Texas Instruments Incorporated - http://www.ti.com/
#
#  USAGE
#     $ browser [attribute] [clock]
#     attribute - can be either rate; flags or usecount
#   clock - clock source to browse; optional parameter; if not specified
#           displays the specified attribute for all the clocks in system 
#  EXAMPLES
#     $browser rate dpll1_fck # Display rate for dpll1_fck
#     $browser rate dpll1 # Display rate for all clocks associated with dpll1
#  ASSUMPTIONS
#     Assumes debug filesystem is available and mounted at /sys/kernel/debug
cd /sys/kernel/debug/clock/
if [ "$2" != "" ]
then find ./ -type f -name $1 | grep $2 > /var/myfile;
else find ./ -type f -name $1 > /var/myfile;
fi
while read line
do
echo "$line ==> `cat $line`";
done < "/var/myfile"

Copy the above script to a file, say "browser", copy this file to your file system(nfs/ramdisk) and chmod to execution,
Mount the debugfs as explianed above then execute: 1. To lis current rate of all colcks

$./browser rate

2. To list rate of a particular clock

$./browser rate gem_ick

3. similarly you can list the usecount.

Future Work[edit]

FAQ[edit]

E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Clock Framework User Guide here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Clock Framework User Guide here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article Clock Framework User Guide here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article Clock Framework User Guide here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article Clock Framework User Guide here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Clock Framework User Guide here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Clock Framework User Guide here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article Clock Framework User Guide here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Clock Framework User Guide here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity