mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -07:00
Merge tag 'clk-for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clock framework updates from Michael Turquette: "The changes to the common clock framework for 4.0 are mostly new clock drivers and updates to existing ones for feature enhancements and bug fixes. There is more churn than usual in the framework core due to the change to introduce per-user unique struct clk pointers in 4.0. This caused several regressions to surface, some of which were sent as fixes to 4.0. New generic clock drivers were added for GPIO- and PWM-based clock controllers. Additionally the common clk-divider code recieved several fixes to the way it rounds rates" * tag 'clk-for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (91 commits) clk: check ->determine/round_rate() return value in clk_calc_new_rates clk: at91: usb: propagate rate modification to the parent clk clk: samsung: exynos4: Disable ARMCLK down feature on Exynos4210 SoC clk: don't use __initconst for non-const arrays clk: at91: change to using endian agnositc IO clk: clk-gpio-gate: Fix active low clk: Add PWM clock driver clk: Add clock driver for mb86s7x clk: pxa: pxa3xx: add missing os timer clock clk: tegra: Use the proper parent for plld_dsi clk: tegra: Use generic tegra_osc_clk_init() on Tegra114 clk: tegra: Model oscillator as clock clk: tegra: Add peripheral registers for bank Y clk: tegra: Register the proper number of resets clk: tegra: Remove needless initializations clk: tegra: Use consistent indentation clk: tegra: Various whitespace cleanups clk: tegra: Enable HDA to HDMI clocks on Tegra124 clk: tegra: Fix a bunch of sparse warnings clk: tegra: Fix typo tabel -> table ...
This commit is contained in:
commit
e98bf5cedf
107 files changed
+13215
-837
No files matched your search
@@ -9,6 +9,8 @@ Required Properties:
|
||||
- "samsung,exynos3250-cmu" - controller compatible with Exynos3250 SoC.
|
||||
- "samsung,exynos3250-cmu-dmc" - controller compatible with
|
||||
Exynos3250 SoC for Dynamic Memory Controller domain.
|
||||
- "samsung,exynos3250-cmu-isp" - ISP block clock controller compatible
|
||||
with Exynos3250 SOC
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
@@ -36,6 +38,12 @@ Example 1: Examples of clock controller nodes are listed below.
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
cmu_isp: clock-controller@10048000 {
|
||||
compatible = "samsung,exynos3250-cmu-isp";
|
||||
reg = <0x10048000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
Example 2: UART controller node that consumes the clock generated by the clock
|
||||
controller. Refer to the standard clock bindings for information
|
||||
about 'clocks' and 'clock-names' property.
|
||||
|
||||
@@ -0,0 +1,462 @@
|
||||
* Samsung Exynos5433 CMU (Clock Management Units)
|
||||
|
||||
The Exynos5433 clock controller generates and supplies clock to various
|
||||
controllers within the Exynos5433 SoC.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be one of the following.
|
||||
- "samsung,exynos5433-cmu-top" - clock controller compatible for CMU_TOP
|
||||
which generates clocks for IMEM/FSYS/G3D/GSCL/HEVC/MSCL/G2D/MFC/PERIC/PERIS
|
||||
domains and bus clocks.
|
||||
- "samsung,exynos5433-cmu-cpif" - clock controller compatible for CMU_CPIF
|
||||
which generates clocks for LLI (Low Latency Interface) IP.
|
||||
- "samsung,exynos5433-cmu-mif" - clock controller compatible for CMU_MIF
|
||||
which generates clocks for DRAM Memory Controller domain.
|
||||
- "samsung,exynos5433-cmu-peric" - clock controller compatible for CMU_PERIC
|
||||
which generates clocks for UART/I2C/SPI/I2S/PCM/SPDIF/PWM/SLIMBUS IPs.
|
||||
- "samsung,exynos5433-cmu-peris" - clock controller compatible for CMU_PERIS
|
||||
which generates clocks for PMU/TMU/MCT/WDT/RTC/SECKEY/TZPC IPs.
|
||||
- "samsung,exynos5433-cmu-fsys" - clock controller compatible for CMU_FSYS
|
||||
which generates clocks for USB/UFS/SDMMC/TSI/PDMA IPs.
|
||||
- "samsung,exynos5433-cmu-g2d" - clock controller compatible for CMU_G2D
|
||||
which generates clocks for G2D/MDMA IPs.
|
||||
- "samsung,exynos5433-cmu-disp" - clock controller compatible for CMU_DISP
|
||||
which generates clocks for Display (DECON/HDMI/DSIM/MIXER) IPs.
|
||||
- "samsung,exynos5433-cmu-aud" - clock controller compatible for CMU_AUD
|
||||
which generates clocks for Cortex-A5/BUS/AUDIO clocks.
|
||||
- "samsung,exynos5433-cmu-bus0", "samsung,exynos5433-cmu-bus1"
|
||||
and "samsung,exynos5433-cmu-bus2" - clock controller compatible for CMU_BUS
|
||||
which generates global data buses clock and global peripheral buses clock.
|
||||
- "samsung,exynos5433-cmu-g3d" - clock controller compatible for CMU_G3D
|
||||
which generates clocks for 3D Graphics Engine IP.
|
||||
- "samsung,exynos5433-cmu-gscl" - clock controller compatible for CMU_GSCL
|
||||
which generates clocks for GSCALER IPs.
|
||||
- "samsung,exynos5433-cmu-apollo"- clock controller compatible for CMU_APOLLO
|
||||
which generates clocks for Cortex-A53 Quad-core processor.
|
||||
- "samsung,exynos5433-cmu-atlas" - clock controller compatible for CMU_ATLAS
|
||||
which generates clocks for Cortex-A57 Quad-core processor, CoreSight and
|
||||
L2 cache controller.
|
||||
- "samsung,exynos5433-cmu-mscl" - clock controller compatible for CMU_MSCL
|
||||
which generates clocks for M2M (Memory to Memory) scaler and JPEG IPs.
|
||||
- "samsung,exynos5433-cmu-mfc" - clock controller compatible for CMU_MFC
|
||||
which generates clocks for MFC(Multi-Format Codec) IP.
|
||||
- "samsung,exynos5433-cmu-hevc" - clock controller compatible for CMU_HEVC
|
||||
which generates clocks for HEVC(High Efficiency Video Codec) decoder IP.
|
||||
- "samsung,exynos5433-cmu-isp" - clock controller compatible for CMU_ISP
|
||||
which generates clocks for FIMC-ISP/DRC/SCLC/DIS/3DNR IPs.
|
||||
- "samsung,exynos5433-cmu-cam0" - clock controller compatible for CMU_CAM0
|
||||
which generates clocks for MIPI_CSIS{0|1}/FIMC_LITE_{A|B|D}/FIMC_3AA{0|1}
|
||||
IPs.
|
||||
- "samsung,exynos5433-cmu-cam1" - clock controller compatible for CMU_CAM1
|
||||
which generates clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs.
|
||||
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
|
||||
- #clock-cells: should be 1.
|
||||
|
||||
- clocks: list of the clock controller input clock identifiers,
|
||||
from common clock bindings. Please refer the next section
|
||||
to find the input clocks for a given controller.
|
||||
|
||||
- clock-names: list of the clock controller input clock names,
|
||||
as described in clock-bindings.txt.
|
||||
|
||||
Input clocks for top clock controller:
|
||||
- oscclk
|
||||
- sclk_mphy_pll
|
||||
- sclk_mfc_pll
|
||||
- sclk_bus_pll
|
||||
|
||||
Input clocks for cpif clock controller:
|
||||
- oscclk
|
||||
|
||||
Input clocks for mif clock controller:
|
||||
- oscclk
|
||||
- sclk_mphy_pll
|
||||
|
||||
Input clocks for fsys clock controller:
|
||||
- oscclk
|
||||
- sclk_ufs_mphy
|
||||
- div_aclk_fsys_200
|
||||
- sclk_pcie_100_fsys
|
||||
- sclk_ufsunipro_fsys
|
||||
- sclk_mmc2_fsys
|
||||
- sclk_mmc1_fsys
|
||||
- sclk_mmc0_fsys
|
||||
- sclk_usbhost30_fsys
|
||||
- sclk_usbdrd30_fsys
|
||||
|
||||
Input clocks for g2d clock controller:
|
||||
- oscclk
|
||||
- aclk_g2d_266
|
||||
- aclk_g2d_400
|
||||
|
||||
Input clocks for disp clock controller:
|
||||
- oscclk
|
||||
- sclk_dsim1_disp
|
||||
- sclk_dsim0_disp
|
||||
- sclk_dsd_disp
|
||||
- sclk_decon_tv_eclk_disp
|
||||
- sclk_decon_vclk_disp
|
||||
- sclk_decon_eclk_disp
|
||||
- sclk_decon_tv_vclk_disp
|
||||
- aclk_disp_333
|
||||
|
||||
Input clocks for bus0 clock controller:
|
||||
- aclk_bus0_400
|
||||
|
||||
Input clocks for bus1 clock controller:
|
||||
- aclk_bus1_400
|
||||
|
||||
Input clocks for bus2 clock controller:
|
||||
- oscclk
|
||||
- aclk_bus2_400
|
||||
|
||||
Input clocks for g3d clock controller:
|
||||
- oscclk
|
||||
- aclk_g3d_400
|
||||
|
||||
Input clocks for gscl clock controller:
|
||||
- oscclk
|
||||
- aclk_gscl_111
|
||||
- aclk_gscl_333
|
||||
|
||||
Input clocks for apollo clock controller:
|
||||
- oscclk
|
||||
- sclk_bus_pll_apollo
|
||||
|
||||
Input clocks for atlas clock controller:
|
||||
- oscclk
|
||||
- sclk_bus_pll_atlas
|
||||
|
||||
Input clocks for mscl clock controller:
|
||||
- oscclk
|
||||
- sclk_jpeg_mscl
|
||||
- aclk_mscl_400
|
||||
|
||||
Input clocks for mfc clock controller:
|
||||
- oscclk
|
||||
- aclk_mfc_400
|
||||
|
||||
Input clocks for hevc clock controller:
|
||||
- oscclk
|
||||
- aclk_hevc_400
|
||||
|
||||
Input clocks for isp clock controller:
|
||||
- oscclk
|
||||
- aclk_isp_dis_400
|
||||
- aclk_isp_400
|
||||
|
||||
Input clocks for cam0 clock controller:
|
||||
- oscclk
|
||||
- aclk_cam0_333
|
||||
- aclk_cam0_400
|
||||
- aclk_cam0_552
|
||||
|
||||
Input clocks for cam1 clock controller:
|
||||
- oscclk
|
||||
- sclk_isp_uart_cam1
|
||||
- sclk_isp_spi1_cam1
|
||||
- sclk_isp_spi0_cam1
|
||||
- aclk_cam1_333
|
||||
- aclk_cam1_400
|
||||
- aclk_cam1_552
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume.
|
||||
|
||||
All available clocks are defined as preprocessor macros in
|
||||
dt-bindings/clock/exynos5433.h header and can be used in device
|
||||
tree sources.
|
||||
|
||||
Example 1: Examples of 'oscclk' source clock node are listed below.
|
||||
|
||||
xxti: xxti {
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "oscclk";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
Example 2: Examples of clock controller nodes are listed below.
|
||||
|
||||
cmu_top: clock-controller@10030000 {
|
||||
compatible = "samsung,exynos5433-cmu-top";
|
||||
reg = <0x10030000 0x0c04>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"sclk_mphy_pll",
|
||||
"sclk_mfc_pll",
|
||||
"sclk_bus_pll";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_cpif CLK_SCLK_MPHY_PLL>,
|
||||
<&cmu_mif CLK_SCLK_MFC_PLL>,
|
||||
<&cmu_mif CLK_SCLK_BUS_PLL>;
|
||||
};
|
||||
|
||||
cmu_cpif: clock-controller@10fc0000 {
|
||||
compatible = "samsung,exynos5433-cmu-cpif";
|
||||
reg = <0x10fc0000 0x0c04>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk";
|
||||
clocks = <&xxti>;
|
||||
};
|
||||
|
||||
cmu_mif: clock-controller@105b0000 {
|
||||
compatible = "samsung,exynos5433-cmu-mif";
|
||||
reg = <0x105b0000 0x100c>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"sclk_mphy_pll";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_cpif CLK_SCLK_MPHY_PLL>;
|
||||
};
|
||||
|
||||
cmu_peric: clock-controller@14c80000 {
|
||||
compatible = "samsung,exynos5433-cmu-peric";
|
||||
reg = <0x14c80000 0x0b08>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
cmu_peris: clock-controller@10040000 {
|
||||
compatible = "samsung,exynos5433-cmu-peris";
|
||||
reg = <0x10040000 0x0b20>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
cmu_fsys: clock-controller@156e0000 {
|
||||
compatible = "samsung,exynos5433-cmu-fsys";
|
||||
reg = <0x156e0000 0x0b04>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"sclk_ufs_mphy",
|
||||
"div_aclk_fsys_200",
|
||||
"sclk_pcie_100_fsys",
|
||||
"sclk_ufsunipro_fsys",
|
||||
"sclk_mmc2_fsys",
|
||||
"sclk_mmc1_fsys",
|
||||
"sclk_mmc0_fsys",
|
||||
"sclk_usbhost30_fsys",
|
||||
"sclk_usbdrd30_fsys";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_cpif CLK_SCLK_UFS_MPHY>,
|
||||
<&cmu_top CLK_DIV_ACLK_FSYS_200>,
|
||||
<&cmu_top CLK_SCLK_PCIE_100_FSYS>,
|
||||
<&cmu_top CLK_SCLK_UFSUNIPRO_FSYS>,
|
||||
<&cmu_top CLK_SCLK_MMC2_FSYS>,
|
||||
<&cmu_top CLK_SCLK_MMC1_FSYS>,
|
||||
<&cmu_top CLK_SCLK_MMC0_FSYS>,
|
||||
<&cmu_top CLK_SCLK_USBHOST30_FSYS>,
|
||||
<&cmu_top CLK_SCLK_USBDRD30_FSYS>;
|
||||
};
|
||||
|
||||
cmu_g2d: clock-controller@12460000 {
|
||||
compatible = "samsung,exynos5433-cmu-g2d";
|
||||
reg = <0x12460000 0x0b08>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"aclk_g2d_266",
|
||||
"aclk_g2d_400";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_top CLK_ACLK_G2D_266>,
|
||||
<&cmu_top CLK_ACLK_G2D_400>;
|
||||
};
|
||||
|
||||
cmu_disp: clock-controller@13b90000 {
|
||||
compatible = "samsung,exynos5433-cmu-disp";
|
||||
reg = <0x13b90000 0x0c04>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"sclk_dsim1_disp",
|
||||
"sclk_dsim0_disp",
|
||||
"sclk_dsd_disp",
|
||||
"sclk_decon_tv_eclk_disp",
|
||||
"sclk_decon_vclk_disp",
|
||||
"sclk_decon_eclk_disp",
|
||||
"sclk_decon_tv_vclk_disp",
|
||||
"aclk_disp_333";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_mif CLK_SCLK_DSIM1_DISP>,
|
||||
<&cmu_mif CLK_SCLK_DSIM0_DISP>,
|
||||
<&cmu_mif CLK_SCLK_DSD_DISP>,
|
||||
<&cmu_mif CLK_SCLK_DECON_TV_ECLK_DISP>,
|
||||
<&cmu_mif CLK_SCLK_DECON_VCLK_DISP>,
|
||||
<&cmu_mif CLK_SCLK_DECON_ECLK_DISP>,
|
||||
<&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>,
|
||||
<&cmu_mif CLK_ACLK_DISP_333>;
|
||||
};
|
||||
|
||||
cmu_aud: clock-controller@114c0000 {
|
||||
compatible = "samsung,exynos5433-cmu-aud";
|
||||
reg = <0x114c0000 0x0b04>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
cmu_bus0: clock-controller@13600000 {
|
||||
compatible = "samsung,exynos5433-cmu-bus0";
|
||||
reg = <0x13600000 0x0b04>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "aclk_bus0_400";
|
||||
clocks = <&cmu_top CLK_ACLK_BUS0_400>;
|
||||
};
|
||||
|
||||
cmu_bus1: clock-controller@14800000 {
|
||||
compatible = "samsung,exynos5433-cmu-bus1";
|
||||
reg = <0x14800000 0x0b04>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "aclk_bus1_400";
|
||||
clocks = <&cmu_top CLK_ACLK_BUS1_400>;
|
||||
};
|
||||
|
||||
cmu_bus2: clock-controller@13400000 {
|
||||
compatible = "samsung,exynos5433-cmu-bus2";
|
||||
reg = <0x13400000 0x0b04>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk", "aclk_bus2_400";
|
||||
clocks = <&xxti>, <&cmu_mif CLK_ACLK_BUS2_400>;
|
||||
};
|
||||
|
||||
cmu_g3d: clock-controller@14aa0000 {
|
||||
compatible = "samsung,exynos5433-cmu-g3d";
|
||||
reg = <0x14aa0000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk", "aclk_g3d_400";
|
||||
clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>;
|
||||
};
|
||||
|
||||
cmu_gscl: clock-controller@13cf0000 {
|
||||
compatible = "samsung,exynos5433-cmu-gscl";
|
||||
reg = <0x13cf0000 0x0b10>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"aclk_gscl_111",
|
||||
"aclk_gscl_333";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_top CLK_ACLK_GSCL_111>,
|
||||
<&cmu_top CLK_ACLK_GSCL_333>;
|
||||
};
|
||||
|
||||
cmu_apollo: clock-controller@11900000 {
|
||||
compatible = "samsung,exynos5433-cmu-apollo";
|
||||
reg = <0x11900000 0x1088>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk", "sclk_bus_pll_apollo";
|
||||
clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_APOLLO>;
|
||||
};
|
||||
|
||||
cmu_atlas: clock-controller@11800000 {
|
||||
compatible = "samsung,exynos5433-cmu-atlas";
|
||||
reg = <0x11800000 0x1088>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk", "sclk_bus_pll_atlas";
|
||||
clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_ATLAS>;
|
||||
};
|
||||
|
||||
cmu_mscl: clock-controller@105d0000 {
|
||||
compatible = "samsung,exynos5433-cmu-mscl";
|
||||
reg = <0x105d0000 0x0b10>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"sclk_jpeg_mscl",
|
||||
"aclk_mscl_400";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_top CLK_SCLK_JPEG_MSCL>,
|
||||
<&cmu_top CLK_ACLK_MSCL_400>;
|
||||
};
|
||||
|
||||
cmu_mfc: clock-controller@15280000 {
|
||||
compatible = "samsung,exynos5433-cmu-mfc";
|
||||
reg = <0x15280000 0x0b08>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk", "aclk_mfc_400";
|
||||
clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>;
|
||||
};
|
||||
|
||||
cmu_hevc: clock-controller@14f80000 {
|
||||
compatible = "samsung,exynos5433-cmu-hevc";
|
||||
reg = <0x14f80000 0x0b08>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk", "aclk_hevc_400";
|
||||
clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>;
|
||||
};
|
||||
|
||||
cmu_isp: clock-controller@146d0000 {
|
||||
compatible = "samsung,exynos5433-cmu-isp";
|
||||
reg = <0x146d0000 0x0b0c>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"aclk_isp_dis_400",
|
||||
"aclk_isp_400";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_top CLK_ACLK_ISP_DIS_400>,
|
||||
<&cmu_top CLK_ACLK_ISP_400>;
|
||||
};
|
||||
|
||||
cmu_cam0: clock-controller@120d0000 {
|
||||
compatible = "samsung,exynos5433-cmu-cam0";
|
||||
reg = <0x120d0000 0x0b0c>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"aclk_cam0_333",
|
||||
"aclk_cam0_400",
|
||||
"aclk_cam0_552";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_top CLK_ACLK_CAM0_333>,
|
||||
<&cmu_top CLK_ACLK_CAM0_400>,
|
||||
<&cmu_top CLK_ACLK_CAM0_552>;
|
||||
};
|
||||
|
||||
cmu_cam1: clock-controller@145d0000 {
|
||||
compatible = "samsung,exynos5433-cmu-cam1";
|
||||
reg = <0x145d0000 0x0b08>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clock-names = "oscclk",
|
||||
"sclk_isp_uart_cam1",
|
||||
"sclk_isp_spi1_cam1",
|
||||
"sclk_isp_spi0_cam1",
|
||||
"aclk_cam1_333",
|
||||
"aclk_cam1_400",
|
||||
"aclk_cam1_552";
|
||||
clocks = <&xxti>,
|
||||
<&cmu_top CLK_SCLK_ISP_UART_CAM1>,
|
||||
<&cmu_top CLK_SCLK_ISP_SPI1_CAM1>,
|
||||
<&cmu_top CLK_SCLK_ISP_SPI0_CAM1>,
|
||||
<&cmu_top CLK_ACLK_CAM1_333>,
|
||||
<&cmu_top CLK_ACLK_CAM1_400>,
|
||||
<&cmu_top CLK_ACLK_CAM1_552>;
|
||||
};
|
||||
|
||||
Example 3: UART controller node that consumes the clock generated by the clock
|
||||
controller.
|
||||
|
||||
serial_0: serial@14C10000 {
|
||||
compatible = "samsung,exynos5433-uart";
|
||||
reg = <0x14C10000 0x100>;
|
||||
interrupts = <0 421 0>;
|
||||
clocks = <&cmu_peric CLK_PCLK_UART0>,
|
||||
<&cmu_peric CLK_SCLK_UART0>;
|
||||
clock-names = "uart", "clk_uart_baud0";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_bus>;
|
||||
status = "disabled";
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
Fujitsu CRG11 clock driver bindings
|
||||
-----------------------------------
|
||||
|
||||
Required properties :
|
||||
- compatible : Shall contain "fujitsu,mb86s70-crg11"
|
||||
- #clock-cells : Shall be 3 {cntrlr domain port}
|
||||
|
||||
The consumer specifies the desired clock pointing to its phandle.
|
||||
|
||||
Example:
|
||||
|
||||
clock: crg11 {
|
||||
compatible = "fujitsu,mb86s70-crg11";
|
||||
#clock-cells = <3>;
|
||||
};
|
||||
|
||||
mhu: mhu0@2b1f0000 {
|
||||
#mbox-cells = <1>;
|
||||
compatible = "arm,mhu";
|
||||
reg = <0 0x2B1F0000 0x1000>;
|
||||
interrupts = <0 36 4>, /* LP Non-Sec */
|
||||
<0 35 4>, /* HP Non-Sec */
|
||||
<0 37 4>; /* Secure */
|
||||
clocks = <&clock 0 2 1>; /* Cntrlr:0 Domain:2 Port:1 */
|
||||
clock-names = "clk";
|
||||
};
|
||||
@@ -23,6 +23,14 @@ The following is a list of provided IDs and clock names on Armada 380/385:
|
||||
2 = l2clk (L2 Cache clock)
|
||||
3 = ddrclk (DDR clock)
|
||||
|
||||
The following is a list of provided IDs and clock names on Armada 39x:
|
||||
0 = tclk (Internal Bus clock)
|
||||
1 = cpuclk (CPU clock)
|
||||
2 = nbclk (Coherent Fabric clock)
|
||||
3 = hclk (SDRAM Controller Internal Clock)
|
||||
4 = dclk (SDRAM Interface Clock)
|
||||
5 = refclk (Reference Clock)
|
||||
|
||||
The following is a list of provided IDs and clock names on Kirkwood and Dove:
|
||||
0 = tclk (Internal Bus clock)
|
||||
1 = cpuclk (CPU0 clock)
|
||||
@@ -39,6 +47,7 @@ Required properties:
|
||||
"marvell,armada-370-core-clock" - For Armada 370 SoC core clocks
|
||||
"marvell,armada-375-core-clock" - For Armada 375 SoC core clocks
|
||||
"marvell,armada-380-core-clock" - For Armada 380/385 SoC core clocks
|
||||
"marvell,armada-390-core-clock" - For Armada 39x SoC core clocks
|
||||
"marvell,armada-xp-core-clock" - For Armada XP SoC core clocks
|
||||
"marvell,dove-core-clock" - for Dove SoC core clocks
|
||||
"marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
* Gated Clock bindings for Marvell EBU SoCs
|
||||
|
||||
Marvell Armada 370/375/380/385/XP, Dove and Kirkwood allow some
|
||||
Marvell Armada 370/375/380/385/39x/XP, Dove and Kirkwood allow some
|
||||
peripheral clocks to be gated to save some power. The clock consumer
|
||||
should specify the desired clock by having the clock ID in its
|
||||
"clocks" phandle cell. The clock ID is directly mapped to the
|
||||
@@ -77,6 +77,18 @@ ID Clock Peripheral
|
||||
28 xor1 XOR 1
|
||||
30 sata1 SATA 1
|
||||
|
||||
The following is a list of provided IDs for Armada 39x:
|
||||
ID Clock Peripheral
|
||||
-----------------------------------
|
||||
5 pex1 PCIe 1
|
||||
6 pex2 PCIe 2
|
||||
7 pex3 PCIe 3
|
||||
8 pex0 PCIe 0
|
||||
9 usb3h0 USB3 Host 0
|
||||
17 sdio SDIO
|
||||
22 xor0 XOR 0
|
||||
28 xor1 XOR 1
|
||||
|
||||
The following is a list of provided IDs for Armada XP:
|
||||
ID Clock Peripheral
|
||||
-----------------------------------
|
||||
@@ -152,6 +164,7 @@ Required properties:
|
||||
"marvell,armada-370-gating-clock" - for Armada 370 SoC clock gating
|
||||
"marvell,armada-375-gating-clock" - for Armada 375 SoC clock gating
|
||||
"marvell,armada-380-gating-clock" - for Armada 380/385 SoC clock gating
|
||||
"marvell,armada-390-gating-clock" - for Armada 39x SoC clock gating
|
||||
"marvell,armada-xp-gating-clock" - for Armada XP SoC clock gating
|
||||
"marvell,dove-gating-clock" - for Dove SoC clock gating
|
||||
"marvell,kirkwood-gating-clock" - for Kirkwood SoC clock gating
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
Binding for an external clock signal driven by a PWM pin.
|
||||
|
||||
This binding uses the common clock binding[1] and the common PWM binding[2].
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
[2] Documentation/devicetree/bindings/pwm/pwm.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be "pwm-clock".
|
||||
- #clock-cells : from common clock binding; shall be set to 0.
|
||||
- pwms : from common PWM binding; this determines the clock frequency
|
||||
via the period given in the PWM specifier.
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names : From common clock binding.
|
||||
- clock-frequency : Exact output frequency, in case the PWM period
|
||||
is not exact but was rounded to nanoseconds.
|
||||
|
||||
Example:
|
||||
clock {
|
||||
compatible = "pwm-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <25000000>;
|
||||
clock-output-names = "mipi_mclk";
|
||||
pwms = <&pwm2 0 40>; /* 1 / 40 ns = 25 MHz */
|
||||
};
|
||||
@@ -8,6 +8,7 @@ Required properties :
|
||||
"qcom,gcc-apq8084"
|
||||
"qcom,gcc-ipq8064"
|
||||
"qcom,gcc-msm8660"
|
||||
"qcom,gcc-msm8916"
|
||||
"qcom,gcc-msm8960"
|
||||
"qcom,gcc-msm8974"
|
||||
"qcom,gcc-msm8974pro"
|
||||
|
||||
@@ -20,6 +20,7 @@ Required properties:
|
||||
"allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23
|
||||
"allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates
|
||||
"allwinner,sun4i-a10-ahb-clk" - for the AHB clock
|
||||
"allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13
|
||||
"allwinner,sun9i-a80-ahb-clk" - for the AHB bus clocks on A80
|
||||
"allwinner,sun4i-a10-ahb-gates-clk" - for the AHB gates on A10
|
||||
"allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
|
||||
@@ -66,6 +67,8 @@ Required properties:
|
||||
"allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20
|
||||
"allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13
|
||||
"allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31
|
||||
"allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80
|
||||
"allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80
|
||||
|
||||
Required properties for all clocks:
|
||||
- reg : shall be the control register address for the clock.
|
||||
|
||||
+2
-1
@@ -2577,6 +2577,7 @@ F: include/linux/cleancache.h
|
||||
|
||||
CLK API
|
||||
M: Russell King <linux@arm.linux.org.uk>
|
||||
L: linux-clk@vger.kernel.org
|
||||
S: Maintained
|
||||
F: include/linux/clk.h
|
||||
|
||||
@@ -2637,7 +2638,7 @@ F: drivers/media/platform/coda/
|
||||
COMMON CLK FRAMEWORK
|
||||
M: Mike Turquette <mturquette@linaro.org>
|
||||
M: Stephen Boyd <sboyd@codeaurora.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: linux-clk@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
|
||||
S: Maintained
|
||||
F: drivers/clk/
|
||||
|
||||
@@ -130,6 +130,13 @@ config COMMON_CLK_PALMAS
|
||||
This driver supports TI Palmas devices 32KHz output KG and KG_AUDIO
|
||||
using common clock framework.
|
||||
|
||||
config COMMON_CLK_PWM
|
||||
tristate "Clock driver for PWMs used as clock outputs"
|
||||
depends on PWM
|
||||
---help---
|
||||
Adapter driver so that any PWM output can be (mis)used as clock signal
|
||||
at 50% duty cycle.
|
||||
|
||||
config COMMON_CLK_PXA
|
||||
def_bool COMMON_CLK && ARCH_PXA
|
||||
---help---
|
||||
|
||||
@@ -28,6 +28,7 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
|
||||
obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o
|
||||
obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
|
||||
obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
|
||||
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
|
||||
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
|
||||
@@ -42,6 +43,7 @@ obj-$(CONFIG_ARCH_U300) += clk-u300.o
|
||||
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
|
||||
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
|
||||
obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
|
||||
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
|
||||
obj-$(CONFIG_COMMON_CLK_AT91) += at91/
|
||||
obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/
|
||||
obj-$(CONFIG_ARCH_BERLIN) += berlin/
|
||||
|
||||
+49
-15
@@ -56,22 +56,55 @@ static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
|
||||
return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1));
|
||||
}
|
||||
|
||||
static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
static long at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long min_rate,
|
||||
unsigned long max_rate,
|
||||
unsigned long *best_parent_rate,
|
||||
struct clk_hw **best_parent_hw)
|
||||
{
|
||||
unsigned long div;
|
||||
struct clk *parent = NULL;
|
||||
long best_rate = -EINVAL;
|
||||
unsigned long tmp_rate;
|
||||
int best_diff = -1;
|
||||
int tmp_diff;
|
||||
int i;
|
||||
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
for (i = 0; i < __clk_get_num_parents(hw->clk); i++) {
|
||||
int div;
|
||||
|
||||
if (rate >= *parent_rate)
|
||||
return *parent_rate;
|
||||
parent = clk_get_parent_by_index(hw->clk, i);
|
||||
if (!parent)
|
||||
continue;
|
||||
|
||||
div = DIV_ROUND_CLOSEST(*parent_rate, rate);
|
||||
if (div > SAM9X5_USB_MAX_DIV + 1)
|
||||
div = SAM9X5_USB_MAX_DIV + 1;
|
||||
for (div = 1; div < SAM9X5_USB_MAX_DIV + 2; div++) {
|
||||
unsigned long tmp_parent_rate;
|
||||
|
||||
return DIV_ROUND_CLOSEST(*parent_rate, div);
|
||||
tmp_parent_rate = rate * div;
|
||||
tmp_parent_rate = __clk_round_rate(parent,
|
||||
tmp_parent_rate);
|
||||
tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div);
|
||||
if (tmp_rate < rate)
|
||||
tmp_diff = rate - tmp_rate;
|
||||
else
|
||||
tmp_diff = tmp_rate - rate;
|
||||
|
||||
if (best_diff < 0 || best_diff > tmp_diff) {
|
||||
best_rate = tmp_rate;
|
||||
best_diff = tmp_diff;
|
||||
*best_parent_rate = tmp_parent_rate;
|
||||
*best_parent_hw = __clk_get_hw(parent);
|
||||
}
|
||||
|
||||
if (!best_diff || tmp_rate < rate)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!best_diff)
|
||||
break;
|
||||
}
|
||||
|
||||
return best_rate;
|
||||
}
|
||||
|
||||
static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
|
||||
@@ -121,7 +154,7 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
static const struct clk_ops at91sam9x5_usb_ops = {
|
||||
.recalc_rate = at91sam9x5_clk_usb_recalc_rate,
|
||||
.round_rate = at91sam9x5_clk_usb_round_rate,
|
||||
.determine_rate = at91sam9x5_clk_usb_determine_rate,
|
||||
.get_parent = at91sam9x5_clk_usb_get_parent,
|
||||
.set_parent = at91sam9x5_clk_usb_set_parent,
|
||||
.set_rate = at91sam9x5_clk_usb_set_rate,
|
||||
@@ -159,7 +192,7 @@ static const struct clk_ops at91sam9n12_usb_ops = {
|
||||
.disable = at91sam9n12_clk_usb_disable,
|
||||
.is_enabled = at91sam9n12_clk_usb_is_enabled,
|
||||
.recalc_rate = at91sam9x5_clk_usb_recalc_rate,
|
||||
.round_rate = at91sam9x5_clk_usb_round_rate,
|
||||
.determine_rate = at91sam9x5_clk_usb_determine_rate,
|
||||
.set_rate = at91sam9x5_clk_usb_set_rate,
|
||||
};
|
||||
|
||||
@@ -179,7 +212,8 @@ at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name,
|
||||
init.ops = &at91sam9x5_usb_ops;
|
||||
init.parent_names = parent_names;
|
||||
init.num_parents = num_parents;
|
||||
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
|
||||
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
|
||||
CLK_SET_RATE_PARENT;
|
||||
|
||||
usb->hw.init = &init;
|
||||
usb->pmc = pmc;
|
||||
@@ -207,7 +241,7 @@ at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name,
|
||||
init.ops = &at91sam9n12_usb_ops;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
init.flags = CLK_SET_RATE_GATE;
|
||||
init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
|
||||
|
||||
usb->hw.init = &init;
|
||||
usb->pmc = pmc;
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
#define CDCE706_CLKOUT_DIVIDER_MASK 0x7
|
||||
#define CDCE706_CLKOUT_ENABLE_MASK 0x8
|
||||
|
||||
static struct regmap_config cdce706_regmap_config = {
|
||||
static const struct regmap_config cdce706_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.val_format_endian = REGMAP_ENDIAN_NATIVE,
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/printk.h>
|
||||
#include "clk.h"
|
||||
|
||||
static int __set_clk_parents(struct device_node *node, bool clk_supplier)
|
||||
{
|
||||
@@ -39,7 +38,7 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
|
||||
}
|
||||
if (clkspec.np == node && !clk_supplier)
|
||||
return 0;
|
||||
pclk = of_clk_get_by_clkspec(&clkspec);
|
||||
pclk = of_clk_get_from_provider(&clkspec);
|
||||
if (IS_ERR(pclk)) {
|
||||
pr_warn("clk: couldn't get parent clock %d for %s\n",
|
||||
index, node->full_name);
|
||||
@@ -54,7 +53,7 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
|
||||
rc = 0;
|
||||
goto err;
|
||||
}
|
||||
clk = of_clk_get_by_clkspec(&clkspec);
|
||||
clk = of_clk_get_from_provider(&clkspec);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_warn("clk: couldn't get parent clock %d for %s\n",
|
||||
index, node->full_name);
|
||||
@@ -98,7 +97,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
|
||||
if (clkspec.np == node && !clk_supplier)
|
||||
return 0;
|
||||
|
||||
clk = of_clk_get_by_clkspec(&clkspec);
|
||||
clk = of_clk_get_from_provider(&clkspec);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_warn("clk: couldn't get clock %d for %s\n",
|
||||
index, node->full_name);
|
||||
|
||||
@@ -36,6 +36,9 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
|
||||
m = (val & fd->mmask) >> fd->mshift;
|
||||
n = (val & fd->nmask) >> fd->nshift;
|
||||
|
||||
if (!n || !m)
|
||||
return parent_rate;
|
||||
|
||||
ret = (u64)parent_rate * m;
|
||||
do_div(ret, n);
|
||||
|
||||
|
||||
+17
-14
@@ -65,10 +65,12 @@ EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of this clock's parent
|
||||
* @gpiod: gpio descriptor to gate this clock
|
||||
* @gpio: gpio number to gate this clock
|
||||
* @active_low: true if gpio should be set to 0 to enable clock
|
||||
* @flags: clock flags
|
||||
*/
|
||||
struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
|
||||
const char *parent_name, struct gpio_desc *gpiod,
|
||||
const char *parent_name, unsigned gpio, bool active_low,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct clk_gpio *clk_gpio = NULL;
|
||||
@@ -77,20 +79,19 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
|
||||
unsigned long gpio_flags;
|
||||
int err;
|
||||
|
||||
if (gpiod_is_active_low(gpiod))
|
||||
gpio_flags = GPIOF_OUT_INIT_HIGH;
|
||||
if (active_low)
|
||||
gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_HIGH;
|
||||
else
|
||||
gpio_flags = GPIOF_OUT_INIT_LOW;
|
||||
|
||||
if (dev)
|
||||
err = devm_gpio_request_one(dev, desc_to_gpio(gpiod),
|
||||
gpio_flags, name);
|
||||
err = devm_gpio_request_one(dev, gpio, gpio_flags, name);
|
||||
else
|
||||
err = gpio_request_one(desc_to_gpio(gpiod), gpio_flags, name);
|
||||
err = gpio_request_one(gpio, gpio_flags, name);
|
||||
|
||||
if (err) {
|
||||
pr_err("%s: %s: Error requesting clock control gpio %u\n",
|
||||
__func__, name, desc_to_gpio(gpiod));
|
||||
__func__, name, gpio);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
|
||||
init.parent_names = (parent_name ? &parent_name : NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
|
||||
clk_gpio->gpiod = gpiod;
|
||||
clk_gpio->gpiod = gpio_to_desc(gpio);
|
||||
clk_gpio->hw.init = &init;
|
||||
|
||||
clk = clk_register(dev, &clk_gpio->hw);
|
||||
@@ -123,7 +124,8 @@ struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
|
||||
kfree(clk_gpio);
|
||||
|
||||
clk_register_gpio_gate_err:
|
||||
gpiod_put(gpiod);
|
||||
if (!dev)
|
||||
gpio_free(gpio);
|
||||
|
||||
return clk;
|
||||
}
|
||||
@@ -149,8 +151,8 @@ static struct clk *of_clk_gpio_gate_delayed_register_get(
|
||||
struct clk *clk;
|
||||
const char *clk_name = data->node->name;
|
||||
const char *parent_name;
|
||||
struct gpio_desc *gpiod;
|
||||
int gpio;
|
||||
enum of_gpio_flags of_flags;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
@@ -159,7 +161,8 @@ static struct clk *of_clk_gpio_gate_delayed_register_get(
|
||||
return data->clk;
|
||||
}
|
||||
|
||||
gpio = of_get_named_gpio_flags(data->node, "enable-gpios", 0, NULL);
|
||||
gpio = of_get_named_gpio_flags(data->node, "enable-gpios", 0,
|
||||
&of_flags);
|
||||
if (gpio < 0) {
|
||||
mutex_unlock(&data->lock);
|
||||
if (gpio != -EPROBE_DEFER)
|
||||
@@ -167,11 +170,11 @@ static struct clk *of_clk_gpio_gate_delayed_register_get(
|
||||
__func__, clk_name);
|
||||
return ERR_PTR(gpio);
|
||||
}
|
||||
gpiod = gpio_to_desc(gpio);
|
||||
|
||||
parent_name = of_clk_get_parent_name(data->node, 0);
|
||||
|
||||
clk = clk_register_gpio_gate(NULL, clk_name, parent_name, gpiod, 0);
|
||||
clk = clk_register_gpio_gate(NULL, clk_name, parent_name, gpio,
|
||||
of_flags & OF_GPIO_ACTIVE_LOW, 0);
|
||||
if (IS_ERR(clk)) {
|
||||
mutex_unlock(&data->lock);
|
||||
return clk;
|
||||
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
|
||||
* Copyright (C) 2015 Linaro Ltd.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/topology.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <soc/mb86s7x/scb_mhu.h>
|
||||
|
||||
#define to_crg_clk(p) container_of(p, struct crg_clk, hw)
|
||||
#define to_clc_clk(p) container_of(p, struct cl_clk, hw)
|
||||
|
||||
struct mb86s7x_peri_clk {
|
||||
u32 payload_size;
|
||||
u32 cntrlr;
|
||||
u32 domain;
|
||||
u32 port;
|
||||
u32 en;
|
||||
u64 frequency;
|
||||
} __packed __aligned(4);
|
||||
|
||||
struct hack_rate {
|
||||
unsigned clk_id;
|
||||
unsigned long rate;
|
||||
int gated;
|
||||
};
|
||||
|
||||
struct crg_clk {
|
||||
struct clk_hw hw;
|
||||
u8 cntrlr, domain, port;
|
||||
};
|
||||
|
||||
static int crg_gate_control(struct clk_hw *hw, int en)
|
||||
{
|
||||
struct crg_clk *crgclk = to_crg_clk(hw);
|
||||
struct mb86s7x_peri_clk cmd;
|
||||
int ret;
|
||||
|
||||
cmd.payload_size = sizeof(cmd);
|
||||
cmd.cntrlr = crgclk->cntrlr;
|
||||
cmd.domain = crgclk->domain;
|
||||
cmd.port = crgclk->port;
|
||||
cmd.en = en;
|
||||
|
||||
/* Port is UngatedCLK */
|
||||
if (cmd.port == 8)
|
||||
return en ? 0 : -EINVAL;
|
||||
|
||||
pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n",
|
||||
__func__, __LINE__, cmd.cntrlr,
|
||||
cmd.domain, cmd.port, cmd.en);
|
||||
|
||||
ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ,
|
||||
&cmd, sizeof(cmd));
|
||||
if (ret < 0) {
|
||||
pr_err("%s:%d failed!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n",
|
||||
__func__, __LINE__, cmd.cntrlr,
|
||||
cmd.domain, cmd.port, cmd.en);
|
||||
|
||||
/* If the request was rejected */
|
||||
if (cmd.en != en)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int crg_port_prepare(struct clk_hw *hw)
|
||||
{
|
||||
return crg_gate_control(hw, 1);
|
||||
}
|
||||
|
||||
static void crg_port_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
crg_gate_control(hw, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate)
|
||||
{
|
||||
struct crg_clk *crgclk = to_crg_clk(hw);
|
||||
struct mb86s7x_peri_clk cmd;
|
||||
int code, ret;
|
||||
|
||||
cmd.payload_size = sizeof(cmd);
|
||||
cmd.cntrlr = crgclk->cntrlr;
|
||||
cmd.domain = crgclk->domain;
|
||||
cmd.port = crgclk->port;
|
||||
cmd.frequency = *rate;
|
||||
|
||||
if (set) {
|
||||
code = CMD_PERI_CLOCK_RATE_SET_REQ;
|
||||
pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
|
||||
__func__, __LINE__, cmd.cntrlr,
|
||||
cmd.domain, cmd.port, cmd.frequency);
|
||||
} else {
|
||||
code = CMD_PERI_CLOCK_RATE_GET_REQ;
|
||||
pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n",
|
||||
__func__, __LINE__, cmd.cntrlr,
|
||||
cmd.domain, cmd.port);
|
||||
}
|
||||
|
||||
ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
|
||||
if (ret < 0) {
|
||||
pr_err("%s:%d failed!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (set)
|
||||
pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
|
||||
__func__, __LINE__, cmd.cntrlr,
|
||||
cmd.domain, cmd.port, cmd.frequency);
|
||||
else
|
||||
pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n",
|
||||
__func__, __LINE__, cmd.cntrlr,
|
||||
cmd.domain, cmd.port, cmd.frequency);
|
||||
|
||||
*rate = cmd.frequency;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
crg_port_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
unsigned long rate;
|
||||
|
||||
crg_rate_control(hw, 0, &rate);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static long
|
||||
crg_port_round_rate(struct clk_hw *hw,
|
||||
unsigned long rate, unsigned long *pr)
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int
|
||||
crg_port_set_rate(struct clk_hw *hw,
|
||||
unsigned long rate, unsigned long parent_rate)
|
||||
{
|
||||
return crg_rate_control(hw, 1, &rate);
|
||||
}
|
||||
|
||||
const struct clk_ops crg_port_ops = {
|
||||
.prepare = crg_port_prepare,
|
||||
.unprepare = crg_port_unprepare,
|
||||
.recalc_rate = crg_port_recalc_rate,
|
||||
.round_rate = crg_port_round_rate,
|
||||
.set_rate = crg_port_set_rate,
|
||||
};
|
||||
|
||||
struct mb86s70_crg11 {
|
||||
struct mutex lock; /* protects CLK populating and searching */
|
||||
};
|
||||
|
||||
static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data)
|
||||
{
|
||||
struct mb86s70_crg11 *crg11 = data;
|
||||
struct clk_init_data init;
|
||||
u32 cntrlr, domain, port;
|
||||
struct crg_clk *crgclk;
|
||||
struct clk *clk;
|
||||
char clkp[20];
|
||||
|
||||
if (clkspec->args_count != 3)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
cntrlr = clkspec->args[0];
|
||||
domain = clkspec->args[1];
|
||||
port = clkspec->args[2];
|
||||
|
||||
if (port > 7)
|
||||
snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain);
|
||||
else
|
||||
snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port);
|
||||
|
||||
mutex_lock(&crg11->lock);
|
||||
|
||||
clk = __clk_lookup(clkp);
|
||||
if (clk) {
|
||||
mutex_unlock(&crg11->lock);
|
||||
return clk;
|
||||
}
|
||||
|
||||
crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL);
|
||||
if (!crgclk) {
|
||||
mutex_unlock(&crg11->lock);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
init.name = clkp;
|
||||
init.num_parents = 0;
|
||||
init.ops = &crg_port_ops;
|
||||
init.flags = CLK_IS_ROOT;
|
||||
crgclk->hw.init = &init;
|
||||
crgclk->cntrlr = cntrlr;
|
||||
crgclk->domain = domain;
|
||||
crgclk->port = port;
|
||||
clk = clk_register(NULL, &crgclk->hw);
|
||||
if (IS_ERR(clk))
|
||||
pr_err("%s:%d Error!\n", __func__, __LINE__);
|
||||
else
|
||||
pr_debug("Registered %s\n", clkp);
|
||||
|
||||
clk_register_clkdev(clk, clkp, NULL);
|
||||
mutex_unlock(&crg11->lock);
|
||||
return clk;
|
||||
}
|
||||
|
||||
static void __init crg_port_init(struct device_node *node)
|
||||
{
|
||||
struct mb86s70_crg11 *crg11;
|
||||
|
||||
crg11 = kzalloc(sizeof(*crg11), GFP_KERNEL);
|
||||
if (!crg11)
|
||||
return;
|
||||
|
||||
mutex_init(&crg11->lock);
|
||||
|
||||
of_clk_add_provider(node, crg11_get, crg11);
|
||||
}
|
||||
CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-crg11", crg_port_init);
|
||||
|
||||
struct cl_clk {
|
||||
struct clk_hw hw;
|
||||
int cluster;
|
||||
};
|
||||
|
||||
struct mb86s7x_cpu_freq {
|
||||
u32 payload_size;
|
||||
u32 cluster_class;
|
||||
u32 cluster_id;
|
||||
u32 cpu_id;
|
||||
u64 frequency;
|
||||
};
|
||||
|
||||
static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get)
|
||||
{
|
||||
struct cl_clk *clc = to_clc_clk(hw);
|
||||
struct mb86s7x_cpu_freq cmd;
|
||||
int code, ret;
|
||||
|
||||
cmd.payload_size = sizeof(cmd);
|
||||
cmd.cluster_class = 0;
|
||||
cmd.cluster_id = clc->cluster;
|
||||
cmd.cpu_id = 0;
|
||||
cmd.frequency = *rate;
|
||||
|
||||
if (get)
|
||||
code = CMD_CPU_CLOCK_RATE_GET_REQ;
|
||||
else
|
||||
code = CMD_CPU_CLOCK_RATE_SET_REQ;
|
||||
|
||||
pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
|
||||
__func__, __LINE__, cmd.cluster_class,
|
||||
cmd.cluster_id, cmd.cpu_id, cmd.frequency);
|
||||
|
||||
ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
|
||||
if (ret < 0) {
|
||||
pr_err("%s:%d failed!\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
|
||||
__func__, __LINE__, cmd.cluster_class,
|
||||
cmd.cluster_id, cmd.cpu_id, cmd.frequency);
|
||||
|
||||
*rate = cmd.frequency;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
clc_recalc_rate(struct clk_hw *hw, unsigned long unused)
|
||||
{
|
||||
unsigned long rate;
|
||||
|
||||
mhu_cluster_rate(hw, &rate, 1);
|
||||
return rate;
|
||||
}
|
||||
|
||||
static long
|
||||
clc_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *unused)
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int
|
||||
clc_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long unused)
|
||||
{
|
||||
unsigned long res = rate;
|
||||
|
||||
mhu_cluster_rate(hw, &res, 0);
|
||||
|
||||
return (res == rate) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static struct clk_ops clk_clc_ops = {
|
||||
.recalc_rate = clc_recalc_rate,
|
||||
.round_rate = clc_round_rate,
|
||||
.set_rate = clc_set_rate,
|
||||
};
|
||||
|
||||
struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct cl_clk *clc;
|
||||
|
||||
clc = kzalloc(sizeof(*clc), GFP_KERNEL);
|
||||
if (!clc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clc->hw.init = &init;
|
||||
clc->cluster = topology_physical_package_id(cpu_dev->id);
|
||||
|
||||
init.name = dev_name(cpu_dev);
|
||||
init.ops = &clk_clc_ops;
|
||||
init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
|
||||
init.num_parents = 0;
|
||||
|
||||
return devm_clk_register(cpu_dev, &clc->hw);
|
||||
}
|
||||
|
||||
static int mb86s7x_clclk_of_init(void)
|
||||
{
|
||||
int cpu, ret = -ENODEV;
|
||||
struct device_node *np;
|
||||
struct clk *clk;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
|
||||
if (!np || !of_device_is_available(np))
|
||||
goto exit;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
struct device *cpu_dev = get_cpu_device(cpu);
|
||||
|
||||
if (!cpu_dev) {
|
||||
pr_err("failed to get cpu%d device\n", cpu);
|
||||
continue;
|
||||
}
|
||||
|
||||
clk = mb86s7x_clclk_register(cpu_dev);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("failed to register cpu%d clock\n", cpu);
|
||||
continue;
|
||||
}
|
||||
if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
|
||||
pr_err("failed to register cpu%d clock lookup\n", cpu);
|
||||
continue;
|
||||
}
|
||||
pr_debug("registered clk for %s\n", dev_name(cpu_dev));
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0);
|
||||
exit:
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
}
|
||||
module_init(mb86s7x_clclk_of_init);
|
||||
@@ -161,7 +161,7 @@ static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct of_device_id palmas_clks_of_match[] = {
|
||||
static const struct of_device_id palmas_clks_of_match[] = {
|
||||
{
|
||||
.compatible = "ti,palmas-clk32kg",
|
||||
.data = &palmas_of_clk32kg,
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Philipp Zabel, Pengutronix
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* PWM (mis)used as clock output
|
||||
*/
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
|
||||
struct clk_pwm {
|
||||
struct clk_hw hw;
|
||||
struct pwm_device *pwm;
|
||||
u32 fixed_rate;
|
||||
};
|
||||
|
||||
static inline struct clk_pwm *to_clk_pwm(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct clk_pwm, hw);
|
||||
}
|
||||
|
||||
static int clk_pwm_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pwm *clk_pwm = to_clk_pwm(hw);
|
||||
|
||||
return pwm_enable(clk_pwm->pwm);
|
||||
}
|
||||
|
||||
static void clk_pwm_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_pwm *clk_pwm = to_clk_pwm(hw);
|
||||
|
||||
pwm_disable(clk_pwm->pwm);
|
||||
}
|
||||
|
||||
static unsigned long clk_pwm_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_pwm *clk_pwm = to_clk_pwm(hw);
|
||||
|
||||
return clk_pwm->fixed_rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_pwm_ops = {
|
||||
.prepare = clk_pwm_prepare,
|
||||
.unprepare = clk_pwm_unprepare,
|
||||
.recalc_rate = clk_pwm_recalc_rate,
|
||||
};
|
||||
|
||||
static int clk_pwm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct clk_init_data init;
|
||||
struct clk_pwm *clk_pwm;
|
||||
struct pwm_device *pwm;
|
||||
const char *clk_name;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk_pwm = devm_kzalloc(&pdev->dev, sizeof(*clk_pwm), GFP_KERNEL);
|
||||
if (!clk_pwm)
|
||||
return -ENOMEM;
|
||||
|
||||
pwm = devm_pwm_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(pwm))
|
||||
return PTR_ERR(pwm);
|
||||
|
||||
if (!pwm->period) {
|
||||
dev_err(&pdev->dev, "invalid PWM period\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(node, "clock-frequency", &clk_pwm->fixed_rate))
|
||||
clk_pwm->fixed_rate = NSEC_PER_SEC / pwm->period;
|
||||
|
||||
if (pwm->period != NSEC_PER_SEC / clk_pwm->fixed_rate &&
|
||||
pwm->period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) {
|
||||
dev_err(&pdev->dev,
|
||||
"clock-frequency does not match PWM period\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = pwm_config(pwm, (pwm->period + 1) >> 1, pwm->period);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
clk_name = node->name;
|
||||
of_property_read_string(node, "clock-output-names", &clk_name);
|
||||
|
||||
init.name = clk_name;
|
||||
init.ops = &clk_pwm_ops;
|
||||
init.flags = CLK_IS_BASIC | CLK_IS_ROOT;
|
||||
init.num_parents = 0;
|
||||
|
||||
clk_pwm->pwm = pwm;
|
||||
clk_pwm->hw.init = &init;
|
||||
clk = devm_clk_register(&pdev->dev, &clk_pwm->hw);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
return of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
}
|
||||
|
||||
static int clk_pwm_remove(struct platform_device *pdev)
|
||||
{
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id clk_pwm_dt_ids[] = {
|
||||
{ .compatible = "pwm-clock" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clk_pwm_dt_ids);
|
||||
|
||||
static struct platform_driver clk_pwm_driver = {
|
||||
.probe = clk_pwm_probe,
|
||||
.remove = clk_pwm_remove,
|
||||
.driver = {
|
||||
.name = "pwm-clock",
|
||||
.of_match_table = of_match_ptr(clk_pwm_dt_ids),
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(clk_pwm_driver);
|
||||
|
||||
MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
|
||||
MODULE_DESCRIPTION("PWM clock driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -68,16 +68,16 @@ struct si5351_driver_data {
|
||||
struct si5351_hw_data *clkout;
|
||||
};
|
||||
|
||||
static const char const *si5351_input_names[] = {
|
||||
static const char * const si5351_input_names[] = {
|
||||
"xtal", "clkin"
|
||||
};
|
||||
static const char const *si5351_pll_names[] = {
|
||||
static const char * const si5351_pll_names[] = {
|
||||
"plla", "pllb", "vxco"
|
||||
};
|
||||
static const char const *si5351_msynth_names[] = {
|
||||
static const char * const si5351_msynth_names[] = {
|
||||
"ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7"
|
||||
};
|
||||
static const char const *si5351_clkout_names[] = {
|
||||
static const char * const si5351_clkout_names[] = {
|
||||
"clk0", "clk1", "clk2", "clk3", "clk4", "clk5", "clk6", "clk7"
|
||||
};
|
||||
|
||||
@@ -207,7 +207,7 @@ static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct regmap_config si5351_regmap_config = {
|
||||
static const struct regmap_config si5351_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
|
||||
Loaded 20 of 107 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user