匿名
未登录
登录
百问网嵌入式Linux wiki
搜索
查看“Clock overview”的源代码
来自百问网嵌入式Linux wiki
名字空间
页面
讨论
更多
更多
页面选项
Read
查看源代码
历史
←
Clock overview
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
This article gives information about the Linux® Clock framework. <br> Clocks are generally provided by internal/external oscillators or PLLs. <br> They can pass through a gate, a muxing, a divider or a multiplier. <br> All peripheral clocks are organized as a tree.<br> All these elements are managed by the Common Clock framework. == Framework purpose == The purpose of this article is to introduce the Common Clock Framework. It provides general information and, based on examples, explains how to use it. Linux Common Clock framework offers a generic API for configuring and controlling the different system clocks.<br/> Drivers can easily enable/disable clocks, change their frequency, change the parent of the clocks associated to peripherals without any knowledge of the clock characteristics.<br/> All clock tree specificities (such as clock source selection, muxing, dividor and gate) are abstracted by the Common Clock framework and the associated system clock driver.<br/> ==System overview== {{ ImageMap|Image:Clock Overview.png {{!}} frame {{!}} center{{!}} Clock Overview rect 322 527 422 555 [[RCC internal peripheral | RCC]] }} ===Component description=== *'''foo driver:''' any peripheral driver which needs to control and activate clock(s) associated to a given peripheral. *'''Clock core:''' the Common Clock framework is the generic Linux kernel interface that controls the clock nodes available in the system. :It features two generic interfaces: :- The upper interface unifies the definition and control of the clocks for all Linux platforms. This agnostic API is used by peripheral drivers for configuring and controlling the clocks associated to a specific peripheral. :- The lower interface allows the registration of platform specific functions in order to manage a platform specific clock tree. *'''clk-stm32mp1:''' stm32mp1 specific clock driver that supports RCC clocks. *'''RCC:''' reset and clock controler [[RCC internal peripheral | RCC]]. <br/> ===API description=== Documentation on the Common Clock framework can be found in the kernel documentation folder: https://www.kernel.org/doc/Documentation/driver-api/clk.rst * Main kernel clock API :*'''devm_get_clk():''' looks up and obtains from the device tree a managed reference to a clock producer, to a root clock or to a clock node. :*'''clk_prepare_enable():''' selects a parent clock, configures the corresponding multiplexor and dividor, and enables the clock gating. :*'''clk_disable_unprepare():''' unprepares and gate a clock. :*'''clk_get_rate():''' obtains the current frequency (in Hz) for a given clock. :*'''clk_set_rate():''' sets the frequency for a given clock. If a clock has several parents, the clock framework can change the parent in order to obtain a better frequency. :*'''clk_get_parent():''' gets the parent clock source for a given clock :*'''clk_set_parent():''' sets the parent clock source for a given clock :*'''...''' ==Configuration== ===Kernel configuration=== By default the Common Clock framework is activated in the kernel configuration. ===Device tree configuration=== A detailed device tree configuration is described in [[Clock device tree configuration]]. == How to use the Common Clock framework== This paragraph describes how a standard peripheral driver can retrieve its clock configuration from the device tree and configure it. The clocks associated to a given peripheral are declared in the device tree as described in https://www.kernel.org/doc/Documentation/devicetree/bindings/clock/clock-bindings.txt. Specific platform define statements that abstract hardware clock offsets are defined in dt-bindings/clock/stm32mp1-clks.h header file. Below an example of clock association to a foo driver: foo: foo@adcdefgh { compatible = "foo-driver"; ... '''clocks = <&rcc FOO_K>;''' ... }; Before using the clock specified in the device tree node, the foo driver has to request it at probe execution. static int foo_probe(struct platform_device *pdev) { '''struct clk *clk;''' ... clk = '''devm_clk_get(&pdev->dev, NULL)'''; if (IS_ERR(clk)) { ret = PTR_ERR(clk); dev_err(&pdev->dev, "clk get failed: %d\n", ret); goto err_master_put; } ... } The clock can then be configured and enabled using the Common Clock framework API. If the peripheral needs several clocks, a name must be associated to each clock handle in the device tree node. The specified names must be used by the driver to retrieve the corresponding pointer for each clock. <br/> Below an example of foo driver managing 2 clocks: foo: foo@abcdefgh { compatible = "foo-driver"; '''clocks = <&rcc FOO1_K>, <&rcc FOO2_K>;''' '''clock-names = "foo1", "foo2";''' }; static int foo_probe(struct platform_device *pdev) { priv->foo1clk = '''devm_clk_get(&pdev->dev, "foo1")'''; if (IS_ERR(priv->foo1clk)) { ret = PTR_ERR(priv->foo1clk); if (ret != -ENOENT) { dev_err(&pdev->dev, "Can't get 'foo1' clock\n"); return ret; } } priv->foo2clk = '''devm_clk_get(&pdev->dev, "foo2")''''; if (IS_ERR(priv->foo2clk)) { ret = PTR_ERR(priv->foo2clk); if (ret != -ENOENT) { dev_err(&pdev->dev, "Can't get 'foo2' clock\n"); return ret; } } } ret = '''clk_prepare_enable(priv->foo1clk)'''; if (ret < 0) { dev_err(dev, "foo1 clk enable failed\n"); goto err_bclk_disable; } ==How to trace and debug the framework== === Tracing using dynamic debug === By default, no kernel log showing the clock activity. However the user can enable the dynamic debug for the clock framework driver: {{Board$}} dmesg -n8 {{Board$}} echo "file drivers/clk/* +p" > /sys/kernel/debug/dynamic_debug/control Refer to [[How to use the kernel dynamic debug|dynamic debug]] for more details. ==== How to monitor with debugfs ==== Information on clocks are available in [[Debugfs]] interface located in the '/sys/kernel/debug/clk' directory. It helps viewing all the clocks registered in tree format. <br/> Show clock tree: Board $> cat /sys/kernel/debug/clk/clk_summary clock enable_cnt prepare_cnt rate accuracy phase ---------------------------------------------------------------------------------------- clk-ext-camera 0 0 24000000 0 0 ck_usbo_48m 1 1 48000000 0 0 usbo_k 1 1 48000000 0 0 ck_dsi_phy 0 0 0 0 0 dsi_k 0 0 0 0 0 i2s_ckin 0 0 0 0 0 clk-csi 0 0 4000000 0 0 ck_csi 0 0 4000000 0 0 rng2_k 0 0 4000000 0 0 rng1_k 0 0 4000000 0 0 clk-lsi 1 1 32000 0 0 ck_lsi 1 1 32000 0 0 dac12_k 0 0 32000 0 0 clk-lse 1 1 32768 0 0 ck_lse 1 1 32768 0 0 ck_rtc 1 1 32768 0 0 cec_k 0 0 32768 0 0 clk-hsi 1 1 64000000 0 0 clk-hsi-div 1 1 64000000 0 0 ck_hsi 2 2 64000000 0 0 ck_mco1 0 0 64000000 0 0 uart8_k 0 0 64000000 0 0 uart7_k 0 0 64000000 0 0 uart6_k 0 0 64000000 0 0 uart5_k 0 0 64000000 0 0 uart4_k 1 1 64000000 0 0 usart3_k 0 0 64000000 0 0 usart2_k 0 0 64000000 0 0 usart1_k 0 0 64000000 0 0 i2c6_k 0 0 64000000 0 0 i2c4_k 1 1 64000000 0 0 i2c5_k 0 0 64000000 0 0 i2c3_k 0 0 64000000 0 0 i2c2_k 0 0 64000000 0 0 i2c1_k 0 0 64000000 0 0 spi6_k 0 0 64000000 0 0 spi5_k 0 0 64000000 0 0 spi4_k 0 0 64000000 0 0 clk-hse 1 1 24000000 0 0 ck_hse 6 6 24000000 0 0 ck_hse_rtc 0 0 1000000 0 0 stgen_k 1 1 24000000 0 0 usbphy_k 1 1 24000000 0 0 ck_per 0 0 24000000 0 0 adc12_k 0 0 24000000 0 0 ref4 1 1 24000000 0 0 pll4 1 1 508000000 0 0 pll4_r 0 0 56444445 0 0 pll4_q 1 1 50800000 0 0 ltdc_px 1 1 50800000 0 0 dsi_px 0 0 50800000 0 0 fdcan_k 0 0 50800000 0 0 pll4_p 0 0 56444445 0 0 ref3 1 1 24000000 0 0 pll3 2 3 786431640 0 0 pll3_r 1 1 98303955 0 0 sdmmc3_k 0 0 98303955 0 0 sdmmc2_k 0 0 98303955 0 0 sdmmc1_k 1 1 98303955 0 0 pll3_q 0 3 49151978 0 0 adfsdm_k 0 0 49151978 0 0 sai4_k 0 1 49151978 0 0 sai3_k 0 0 49151978 0 0 sai2_k 0 2 49151978 0 0 sai1_k 0 0 49151978 0 0 spi3_k 0 0 49151978 0 0 spi2_k 0 0 49151978 0 0 spi1_k 0 0 49151978 0 0 spdif_k 0 1 49151978 0 0 pll3_p 1 1 196607910 0 0 ck_mcu 6 19 196607910 0 0 dfsdm_k 0 1 196607910 0 0 gpiok 0 1 196607910 0 0 gpioj 0 1 196607910 0 0 gpioi 0 1 196607910 0 0 gpioh 0 1 196607910 0 0 gpiog 0 1 196607910 0 0 gpiof 0 1 196607910 0 0 gpioe 0 1 196607910 0 0 gpiod 0 1 196607910 0 0 gpioc 0 1 196607910 0 0 gpiob 0 1 196607910 0 0 gpioa 0 1 196607910 0 0 ipcc 2 2 196607910 0 0 hsem 0 0 196607910 0 0 crc2 0 0 196607910 0 0 rng2 0 0 196607910 0 0 hash2 0 0 196607910 0 0 cryp2 0 0 196607910 0 0 dcmi 0 0 196607910 0 0 sdmmc3 0 0 196607910 0 0 usbo 0 0 196607910 0 0 adc12 0 0 196607910 0 0 dmamux 1 1 196607910 0 0 dma2 1 1 196607910 0 0 dma1 1 1 196607910 0 0 pclk3 1 1 98303955 0 0 lptim5_k 0 0 98303955 0 0 lptim4_k 0 0 98303955 0 0 lptim3_k 0 0 98303955 0 0 lptim2_k 0 0 98303955 0 0 hdp 0 0 98303955 0 0 pmbctrl 0 0 98303955 0 0 tmpsens 0 0 98303955 0 0 vref 0 0 98303955 0 0 syscfg 1 1 98303955 0 0 sai4 0 0 98303955 0 0 lptim5 0 0 98303955 0 0 lptim4 0 0 98303955 0 0 lptim3 0 0 98303955 0 0 lptim2 0 0 98303955 0 0 pclk2 0 0 98303955 0 0 fdcan 0 0 98303955 0 0 dfsdm 0 0 98303955 0 0 sai3 0 0 98303955 0 0 sai2 0 0 98303955 0 0 sai1 0 0 98303955 0 0 usart6 0 0 98303955 0 0 spi5 0 0 98303955 0 0 spi4 0 0 98303955 0 0 spi1 0 0 98303955 0 0 tim17 0 0 98303955 0 0 tim16 0 0 98303955 0 0 tim15 0 0 98303955 0 0 tim8 0 0 98303955 0 0 tim1 0 0 98303955 0 0 ck2_tim 0 0 196607910 0 0 tim17_k 0 0 196607910 0 0 tim16_k 0 0 196607910 0 0 tim15_k 0 0 196607910 0 0 tim8_k 0 0 196607910 0 0 tim1_k 0 0 196607910 0 0 pclk1 0 2 98303955 0 0 lptim1_k 0 0 98303955 0 0 mdio 0 0 98303955 0 0 dac12 0 1 98303955 0 0 cec 0 0 98303955 0 0 spdif 0 0 98303955 0 0 i2c5 0 0 98303955 0 0 i2c3 0 0 98303955 0 0 i2c2 0 0 98303955 0 0 i2c1 0 0 98303955 0 0 uart8 0 0 98303955 0 0 uart7 0 0 98303955 0 0 uart5 0 0 98303955 0 0 uart4 0 0 98303955 0 0 usart3 0 0 98303955 0 0 usart2 0 0 98303955 0 0 spi3 0 0 98303955 0 0 spi2 0 0 98303955 0 0 lptim1 0 0 98303955 0 0 tim14 0 0 98303955 0 0 tim13 0 0 98303955 0 0 tim12 0 0 98303955 0 0 tim7 0 0 98303955 0 0 tim6 0 0 98303955 0 0 tim5 0 0 98303955 0 0 tim4 0 0 98303955 0 0 tim3 0 0 98303955 0 0 tim2 0 0 98303955 0 0 ck1_tim 0 1 196607910 0 0 tim14_k 0 0 196607910 0 0 tim13_k 0 0 196607910 0 0 tim12_k 0 0 196607910 0 0 tim7_k 0 0 196607910 0 0 tim6_k 0 1 196607910 0 0 tim5_k 0 0 196607910 0 0 tim4_k 0 0 196607910 0 0 tim3_k 0 0 196607910 0 0 tim2_k 0 0 196607910 0 0 ref1 2 2 24000000 0 0 pll2 2 2 533000000 0 0 pll2_r 1 1 533000000 0 0 pll2_q 0 0 533000000 0 0 gpu_k 0 0 533000000 0 0 pll2_p 1 1 266500000 0 0 ck_axi 9 10 266500000 0 0 ck_trace 0 0 133250000 0 0 ck_sys_dbg 0 0 266500000 0 0 qspi_k 1 1 266500000 0 0 fmc_k 0 0 266500000 0 0 ethstp 0 0 266500000 0 0 usbh 1 1 266500000 0 0 crc1 0 0 266500000 0 0 sdmmc2 0 0 266500000 0 0 sdmmc1 0 0 266500000 0 0 qspi 0 0 266500000 0 0 fmc 0 0 266500000 0 0 ethmac 1 1 266500000 0 0 ethrx 1 1 266500000 0 0 ethtx 1 1 266500000 0 0 gpu 0 0 266500000 0 0 mdma 1 1 266500000 0 0 bkpsram 0 0 266500000 0 0 rng1 0 0 266500000 0 0 hash1 0 0 266500000 0 0 cryp1 0 0 266500000 0 0 gpioz 0 1 266500000 0 0 tzc2 0 0 266500000 0 0 tzc1 0 0 266500000 0 0 pclk5 1 1 66625000 0 0 stgen 0 0 66625000 0 0 bsec 0 0 66625000 0 0 iwdg1 0 0 66625000 0 0 tzpc 0 0 66625000 0 0 rtcapb 2 2 66625000 0 0 usart1 0 0 66625000 0 0 i2c6 0 0 66625000 0 0 i2c4 0 0 66625000 0 0 spi6 0 0 66625000 0 0 pclk4 1 1 133250000 0 0 stgenro 0 0 133250000 0 0 usbphy 0 0 133250000 0 0 iwdg2 1 1 133250000 0 0 dsi 0 0 133250000 0 0 ltdc 0 0 133250000 0 0 pll1 1 1 650000000 0 0 pll1_p 1 1 650000000 0 0 ck_mpu 1 1 650000000 0 0 ck_mco2 0 0 650000000 0 0 clk-hse-div2 0 0 12000000 0 0 ethptp_k 0 0 0 0 0 ethck_k In addition, each clock has a dedicated directory in which you can find the information such as prepare count, enable count, rate and accuracy: Board $>/sys/kernel/debug/clk# cd usart2_k Board $>/sys/kernel/debug/clk/usart2_k# ls clk_accuracy clk_flags clk_phase clk_prepare_count clk_enable_count clk_notifier_count clk_possible_parents clk_rate Additional information, such as flags, notifier count and possible parents (for clocks with multiple parents) are also available. Just execute a 'cat' command to display them. Board $>:/sys/kernel/debug/clk/usart2_k# cat clk_possible_parents pclk1 pll4_q ck_hsi ck_csi ck_hse ==Source code location== stm32mp1 clock driver source <ref>{{CodeSource | Linux kernel |drivers/clk/clk-stm32mp1.c}}</ref> <br> clock dt-binding interface <ref>{{CodeSource | Linux kernel | include/dt-bindings/clock/stm32mp1-clks.h}}</ref> ==To go further== See "how to build a clock tree" in [[STM32MP15_clock_tree]]. ==References== <references /> <noinclude> {{ArticleBasedOnModel | Framework overview article model}} {{PublicationRequestId | 10342 | 2019-01-21 | AnneJ}} [[Category:Clock]] </noinclude>
该页面使用的模板:
模板:ArticleBasedOnModel
(
查看源代码
)
模板:Board$
(
查看源代码
)
模板:CodeSource
(
查看源代码
)
模板:ImageMap
(
查看源代码
)
模板:PublicationRequestId
(
查看源代码
)
返回至
Clock overview
。
导航
导航
WIKI首页
官方店铺
资料下载
交流社区
所有页面
所有产品
MPU-Linux开发板
MCU-单片机开发板
Linux开发系列视频
单片机开发系列视频
所有模块配件
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志